From 657ed1c6da6efb7728ee7677528c1fda0c23e560 Mon Sep 17 00:00:00 2001 From: Tim Ruehsen Date: Mon, 3 Sep 2012 15:02:41 +0200 Subject: [PATCH] added support for MD5-sess authentication --- src/ChangeLog | 6 ++++++ src/http.c | 55 +++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index e425e7d..12bffb3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-09-03 Tim Ruehsen + + * (digest_authentication_encode): Add support for RFC 2617 + MD5-sess authentication algorithm. + Feature request and testing by Avinash + 2012-08-28 Tim Ruehsen * gnutls.c/ssl_check_certificate: deinit gnutls_x509_crt_t diff --git a/src/http.c b/src/http.c index 02988d2..eef2cea 100644 --- a/src/http.c +++ b/src/http.c @@ -3657,7 +3657,7 @@ digest_authentication_encode (const char *au, const char *user, const char *passwd, const char *method, const char *path) { - static char *realm, *opaque, *nonce, *qop; + static char *realm, *opaque, *nonce, *qop, *algorithm; static struct { const char *name; char **variable; @@ -3665,15 +3665,17 @@ digest_authentication_encode (const char *au, const char *user, { "realm", &realm }, { "opaque", &opaque }, { "nonce", &nonce }, - { "qop", &qop } + { "qop", &qop }, + { "algorithm", &algorithm } }; char cnonce[16] = ""; char *res; + int res_len; size_t res_size; param_token name, value; - realm = opaque = nonce = qop = NULL; + realm = opaque = nonce = qop = algorithm = NULL; au += 6; /* skip over `Digest' */ while (extract_param (&au, &name, &value, ',')) @@ -3696,12 +3698,19 @@ digest_authentication_encode (const char *au, const char *user, user = NULL; /* force freeing mem and return */ } + if (algorithm != NULL && strcmp(algorithm,"MD5") && strcmp(algorithm,"MD5-sess")) + { + logprintf (LOG_NOTQUIET, _("Unsupported algorithm '%s'.\n"), algorithm); + user = NULL; /* force freeing mem and return */ + } + if (!realm || !nonce || !user || !passwd || !path || !method) { xfree_null (realm); xfree_null (opaque); xfree_null (nonce); xfree_null (qop); + xfree_null (algorithm); return NULL; } @@ -3720,8 +3729,26 @@ digest_authentication_encode (const char *au, const char *user, md5_process_bytes ((unsigned char *)":", 1, &ctx); md5_process_bytes ((unsigned char *)passwd, strlen (passwd), &ctx); md5_finish_ctx (&ctx, hash); + dump_hash (a1buf, hash); + if (!strcmp(algorithm, "MD5-sess")) + { + /* A1BUF = H( H(user ":" realm ":" password) ":" nonce ":" cnonce ) */ + snprintf(cnonce, sizeof(cnonce), "%08x", random_number(INT_MAX)); + + md5_init_ctx (&ctx); + // md5_process_bytes (hash, MD5_DIGEST_SIZE, &ctx); + md5_process_bytes (a1buf, MD5_DIGEST_SIZE * 2, &ctx); + md5_process_bytes ((unsigned char *)":", 1, &ctx); + md5_process_bytes ((unsigned char *)nonce, strlen (nonce), &ctx); + md5_process_bytes ((unsigned char *)":", 1, &ctx); + md5_process_bytes ((unsigned char *)cnonce, strlen (cnonce), &ctx); + md5_finish_ctx (&ctx, hash); + + dump_hash (a1buf, hash); + } + /* A2BUF = H(method ":" path) */ md5_init_ctx (&ctx); md5_process_bytes ((unsigned char *)method, strlen (method), &ctx); @@ -3730,11 +3757,12 @@ digest_authentication_encode (const char *au, const char *user, md5_finish_ctx (&ctx, hash); dump_hash (a2buf, hash); - if (!strcmp(qop,"auth")) + if (!strcmp(qop,"auth") || !strcmp(qop,"auth-int")) { /* RFC 2617 Digest Access Authentication */ /* generate random hex string */ - snprintf(cnonce, sizeof(cnonce), "%08x", random_number(INT_MAX)); + if (!*cnonce) + snprintf(cnonce, sizeof(cnonce), "%08x", random_number(INT_MAX)); /* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" noncecount ":" clientnonce ":" qop ": " A2BUF) */ md5_init_ctx (&ctx); @@ -3767,20 +3795,21 @@ digest_authentication_encode (const char *au, const char *user, dump_hash (response_digest, hash); res_size = strlen (user) - + strlen (user) + strlen (realm) + strlen (nonce) + strlen (path) + 2 * MD5_DIGEST_SIZE /*strlen (response_digest)*/ + (opaque ? strlen (opaque) : 0) + + (algorithm ? strlen (algorithm) : 0) + (qop ? 128: 0) + + strlen (cnonce) + 128; res = xmalloc (res_size); if (!strcmp(qop,"auth")) { - snprintf (res, res_size, "Digest "\ + res_len = snprintf (res, res_size, "Digest "\ "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\""\ ", qop=auth, nc=00000001, cnonce=\"%s\"", user, realm, nonce, path, response_digest, cnonce); @@ -3788,17 +3817,19 @@ digest_authentication_encode (const char *au, const char *user, } else { - snprintf (res, res_size, "Digest "\ + res_len = snprintf (res, res_size, "Digest "\ "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"", user, realm, nonce, path, response_digest); } if (opaque) { - char *p = res + strlen (res); - strcat (p, ", opaque=\""); - strcat (p, opaque); - strcat (p, "\""); + res_len += snprintf(res + res_len, res_size - res_len, ", opaque=\"%s\"", opaque); + } + + if (algorithm) + { + snprintf(res + res_len, res_size - res_len, ", algorithm=\"%s\"", algorithm); } } return res; -- 1.7.10.4