gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r35838 - in libmicrohttpd: . src/microhttpd src/testcurl


From: gnunet
Subject: [GNUnet-SVN] r35838 - in libmicrohttpd: . src/microhttpd src/testcurl
Date: Fri, 29 May 2015 12:20:53 +0200

Author: grothoff
Date: 2015-05-29 12:20:53 +0200 (Fri, 29 May 2015)
New Revision: 35838

Modified:
   libmicrohttpd/ChangeLog
   libmicrohttpd/src/microhttpd/digestauth.c
   libmicrohttpd/src/testcurl/test_digestauth.c
Log:
fix digest authentication with escaped urls, as reported on mailinglist

Modified: libmicrohttpd/ChangeLog
===================================================================
--- libmicrohttpd/ChangeLog     2015-05-28 19:32:22 UTC (rev 35837)
+++ libmicrohttpd/ChangeLog     2015-05-29 10:20:53 UTC (rev 35838)
@@ -1,3 +1,7 @@
+Fri May 29 12:23:01 CEST 2015
+       Fixing digest authentication when used in combination
+       with escaped characters in URLs. -CG/AW
+
 Wed May 13 11:49:09 CEST 2015
        Releasing libmicrohttpd 0.9.42. -CG
 

Modified: libmicrohttpd/src/microhttpd/digestauth.c
===================================================================
--- libmicrohttpd/src/microhttpd/digestauth.c   2015-05-28 19:32:22 UTC (rev 
35837)
+++ libmicrohttpd/src/microhttpd/digestauth.c   2015-05-29 10:20:53 UTC (rev 
35838)
@@ -1,6 +1,6 @@
 /*
      This file is part of libmicrohttpd
-     Copyright (C) 2010, 2011, 2012 Daniel Pittman and Christian Grothoff
+     Copyright (C) 2010, 2011, 2012, 2015 Daniel Pittman and Christian Grothoff
 
      This library is free software; you can redistribute it and/or
      modify it under the terms of the GNU Lesser General Public
@@ -472,8 +472,8 @@
  *
  * @param connection connections with headers to compare against
  * @param args argument URI string (after "?" in URI)
- * @return MHD_YES if the arguments match,
- *         MHD_NO if not
+ * @return #MHD_YES if the arguments match,
+ *         #MHD_NO if not
  */
 static int
 check_argument_match (struct MHD_Connection *connection,
@@ -632,10 +632,83 @@
        header value. */
     return MHD_NO;
   }
+  /* 8 = 4 hexadecimal numbers for the timestamp */
+  nonce_time = strtoul (nonce + len - 8, (char **)NULL, 16);
+  t = (uint32_t) MHD_monotonic_time();
+  /*
+   * First level vetting for the nonce validity: if the timestamp
+   * attached to the nonce exceeds `nonce_timeout', then the nonce is
+   * invalid.
+   */
+  if ( (t > nonce_time + nonce_timeout) ||
+       (nonce_time + nonce_timeout < nonce_time) )
+    {
+      /* too old */
+      return MHD_INVALID_NONCE;
+    }
+
+  calculate_nonce (nonce_time,
+                   connection->method,
+                   connection->daemon->digest_auth_random,
+                   connection->daemon->digest_auth_rand_size,
+                   connection->url,
+                   realm,
+                   noncehashexp);
+  /*
+   * Second level vetting for the nonce validity
+   * if the timestamp attached to the nonce is valid
+   * and possibly fabricated (in case of an attack)
+   * the attacker must also know the random seed to be
+   * able to generate a "sane" nonce, which if he does
+   * not, the nonce fabrication process going to be
+   * very hard to achieve.
+   */
+
+  if (0 != strcmp (nonce, noncehashexp))
+    {
+      return MHD_INVALID_NONCE;
+    }
+  if ( (0 == lookup_sub_value (cnonce,
+                               sizeof (cnonce),
+                               header, "cnonce")) ||
+       (0 == lookup_sub_value (qop, sizeof (qop), header, "qop")) ||
+       ( (0 != strcmp (qop, "auth")) &&
+         (0 != strcmp (qop, "")) ) ||
+       (0 == lookup_sub_value (nc, sizeof (nc), header, "nc"))  ||
+       (0 == lookup_sub_value (response, sizeof (response), header, 
"response")) )
+    {
+#if HAVE_MESSAGES
+      MHD_DLOG (connection->daemon,
+               "Authentication failed, invalid format.\n");
+#endif
+      return MHD_NO;
+    }
+  nci = strtoul (nc, &end, 16);
+  if ( ('\0' != *end) ||
+       ( (LONG_MAX == nci) &&
+         (ERANGE == errno) ) )
+    {
+#if HAVE_MESSAGES
+      MHD_DLOG (connection->daemon,
+               "Authentication failed, invalid format.\n");
+#endif
+      return MHD_NO; /* invalid nonce format */
+    }
+  /*
+   * Checking if that combination of nonce and nc is sound
+   * and not a replay attack attempt. Also adds the nonce
+   * to the nonce-nc map if it does not exist there.
+   */
+
+  if (MHD_YES != check_nonce_nc (connection, nonce, nci))
+    {
+      return MHD_NO;
+    }
+
   {
     char *uri;
-    
-    uri = malloc(left + 1);
+
+    uri = malloc (left + 1);
     if (NULL == uri)
     {
 #if HAVE_MESSAGES
@@ -648,24 +721,31 @@
                                left + 1,
                                header, "uri"))
     {
-      free(uri);
+      free (uri);
       return MHD_NO;
     }
 
