소스 검색

Digest Auth public structs: removed redundant member

Added one more check for data validity.
Evgeny Grin (Karlson2k) 3 년 전
부모
커밋
4baec145d4
3개의 변경된 파일39개의 추가작업 그리고 28개의 파일을 삭제
  1. 29 16
      src/include/microhttpd.h
  2. 10 8
      src/microhttpd/digestauth.c
  3. 0 4
      src/testcurl/test_digestauth_emu_ext.c

+ 29 - 16
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 0x00097523
+#define MHD_VERSION 0x00097525
 
 /* If generic headers don't work on your platform, include headers
    which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t',
@@ -4664,7 +4664,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 0x00097519
+ * @note Available since #MHD_VERSION 0x00097525
  */
 struct MHD_DigestAuthInfo
 {
@@ -4676,10 +4676,12 @@ struct MHD_DigestAuthInfo
    *          which uses other values!
    */
   enum MHD_DigestAuthAlgo3 algo;
+
   /**
    * The type of username used by client.
    */
   enum MHD_DigestAuthUsernameType uname_type;
+
   /**
    * The username string.
    * Valid only if username is standard, extended, or userhash.
@@ -4691,46 +4693,54 @@ struct MHD_DigestAuthInfo
    * This can be NULL is username is missing or invalid.
    */
   char *username;
+
   /**
    * The length of the @a username.
    * When the @a username is NULL, this member is always zero.
    */
   size_t username_len;
+
   /**
    * The userhash decoded to binary form.
    * Used only if username type is userhash, always NULL otherwise.
-   * @warning this is a binary data, no zero termination
+   * When not NULL, this points to binary sequence @a username_len /2 bytes
+   * long.
+   * @warning This is binary data, no zero termination.
+   * @warning To avoid buffer overruns, always check the size of the data before
+   *          use, because @ userhash_bin can point even to zero-sized
+   *          data.
    */
   uint8_t *userhash_bin;
-  /**
-   * The number of bytes pointed by the @a userhash_bin.
-   * When the @a userhash_bin is NULL, this member is always zero.
-   */
-  size_t userhash_bin_size;
+
   /**
    * The 'opaque' parameter value, as specified by client.
    * NULL if not specified by client.
    */
   char *opaque;
+
   /**
    * The length of the @a opaque.
    * When the @a opaque is NULL, this member is always zero.
    */
   size_t opaque_len;
+
   /**
    * The 'realm' parameter value, as specified by client.
    * NULL if not specified by client.
    */
   char *realm;
+
   /**
    * The length of the @a realm.
    * When the @a realm is NULL, this member is always zero.
    */
   size_t realm_len;
+
   /**
    * The 'qop' parameter value.
    */
   enum MHD_DigestAuthQOP qop;
+
   /**
    * The length of the 'cnonce' parameter value, including possible
    * backslash-escape characters.
@@ -4740,6 +4750,7 @@ struct MHD_DigestAuthInfo
    * characters long.
    */
   size_t cnonce_len;
+
   /**
    * The nc parameter value.
    * Can be used by application to limit the number of nonce re-uses. If @ nc
@@ -4773,7 +4784,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 0x00097519
+ * @note Available since #MHD_VERSION 0x00097525
  */
 struct MHD_DigestAuthUsernameInfo
 {
@@ -4783,6 +4794,7 @@ struct MHD_DigestAuthUsernameInfo
    * instead NULL is returned by #MHD_digest_auth_get_username3().
    */
   enum MHD_DigestAuthUsernameType uname_type;
+
   /**
    * The username string.
    * Valid only if username is standard, extended, or userhash.
@@ -4794,22 +4806,23 @@ struct MHD_DigestAuthUsernameInfo
    * This can be NULL is username is missing or invalid.
    */
   char *username;
+
   /**
    * The length of the @a username.
    * When the @a username is NULL, this member is always zero.
    */
   size_t username_len;
+
   /**
    * The userhash decoded to binary form.
-   * Used only if username type is userhash, always NULL if not used.
-   * @warning this is a binary data, no zero termination
+   * When not NULL, this points to binary sequence @a username_len /2 bytes
+   * long.
+   * @warning This is binary data, no zero termination.
+   * @warning To avoid buffer overruns, always check the size of the data before
+   *          use, because @ userhash_bin can point even to zero-sized
+   *          data.
    */
   uint8_t *userhash_bin;
-  /**
-   * The number of bytes pointed by the @a userhash_bin.
-   * When the @a userhash_bin is NULL, this member is always zero.
-   */
-  size_t userhash_bin_size;
 };
 
 /**

+ 10 - 8
src/microhttpd/digestauth.c

@@ -881,20 +881,23 @@ get_rq_uname (const struct MHD_RqDAuth *params,
     buf_used += uname_info->username_len + 1;
     if (MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH == uname_type)
     {
-      uname_info->userhash_bin_size = MHD_hex_to_bin (uname_info->username,
-                                                      uname_info->username_len,
-                                                      buf + buf_used);
-      if ( (0 == uname_info->userhash_bin_size) &&
-           (0 != uname_info->username_len) )
+      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
       {
-        uname_info->userhash_bin = (uint8_t *) (buf + buf_used);
+        /* 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 += uname_info->userhash_bin_size;
+        buf_used += res;
       }
     }
     else
@@ -1093,7 +1096,6 @@ MHD_digest_auth_get_request_info3 (struct MHD_Connection *connection)
     info->username = uname_strct.username;
     info->username_len = uname_strct.username_len;
     info->userhash_bin = uname_strct.userhash_bin;
-    info->userhash_bin_size = uname_strct.userhash_bin_size;
   }
   else
     info->uname_type = uname_type;

+ 0 - 4
src/testcurl/test_digestauth_emu_ext.c

@@ -383,8 +383,6 @@ ahc_echo (void *cls,
     }
     else if (NULL != creds->userhash_bin)
       mhdErrorExitDesc ("'userhash_bin' is NOT NULL");
-    else if (0 != creds->userhash_bin_size)
-      mhdErrorExitDesc ("'userhash_bin_size' is NOT zero");
     MHD_free (creds);
 
     dinfo = MHD_digest_auth_get_request_info3 (connection);
@@ -419,8 +417,6 @@ ahc_echo (void *cls,
     }
     else if (NULL != dinfo->userhash_bin)
       mhdErrorExitDesc ("'userhash_bin' is NOT NULL");
-    else if (0 != dinfo->userhash_bin_size)
-      mhdErrorExitDesc ("'userhash_bin_size' is NOT zero");
     else if (MHD_DIGEST_AUTH_ALGO3_MD5 != dinfo->algo)
     {
       fprintf (stderr, "Unexpected 'algo'.\n"