gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] 22/31: test_https_session_info: removed hardcoded TLS ve


From: gnunet
Subject: [libmicrohttpd] 22/31: test_https_session_info: removed hardcoded TLS version
Date: Mon, 10 Oct 2022 13:01:07 +0200

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

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit cfe614ca375d068b203db10207c97930936f779b
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Sat Oct 8 18:46:15 2022 +0300

    test_https_session_info: removed hardcoded TLS version
    
    Test rewritten to use several known TLS versions. If all known TLS
    version fail, test is skipped instead of error.
    This way MHD is forward-compatible with TLS libraries versions, as
    TLS versions are phased out from time to time.
---
 src/testcurl/https/test_https_session_info.c | 311 +++++++++++++++++++--------
 src/testcurl/https/tls_test_common.c         |  23 ++
 src/testcurl/https/tls_test_common.h         |  29 +++
 3 files changed, 276 insertions(+), 87 deletions(-)

diff --git a/src/testcurl/https/test_https_session_info.c 
b/src/testcurl/https/test_https_session_info.c
index c3ddae4f..c5c38742 100644
--- a/src/testcurl/https/test_https_session_info.c
+++ b/src/testcurl/https/test_https_session_info.c
@@ -35,7 +35,6 @@
 #include "tls_test_common.h"
 #include "tls_test_keys.h"
 
-#if LIBCURL_VERSION_NUM >= 0x072200
 static struct MHD_Daemon *d;
 
 /*
@@ -43,45 +42,45 @@ static struct MHD_Daemon *d;
  * used to query negotiated security parameters
  */
 static enum MHD_Result
