gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] 03/05: Added new daemon option MHD_OPTION_CLIENT_DISCIPL


From: gnunet
Subject: [libmicrohttpd] 03/05: Added new daemon option MHD_OPTION_CLIENT_DISCIPLINE_LV
Date: Thu, 22 Dec 2022 18:18:33 +0100

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

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit 5c3a61d68c04ebfd62695fa2a90e6212e42a1cae
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Thu Dec 22 16:30:12 2022 +0300

    Added new daemon option MHD_OPTION_CLIENT_DISCIPLINE_LV
    
    Reject URIs with spaces as per RFC.
    Fixed check for space before colon in headers (previously it was checked
    only when MHD was NOT strict).
    Reject HTTP/1.1 requests without host by default (as per RFC).
---
 src/examples/connection_close.c          |  2 +-
 src/examples/minimal_example.c           |  1 -
 src/examples/minimal_example_empty.c     |  1 -
 src/examples/minimal_example_empty_tls.c |  2 +-
 src/include/microhttpd.h                 | 74 +++++++++++++++++++++++++++-----
 src/microhttpd/connection.c              | 18 ++++----
 src/microhttpd/daemon.c                  | 32 +++++++++++---
 src/microhttpd/internal.h                |  5 ++-
 8 files changed, 103 insertions(+), 32 deletions(-)

diff --git a/src/examples/connection_close.c b/src/examples/connection_close.c
index 8558eb46..de79d9f1 100644
--- a/src/examples/connection_close.c
+++ b/src/examples/connection_close.c
@@ -118,7 +118,7 @@ main (int argc, char *const *argv)
     MHD_OPTION_NOTIFY_COMPLETED, &request_completed, NULL,
     MHD_OPTION_NOTIFY_CONNECTION, &connection_completed, NULL,
     MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
-    MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+    MHD_OPTION_CLIENT_DISCIPLINE_LVL, (int) 1,
     MHD_OPTION_END);
   if (d == NULL)
     return 1;
diff --git a/src/examples/minimal_example.c b/src/examples/minimal_example.c
index f7a0e64c..f3fb1c88 100644
--- a/src/examples/minimal_example.c
+++ b/src/examples/minimal_example.c
@@ -105,7 +105,6 @@ main (int argc,
     (uint16_t) port,
     NULL, NULL, &ahc_echo, &data_for_handler,
     MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
-    MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
     MHD_OPTION_END);
   if (d == NULL)
     return 1;
diff --git a/src/examples/minimal_example_empty.c 
b/src/examples/minimal_example_empty.c
index 3556d753..2c76654a 100644
--- a/src/examples/minimal_example_empty.c
+++ b/src/examples/minimal_example_empty.c
@@ -93,7 +93,6 @@ main (int argc,
     (uint16_t) port,
     NULL, NULL, &ahc_echo, NULL,
     MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
-    MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
     MHD_OPTION_END);
   if (d == NULL)
     return 1;
