Просмотр исходного кода

digest_auth_check(): added support for userhash

Evgeny Grin (Karlson2k) 3 лет назад
Родитель
Сommit
7e5206cc03
1 измененных файлов с 47 добавлено и 25 удалено
  1. 47 25
      src/microhttpd/digestauth.c

+ 47 - 25
src/microhttpd/digestauth.c

@@ -1963,7 +1963,13 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
     return MHD_DAUTH_WRONG_HEADER; /* Parameters cannot be used together */
   else if ((NULL != params->username_ext.value.str) &&
            (MHD_DAUTH_EXT_PARAM_MIN_LEN > params->username_ext.value.len))
-    return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */
+    return MHD_DAUTH_WRONG_HEADER;  /* Broken extended notation */
+  else if (params->userhash && (NULL == params->username.value.str))
+    return MHD_DAUTH_WRONG_HEADER;  /* Userhash cannot be used with extended notation */
+  else if (params->userhash && (digest_size * 2 > params->username.value.len))
+    return MHD_DAUTH_WRONG_HEADER;  /* Too few chars for correct userhash */
+  else if (params->userhash && (digest_size * 4 < params->username.value.len))
+    return MHD_DAUTH_WRONG_HEADER;  /* Too many chars for correct userhash */
 
   if (NULL == params->realm.value.str)
     return MHD_DAUTH_WRONG_HEADER;
@@ -2039,32 +2045,48 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
 
   /* Check 'username' */
   username_len = strlen (username);
-  if (NULL != params->username.value.str)
-  { /* Username in standard notation */
-    if (! is_param_equal (&params->username, username, username_len))
-      return MHD_DAUTH_WRONG_USERNAME;
+  if (! params->userhash)
+  {
+    if (NULL != params->username.value.str)
+    { /* Username in standard notation */
+      if (! is_param_equal (&params->username, username, username_len))
+        return MHD_DAUTH_WRONG_USERNAME;
+    }
+    else
+    { /* Username in extended notation */
+      char *r_uname;
+      size_t buf_size = params->username_ext.value.len;
+      ssize_t res;
+
+      mhd_assert (NULL != params->username_ext.value.str);
+      mhd_assert (MHD_DAUTH_EXT_PARAM_MIN_LEN <= buf_size); /* It was checked already */
+      buf_size += 1; /* For zero-termination */
+      buf_size -= MHD_DAUTH_EXT_PARAM_MIN_LEN;
+      r_uname = get_buffer_for_size (tmp1, ptmp2, &tmp2_size, buf_size);
+      if (NULL == r_uname)
+        return (_MHD_AUTH_DIGEST_MAX_PARAM_SIZE < buf_size) ?
+               MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR;
+      res = get_rq_extended_uname_copy_z (params->username_ext.value.str,
+                                          params->username_ext.value.len,
+                                          r_uname, buf_size);
+      if (0 > res)
+        return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */
+      if ((username_len != (size_t) res) ||
+          (0 != memcmp (username, r_uname, username_len)))
+        return MHD_DAUTH_WRONG_USERNAME;
+    }
   }
   else
-  { /* Username in extended notation */
-    char *r_uname;
-    size_t buf_size = params->username_ext.value.len;
-    ssize_t res;
-
-    mhd_assert (NULL != params->username_ext.value.str);
-    mhd_assert (MHD_DAUTH_EXT_PARAM_MIN_LEN <= buf_size); /* It was checked already */
-    buf_size += 1; /* For zero-termination */
-    buf_size -= MHD_DAUTH_EXT_PARAM_MIN_LEN;
-    r_uname = get_buffer_for_size (tmp1, ptmp2, &tmp2_size, buf_size);
-    if (NULL == r_uname)
-      return (_MHD_AUTH_DIGEST_MAX_PARAM_SIZE < buf_size) ?
-             MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR;
-    res = get_rq_extended_uname_copy_z (params->username_ext.value.str,
-                                        params->username_ext.value.len,
-                                        r_uname, buf_size);
-    if (0 > res)
-      return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */
-    if ((username_len != (size_t) res) ||
-        (0 != memcmp (username, r_uname, username_len)))
+  { /* Userhash */
+    mhd_assert (NULL != params->username.value.str);
+    digest_init (da);
+    digest_update (da, username, username_len);
+    digest_update_with_colon (da);
+    digest_update (da, realm, realm_len);
+    digest_calc_hash (da, hash1_bin);
+    mhd_assert (sizeof (tmp1) >= (2 * digest_size + 1));
+    MHD_bin_to_hex (hash1_bin, digest_size, tmp1);
+    if (! is_param_equal_caseless (&params->username, tmp1, 2 * digest_size))
       return MHD_DAUTH_WRONG_USERNAME;
   }
   /* 'username' valid */