gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] branch master updated (84619630 -> 5524197d)


From: gnunet
Subject: [libmicrohttpd] branch master updated (84619630 -> 5524197d)
Date: Mon, 13 Jun 2022 11:28:55 +0200

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

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from 84619630 MHD_free(): updated doxy
     new c0effdb3 test_basicauth: cosmetic correction
     new bb0addb5 microhttpd.h: cosmetics and doxy minor improvements
     new c2414ffc Updated examples to use new API for Basic Authorization
     new 5249d333 Updated documentation for the new Basic Authorization API
     new 5524197d libmicrohttpd.texi: updated list of used external data types

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 doc/chapters/basicauthentication.inc |  78 ++++++++++++++-----------
 doc/examples/basicauthentication.c   |  49 ++++++++++------
 doc/examples/tlsauthentication.c     | 110 ++++++-----------------------------
 doc/libmicrohttpd.texi               |  27 +++++----
 src/examples/authorization_example.c |  31 +++++-----
 src/include/microhttpd.h             |   8 ++-
 src/testcurl/test_basicauth.c        |   2 +-
 7 files changed, 133 insertions(+), 172 deletions(-)

diff --git a/doc/chapters/basicauthentication.inc 
b/doc/chapters/basicauthentication.inc
index 7aa33637..ec0dd386 100644
--- a/doc/chapters/basicauthentication.inc
+++ b/doc/chapters/basicauthentication.inc
@@ -101,7 +101,7 @@ minor change, we can proceed to implement the actual 
authentication process.
 
 Let us assume we had only files not intended to be handed out without the
 correct username/password, so every "GET" request will be challenged.
-@emph{RFC 2617} describes how the server shall ask for authentication by
+@emph{RFC 7617} describes how the server shall ask for authentication by
 adding a @emph{WWW-Authenticate} response header with the name of the
 @emph{realm} protected.  MHD can generate and queue such a failure response
 for you using the @code{MHD_queue_basic_auth_fail_response} API.  The only
@@ -112,50 +112,60 @@ the proper credentials were already supplied using the
 
 Your code would then look like this:
 @verbatim
-static int
+static enum MHD_Result
 answer_to_connection (void *cls, struct MHD_Connection *connection,
                       const char *url, const char *method,
                       const char *version, const char *upload_data,
                       size_t *upload_data_size, void **req_cls)
 {
-  char *user;
-  char *pass;
-  int fail;
+  struct MHD_BasicAuthInfo *auth_info;
   enum MHD_Result ret;
   struct MHD_Response *response;
 
-  if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
+  if (0 != strcmp (method, "GET"))
     return MHD_NO;
   if (NULL == *req_cls)
-    {
-      *req_cls = connection;
-      return MHD_YES;
-    }
-  pass = NULL;
-  user = MHD_basic_auth_get_username_password (connection, &pass);
-  fail = ( (user == NULL) ||
-          (0 != strcmp (user, "root")) ||
-          (0 != strcmp (pass, "pa$$w0rd") ) );
-  if (user != NULL) free (user);
-  if (pass != NULL) free (pass);
-  if (fail)
-    {
-      const char *page = "<html><body>Go away.</body></html>";
-      response =
-       MHD_create_response_from_buffer (strlen (page), (void *) page,
-                                      MHD_RESPMEM_PERSISTENT);
-      ret = MHD_queue_basic_auth_fail_response (connection,
-                                               "my realm",
-                                               response);
-    }
+  {
+    *req_cls = connection;
+    return MHD_YES;
+  }
+  auth_info = MHD_basic_auth_get_username_password3 (connection);
+  if (NULL == auth_info)
+  {
+    static const char *page =
+      "<html><body>Authorization required</body></html>";
+    response = MHD_create_response_from_buffer_static (strlen (page), page);
+    ret = MHD_queue_basic_auth_fail_response3 (connection,
+                                               "admins",
+                                               MHD_YES,
+                                               response);
+  }
+  else if ((strlen ("root") != auth_info->username_len) ||
+           (0 != memcmp (auth_info->username, "root",
+                         auth_info->username_len)) ||
+           /* The next check against NULL is optional,
+            * if 'password' is NULL then 'password_len' is always zero. */
+           (NULL == auth_info->password) ||
+           (strlen ("pa$$w0rd") != auth_info->password_len) ||
+           (0 != memcmp (auth_info->password, "pa$$w0rd",
+                         auth_info->password_len)))
+  {
+    static const char *page =
+      "<html><body>Wrong username or password</body></html>";
+    response = MHD_create_response_from_buffer_static (strlen (page), page);
+    ret = MHD_queue_basic_auth_fail_response3 (connection,
+                                               "admins",
+                                               MHD_YES,
+                                               response);
+  }
   else
-    {
-      const char *page = "<html><body>A secret.</body></html>";
-      response =
-       MHD_create_response_from_buffer (strlen (page), (void *) page,
-                                      MHD_RESPMEM_PERSISTENT);
-      ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
-    }
+  {
+    static const char *page = "<html><body>A secret.</body></html>";
+    response = MHD_create_response_from_buffer_static (strlen (page), page);
+    ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  }
+  if (NULL != auth_info)
+    MHD_free (auth_info);
   MHD_destroy_response (response);
   return ret;
 }