diff --git a/src/examples/minimal_example_empty_tls.c 
b/src/examples/minimal_example_empty_tls.c
index 465f7492..d0a4d6ff 100644
--- a/src/examples/minimal_example_empty_tls.c
+++ b/src/examples/minimal_example_empty_tls.c
@@ -160,7 +160,7 @@ main (int argc,
     (uint16_t) port,
     NULL, NULL, &ahc_echo, NULL,
     MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
-    MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+    MHD_OPTION_CLIENT_DISCIPLINE_LVL, (int) 1,
     /* Optionally, the gnutls_load_file() can be used to
        load the key and the certificate from file. */
     MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index b66f4b3d..93967c60 100644
--- a/src/include/microhttpd.h
+++ b/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 0x00097544
+#define MHD_VERSION 0x00097545
 
 /* If generic headers don't work on your platform, include headers
    which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t',
@@ -1291,12 +1291,14 @@ enum MHD_FLAG
    * as liberal as possible in what you accept" norm.  It is
    * recommended to turn this ON if you are testing clients against
    * MHD, and OFF in production.
+   * @sa #MHD_OPTION_CLIENT_DISCIPLINE_LVL
    */
   MHD_USE_PEDANTIC_CHECKS = 32,
 #if 0 /* Will be marked for real deprecation later. */
 #define MHD_USE_PEDANTIC_CHECKS \
   _MHD_DEPR_IN_MACRO ( \
-    "Flag MHD_USE_PEDANTIC_CHECKS is deprecated, use option 
MHD_OPTION_STRICT_FOR_CLIENT instead") \
+    "Flag MHD_USE_PEDANTIC_CHECKS is deprecated, " \
+    "use option MHD_OPTION_CLIENT_DISCIPLINE_LVL instead") \
   32
 #endif /* 0 */
 
@@ -1939,15 +1941,18 @@ enum MHD_OPTION
    * If set to 1 - be strict about the protocol.  Use -1 to be
    * as tolerant as possible.
    *
-   * Specifically, at the moment, at 1 this flag
-   * causes MHD to reject HTTP 1.1 connections without a "Host" header,
-   * and to disallow spaces in the URL or (at -1) in HTTP header key strings.
+   * The more flexible option #MHD_OPTION_CLIENT_DISCIPLINE_LVL is recommended
+   * instead of this option.
    *
-   * These are required by some versions of the standard, but of
-   * course in violation of the "be as liberal as possible in what you
-   * accept" norm.  It is recommended to set this to 1 if you are
-   * testing clients against MHD, and 0 in production.  This option
-   * should be followed by an `int` argument.
+   * The values mapping table:
+   * #MHD_OPTION_STRICT_FOR_CLIENT | #MHD_OPTION_CLIENT_DISCIPLINE_LVL
+   * -----------------------------:|:---------------------------------
+   * 1                             | 1
+   * 0                             | 0
+   * -1                            | -3
+   *
+   * This option should be followed by an `int` argument.
+   * @sa #MHD_OPTION_CLIENT_DISCIPLINE_LVL
    */
   MHD_OPTION_STRICT_FOR_CLIENT = 29,
 
@@ -2037,7 +2042,54 @@ enum MHD_OPTION
    * default priorities.
    * @note Available since #MHD_VERSION 0x00097542
    */
-  MHD_OPTION_HTTPS_PRIORITIES_APPEND = 37
+  MHD_OPTION_HTTPS_PRIORITIES_APPEND = 37,
+
+  /**
+   * Sets specified client discipline level (i.e. HTTP protocol parsing
+   * strictness level).
+   *
+   * The following basic values are supported:
+   *  0 - default MHD level, a balance between extra security and broader
+   *      compatibility, as allowed by RFCs for HTTP servers;
+   *  1 - more strict protocol interpretation, within the limits set by
+   *      RFCs for HTTP servers;
+   * -1 - more lenient protocol interpretation, within the limits set by
+   *      RFCs for HTTP servers.
+   * The following extended values could be used as well:
+   *  2 - stricter protocol interpretation, even stricter then allowed
+   *      by RFCs for HTTP servers, however it should be absolutely compatible
+   *      with clients following at least RFCs' "MUST" type of requirements
+   *      for HTTP clients;
+   *  3 - strictest protocol interpretation, even stricter then allowed
+   *      by RFCs for HTTP servers, however it should be absolutely compatible
+   *      with clients following RFCs' "SHOULD" and "MUST" types of 
requirements
+   *      for HTTP clients;
+   * -2 - more relaxed protocol interpretation, violating RFCs' "SHOULD" type
+   *      of requirements for HTTP servers;
+   * -3 - the most flexible protocol interpretation, beyond RFCs' "MUST" type 
of
+   *      requirements for HTTP server.
+   * Values higher than "3" or lower than "-3" are interpreted as "3" or "-3"
+   * respectively.
+   *
+   * Higher values are more secure, lower values are more compatible with
+   * various HTTP clients.
+   *
+   * The default value ("0") could be used in most cases.
+   * Value "1" is suitable for highly loaded public servers.
+   * Values "2" and "3" are generally recommended only for testing of HTTP
+   * clients against MHD.
+   * Value "2" may be used for security-centric application, however it is
+   * slight violation of RFCs' requirements.
+   * Negative values are not recommended for public servers.
+   * Values "-1" and "-2" could be used for servers in isolated environment.
+   * Value "-3" is not recommended unless it is absolutely necessary to
+   * communicate with some client(s) with badly broken HTTP implementation.
+   *
+   * This option should be followed by an `int` argument.
+   * @note Available since #MHD_VERSION 0x00097545
+   */
+  MHD_OPTION_CLIENT_DISCIPLINE_LVL = 38
+
 } _MHD_FIXED_ENUM;
 
 
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 5e5c2f13..1c6070e8 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2846,15 +2846,15 @@ parse_cookies_string (char *str,
   size_t i;
   bool non_strict;
   /* Skip extra whitespaces and empty cookies */
-  const bool allow_wsp_empty = (0 >= connection->daemon->strict_for_client);
+  const bool allow_wsp_empty = (0 >= connection->daemon->client_discipline);
   /* Allow whitespaces around '=' character */
-  const bool wsp_around_eq = (0 > connection->daemon->strict_for_client);
+  const bool wsp_around_eq = (-3 >= connection->daemon->client_discipline);
   /* Allow whitespaces in quoted cookie value */
-  const bool wsp_in_quoted = (0 >= connection->daemon->strict_for_client);
+  const bool wsp_in_quoted = (0 >= connection->daemon->client_discipline);
   /* Allow tab as space after semicolon between cookies */
-  const bool tab_as_sp = (0 >= connection->daemon->strict_for_client);
+  const bool tab_as_sp = (0 >= connection->daemon->client_discipline);
   /* Allow no space after semicolon between cookies */
-  const bool allow_no_space = (0 >= connection->daemon->strict_for_client);
+  const bool allow_no_space = (0 >= connection->daemon->client_discipline);
 
   non_strict = false;
   i = 0;
@@ -3327,7 +3327,7 @@ parse_initial_message_line (struct MHD_Connection 
*connection,
       uri_len = line_len - (size_t) (uri - line);
     }
     /* check for spaces in URI if we are "strict" */
-    if ( (1 <= daemon->strict_for_client) &&
+    if ( (-2 < daemon->client_discipline) &&
          (NULL != memchr (uri,
                           ' ',
                           uri_len)) )
@@ -3752,7 +3752,7 @@ process_header_line (struct MHD_Connection *connection,
     /* error in header line, die hard */
     return MHD_NO;
   }
-  if (-1 >= connection->daemon->strict_for_client)
+  if (-3 < connection->daemon->client_discipline)
   {
     /* check for whitespace before colon, which is not allowed
  by RFC 7230 section 3.2.4; we count space ' ' and
@@ -3897,7 +3897,7 @@ parse_connection_headers (struct MHD_Connection 
*connection)
     return;
   }
 #endif /* COOKIE_SUPPORT */
-  if ( (1 <= connection->daemon->strict_for_client) &&
+  if ( (-3 < connection->daemon->client_discipline) &&
        (MHD_IS_HTTP_VER_1_1_COMPAT (connection->rq.http_ver)) &&
        (MHD_NO ==
         MHD_lookup_connection_value_n (connection,
@@ -3946,7 +3946,7 @@ parse_connection_headers (struct MHD_Connection 
*connection)
                                             NULL))
     {
       /* TODO: add individual settings */
-      if (1 <= connection->daemon->strict_for_client)
+      if (1 <= connection->daemon->client_discipline)
       {
         transmit_error_response_static (connection,
                                         MHD_HTTP_BAD_REQUEST,
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index d854de31..746d9493 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -5729,7 +5729,7 @@ unescape_wrapper (void *cls,
   (void) cls; /* Mute compiler warning. */
 
   /* TODO: add individual parameter */
-  if (1 <= connection->daemon->strict_for_client)
+  if (0 <= connection->daemon->client_discipline)
     return MHD_str_pct_decode_in_place_strict_ (val);
 
   res = MHD_str_pct_decode_in_place_lenient_ (val, &broken);
@@ -6653,14 +6653,33 @@ parse_options_va (struct MHD_Daemon *daemon,
                                             unsigned int);
       break;
     case MHD_OPTION_STRICT_FOR_CLIENT:
-      daemon->strict_for_client = va_arg (ap, int);
+      daemon->client_discipline = va_arg (ap, int); /* Temporal assignment */
+      /* Map to correct value */
+      if (-1 >= daemon->client_discipline)
+        daemon->client_discipline = -3;
+      else if (1 <= daemon->client_discipline)
+        daemon->client_discipline = 1;
 #ifdef HAVE_MESSAGES
       if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
-           (1 != daemon->strict_for_client) )
+           (1 != daemon->client_discipline) )
       {
         MHD_DLOG (daemon,
                   _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
-                     "another behavior is specified by 
MHD_OPTION_STRICT_CLIENT.\n"));
+                     "another behaviour is specified by "
+                     "MHD_OPTION_STRICT_CLIENT.\n"));
+      }
+#endif /* HAVE_MESSAGES */
+      break;
+    case MHD_OPTION_CLIENT_DISCIPLINE_LVL:
+      daemon->client_discipline = va_arg (ap, int);
+#ifdef HAVE_MESSAGES
+      if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
+           (1 != daemon->client_discipline) )
+      {
+        MHD_DLOG (daemon,
+                  _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
+                     "another behaviour is specified by "
+                     "MHD_OPTION_CLIENT_DISCIPLINE_LVL.\n"));
       }
 #endif /* HAVE_MESSAGES */
       break;
@@ -6723,6 +6742,7 @@ parse_options_va (struct MHD_Daemon *daemon,
           break;
         /* all options taking 'int' */
         case MHD_OPTION_STRICT_FOR_CLIENT:
+        case MHD_OPTION_CLIENT_DISCIPLINE_LVL:
         case MHD_OPTION_SIGPIPE_HANDLED_BY_APP:
         case MHD_OPTION_TLS_NO_ALPN:
           if (MHD_NO == parse_options (daemon,
@@ -7102,8 +7122,8 @@ MHD_start_daemon_va (unsigned int flags,
   daemon->listening_address_reuse = 0;
   daemon->options = *pflags;
   pflags = &daemon->options;
-  daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 :
-                              0;
+  daemon->client_discipline = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ?
+                              1 : 0;
   daemon->port = port;
   daemon->apc = apc;
   daemon->apc_cls = apc_cls;
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 78481b21..9f5ed442 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -2104,9 +2104,10 @@ struct MHD_Daemon
   unsigned int per_ip_connection_limit;
 
   /**
-   * Be neutral (zero), strict (1) or permissive (-1) to client.
+   * The strictness level for parsing of incoming data.
+   * @see #MHD_OPTION_CLIENT_DISCIPLINE_LVL
    */
-  int strict_for_client;
+  int client_discipline;
 
   /**
    * True if SIGPIPE is blocked

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