-query_session_ahc (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)
+query_info_ahc (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)
 {
   struct MHD_Response *response;
   enum MHD_Result ret;
-  int gret;
-  (void) cls; (void) url; (void) method; (void) version;   /* Unused. Silent 
compiler warning. */
-  (void) upload_data; (void) upload_data_size;             /* Unused. Silent 
compiler warning. */
+  const union MHD_ConnectionInfo *conn_info;
+  enum know_gnutls_tls_id *used_tls_ver;
+  (void) url; (void) method; (void) version;   /* Unused. Silent compiler 
warning. */
+  (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler 
warning. */
+  used_tls_ver = (enum know_gnutls_tls_id *) cls;
 
   if (NULL == *req_cls)
   {
-    *req_cls = (void *) &query_session_ahc;
+    *req_cls = (void *) &query_info_ahc;
     return MHD_YES;
   }
 
-  if (GNUTLS_TLS1_1 !=
-      (gret = MHD_get_connection_info
-                (connection,
-                MHD_CONNECTION_INFO_PROTOCOL)->protocol))
+  conn_info = MHD_get_connection_info (connection,
+                                       MHD_CONNECTION_INFO_PROTOCOL);
+  if (NULL == conn_info)
   {
-    if (GNUTLS_TLS1_2 == gret)
-    {
-      /* as usual, TLS implementations sometimes don't
-         quite do what was asked, just mildly complain... */
-      fprintf (stderr,
-               "Warning: requested TLS 1.1, got TLS 1.2\n");
-    }
-    else
-    {
-      /* really different version... */
-      fprintf (stderr,
-               "Error: requested protocol mismatch (wanted %d, got %d)\n",
-               GNUTLS_TLS1_1,
-               gret);
-      return MHD_NO;
-    }
+    fflush (stderr);
+    fflush (stdout);
+    fprintf (stderr, "MHD_get_connection_info() failed.\n");
+    fflush (stderr);
+    return MHD_NO;
   }
+  if (0 == (unsigned int) conn_info->protocol)
+  {
+    fflush (stderr);
+    fflush (stdout);
+    fprintf (stderr, "MHD_get_connection_info()->protocol has "
+             "wrong zero value.\n");
+    fflush (stderr);
+    return MHD_NO;
+  }
+  *used_tls_ver = (enum know_gnutls_tls_id) conn_info->protocol;
 
   response = MHD_create_response_from_buffer_static (strlen (EMPTY_PAGE),
                                                      EMPTY_PAGE);
@@ -95,30 +94,27 @@ query_session_ahc (void *cls, struct MHD_Connection 
*connection,
  * negotiate a secure connection with server & query negotiated security 
parameters
  */
 static unsigned int
-test_query_session (void)
+test_query_session (enum know_gnutls_tls_id tls_ver, uint16_t *pport)
 {
   CURL *c;
   struct CBC cbc;
   CURLcode errornum;
   char url[256];
-  uint16_t port;
-
-  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
-    port = 0;
-  else
-    port = 3060;
+  enum know_gnutls_tls_id found_tls_ver;
 
   if (NULL == (cbc.buf = malloc (sizeof (char) * 255)))
-    return 16;
+    return 99;
   cbc.size = 255;
   cbc.pos = 0;
 
   /* setup test */
+  found_tls_ver = KNOWN_BAD;
   d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
                         | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
-                        | MHD_USE_ERROR_LOG, port,
-                        NULL, NULL, &query_session_ahc, NULL,
-                        MHD_OPTION_HTTPS_PRIORITIES, "NORMAL:+ARCFOUR-128",
+                        | MHD_USE_ERROR_LOG, *pport,
+                        NULL, NULL,
+                        &query_info_ahc, &found_tls_ver,
+                        MHD_OPTION_HTTPS_PRIORITIES, priorities_map[tls_ver],
                         MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
                         MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
                         MHD_OPTION_END);
@@ -126,63 +122,219 @@ test_query_session (void)
   if (d == NULL)
   {
     free (cbc.buf);
-    return 2;
+    fflush (stderr);
+    fflush (stdout);
+    fprintf (stderr, "MHD_start_daemon() with %s failed.\n",
+             tls_names[tls_ver]);
+    fflush (stderr);
+    return 77;
   }
-  if (0 == port)
+  if (0 == *pport)
   {
     const union MHD_DaemonInfo *dinfo;
     dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
     if ((NULL == dinfo) || (0 == dinfo->port) )
     {
       MHD_stop_daemon (d);
+      fflush (stderr);
+      fflush (stdout);
+      fprintf (stderr, "MHD_get_daemon_info() failed.\n");
+      fflush (stderr);
       free (cbc.buf);
-      return 32;
+      return 10;
     }
-    port = dinfo->port;
+    *pport = dinfo->port; /* Use the same port for rest of the checks */
   }
 
   gen_test_uri (url,
                 sizeof (url),
-                port);
+                *pport);
   c = curl_easy_init ();
 #ifdef _DEBUG
   curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
 #endif
-  curl_easy_setopt (c, CURLOPT_URL, url);
-  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
-  curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);
-  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L);
-  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
-  curl_easy_setopt (c, CURLOPT_FILE, &cbc);
-  /* TLS options */
-  curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
-  /* currently skip any peer authentication */
-  curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
-  curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L);
-  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
-
-  /* NOTE: use of CONNECTTIMEOUT without also
-   * setting NOSIGNAL results in really weird
-   * crashes on my system! */
-  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
-  if (CURLE_OK != (errornum = curl_easy_perform (c)))
+
+  if ((CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_URL, url))) ||
+      (CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+                                                 CURL_HTTP_VERSION_1_1))) ||
+      (CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L))) ||
+      (CURLE_OK !=
+       (errornum = curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L))) ||
+      (CURLE_OK !=
+       (errornum = curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer))) 
||
+      (CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_WRITEDATA,
+                                                 &cbc))) ||
+      /* TLS options */
+      /* currently skip any peer authentication */
+      (CURLE_OK !=
+       (errornum = curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L))) ||
+      (CURLE_OK !=
+       (errornum = curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L))) ||
+      (CURLE_OK !=
+       (errornum = curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L))) ||
+      (CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L))))
   {
-    fprintf (stderr, "curl_easy_perform failed: `%s'\n",
+    fflush (stderr);
+    fflush (stdout);
+    fprintf (stderr, "Error setting libcurl option: %s.\n",
              curl_easy_strerror (errornum));
+    fflush (stderr);
+    return 99;
+  }
 
+  if (CURLE_OK != (errornum = curl_easy_perform (c)))
+  {
+    unsigned int ret;
     MHD_stop_daemon (d);
     curl_easy_cleanup (c);
     free (cbc.buf);
-    return 1;
+
+    fflush (stderr);
+    fflush (stdout);
+    if ((CURLE_SSL_CONNECT_ERROR == errornum) ||
+        (CURLE_SSL_CIPHER == errornum))
+    {
+      ret = 77;
+      fprintf (stderr, "libcurl request failed due to TLS error: '%s'\n",
+               curl_easy_strerror (errornum));
+
+    }
+    else
+    {
+      ret = 1;
+      fprintf (stderr, "curl_easy_perform failed: '%s'\n",
+               curl_easy_strerror (errornum));
+    }
+    fflush (stderr);
+
+    return ret;
   }
 
   curl_easy_cleanup (c);
   MHD_stop_daemon (d);
   free (cbc.buf);
+
+  if (tls_ver != found_tls_ver)
+  {
+    fflush (stderr);
+    fflush (stdout);
+    fprintf (stderr, "MHD_get_connection_info (conn, "
+             "MHD_CONNECTION_INFO_PROTOCOL) returned unexpected "
+             "protocol version.\n"
+             "\tReturned: %s (%u)\tExpected: %s (%u)\n",
+             ((unsigned int) found_tls_ver) > KNOWN_TLS_MAX ?
+             "[wrong value]" : tls_names[found_tls_ver],
+             (unsigned int) found_tls_ver,
+             tls_names[tls_ver], (unsigned int) tls_ver);
+    fflush (stderr);
+    return 2;
+  }
   return 0;
 }
 
 
