gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] 05/06: Basic Auth: switched to the internal Base64 decod


From: gnunet
Subject: [libmicrohttpd] 05/06: Basic Auth: switched to the internal Base64 decoding implementation
Date: Thu, 09 Jun 2022 15:56:20 +0200

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

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit 483d47c90e6073839ab969902fe55d49a7732dd6
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Thu Jun 9 16:47:57 2022 +0300

    Basic Auth: switched to the internal Base64 decoding implementation
    
    Internal implementation able to detect all kind of problems with broken
    base64 encoding and more secure.
---
 src/include/microhttpd.h   |   7 +-
 src/microhttpd/basicauth.c | 200 +++++++++++++++++++++------------------------
 2 files changed, 98 insertions(+), 109 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index ada9af5d..4936e912 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -4670,9 +4670,10 @@ struct MHD_BasicAuthInfo
  * sent by the client
  *
  * @param connection the MHD connection structure
- * @return NULL not valid Basic Authentication header is present in
- *         current request, or pointer to structure with username and
- *         password, which must be freed by #MHD_free().
+ * @return NULL if no valid Basic Authentication header is present in
+ *         current request, or
+ *         pointer to structure with username and password, which must be
+ *         freed by #MHD_free().
  * @note Available since #MHD_VERSION 0x00097517
  * @ingroup authentication
  */
diff --git a/src/microhttpd/basicauth.c b/src/microhttpd/basicauth.c
index fb7bed0f..8c3adbdb 100644
--- a/src/microhttpd/basicauth.c
+++ b/src/microhttpd/basicauth.c
@@ -29,7 +29,6 @@
 #include "platform.h"
 #include "mhd_limits.h"
 #include "internal.h"
-#include "base64.h"
 #include "mhd_compat.h"
 #include "mhd_str.h"
 
@@ -60,9 +59,10 @@ get_rq_bauth_params (struct MHD_Connection *connection)
  * sent by the client
  *
  * @param connection the MHD connection structure
- * @return NULL not valid Basic Authentication header is present in
- *         current request, or pointer to structure with username and
- *         password, which must be freed by #MHD_free().
+ * @return NULL if no valid Basic Authentication header is present in
+ *         current request, or
+ *         pointer to structure with username and password, which must be
+ *         freed by #MHD_free().
  * @note Available since #MHD_VERSION 0x00097517
  * @ingroup authentication
  */
@@ -70,13 +70,8 @@ _MHD_EXTERN struct MHD_BasicAuthInfo *
 MHD_basic_auth_get_username_password3 (struct MHD_Connection *connection)
 {
   const struct MHD_RqBAuth *params;
-  char *decoded;
-  size_t decoded_len;
+  size_t decoded_max_len;
   struct MHD_BasicAuthInfo *ret;
-  size_t username_len;
-  char *colon;
-  size_t password_pos;
-  size_t password_len;
 
   params = get_rq_bauth_params (connection);
 
@@ -86,63 +81,66 @@ MHD_basic_auth_get_username_password3 (struct 
MHD_Connection *connection)
   if ((NULL == params->token68.str) || (0 == params->token68.len))
     return NULL;
 
-  decoded = BASE64Decode (params->token68.str, params->token68.len,
-                          &decoded_len);
-  if ((NULL == decoded) || (0 == decoded_len))
+  decoded_max_len = (params->token68.len / 4) * 3;
+  ret = (struct MHD_BasicAuthInfo *) malloc (sizeof(struct MHD_BasicAuthInfo)
+                                             + decoded_max_len + 1);
+  if (NULL != ret)
   {
+    size_t decoded_len;
+    char *decoded;
+
+    decoded = (char *) (ret + 1);
+    decoded_len = MHD_base64_to_bin_n (params->token68.str, 
params->token68.len,
+                                       decoded, decoded_max_len);
+    mhd_assert (decoded_max_len >= decoded_len);
+    if (0 != decoded_len)
+    {
+      size_t username_len;
+      char *colon;
+
+      colon = memchr (decoded, ':', decoded_len);
+      if (NULL != colon)
+      {
+        size_t password_pos;
+        size_t password_len;
+
+        username_len = (size_t) (colon - decoded);
+        password_pos = username_len + 1;
+        password_len = decoded_len - password_pos;
+        ret->password = decoded + password_pos;
+        ret->password[password_len] = 0;  /* Zero-terminate the string */
+        ret->password_len = password_len;
+      }
+      else
+      {
+        username_len = decoded_len;
+        ret->password = NULL;
+        ret->password_len = 0;
+      }
+      ret->username = decoded;
+      ret->username[username_len] = 0;  /* Zero-terminate the string */
+      ret->username_len = username_len;
+
+      return ret; /* Success exit point */
+    }
 #ifdef HAVE_MESSAGES
-    MHD_DLOG (connection->daemon,
-              _ ("Error decoding Basic Authorization authentication.\n"));
+    else
+      MHD_DLOG (connection->daemon,
+                _ ("Error decoding Basic Authorization authentication.\n"));
 #endif /* HAVE_MESSAGES */
-    if (NULL != decoded)
-      free (decoded);
-    return NULL;
-  }
-  colon = memchr (decoded, ':', decoded_len);
-  if (NULL != colon)
-  {
-    username_len = (size_t) (colon - decoded);
-    password_pos = username_len + 1;
-    password_len = decoded_len - password_pos;
+
+    free (ret);
   }
+#ifdef HAVE_MESSAGES
   else
-    username_len = decoded_len;
-
-  ret = (struct MHD_BasicAuthInfo *) malloc (sizeof(struct MHD_BasicAuthInfo)
-                                             + decoded_len + 1);
-  if (NULL == ret)
   {
-    free (decoded);
-#ifdef HAVE_MESSAGES
     MHD_DLOG (connection->daemon,
               _ ("Failed to allocate memory to process " \
                  "Basic Authorization authentication.\n"));
-#endif /* HAVE_MESSAGES */
-    return NULL;
-  }
-
-  ret->username = (char *) (ret + 1);
-  memcpy (ret->username, decoded, decoded_len);
-  free (decoded);
-  ret->username[username_len] = 0; /* Zero-terminate the string */
-  ret->username_len = username_len;
-  if (NULL != colon)
-  {
-    mhd_assert (decoded_len >= password_pos);
-    mhd_assert (decoded_len > password_pos || 0 == password_len);
-    mhd_assert (decoded_len > password_len);
-    mhd_assert (decoded_len > username_len);
-    ret->password = ret->username + password_pos;
-    ret->password[password_len] = 0; /* Zero-terminate the string */
-    ret->password_len = password_len;
-  }
-  else
-  {
-    ret->password = NULL;
-    ret->password_len = 0;
   }
+#endif /* HAVE_MESSAGES */
 
-  return ret;
+  return NULL; /* Failure exit point */
 }
 
 