diff --git a/doc/examples/basicauthentication.c 
b/doc/examples/basicauthentication.c
index d75ba636..6e1493a3 100644
--- a/doc/examples/basicauthentication.c
+++ b/doc/examples/basicauthentication.c
@@ -23,9 +23,7 @@ answer_to_connection (void *cls, struct MHD_Connection 
*connection,
                       const char *version, const char *upload_data,
                       size_t *upload_data_size, void **req_cls)
 {
-  char *user;
-  char *pass;
-  int fail;
+  struct MHD_BasicAuthInfo *auth_info;
   enum MHD_Result ret;
   struct MHD_Response *response;
   (void) cls;               /* Unused. Silent compiler warning. */
@@ -41,30 +39,43 @@ answer_to_connection (void *cls, struct MHD_Connection 
*connection,
     *req_cls = connection;
     return MHD_YES;
   }
-  pass = NULL;
-  user = MHD_basic_auth_get_username_password (connection,
-                                               &pass);
-  fail = ( (NULL == user) ||
-           (0 != strcmp (user, "root")) ||
-           (0 != strcmp (pass, "pa$$w0rd") ) );
-  if (NULL != user)
-    MHD_free (user);
-  if (NULL != pass)
-    MHD_free (pass);
-  if (fail)
+  auth_info = MHD_basic_auth_get_username_password3 (connection);
+  if (NULL == auth_info)
   {
-    const char *page = "<html><body>Go away.</body></html>";
+    static const char *page =
+      "<html><body>Authorization required</body></html>";
     response = MHD_create_response_from_buffer_static (strlen (page), page);
-    ret = MHD_queue_basic_auth_fail_response (connection,
-                                              "my realm",
-                                              response);
+    ret = MHD_queue_basic_auth_fail_response3 (connection,
+                                               "admins",
+                                               MHD_YES,
+                                               response);
+  }
+  else if ((strlen ("root") != auth_info->username_len) ||
+           (0 != memcmp (auth_info->username, "root",
+                         auth_info->username_len)) ||
+           /* The next check against NULL is optional,
+            * if 'password' is NULL then 'password_len' is always zero. */
+           (NULL == auth_info->password) ||
+           (strlen ("pa$$w0rd") != auth_info->password_len) ||
+           (0 != memcmp (auth_info->password, "pa$$w0rd",
+                         auth_info->password_len)))
+  {
+    static const char *page =
+      "<html><body>Wrong username or password</body></html>";
+    response = MHD_create_response_from_buffer_static (strlen (page), page);
+    ret = MHD_queue_basic_auth_fail_response3 (connection,
+                                               "admins",
+                                               MHD_YES,
+                                               response);
   }
   else
   {
-    const char *page = "<html><body>A secret.</body></html>";
+    static const char *page = "<html><body>A secret.</body></html>";
     response = MHD_create_response_from_buffer_static (strlen (page), page);
     ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
   }
+  if (NULL != auth_info)
+    MHD_free (auth_info);
   MHD_destroy_response (response);
   return ret;
 }