-    /* 8 = 4 hexadecimal numbers for the timestamp */
-    nonce_time = strtoul (nonce + len - 8, (char **)NULL, 16);
-    t = (uint32_t) MHD_monotonic_time();
-    /*
-     * First level vetting for the nonce validity: if the timestamp
-     * attached to the nonce exceeds `nonce_timeout', then the nonce is
-     * invalid.
-     */
-    if ( (t > nonce_time + nonce_timeout) ||
-        (nonce_time + nonce_timeout < nonce_time) )
-    { 
-      free(uri);
-      return MHD_INVALID_NONCE;
-    }
+    digest_calc_ha1("md5",
+                   username,
+                   realm,
+                   password,
+                   nonce,
+                   cnonce,
+                   ha1);
+    digest_calc_response (ha1,
+                         nonce,
+                         nc,
+                         cnonce,
+                         qop,
+                         connection->method,
+                         uri,
+                         hentity,
+                         respexp);
+
+    /* Need to unescape URI before comparing with connection->url */
+    connection->daemon->unescape_callback 
(connection->daemon->unescape_callback_cls,
+                                           connection,
+                                           uri);
     if (0 != strncmp (uri,
                      connection->url,
                      strlen (connection->url)))
@@ -674,9 +754,10 @@
       MHD_DLOG (connection->daemon,
                "Authentication failed, URI does not match.\n");
 #endif
-      free(uri);
+      free (uri);
       return MHD_NO;
     }
+
     {
       const char *args = strchr (uri, '?');
 
@@ -692,89 +773,11 @@
        MHD_DLOG (connection->daemon,
                  "Authentication failed, arguments do not match.\n");
 #endif
-       free(uri);
+       free (uri);
        return MHD_NO;
       }
     }
-    calculate_nonce (nonce_time,
-                    connection->method,
-                    connection->daemon->digest_auth_random,
-                    connection->daemon->digest_auth_rand_size,
-                    connection->url,
-                    realm,
-                    noncehashexp);
-    /*
-     * Second level vetting for the nonce validity
-     * if the timestamp attached to the nonce is valid
-     * and possibly fabricated (in case of an attack)
-     * the attacker must also know the random seed to be
-     * able to generate a "sane" nonce, which if he does
-     * not, the nonce fabrication process going to be
-     * very hard to achieve.
-     */
-
-    if (0 != strcmp (nonce, noncehashexp))
-    {
-      free(uri);
-      return MHD_INVALID_NONCE;
-    }
-    if ( (0 == lookup_sub_value (cnonce,
-                                sizeof (cnonce),
-                                header, "cnonce")) ||
-        (0 == lookup_sub_value (qop, sizeof (qop), header, "qop")) ||
-        ( (0 != strcmp (qop, "auth")) &&
-          (0 != strcmp (qop, "")) ) ||
-        (0 == lookup_sub_value (nc, sizeof (nc), header, "nc"))  ||
-        (0 == lookup_sub_value (response, sizeof (response), header, 
"response")) )
-    {
-#if HAVE_MESSAGES
-      MHD_DLOG (connection->daemon,
-               "Authentication failed, invalid format.\n");
-#endif
-      free(uri);
-      return MHD_NO;
-    }
-    nci = strtoul (nc, &end, 16);
-    if ( ('\0' != *end) ||
-        ( (LONG_MAX == nci) &&
-          (ERANGE == errno) ) )
-    {
-#if HAVE_MESSAGES
-      MHD_DLOG (connection->daemon,
-               "Authentication failed, invalid format.\n");
-#endif
-      free(uri);
-      return MHD_NO; /* invalid nonce format */
-    }
-    /*
-     * Checking if that combination of nonce and nc is sound
-     * and not a replay attack attempt. Also adds the nonce
-     * to the nonce-nc map if it does not exist there.
-     */
-
-    if (MHD_YES != check_nonce_nc (connection, nonce, nci))
-    {
-      free(uri);
-      return MHD_NO;
-    }
-
-    digest_calc_ha1("md5",
-                   username,
-                   realm,
-                   password,
-                   nonce,
-                   cnonce,
-                   ha1);
-    digest_calc_response (ha1,
-                         nonce,
-                         nc,
-                         cnonce,
-                         qop,
-                         connection->method,
-                         uri,
-                         hentity,
-                         respexp);
-    free(uri);
+    free (uri);
     return (0 == strcmp(response, respexp))
       ? MHD_YES
       : MHD_NO;