+static unsigned int
+test_all_supported_versions (void)
+{
+  enum know_gnutls_tls_id ver_for_test; /**< TLS version used for test */
+  const gnutls_protocol_t *vers_list;    /**< The list of GnuTLS supported TLS 
versions */
+  uint16_t port;
+  unsigned int num_success; /**< Number of tests succeeded */
+  unsigned int num_failed;  /**< Number of tests failed */
+
+  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+    port = 0;     /* Use system automatic assignment */
+  else
+    port = 3060;  /* Use predefined port, may break parallel testing of 
another MHD build */
+
+  vers_list = gnutls_protocol_list ();
+  if (NULL == vers_list)
+  {
+    fflush (stderr);
+    fflush (stdout);
+    fprintf (stderr, "Error getting GnuTLS supported TLS versions");
+    fflush (stdout);
+    return 99;
+  }
+  num_success = 0;
+  num_failed = 0;
+
+  for (ver_for_test = KNOWN_TLS_MIN; KNOWN_TLS_MAX >= ver_for_test;
+       ++ver_for_test)
+  {
+    const gnutls_protocol_t *ver_ptr;      /**< The pointer to the position on 
the @a vers_list */
+    unsigned int res;
+    for (ver_ptr = vers_list; 0 != *ver_ptr; ++ver_ptr)
+    {
+      if (ver_for_test == (enum know_gnutls_tls_id) *ver_ptr)
+        break;
+    }
+    if (0 == *ver_ptr)
+    {
+      fflush (stderr);
+      printf ("%s is not supported by GnuTLS, skipping.\n\n",
+              tls_names[ver_for_test]);
+      fflush (stdout);
+      continue;
+    }
+    fflush (stderr);
+    printf ("Starting check for %s...\n",
+            tls_names[ver_for_test]);
+    fflush (stdout);
+    res = test_query_session (ver_for_test, &port);
+    if (99 == res)
+    {
+      fflush (stderr);
+      fflush (stdout);
+      fprintf (stderr, "Hard error. Test stopped.\n");
+      fflush (stderr);
+      return 99;
+    }
+    else if (77 == res)
+    {
+      fflush (stderr);
+      printf ("%s does not work with libcurl client and GnuTLS "
+              "server combination, skipping.\n",
+              tls_names[ver_for_test]);
+      fflush (stdout);
+    }
+    else if (0 != res)
+    {
+      fflush (stderr);
+      fflush (stdout);
+      fprintf (stderr, "Check failed for %s.\n",
+               tls_names[ver_for_test]);
+      fflush (stderr);
+      num_failed++;
+    }
+    else
+    {
+      fflush (stderr);
+      printf ("Check succeeded for %s.\n",
+              tls_names[ver_for_test]);
+      fflush (stdout);
+      num_success++;
+    }
+    printf ("\n");
+    fflush (stdout);
+  }
+
+  if (0 == num_failed)
+  {
+    if (0 == num_success)
+    {
+      fflush (stderr);
+      fflush (stdout);
+      fprintf (stderr, "No supported TLS version was found.\n");
+      fflush (stderr);
+      return 77;
+    }
+    return 0;
+  }
+  return num_failed;
+}
+
+
 int
 main (int argc, char *const *argv)
 {
@@ -206,29 +358,14 @@ main (int argc, char *const *argv)
     curl_global_cleanup ();
     return 77;
   }