diff --git a/doc/examples/tlsauthentication.c b/doc/examples/tlsauthentication.c
index 65d9d8db..0cd6c4e6 100644
--- a/doc/examples/tlsauthentication.c
+++ b/doc/examples/tlsauthentication.c
@@ -15,7 +15,7 @@
 
 #define PORT 8888
 
-#define REALM     "\"Maintenance\""
+#define REALM     "Maintenance"
 #define USER      "a legitimate user"
 #define PASSWORD  "and his password"
 
@@ -23,48 +23,6 @@
 #define SERVERCERTFILE "server.pem"
 
 
-static char *
-string_to_base64 (const char *message)
-{
-  const char *lookup =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  unsigned long l;
-  size_t i;
-  size_t j;
-  char *tmp;
-  size_t length = strlen (message);
-
-  tmp = malloc (length * 2 + 1);
-  if (NULL == tmp)
-    return NULL;
-  j = 0;
-  for (i = 0; i < length; i += 3)
-  {
-    l = (((unsigned long) message[i]) << 16)
-        | (((i + 1) < length) ? (((unsigned long) message[i + 1]) << 8) : 0)
-        | (((i + 2) < length) ? ((unsigned long) message[i + 2]) : 0);
-
-
-    tmp [j++] = lookup[(l >> 18) & 0x3F];
-    tmp [j++] = lookup[(l >> 12) & 0x3F];
-
-    if (i + 1 < length)
-      tmp [j++] = lookup[(l >> 6) & 0x3F];
-    if (i + 2 < length)
-      tmp [j++] = lookup[l & 0x3F];
-  }
-
-  if (0 != length % 3)
-    tmp [j++] = '=';
-  if (1 == length % 3)
-    tmp [j++] = '=';
-
-  tmp [j] = 0;
-
-  return tmp;
-}
-
-
 static size_t
 get_file_size (const char *filename)
 {
@@ -126,35 +84,15 @@ ask_for_authentication (struct MHD_Connection *connection, 
const char *realm)
 {
   enum MHD_Result ret;
   struct MHD_Response *response;
-  char *headervalue;
-  size_t slen;
-  const char *strbase = "Basic realm=";
 
   response = MHD_create_response_empty (MHD_RF_NONE);
   if (! response)
     return MHD_NO;
 
-  slen = strlen (strbase) + strlen (realm) + 1;
-  if (NULL == (headervalue = malloc (slen)))
-    return MHD_NO;
-  snprintf (headervalue,
-            slen,
-            "%s%s",
-            strbase,
-            realm);
-  ret = MHD_add_response_header (response,
-                                 "WWW-Authenticate",
-                                 headervalue);
-  free (headervalue);
-  if (! ret)
-  {
-    MHD_destroy_response (response);
-    return MHD_NO;
-  }
-
-  ret = MHD_queue_response (connection,
-                            MHD_HTTP_UNAUTHORIZED,
-                            response);
+  ret = MHD_queue_basic_auth_fail_response3 (connection,
+                                             realm,
+                                             MHD_YES,
+                                             response);
   MHD_destroy_response (response);
   return ret;
 }
@@ -165,37 +103,23 @@ is_authenticated (struct MHD_Connection *connection,
                   const char *username,
                   const char *password)
 {
-  const char *headervalue;
-  char *expected_b64;
-  char *expected;
-  const char *strbase = "Basic ";
+  struct MHD_BasicAuthInfo *auth_info;
   int authenticated;
-  size_t slen;
 
-  headervalue =
-    MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
-                                 "Authorization");
-  if (NULL == headervalue)
-    return 0;
-  if (0 != strncmp (headervalue, strbase, strlen (strbase)))
+  auth_info = MHD_basic_auth_get_username_password3 (connection);
+  if (NULL == auth_info)
     return 0;
+  authenticated =
+    ( (strlen (username) == auth_info->username_len) &&
+      (0 == memcmp (auth_info->username, username, auth_info->username_len)) &&
+      /* The next check against NULL is optional,
+       * if 'password' is NULL then 'password_len' is always zero. */
+      (NULL != auth_info->password) &&
+      (strlen (password) == auth_info->password_len) &&
+      (0 == memcmp (auth_info->password, password, auth_info->password_len)) );
 
-  slen = strlen (username) + 1 + strlen (password) + 1;
-  if (NULL == (expected = malloc (slen)))
-    return 0;
-  snprintf (expected,
-            slen,
-            "%s:%s",
-            username,
-            password);
-  expected_b64 = string_to_base64 (expected);
-  free (expected);
-  if (NULL == expected_b64)
-    return 0;
+  MHD_free (auth_info);
 
-  authenticated =
-    (strcmp (headervalue + strlen (strbase), expected_b64) == 0);
-  free (expected_b64);
   return authenticated;
 }
 
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
index 57cdb000..265496a0 100644
--- a/doc/libmicrohttpd.texi
+++ b/doc/libmicrohttpd.texi
@@ -332,11 +332,13 @@ valid as long as the response itself is valid.
 @cindex microhttpd.h
 
 Ideally, before including "microhttpd.h" you should add the necessary