@@ -835,7 +838,7 @@
                   : "");
   {
     char *header;
-    
+
     header = malloc(hlen + 1);
     if (NULL == header)
     {

Modified: libmicrohttpd/src/testcurl/test_digestauth.c
===================================================================
--- libmicrohttpd/src/testcurl/test_digestauth.c        2015-05-28 19:32:22 UTC 
(rev 35837)
+++ libmicrohttpd/src/testcurl/test_digestauth.c        2015-05-29 10:20:53 UTC 
(rev 35838)
@@ -73,7 +73,8 @@
           const char *url,
           const char *method,
           const char *version,
-          const char *upload_data, size_t *upload_data_size,
+          const char *upload_data,
+          size_t *upload_data_size,
           void **unused)
 {
   struct MHD_Response *response;
@@ -82,44 +83,47 @@
   const char *realm = "address@hidden";
   int ret;
 
-  username = MHD_digest_auth_get_username(connection);
+  username = MHD_digest_auth_get_username (connection);
   if ( (username == NULL) ||
        (0 != strcmp (username, "testuser")) )
     {
-      response = MHD_create_response_from_buffer(strlen (DENIED), 
-                                                DENIED,
-                                                MHD_RESPMEM_PERSISTENT);  
+      response = MHD_create_response_from_buffer (strlen (DENIED),
+                                                  DENIED,
+                                                  MHD_RESPMEM_PERSISTENT);
       ret = MHD_queue_auth_fail_response(connection, realm,
                                         MY_OPAQUE,
                                         response,
-                                        MHD_NO);    
-      MHD_destroy_response(response);  
+                                        MHD_NO);
+      MHD_destroy_response(response);
       return ret;
     }
   ret = MHD_digest_auth_check(connection, realm,
-                             username, 
-                             password, 
+                             username,
+                             password,
                              300);
   free(username);
   if ( (ret == MHD_INVALID_NONCE) ||
        (ret == MHD_NO) )
     {
-      response = MHD_create_response_from_buffer(strlen (DENIED), 
+      response = MHD_create_response_from_buffer(strlen (DENIED),
                                                 DENIED,
-                                                MHD_RESPMEM_PERSISTENT);  
-      if (NULL == response) 
+                                                MHD_RESPMEM_PERSISTENT);
+      if (NULL == response)
        return MHD_NO;
       ret = MHD_queue_auth_fail_response(connection, realm,
                                         MY_OPAQUE,
                                         response,
-                                        (ret == MHD_INVALID_NONCE) ? MHD_YES : 
MHD_NO);  
-      MHD_destroy_response(response);  
+                                        (ret == MHD_INVALID_NONCE) ? MHD_YES : 
MHD_NO);
+      MHD_destroy_response(response);
       return ret;
     }
-  response = MHD_create_response_from_buffer(strlen(PAGE), PAGE,
-                                            MHD_RESPMEM_PERSISTENT);
-  ret = MHD_queue_response(connection, MHD_HTTP_OK, response);  
-  MHD_destroy_response(response);
+  response = MHD_create_response_from_buffer (strlen(PAGE),
+                                              PAGE,
+                                              MHD_RESPMEM_PERSISTENT);
+  ret = MHD_queue_response (connection,
+                            MHD_HTTP_OK,
+                            response);
+  MHD_destroy_response (response);
   return ret;
 }
 
@@ -144,24 +148,24 @@
   fd = open("/dev/urandom", O_RDONLY);
   if (-1 == fd)
     {
-         fprintf(stderr, "Failed to open `%s': %s\n",
-              "/dev/urandom",
-                  strerror(errno));
-         return 1;
-       }
+      fprintf(stderr, "Failed to open `%s': %s\n",
+              "/dev/urandom",
+              strerror(errno));
+      return 1;
+    }
   while (off < 8)
-       {
-         len = read(fd, rnd, 8);
-         if (len == -1)
-           {
-                 fprintf(stderr, "Failed to read `%s': %s\n",
-                      "/dev/urandom",
-                          strerror(errno));
-                 (void) close(fd);
-                 return 1;
-               }
-         off += len;
-       }
+    {
+      len = read(fd, rnd, 8);
+      if (len == -1)
+        {
+          fprintf(stderr, "Failed to read `%s': %s\n",
+                  "/dev/urandom",
+                  strerror(errno));
+          (void) close(fd);
+          return 1;
+        }
+      off += len;
+    }
   (void) close(fd);
 #else
   {
@@ -193,7 +197,7 @@
   if (d == NULL)
     return 1;
   c = curl_easy_init ();
-  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/";);
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/bar%20 
foo?a=bü%20");
   curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
   curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
   curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
@@ -225,7 +229,6 @@
 }
 
 
-
 int
 main (int argc, char *const *argv)
 {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]