-  if (! curl_tls_is_gnutls ())
-  {
-    fprintf (stderr, "This test can be run only with libcurl-gnutls.\n");
-    curl_global_cleanup ();
+  errorCount = test_all_supported_versions ();
+  fflush (stderr);
+  fflush (stdout);
+  curl_global_cleanup ();
+  if (77 == errorCount)
     return 77;
-  }
-  errorCount += test_query_session ();
+  else if (99 == errorCount)
+    return 99;
   print_test_result (errorCount, argv[0]);
-  curl_global_cleanup ();
   return errorCount != 0 ? 1 : 0;
 }
-
-
-#else  /* LIBCURL_VERSION_NUM < 0x072200 */
-
-int
-main (int argc, char *const *argv)
-{
-  (void) argc; (void) argv;   /* Unused. Silent compiler warning. */
-  fprintf (stderr, "libcurl version 7.34.0 or later is required.\n" \
-           "Cannot run the test.\n");
-  return 77;
-}
-
-
-#endif /* LIBCURL_VERSION_NUM < 0x072200 */
diff --git a/src/testcurl/https/tls_test_common.c 
b/src/testcurl/https/tls_test_common.c
index da62b267..fba9068a 100644
--- a/src/testcurl/https/tls_test_common.c
+++ b/src/testcurl/https/tls_test_common.c
@@ -26,6 +26,29 @@
 #include "tls_test_common.h"
 #include "tls_test_keys.h"
 
+/**
+ * Map @a know_gnutls_tls_ids values to printable names.
+ */
+const char *tls_names[6] = {
+  "Bad value",
+  "SSL version 3",
+  "TLS version 1.0",
+  "TLS version 1.1",
+  "TLS version 1.2",
+  "TLS version 1.3"
+};
+
+/**
+ * Map @a know_gnutls_tls_ids values to GnuTLS priorities strings.
+ */
+const char *priorities_map[6] = {
+  "NONE",
+  "NORMAL:!VERS-ALL:+VERS-SSL3.0",
+  "NORMAL:!VERS-ALL:+VERS-TLS1.0",
+  "NORMAL:!VERS-ALL:+VERS-TLS1.1",
+  "NORMAL:!VERS-ALL:+VERS-TLS1.2",
+  "NORMAL:!VERS-ALL:+VERS-TLS1.3"
+};
 
 /*
  * test HTTPS transfer
diff --git a/src/testcurl/https/tls_test_common.h 
b/src/testcurl/https/tls_test_common.h
index a3fcc5dc..784ab173 100644
--- a/src/testcurl/https/tls_test_common.h
+++ b/src/testcurl/https/tls_test_common.h
@@ -44,6 +44,35 @@
 #define MHD_E_FAILED_TO_CONNECT \
   "Error: server connection could not be established\n"
 
+
+/* The local copy if GnuTLS IDs to avoid long #ifdefs list with various
+ * GnuTLS versions */
+/**
+ * The list of know (at the moment of writing) GnuTLS IDs of TLS versions.
+ * Can be safely casted to/from @a gnutls_protocol_t.
+ */
+enum know_gnutls_tls_id
+{
+  KNOWN_BAD = 0,       /**< No TLS */
+  KNOWN_TLS_SSLv3 = 1, /**< GNUTLS_SSL3 */
+  KNOWN_TLS_V1_0 =  2, /**< GNUTLS_TLS1_0 */
+  KNOWN_TLS_V1_1 =  3, /**< GNUTLS_TLS1_1 */
+  KNOWN_TLS_V1_2 =  4, /**< GNUTLS_TLS1_2 */
+  KNOWN_TLS_V1_3 =  5, /**< GNUTLS_TLS1_3 */
+  KNOWN_TLS_MIN = KNOWN_TLS_SSLv3, /**< Minimum valid value */
+  KNOWN_TLS_MAX = KNOWN_TLS_V1_3   /**< Maximum valid value */
+};
+
+/**
+ * Map @a know_gnutls_tls_ids values to printable names.
+ */
+extern const char *tls_names[6];
+
+/**
+ * Map @a know_gnutls_tls_ids values to GnuTLS priorities strings.
+ */
+extern const char *priorities_map[6];
+
 struct https_test_data
 {
   void *cls;

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