-includes to define the @code{uint64_t}, @code{size_t}, @code{fd_set},
-@code{socklen_t} and @code{struct sockaddr} data types.  Which
-specific headers are needed may depend on your platform and your build
-system might include some tests to provide you with the necessary
-conditional operations.  For possible suggestions consult
+includes to define the @code{va_list}, @code{size_t}, @code{ssize_t},
+@code{intptr_t}, @code{off_t}, @code{uint8_t}, @code{uint16_t},
+@code{int32_t}, @code{uint32_t}, @code{int64_t}, @code{uint64_t},
+@code{fd_set}, @code{socklen_t} and @code{struct sockaddr} data types.
+Which specific headers are needed may depend on your platform and your
+build system might include some tests to provide you with the
+necessary conditional operations.  For possible suggestions consult
 @code{platform.h} and @code{configure.ac} in the MHD distribution.
 
 Once you have ensured that you manually (!) included the right headers
@@ -3114,21 +3116,24 @@ client certificates is presented in the MHD tutorial.
 Free the memory given at @code{ptr}.  Used to free data structures allocated 
by MHD. Calls @code{free(ptr)}.
 @end deftypefun
 
-@deftypefun {char *} MHD_basic_auth_get_username_password (struct 
MHD_Connection *connection, char** password)
+@deftypefun {char *} MHD_basic_auth_get_username_password3 (struct 
MHD_Connection *connection)
 Get the username and password from the basic authorization header sent by the 
client.
-Return @code{NULL} if no username could be found, a pointer to the username if 
found.
-If returned value is not @code{NULL}, the value must be @code{MHD_free()}'ed.
-
-@var{password} reference a buffer to store the password. It can be @code{NULL}.
+Return @code{NULL} if no Basic Authorization header set by the client or if 
Base64
+encoding is invalid; a pointer to the structure with username and password
+if found values set by the client.
 If returned value is not @code{NULL}, the value must be @code{MHD_free()}'ed.
 @end deftypefun
 
-@deftypefun {enum MHD_Result} MHD_queue_basic_auth_fail_response (struct 
MHD_Connection *connection, const char *realm, struct MHD_Response *response)
+@deftypefun {enum MHD_Result} MHD_queue_basic_auth_fail_response3 (struct 
MHD_Connection *connection, const char *realm, int prefer_utf8, struct 
MHD_Response *response)
 Queues a response to request basic authentication from the client.
 Return @code{MHD_YES} if successful, otherwise @code{MHD_NO}.
 
 @var{realm} must reference to a zero-terminated string representing the realm.
 
+@var{prefer_utf8} if set to @code{MHD_YES} then parameter @code{charset} with 
value
+@code{UTF-8} will be added to the response authentication header which 
indicates
+that UTF-8 encoding is preferred for username and password.
+
 @var{response} a response structure to specify what shall be presented to the
 client with a 401 HTTP status.
 @end deftypefun
