]> sjero.net Git - wget/commitdiff
Added support for MD5-sess authentication
authorTim Ruehsen <tim.ruehsen@gmx.de>
Mon, 3 Sep 2012 13:02:41 +0000 (15:02 +0200)
committerGiuseppe Scrivano <gscrivano@gnu.org>
Sun, 25 Nov 2012 17:16:20 +0000 (18:16 +0100)
NEWS
src/ChangeLog
src/http.c

diff --git a/NEWS b/NEWS
index 0a4efd7a8a2fd340213462708b8a5aa845621238..93a74f31626a1fcdf32688595a009331262bf581 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ Please send GNU Wget bug reports to <bug-wget@gnu.org>.
 ** Support shorthand URLs in an input file.
 
 ** Fix -c with servers that don't specify a content-length.
+
+** Add support for MD5-SESS
 \f
 * Changes in Wget 1.14
 
index 7673778b256f9d8da14987178bb1e58befaa3656..0755541df979a3d1cbcd2b05c0f7035562b75177 100644 (file)
@@ -1,4 +1,11 @@
+2012-09-03  Tim Ruehsen  <tim.ruehsen@gmx.de>
+
+       * http.c (digest_authentication_encode): Add support for RFC 2617
+       MD5-sess authentication algorithm.
+       Feature request and testing by: Avinash <pavinash@gmail.com>
+
 2012-11-14  Ángel González  <keisial@gmail.com>
+
        * warc.c (warc_sha1_stream_with_payload): Fix compilation under
        gcc -std=c89.
 
index 588847486a5ea93dfe8adafed682663bbd59265f..fdb0d7e4b485ad3994ef84fce9fedd80630c6def 100644 (file)
@@ -3662,7 +3662,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;
@@ -3670,15 +3670,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, ','))
@@ -3701,12 +3703,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;
     }
 
@@ -3725,8 +3734,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);
@@ -3735,11 +3762,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);
@@ -3772,20 +3800,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);
@@ -3793,17 +3822,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;