gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] 01/09: Digest Auth API: do not store 'userhash' in 'user


From: gnunet
Subject: [libmicrohttpd] 01/09: Digest Auth API: do not store 'userhash' in 'username' members
Date: Sun, 11 Sep 2022 19:56:03 +0200

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit c3680cb737bcac2a4dc14cca5a80af6ca0de21e7
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Mon Sep 5 14:53:05 2022 +0300

    Digest Auth API: do not store 'userhash' in 'username' members
    
    While the 'username' is used to carry 'userhash' in headers, it is
    confusing as 'userhash' type of the data is different from type of
    the 'username'. To make a clear distinction, use dedicated members
    to store 'userhash'.
---
 src/include/microhttpd.h               | 79 +++++++++++++++++++++++++---------
 src/microhttpd/digestauth.c            | 54 +++++++++++++----------
 src/testcurl/test_digestauth2.c        | 62 ++++++++++++++++----------
 src/testcurl/test_digestauth_emu_ext.c |  8 ++++
 4 files changed, 138 insertions(+), 65 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 7b72dfa6..c545ecc3 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -96,7 +96,7 @@ extern "C"
  * they are parsed as decimal numbers.
  * Example: 0x01093001 = 1.9.30-1.
  */
-#define MHD_VERSION 0x00097536
+#define MHD_VERSION 0x00097537
 
 /* If generic headers don't work on your platform, include headers
    which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t',
@@ -4738,7 +4738,16 @@ MHD_digest_auth_calc_userhash_hex (enum 
MHD_DigestAuthAlgo3 algo3,
 /**
  * The type of username used by client in Digest Authorization header
  *
- * @note Available since #MHD_VERSION 0x00097519
+ * Values are sorted so simplified checks could be used.
+ * For example:
+ * * (value <= MHD_DIGEST_AUTH_UNAME_TYPE_INVALID) is true if not valid 
username
+ *   is provided by the client
+ * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH) is true if username is
+ *   provided in any form
+ * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD) is true if username is
+ *   provided in clear text (not userhash matching is needed)
+ *
+ * @note Available since #MHD_VERSION 0x00097537
  */
 enum MHD_DigestAuthUsernameType
 {
@@ -4751,7 +4760,7 @@ enum MHD_DigestAuthUsernameType
   /**
    * The 'username' parameter is used to specify the username.
    */
-  MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD = 1,
+  MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD = (1 << 2),
 
   /**
    * The username is specified by 'username*' parameter with
@@ -4759,14 +4768,14 @@ enum MHD_DigestAuthUsernameType
    * The only difference between standard and extended types is
    * the way how username value is encoded in the header.
    */
-  MHD_DIGEST_AUTH_UNAME_TYPE_EXTENDED = 2,
+  MHD_DIGEST_AUTH_UNAME_TYPE_EXTENDED = (1 << 3),
 
   /**
    * The username provided in form of 'userhash' as
    * specified by RFC 7616 #section-3.4.4.
    * @sa #MHD_digest_auth_calc_userhash_hex(), #MHD_digest_auth_calc_userhash()
    */
-  MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH = 3,
+  MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH = (1 << 1),
 
   /**
    * The invalid combination of username parameters are used by client.
@@ -4776,7 +4785,7 @@ enum MHD_DigestAuthUsernameType
    * * 'username*' used with invalid extended notation
    * * 'username' is not hexadecimal digits, while 'userhash' set to 'true'
    */
-  MHD_DIGEST_AUTH_UNAME_TYPE_INVALID = 15
+  MHD_DIGEST_AUTH_UNAME_TYPE_INVALID = (1 << 0)
 } _MHD_FIXED_ENUM;
 
 /**
@@ -4883,7 +4892,7 @@ enum MHD_DigestAuthMultiQOP
  *
  * Application may modify buffers as needed until #MHD_free() is called for
  * pointer to this structure
- * @note Available since #MHD_VERSION 0x00097533
+ * @note Available since #MHD_VERSION 0x00097537
  */
 struct MHD_DigestAuthInfo
 {
@@ -4902,14 +4911,12 @@ struct MHD_DigestAuthInfo
 
   /**
    * The username string.
-   * Valid only if username is standard, extended, or userhash.
-   * For userhash this is unqoted string without decoding of the
-   * hexadecimal digits (as provided by the client).
+   * Used only if username type is standard or extended, always NULL otherwise.
    * If extended notation is used, this string is pct-decoded string
    * with charset and language tag removed (i.e. it is original username
    * extracted from the extended notation).
-   * This can be NULL is username is missing or invalid.
-   * @sa #MHD_digest_auth_calc_userhash_hex()
+   * When userhash is used by the client, this member is NULL and
+   * @a userhash_hex is set.
    */
   char *username;
 
@@ -4919,12 +4926,28 @@ struct MHD_DigestAuthInfo
    */
   size_t username_len;
 
+  /**
+   * The userhash string.
+   * Valid only if username type is userhash.
+   * This is unqoted string without decoding of the hexadecimal
+   * digits (as provided by the client).
+   * @sa #MHD_digest_auth_calc_userhash_hex()
+   */
+  char *userhash_hex;
+
+  /**
+   * The length of the @a userhash_hex in characters.
+   * The valid size should be #MHD_digest_get_hash_size(algo3) * 2 characters.
+   * When the @a userhash_hex is NULL, this member is always zero.
+   */
+  size_t userhash_hex_len;
+
   /**
    * The userhash decoded to binary form.
    * Used only if username type is userhash, always NULL otherwise.
-   * When not NULL, this points to binary sequence @a username_len /2 bytes
+   * When not NULL, this points to binary sequence @a userhash_hex_len /2 bytes
    * long.
-   * The valid size should be #MHD_digest_get_hash_size(algo) bytes.
+   * The valid size should be #MHD_digest_get_hash_size(algo3) bytes.
    * @warning This is binary data, no zero termination.
    * @warning To avoid buffer overruns, always check the size of the data 
before
    *          use, because @a userhash_bin can point even to zero-sized
@@ -5007,7 +5030,7 @@ MHD_digest_auth_get_request_info3 (struct MHD_Connection 
*connection);
  *
  * Application may modify buffers as needed until #MHD_free() is called for
  * pointer to this structure
- * @note Available since #MHD_VERSION 0x00097534
+ * @note Available since #MHD_VERSION 0x00097537
  */
 struct MHD_DigestAuthUsernameInfo
 {
@@ -5028,12 +5051,12 @@ struct MHD_DigestAuthUsernameInfo
 
   /**
    * The username string.
-   * For userhash this is unqoted string without decoding of the
-   * hexadecimal digits (as provided by client).
+   * Used only if username type is standard or extended, always NULL otherwise.
    * If extended notation is used, this string is pct-decoded string
    * with charset and language tag removed (i.e. it is original username
    * extracted from the extended notation).
-   * @sa #MHD_digest_auth_calc_userhash_hex()
+   * When userhash is used by the client, this member is NULL and
+   * @a userhash_hex is set.
    */
   char *username;
 
@@ -5043,12 +5066,28 @@ struct MHD_DigestAuthUsernameInfo
    */
   size_t username_len;
 
+  /**
+   * The userhash string.
+   * Valid only if username type is userhash.
+   * This is unqoted string without decoding of the hexadecimal
+   * digits (as provided by the client).
+   * @sa #MHD_digest_auth_calc_userhash_hex()
+   */
+  char *userhash_hex;
+
+  /**
+   * The length of the @a userhash_hex in characters.
+   * The valid size should be #MHD_digest_get_hash_size(algo3) * 2 characters.
+   * When the @a userhash_hex is NULL, this member is always zero.
+   */
+  size_t userhash_hex_len;
+
   /**
    * The userhash decoded to binary form.
    * Used only if username type is userhash, always NULL otherwise.
-   * When not NULL, this points to binary sequence @a username_len /2 bytes
+   * When not NULL, this points to binary sequence @a userhash_hex_len /2 bytes
    * long.
-   * The valid size should be #MHD_digest_get_hash_size(algo) bytes.
+   * The valid size should be #MHD_digest_get_hash_size(algo3) bytes.
    * @warning This is binary data, no zero termination.
    * @warning To avoid buffer overruns, always check the size of the data 
before
    *          use, because @a userhash_bin can point even to zero-sized
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index fac3e280..d3f5f595 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -801,37 +801,47 @@ get_rq_uname (const struct MHD_RqDAuth *params,
   mhd_assert (MHD_DIGEST_AUTH_UNAME_TYPE_INVALID != uname_type);
   mhd_assert (MHD_DIGEST_AUTH_UNAME_TYPE_MISSING != uname_type);
 
-  if ( (MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD == uname_type) ||
-       (MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH == uname_type) )
+  uname_info->username = NULL;
+  uname_info->username_len = 0;
+  uname_info->userhash_hex = NULL;
+  uname_info->userhash_hex_len = 0;
+  uname_info->userhash_bin = NULL;
+
+  if (MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD == uname_type)
   {
     uname_info->username = (char *) (buf + buf_used);
     uname_info->username_len =
       get_rq_param_unquoted_copy_z (&params->username,
                                     uname_info->username);
     buf_used += uname_info->username_len + 1;
-    if (MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH == uname_type)
+    uname_info->uname_type = MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD;
+  }
+  else if (MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH == uname_type)
+  {
+    size_t res;
+
+    uname_info->userhash_hex = (char *) (buf + buf_used);
+    uname_info->userhash_hex_len =
+      get_rq_param_unquoted_copy_z (&params->username,
+                                    uname_info->userhash_hex);
+    buf_used += uname_info->userhash_hex_len + 1;
+    uname_info->userhash_bin = (uint8_t *) (buf + buf_used);
+    res = MHD_hex_to_bin (uname_info->userhash_hex,
+                          uname_info->userhash_hex_len,
+                          uname_info->userhash_bin);
+    if (res != uname_info->username_len / 2)
     {
-      size_t res;
-      uint8_t *const bin_data = (uint8_t *) (buf + buf_used);
-      res = MHD_hex_to_bin (uname_info->username,
-                            uname_info->username_len,
-                            bin_data);
-      if (res != uname_info->username_len / 2)
-      {
-        uname_info->userhash_bin = NULL;
-        uname_info->uname_type = MHD_DIGEST_AUTH_UNAME_TYPE_INVALID;
-      }
-      else
-      {
-        /* Avoid pointers outside allocated region when the size is zero */
-        uname_info->userhash_bin = (0 != res) ?
-                                   bin_data : (uint8_t *) uname_info->username;
-        uname_info->uname_type = MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH;
-        buf_used += res;
-      }
+      uname_info->userhash_bin = NULL;
+      uname_info->uname_type = MHD_DIGEST_AUTH_UNAME_TYPE_INVALID;
     }
     else
