Exemple #1
0
static char *make_nonce(const struct timeval *tv)
{
    char *buf = NULL;
    size_t size = 0, offset = 0;
    MD5_CTX md5;
    unsigned char hashbuf[MD5_DIGEST_LENGTH];
    char hash_hex[MD5_DIGEST_LENGTH * 2 + 1];
    char time_buf[32];

    /* Crash if someone forgot to call http_digest_init_secret. */
    if (!secret_initialized)
        bye("Server secret not initialized for Digest authentication. Call http_digest_init_secret.");

    Snprintf(time_buf, sizeof(time_buf), "%lu.%06lu",
        (long unsigned) tv->tv_sec, (long unsigned) tv->tv_usec);

    MD5_Init(&md5);
    MD5_Update(&md5, secret, sizeof(secret));
    MD5_Update(&md5, ":", 1);
    MD5_Update(&md5, time_buf, strlen(time_buf));
    MD5_Final(hashbuf, &md5);
    enhex(hash_hex, hashbuf, sizeof(hashbuf));

    strbuf_sprintf(&buf, &size, &offset, "%s-%s", time_buf, hash_hex);

    return buf;
}
Exemple #2
0
/* Arguments are assumed to be non-NULL, with the exception of nc and cnonce,
   which may be garbage only if qop == QOP_NONE. */
static void make_response(char buf[MD5_DIGEST_LENGTH * 2 + 1],
    const char *username, const char *realm, const char *password,
    const char *method, const char *uri, const char *nonce,
    enum http_digest_qop qop, const char *nc, const char *cnonce)
{
    char HA1_hex[MD5_DIGEST_LENGTH * 2 + 1], HA2_hex[MD5_DIGEST_LENGTH * 2 + 1];
    unsigned char hashbuf[MD5_DIGEST_LENGTH];
    MD5_CTX md5;

    /* Calculate H(A1). */
    MD5_Init(&md5);
    MD5_Update(&md5, username, strlen(username));
    MD5_Update(&md5, ":", 1);
    MD5_Update(&md5, realm, strlen(realm));
    MD5_Update(&md5, ":", 1);
    MD5_Update(&md5, password, strlen(password));
    MD5_Final(hashbuf, &md5);
    enhex(HA1_hex, hashbuf, sizeof(hashbuf));

    /* Calculate H(A2). */
    MD5_Init(&md5);
    MD5_Update(&md5, method, strlen(method));
    MD5_Update(&md5, ":", 1);
    MD5_Update(&md5, uri, strlen(uri));
    MD5_Final(hashbuf, &md5);
    enhex(HA2_hex, hashbuf, sizeof(hashbuf));

    /* Calculate response. */
    MD5_Init(&md5);
    MD5_Update(&md5, HA1_hex, strlen(HA1_hex));
    MD5_Update(&md5, ":", 1);
    MD5_Update(&md5, nonce, strlen(nonce));
    if (qop == QOP_AUTH) {
        MD5_Update(&md5, ":", 1);
        MD5_Update(&md5, nc, strlen(nc));
        MD5_Update(&md5, ":", 1);
        MD5_Update(&md5, cnonce, strlen(cnonce));
        MD5_Update(&md5, ":", 1);
        MD5_Update(&md5, "auth", strlen("auth"));
    }
    MD5_Update(&md5, ":", 1);
    MD5_Update(&md5, HA2_hex, strlen(HA2_hex));
    MD5_Final(hashbuf, &md5);