diff --git a/src/examples/authorization_example.c 
b/src/examples/authorization_example.c
index 8d26869a..fab6bd45 100644
--- a/src/examples/authorization_example.c
+++ b/src/examples/authorization_example.c
@@ -52,8 +52,7 @@ ahc_echo (void *cls,
   static int aptr;
   struct MHD_Response *response;
   enum MHD_Result ret;
-  char *user;
-  char *pass;
+  struct MHD_BasicAuthInfo *auth_info;
   int fail;
   (void) cls;               /* Unused. Silent compiler warning. */
   (void) url;               /* Unused. Silent compiler warning. */
@@ -72,18 +71,26 @@ ahc_echo (void *cls,
   *req_cls = NULL;                  /* reset when done */
 
   /* require: "Aladdin" with password "open sesame" */
-  pass = NULL;
-  user = MHD_basic_auth_get_username_password (connection,
-                                               &pass);
-  fail = ( (NULL == user) ||
-           (0 != strcmp (user, "Aladdin")) ||
-           (0 != strcmp (pass, "open sesame") ) );
+  auth_info = MHD_basic_auth_get_username_password3 (connection);
+  fail = ( (NULL == auth_info) ||
+           (strlen ("Aladdin") != auth_info->username_len) ||
+           (0 != memcmp (auth_info->username, "Aladdin",
+                         auth_info->username_len)) ||
+           /* The next check against NULL is optional,
+            * if 'password' is NULL then 'password_len' is always zero. */
+           (NULL == auth_info->password) ||
+           (strlen ("open sesame") != auth_info->password_len) ||
+           (0 != memcmp (auth_info->password, "open sesame",
+                         auth_info->password_len)) );
   if (fail)
   {
     response =
       MHD_create_response_from_buffer_static (strlen (DENIED),
                                               (const void *) DENIED);
-    ret = MHD_queue_basic_auth_fail_response (connection,"TestRealm",response);
+    ret = MHD_queue_basic_auth_fail_response3 (connection,
+                                               "TestRealm",
+                                               MHD_NO,
+                                               response);
   }
   else
   {
@@ -92,10 +99,8 @@ ahc_echo (void *cls,
                                               (const void *) PAGE);
     ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
   }
-  if (NULL != user)
-    MHD_free (user);
-  if (NULL != pass)
-    MHD_free (pass);
+  if (NULL != auth_info)
+    MHD_free (auth_info);
   MHD_destroy_response (response);
   return ret;
 }
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 5ddd60da..8a6fea2f 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -3532,6 +3532,8 @@ enum MHD_ResponseFlags
    * (zero-size body).
    * Responses with this flag enabled cannot be used in situations where
    * reply body must be sent to the client.
+   * This flag is primarily intended to be used when automatic "Content-Length"
+   * header is undesirable in response to HEAD requests.
    * @note Available since #MHD_VERSION 0x00097502
    */
   MHD_RF_HEAD_ONLY_RESPONSE = 1 << 4
@@ -4655,16 +4657,20 @@ struct MHD_BasicAuthInfo
    * The username, cannot be NULL
    */
   char *username;
+
   /**
    * The length of the @a username, not including zero-termination
    */
   size_t username_len;
+
   /**
    * The password, may be NULL if password is not encoded by the client
    */
   char *password;
+
   /**
-   * The length of the @a password, not including zero-termination
+   * The length of the @a password, not including zero-termination;
+   * when the @a password is NULL, the length is always zero.
    */
   size_t password_len;
 };
diff --git a/src/testcurl/test_basicauth.c b/src/testcurl/test_basicauth.c
index e95047dd..a46e6bd1 100644
--- a/src/testcurl/test_basicauth.c
+++ b/src/testcurl/test_basicauth.c
@@ -365,7 +365,7 @@ ahc_echo (void *cls,
                                                 (const void *) DENIED);
       if (NULL == response)
         mhdErrorExitDesc ("Response creation failed");
-      ret = MHD_queue_basic_auth_fail_response3 (connection, REALM, 1,
+      ret = MHD_queue_basic_auth_fail_response3 (connection, REALM, MHD_YES,
                                                  response);
       if (MHD_YES != ret)
         mhdErrorExitDesc ("'MHD_queue_basic_auth_fail_response3()' failed");

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