-      uname_info->uname_type = MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD;
+    {
+      /* Avoid pointers outside allocated region when the size is zero */
+      if (0 == res)
+        uname_info->userhash_bin = (uint8_t *) uname_info->username;
+      uname_info->uname_type = MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH;
+      buf_used += res;
+    }
   }
   else if (MHD_DIGEST_AUTH_UNAME_TYPE_EXTENDED == uname_type)
   {
diff --git a/src/testcurl/test_digestauth2.c b/src/testcurl/test_digestauth2.c
index f92d6d14..81a93b5e 100644
--- a/src/testcurl/test_digestauth2.c
+++ b/src/testcurl/test_digestauth2.c
@@ -476,8 +476,6 @@ ahc_echo (void *cls,
       enum MHD_DigestAuthResult check_res;
       enum MHD_DigestAuthResult expect_res;
 
-      if (NULL == dinfo->username)
-        mhdErrorExitDesc ("'username' is NULL");
       if (curl_uses_usehash)
       {
         if (MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH != dinfo->uname_type)
@@ -488,29 +486,33 @@ ahc_echo (void *cls,
                    (int) dinfo->uname_type);
           mhdErrorExitDesc ("Wrong 'uname_type'");
         }
-        else if (dinfo->username_len != userhash_hex_len)
+        else if (dinfo->userhash_hex_len != userhash_hex_len)
         {
-          fprintf (stderr, "'username_len' does not match.\n"
+          fprintf (stderr, "'userhash_hex_len' does not match.\n"
                    "Expected: %u\tRecieved: %u. ",
                    (unsigned) userhash_hex_len,
-                   (unsigned) dinfo->username_len);
-          mhdErrorExitDesc ("Wrong 'username_len'");
+                   (unsigned) dinfo->userhash_hex_len);
+          mhdErrorExitDesc ("Wrong 'userhash_hex_len'");
         }
-        else if (0 != memcmp (dinfo->username, userhash_hex,
-                              dinfo->username_len))
+        else if (0 != memcmp (dinfo->userhash_hex, userhash_hex,
+                              dinfo->userhash_hex_len))
         {
-          fprintf (stderr, "'username' does not match.\n"
+          fprintf (stderr, "'userhash_hex' does not match.\n"
                    "Expected: '%s'\tRecieved: '%.*s'. ",
                    userhash_hex,
-                   (int) dinfo->username_len,
-                   dinfo->username);
-          mhdErrorExitDesc ("Wrong 'username'");
+                   (int) dinfo->userhash_hex_len,
+                   dinfo->userhash_hex);
+          mhdErrorExitDesc ("Wrong 'userhash_hex'");
         }
         else if (NULL == dinfo->userhash_bin)
           mhdErrorExitDesc ("'userhash_bin' is NULL");
         else if (0 != memcmp (dinfo->userhash_bin, userhash_bin,
                               dinfo->username_len / 2))
           mhdErrorExitDesc ("Wrong 'userhash_bin'");
+        else if (NULL != dinfo->username)
+          mhdErrorExitDesc ("'username' is NOT NULL");
+        else if (0 != dinfo->username_len)
+          mhdErrorExitDesc ("'username_len' is NOT zero");
       }
       else
       {
@@ -522,6 +524,8 @@ ahc_echo (void *cls,
                    (int) dinfo->uname_type);
           mhdErrorExitDesc ("Wrong 'uname_type'");
         }
+        else if (NULL == dinfo->username)
+          mhdErrorExitDesc ("'username' is NULL");
         else if (dinfo->username_len != strlen (username_ptr))
         {
           fprintf (stderr, "'username_len' does not match.\n"
@@ -540,6 +544,10 @@ ahc_echo (void *cls,
                    dinfo->username);
           mhdErrorExitDesc ("Wrong 'username'");
         }
+        else if (NULL != dinfo->userhash_hex)
+          mhdErrorExitDesc ("'userhash_hex' is NOT NULL");
+        else if (0 != dinfo->userhash_hex_len)
+          mhdErrorExitDesc ("'userhash_hex_len' is NOT zero");
         else if (NULL != dinfo->userhash_bin)
           mhdErrorExitDesc ("'userhash_bin' is NOT NULL");
       }
@@ -620,8 +628,6 @@ ahc_echo (void *cls,
       uname = MHD_digest_auth_get_username3 (connection);
       if (NULL == uname)
         mhdErrorExitDesc ("MHD_digest_auth_get_username3() returned NULL");
-      else if (NULL == uname->username)
-        mhdErrorExitDesc ("'username' is NULL");
       if (curl_uses_usehash)
       {
         if (MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH != uname->uname_type)
@@ -632,29 +638,33 @@ ahc_echo (void *cls,
                    (int) uname->uname_type);
           mhdErrorExitDesc ("Wrong 'uname_type'");
         }
-        else if (uname->username_len != userhash_hex_len)
+        else if (uname->userhash_hex_len != userhash_hex_len)
         {
-          fprintf (stderr, "'username_len' does not match.\n"
+          fprintf (stderr, "'userhash_hex_len' does not match.\n"
                    "Expected: %u\tRecieved: %u. ",
                    (unsigned) userhash_hex_len,
-                   (unsigned) uname->username_len);
-          mhdErrorExitDesc ("Wrong 'username_len'");
+                   (unsigned) uname->userhash_hex_len);
+          mhdErrorExitDesc ("Wrong 'userhash_hex_len'");
         }
-        else if (0 != memcmp (uname->username, userhash_hex,
-                              uname->username_len))
+        else if (0 != memcmp (uname->userhash_hex, userhash_hex,
+                              uname->userhash_hex_len))
         {
           fprintf (stderr, "'username' does not match.\n"
                    "Expected: '%s'\tRecieved: '%.*s'. ",
                    userhash_hex,
-                   (int) uname->username_len,
-                   uname->username);
-          mhdErrorExitDesc ("Wrong 'username'");
+                   (int) uname->userhash_hex_len,
+                   uname->userhash_hex);
+          mhdErrorExitDesc ("Wrong 'userhash_hex'");
         }
         else if (NULL == uname->userhash_bin)
           mhdErrorExitDesc ("'userhash_bin' is NULL");
         else if (0 != memcmp (uname->userhash_bin, userhash_bin,
                               uname->username_len / 2))
           mhdErrorExitDesc ("Wrong 'userhash_bin'");
+        else if (NULL != uname->username)
+          mhdErrorExitDesc ("'username' is NOT NULL");
+        else if (0 != uname->username_len)
+          mhdErrorExitDesc ("'username_len' is NOT zero");
       }
       else
       {
@@ -666,6 +676,8 @@ ahc_echo (void *cls,
                    (int) uname->uname_type);
           mhdErrorExitDesc ("Wrong 'uname_type'");
         }