    enhex(buf, hashbuf, sizeof(hashbuf));
}
Exemple #3
0
void
hexdump(
    char *desc,
    void *addr,
    int len
    )
{
#define BYTE_LEN        (16)
// each byte is two characters (00-FF), plus the whitespace inbetween (BYTE_LEN
// - 1 spaces)
#define BYTE_LEN_HEXED  (BYTE_LEN*2 + BYTE_LEN - 1)

    int i, isZero, beenZero, byte_len, hex_len;
    unsigned char bytes[BYTE_LEN+1], hexed[BYTE_LEN_HEXED+1];
    unsigned char *pc = (unsigned char*)addr;

    if (desc != NULL) {
        printf("%s:\n", desc);
    }

    beenZero = 0;
    for (i = 0; i < len; i += byte_len) {
        hex_len = BYTE_LEN_HEXED;
        byte_len = MIN(BYTE_LEN, len - i);

        hexed[0] = '\0';
        memcpy(bytes, &pc[i], byte_len);
        isZero = all_zero(bytes, byte_len);
        enhex(hexed, hex_len, bytes, byte_len);
        asciify(bytes, byte_len);

        if (!isZero) {
            beenZero = 0;
        }

        if (!beenZero) {
            hexed[hex_len] = '\0';
            bytes[byte_len] = '\0';
            printf("%04x  %-*s  %*s\n", i, hex_len, hexed, byte_len, bytes);

            if (isZero) {
                beenZero = 1;
                printf("*\n");
            }
        }
    }
    printf("%04x\n", i);
}
Exemple #4
0
char *http_digest_proxy_authorization(const struct http_challenge *challenge,
    const char *username, const char *password,
    const char *method, const char *uri)
{
    /* For now we authenticate successfully at most once, so we don't need a
       varying client nonce count. */
    static const u32 nc = 0x00000001;

    char response_hex[MD5_DIGEST_LENGTH * 2 + 1];
    unsigned char cnonce[CNONCE_LENGTH];
    char cnonce_buf[CNONCE_LENGTH * 2 + 1];
    char nc_buf[8 + 1];
    char *buf = NULL;
    size_t size = 0, offset = 0;
    enum http_digest_qop qop;

    if (challenge->scheme != AUTH_DIGEST || challenge->realm == NULL
        || challenge->digest.nonce == NULL
        || challenge->digest.algorithm != ALGORITHM_MD5)
        return NULL;

    if (challenge->digest.qop & QOP_AUTH) {
        Snprintf(nc_buf, sizeof(nc_buf), "%08x", nc);
        if (!RAND_status())
            return NULL;
        if (RAND_bytes(cnonce, sizeof(cnonce)) != 1)
            return NULL;
        enhex(cnonce_buf, cnonce, sizeof(cnonce));
        qop = QOP_AUTH;
    } else {
        qop = QOP_NONE;
    }

    strbuf_append_str(&buf, &size, &offset, " Digest");
    strbuf_append_str(&buf, &size, &offset, " username="******", realm=");
    append_quoted_string(&buf, &size, &offset, challenge->realm);
    strbuf_append_str(&buf, &size, &offset, ", nonce=");
    append_quoted_string(&buf, &size, &offset, challenge->digest.nonce);
    strbuf_append_str(&buf, &size, &offset, ", uri=");
    append_quoted_string(&buf, &size, &offset, uri);

    if (qop == QOP_AUTH) {
        strbuf_append_str(&buf, &size, &offset, ", qop=auth");
        strbuf_append_str(&buf, &size, &offset, ", cnonce=");
        append_quoted_string(&buf, &size, &offset, cnonce_buf);
        strbuf_sprintf(&buf, &size, &offset, ", nc=%s", nc_buf);
    }

    make_response(response_hex, username, challenge->realm, password,
        method, uri, challenge->digest.nonce, qop, nc_buf, cnonce_buf);
    strbuf_append_str(&buf, &size, &offset, ", response=");
    append_quoted_string(&buf, &size, &offset, response_hex);

    if (challenge->digest.opaque != NULL) {
        strbuf_append_str(&buf, &size, &offset, ", opaque=");
        append_quoted_string(&buf, &size, &offset, challenge->digest.opaque);
    }

    strbuf_append_str(&buf, &size, &offset, "\r\n");

    return buf;
}