¿Límite en las líneas de módulo en el archivo OpenSSH / etc / ssh / moduli?

2

Entiendo que el servidor OpenSSH busca en /etc/ssh/moduli y selecciona un módulo al azar para cada intercambio de grupo de Diffie-Hellman. Lo que me pregunto es si existe un límite práctico sobre cuántas líneas de módulo puede haber en ese archivo.

¿Un número absurdamente grande, como 50,000 líneas, plantearía un problema o crearía un comportamiento extraño?

    
pregunta OpenSSH Question 18.11.2017 - 21:38
fuente

1 respuesta

1

Muy probablemente 4294967295.

En el archivo fuente dh.c , el archivo de módulo se abre con fopen , y se usa un bucle fgets para extraer cada línea. La línea actual que se procesa se registra en una variable declarada como int linenum . Esto significa que es un entero con signo de 32 bits, capaz de representar 2 valores posibles de 32 . Dado que está firmado, esto equivale a -2147483648 a 2147483647 (uno menos porque 0 sigue siendo un número y se considera positivo). Dado que comienza en 0 e incrementa, el valor máximo es, por lo tanto, 2 32 / 2 - 1. Se convertirá en negativo si supera este límite y se envuelve.

Hay alguna conversión entre firmado y sin firmar en el código fuente. int linenum contiene el número de líneas, mientras que int bestcount tiene el número de líneas adecuadas y se pasa a arc4random_uniform , que genera un valor aleatorio entre 0 y bestcount . El valor que acepta y el valor que devuelve no está firmado, pero se almacena en otro entero con signo, which . Ese entero se usa para especificar qué línea aleatoria se va a usar. Si el número de líneas supera lo que puede contener un entero de 32 bits, la elección aleatoria del límite superior de la línea será más pequeña, quizás mucho más pequeña, que el número real de líneas.

Esta limitación no es un problema en la práctica. ¡La longitud máxima de una línea es 4096 bytes y 2 líneas 32 (no - 1 porque la primera línea comienza en 0) de 4096 bytes cada una da un tamaño máximo de archivo de 16 terabytes! Buena suerte esperando a openssl dhparam para generar terabytes de módulos.

Toda la función en el código fuente, a partir de OpenSSH 7.5p1:

DH *
choose_dh(int min, int wantbits, int max)
{
    FILE *f;
    char line[4096];
    int best, bestcount, which;
    int linenum;
    struct dhgroup dhg;

    if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
        logit("WARNING: could not open %s (%s), using fixed modulus",
            _PATH_DH_MODULI, strerror(errno));
        return (dh_new_group_fallback(max));
    }

    linenum = 0;
    best = bestcount = 0;
    while (fgets(line, sizeof(line), f)) {
        linenum++;
        if (!parse_prime(linenum, line, &dhg))
            continue;
        BN_clear_free(dhg.g);
        BN_clear_free(dhg.p);

        if (dhg.size > max || dhg.size < min)
            continue;

        if ((dhg.size > wantbits && dhg.size < best) ||
            (dhg.size > best && best < wantbits)) {
            best = dhg.size;
            bestcount = 0;
        }
        if (dhg.size == best)
            bestcount++;
    }
    rewind(f);

    if (bestcount == 0) {
        fclose(f);
        logit("WARNING: no suitable primes in %s", _PATH_DH_MODULI);
        return (dh_new_group_fallback(max));
    }

    linenum = 0;
    which = arc4random_uniform(bestcount);
    while (fgets(line, sizeof(line), f)) {
        if (!parse_prime(linenum, line, &dhg))
            continue;
        if ((dhg.size > max || dhg.size < min) ||
            dhg.size != best ||
            linenum++ != which) {
            BN_clear_free(dhg.g);
            BN_clear_free(dhg.p);
            continue;
        }
        break;
    }
    fclose(f);
    if (linenum != which+1) {
        logit("WARNING: line %d disappeared in %s, giving up",
            which, _PATH_DH_MODULI);
        return (dh_new_group_fallback(max));
    }

    return (dh_new_group(dhg.g, dhg.p));
}

Tenga en cuenta que todo esto se debe a un rápido vistazo al código fuente. Si hay otros problemas que pueden ocurrir en la línea por razones que no puedo predecir causadas por un archivo grande, el límite superior puede ser menor. Sin embargo, no veo ninguna razón para pensar que sería.

    
respondido por el guest 19.11.2017 - 02:51
fuente

Lea otras preguntas en las etiquetas