+        else if (NULL == uname->username)
+          mhdErrorExitDesc ("'username' is NULL");
         else if (uname->username_len != strlen (username_ptr))
         {
           fprintf (stderr, "'username_len' does not match.\n"
@@ -684,6 +696,10 @@ ahc_echo (void *cls,
                    uname->username);
           mhdErrorExitDesc ("Wrong 'username'");
         }
+        else if (NULL != uname->userhash_hex)
+          mhdErrorExitDesc ("'userhash_hex' is NOT NULL");
+        else if (0 != uname->userhash_hex_len)
+          mhdErrorExitDesc ("'userhash_hex_len' is NOT zero");
         else if (NULL != uname->userhash_bin)
           mhdErrorExitDesc ("'userhash_bin' is NOT NULL");
       }
diff --git a/src/testcurl/test_digestauth_emu_ext.c 
b/src/testcurl/test_digestauth_emu_ext.c
index fc4f4aaa..b3925d13 100644
--- a/src/testcurl/test_digestauth_emu_ext.c
+++ b/src/testcurl/test_digestauth_emu_ext.c
@@ -381,6 +381,10 @@ ahc_echo (void *cls,
                creds->username);
       mhdErrorExitDesc ("Wrong 'username'");
     }
+    else if (NULL != creds->userhash_hex)
+      mhdErrorExitDesc ("'userhash_hex' is NOT NULL");
+    else if (0 != creds->userhash_hex_len)
+      mhdErrorExitDesc ("'userhash_hex' is NOT zero");
     else if (NULL != creds->userhash_bin)
       mhdErrorExitDesc ("'userhash_bin' is NOT NULL");
     MHD_free (creds);
@@ -415,6 +419,10 @@ ahc_echo (void *cls,
                dinfo->username);
       mhdErrorExitDesc ("Wrong 'username'");
     }
+    else if (NULL != dinfo->userhash_hex)
+      mhdErrorExitDesc ("'userhash_hex' is NOT NULL");
+    else if (0 != dinfo->userhash_hex_len)
+      mhdErrorExitDesc ("'userhash_hex' is NOT zero");
     else if (NULL != dinfo->userhash_bin)
       mhdErrorExitDesc ("'userhash_bin' is NOT NULL");
     else if (MHD_DIGEST_AUTH_ALGO3_MD5 != dinfo->algo3)

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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