@@ -160,69 +158,59 @@ _MHD_EXTERN char *
 MHD_basic_auth_get_username_password (struct MHD_Connection *connection,
                                       char **password)
 {
-  const struct MHD_RqBAuth *params;
-  char *decode;
-  size_t decode_len;
-  const char *separator;
-
-  params = get_rq_bauth_params (connection);
+  struct MHD_BasicAuthInfo *info;
 
-  if (NULL == params)
+  info = MHD_basic_auth_get_username_password3 (connection);
+  if (NULL == info)
     return NULL;
 
-  if ((NULL == params->token68.str) || (0 == params->token68.len))
-    return NULL;
-
-  decode = BASE64Decode (params->token68.str, params->token68.len, 
&decode_len);
-  if ((NULL == decode) || (0 == decode_len))
-  {
-#ifdef HAVE_MESSAGES
-    MHD_DLOG (connection->daemon,
-              _ ("Error decoding basic authentication.\n"));
-#endif
-    if (NULL != decode)
-      free (decode);
-    return NULL;
-  }
-  /* Find user:password pattern */
-  if (NULL != (separator = memchr (decode,
-                                   ':',
-                                   decode_len)))
+  /* For backward compatibility this function must return NULL if
+   * no password is provided */
+  if (NULL != info->password)
   {
-    char *user;
-    size_t user_len;
-    size_t password_len;
-
-    user = decode; /* Reuse already allocated buffer */
-    user_len = (size_t) (separator - decode);
-    user[user_len] = 0;
+    char *username;
 
-    if (NULL == password)
-      return user;
-
-    password_len = decode_len - user_len - 1;
-    *password = (char *) malloc (password_len + 1);
-    if (NULL != *password)
+    username = malloc (info->username_len + 1);
+    if (NULL != username)
     {
-      if (0 != password_len)
-        memcpy (*password, decode + user_len + 1, password_len);
-      (*password)[password_len] = 0;
-
-      return user;
+      memcpy (username, info->username, info->username_len + 1);
+      mhd_assert (0 == username[info->username_len]);
+      if (NULL != password)
+      {
+        *password = malloc (info->password_len + 1);
+        if (NULL != *password)
+        {
+          memcpy (*password, info->password, info->password_len + 1);
+          mhd_assert (0 == (*password)[info->password_len]);
+
+          free (info);
+          return username; /* Success exit point */
+        }
+#ifdef HAVE_MESSAGES
+        else
+          MHD_DLOG (connection->daemon,
+                    _ ("Failed to allocate memory.\n"));
+#endif /* HAVE_MESSAGES */
+      }
+      else
+      {
+        free (info);
+        return username; /* Success exit point */
+      }
+
+      free (username);
     }
 #ifdef HAVE_MESSAGES
     else
       MHD_DLOG (connection->daemon,
                 _ ("Failed to allocate memory.\n"));
 #endif /* HAVE_MESSAGES */
+
   }
-#ifdef HAVE_MESSAGES
-  else
-    MHD_DLOG (connection->daemon,
-              _ ("Basic authentication doesn't contain ':' separator.\n"));
-#endif
-  free (decode);
-  return NULL;
+  free (info);
+  if (NULL != password)
+    *password = NULL;
+  return NULL;  /* Failure exit point */
 }
 
 

-- 
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]