Kaynağa Gözat

Basic auth: switched to internal base64 decoding

The new implementation should catch all encoding errors.
Evgeny Grin (Karlson2k) 2 yıl önce
ebeveyn
işleme
244a0a42c8

+ 0 - 2
po/POTFILES.in

@@ -1,6 +1,4 @@
 src/include/microhttpd.h
-src/microhttpd/base64.c
-src/microhttpd/base64.h
 src/microhttpd/basicauth.c
 src/microhttpd/connection.c
 src/microhttpd/connection.h

+ 66 - 37
src/microhttpd/basicauth.c

@@ -25,7 +25,7 @@
 #include "platform.h"
 #include "mhd_limits.h"
 #include "internal.h"
-#include "base64.h"
+#include "mhd_str.h"
 #include "mhd_compat.h"
 
 /**
@@ -45,66 +45,95 @@
  */
 char *
 MHD_basic_auth_get_username_password (struct MHD_Connection *connection,
-                                      char**password)
+                                      char **password)
 {
   const char *header;
+  size_t enc_size;
+  size_t value_size;
+  size_t dec_size;
   char *decode;
-  const char *separator;
-  char *user;
-
-  if ( (MHD_NO == MHD_lookup_connection_value_n (connection,
-                                                 MHD_HEADER_KIND,
-                                                 MHD_HTTP_HEADER_AUTHORIZATION,
-                                                 MHD_STATICSTR_LEN_ (
-                                                   MHD_HTTP_HEADER_AUTHORIZATION),
-                                                 &header,
-                                                 NULL)) ||
-       (0 != strncmp (header,
-                      _BASIC_BASE,
-                      MHD_STATICSTR_LEN_ (_BASIC_BASE))) )
+  char *separator;
+
+  if (NULL != password)
+    *password = NULL;
+
+  if (MHD_NO ==
+      MHD_lookup_connection_value_n (connection,
+                                     MHD_HEADER_KIND,
+                                     MHD_HTTP_HEADER_AUTHORIZATION,
+                                     MHD_STATICSTR_LEN_ ( \
+                                       MHD_HTTP_HEADER_AUTHORIZATION),
+                                     &header,
+                                     &value_size))
     return NULL;
+
+  if (0 != strncmp (header,
+                    _BASIC_BASE,
+                    MHD_STATICSTR_LEN_ (_BASIC_BASE)))
+    return NULL;
+
   header += MHD_STATICSTR_LEN_ (_BASIC_BASE);
-  if (NULL == (decode = BASE64Decode (header)))
+  enc_size = value_size - MHD_STATICSTR_LEN_ (_BASIC_BASE);
+  if (0 != (enc_size % 4))
   {
 #ifdef HAVE_MESSAGES
     MHD_DLOG (connection->daemon,
-              _ ("Error decoding basic authentication.\n"));
+              _ ("Bad length of basic authentication value.\n"));
 #endif
     return NULL;
   }
-  /* Find user:password pattern */
-  if (NULL == (separator = strchr (decode,
-                                   ':')))
+  dec_size = MHD_base64_max_dec_size_ (enc_size);
+  decode = (char *) malloc (dec_size + 1);
+  if (NULL == decode)
   {
 #ifdef HAVE_MESSAGES
     MHD_DLOG (connection->daemon,
-              _ ("Basic authentication doesn't contain ':' separator.\n"));
+              _ ("Failed to allocate memory.\n"));
 #endif
-    free (decode);
-    return NULL;
-  }
-  if (NULL == (user = strdup (decode)))
-  {
-    free (decode);
     return NULL;
   }
-  user[separator - decode] = '\0'; /* cut off at ':' */
-  if (NULL != password)
+  dec_size = MHD_base64_to_bin_n (header, enc_size, decode, dec_size);
+  if (0 != dec_size)
   {
-    *password = strdup (separator + 1);
-    if (NULL == *password)
+    decode[dec_size] = 0; /* Zero-terminate */
+    /* Find user:password pattern */
+    separator = memchr (decode, ':', dec_size);
+    if (NULL != separator)
     {
+      *separator = 0; /* Zero-terminate 'username' */
+      if (NULL == password)
+        return decode;  /* Success exit point */
+      else
+      {
+        *password = strdup (separator + 1);
+        if (NULL != *password)
+          return decode; /* Success exit point */
+#ifdef HAVE_MESSAGES
+        else
+        {
+          MHD_DLOG (connection->daemon,
+                    _ ("Failed to allocate memory for password.\n"));
+        }
+#endif /* HAVE_MESSAGES */
+      }
+    }
 #ifdef HAVE_MESSAGES
+    else
+    {
       MHD_DLOG (connection->daemon,
-                _ ("Failed to allocate memory for password.\n"));
-#endif
-      free (decode);
-      free (user);
-      return NULL;
+                _ ("Basic authentication doesn't contain ':' separator.\n"));
     }
+#endif /* HAVE_MESSAGES */
+  }
+#ifdef HAVE_MESSAGES
+  else
+  {
+    MHD_DLOG (connection->daemon,
+              _ ("Error decoding basic authentication.\n"));
   }
+#endif /* HAVE_MESSAGES */
   free (decode);
-  return user;
+  return NULL;  /* Failure exit point */
 }
 
 

+ 0 - 2
w32/common/libmicrohttpd-files.vcxproj

@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <ClCompile Include="$(MhdSrc)microhttpd\base64.c" />
     <ClCompile Include="$(MhdSrc)microhttpd\basicauth.c" />
     <ClCompile Include="$(MhdSrc)microhttpd\connection.c" />
     <ClCompile Include="$(MhdSrc)microhttpd\daemon.c" />
@@ -30,7 +29,6 @@
     <ClInclude Include="$(MhdSrc)include\microhttpd.h" />
     <ClInclude Include="$(MhdSrc)include\mhd_options.h" />
     <ClInclude Include="$(MhdSrc)include\platform.h" />
-    <ClInclude Include="$(MhdSrc)microhttpd\base64.h" />
     <ClInclude Include="$(MhdSrc)microhttpd\connection.h" />
     <ClInclude Include="$(MhdSrc)microhttpd\internal.h" />
     <ClInclude Include="$(MhdSrc)microhttpd\md5.h" />

+ 0 - 6
w32/common/libmicrohttpd-filters.vcxproj

@@ -40,9 +40,6 @@
     <ClInclude Include="$(MhdW32Common)MHD_config.h">
       <Filter>Internal Headers</Filter>
     </ClInclude>
-    <ClInclude Include="$(MhdSrc)microhttpd\base64.h">
-      <Filter>Internal Headers</Filter>
-    </ClInclude>
     <ClInclude Include="$(MhdSrc)microhttpd\connection.h">
       <Filter>Internal Headers</Filter>
     </ClInclude>
@@ -111,9 +108,6 @@
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="$(MhdSrc)microhttpd\base64.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="$(MhdSrc)microhttpd\basicauth.c">
       <Filter>Source Files</Filter>
     </ClCompile>