aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-10-11 09:41:15 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-10-13 09:07:02 +0300
commit6e95c305e4f0a3b0c33d8d4db7db8058f998e089 (patch)
treebcdef304d833a5dd25b64471f20cf63f09a86a3c
parentce538bc10254dbe52ea8ae66aeb0bc77605d1547 (diff)
downloadlibmicrohttpd-6e95c305e4f0a3b0c33d8d4db7db8058f998e089.tar.gz
libmicrohttpd-6e95c305e4f0a3b0c33d8d4db7db8058f998e089.zip
TLS: use application-specific system-wide configuration with fallbacks
Implemented more flexible GnuTLS priorities string initialisation. Now MHD tries to use "@LIBMICROHTTPD" configuration at first, so all MHD instances on particular system can be configured by specifying the string like "LIBMICROHTTPD = ..." in GnuTLS system-wide configuration. For example "LIBMICROHTTPD = NORMAL:-VERS-TLS1.0:-VERS-TLS1.1" could be used to disable TLS v1.0 and TLS v1.1 for all MHD instances. If application-specific configuration is not available, then default "@SYSTEM" run-time configuration is used. If "@SYSTEM" is not defined, then GnuTLS build-time default string is used. Standard "NORMAL" configuration is used if everything else fails.
-rw-r--r--src/include/microhttpd.h13
-rw-r--r--src/microhttpd/daemon.c117
2 files changed, 119 insertions, 11 deletions
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 63afc9e0..94e6095c 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -96,7 +96,7 @@ extern "C"
96 * they are parsed as decimal numbers. 96 * they are parsed as decimal numbers.
97 * Example: 0x01093001 = 1.9.30-1. 97 * Example: 0x01093001 = 1.9.30-1.
98 */ 98 */
99#define MHD_VERSION 0x00097540 99#define MHD_VERSION 0x00097541
100 100
101/* If generic headers don't work on your platform, include headers 101/* If generic headers don't work on your platform, include headers
102 which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t', 102 which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t',
@@ -1732,8 +1732,15 @@ enum MHD_OPTION
1732 MHD_OPTION_HTTPS_CRED_TYPE = 10, 1732 MHD_OPTION_HTTPS_CRED_TYPE = 10,
1733 1733
1734 /** 1734 /**
1735 * Memory pointer to a `const char *` specifying the 1735 * Memory pointer to a `const char *` specifying the GnuTLS priorities string.
1736 * cipher algorithm (default: "NORMAL"). 1736 * If this options is not specified, then MHD will try the following strings:
1737 * * "@LIBMICROHTTPD" (application-specific system-wide configuration)
1738 * * "@SYSTEM" (system-wide configuration)
1739 * * default GnuTLS priorities string
1740 * * "NORMAL"
1741 * The first configuration accepted by GnuTLS will be used.
1742 * For more details see GnuTLS documentation for "Application-specific
1743 * priority strings".
1737 */ 1744 */
1738 MHD_OPTION_HTTPS_PRIORITIES = 11, 1745 MHD_OPTION_HTTPS_PRIORITIES = 11,
1739 1746
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 25571f61..a12bbadb 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -5892,6 +5892,100 @@ parse_options (struct MHD_Daemon *daemon,
5892} 5892}
5893 5893
5894 5894
5895#ifdef HTTPS_SUPPORT
5896/**
5897 * Type of GnuTLS priorities base string
5898 */
5899enum MHD_TlsPrioritiesBaseType
5900{
5901 MHD_TLS_PRIO_BASE_LIBMHD = 0, /**< @c "@LIBMICROHTTPD" */
5902 MHD_TLS_PRIO_BASE_SYSTEM = 1, /**< @c "@SYSTEM" */
5903#if GNUTLS_VERSION_NUMBER >= 0x030300
5904 MHD_TLS_PRIO_BASE_DEFAULT, /**< Default priorities string */
5905#endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
5906 MHD_TLS_PRIO_BASE_NORMAL /**< @c "NORMAL */
5907};
5908
5909static const struct _MHD_cstr_w_len MHD_TlsBasePriotities[] = {
5910 _MHD_S_STR_W_LEN ("@LIBMICROHTTPD"),
5911 _MHD_S_STR_W_LEN ("@SYSTEM"),
5912#if GNUTLS_VERSION_NUMBER >= 0x030300
5913 {NULL, 0},
5914#endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
5915 _MHD_S_STR_W_LEN ("NORMAL")
5916};
5917
5918/**
5919 * Initialise TLS priorities with default settings
5920 * @param daemon the daemon to initialise TLS priorities
5921 * @return true on success, false on error
5922 */
5923static bool
5924daemon_tls_priorities_init_default (struct MHD_Daemon *daemon)
5925{
5926 unsigned int p;
5927 int res;
5928
5929 mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS));
5930 mhd_assert (NULL == daemon->priority_cache);
5931 mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \
5932 sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]));
5933
5934 for (p = 0;
5935 p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]);
5936 ++p)
5937 {
5938 res = gnutls_priority_init (&daemon->priority_cache,
5939 MHD_TlsBasePriotities[p].str, NULL);
5940 if (GNUTLS_E_SUCCESS == res)
5941 {
5942#ifdef _DEBUG
5943#ifdef HAVE_MESSAGES
5944 switch ((enum MHD_TlsPrioritiesBaseType) p)
5945 {
5946 case MHD_TLS_PRIO_BASE_LIBMHD:
5947 MHD_DLOG (daemon,
5948 _ ("GnuTLS priorities have been initialised with " \
5949 "@LIBMICROHTTPD application-specific system-wide " \
5950 "configuration.\n") );
5951 break;
5952 case MHD_TLS_PRIO_BASE_SYSTEM:
5953 MHD_DLOG (daemon,
5954 _ ("GnuTLS priorities have been initialised with " \
5955 "@SYSTEM system-wide configuration.\n") );
5956 break;
5957#if GNUTLS_VERSION_NUMBER >= 0x030300
5958 case MHD_TLS_PRIO_BASE_DEFAULT:
5959 MHD_DLOG (daemon,
5960 _ ("GnuTLS priorities have been initialised with " \
5961 "GnuTLS default configuration.\n") );
5962 break;
5963#endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
5964 case MHD_TLS_PRIO_BASE_NORMAL:
5965 MHD_DLOG (daemon,
5966 _ ("GnuTLS priorities have been initialised with " \
5967 "NORMAL configuration.\n") );
5968 break;
5969 default:
5970 mhd_assert (0);
5971 }
5972#endif /* HAVE_MESSAGES */
5973#endif /* _DEBUG */
5974 return true;
5975 }
5976 }
5977#ifdef HAVE_MESSAGES
5978 MHD_DLOG (daemon,
5979 _ ("Failed to set GnuTLS priorities. Last error: %s\n"),
5980 gnutls_strerror (res));
5981#endif /* HAVE_MESSAGES */
5982 return false;
5983}
5984
5985
5986#endif /* HTTPS_SUPPORT */
5987
5988
5895/** 5989/**
5896 * Parse a list of options given as varargs. 5990 * Parse a list of options given as varargs.
5897 * 5991 *
@@ -6158,7 +6252,8 @@ parse_options_va (struct MHD_Daemon *daemon,
6158 if (0 != (daemon->options & MHD_USE_TLS)) 6252 if (0 != (daemon->options & MHD_USE_TLS))
6159 { 6253 {
6160 int init_res; 6254 int init_res;
6161 gnutls_priority_deinit (daemon->priority_cache); 6255 if (NULL != daemon->priority_cache)
6256 gnutls_priority_deinit (daemon->priority_cache);
6162 init_res = gnutls_priority_init (&daemon->priority_cache, 6257 init_res = gnutls_priority_init (&daemon->priority_cache,
6163 pstr, 6258 pstr,
6164 NULL); 6259 NULL);
@@ -6653,7 +6748,6 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
6653 6748
6654#endif 6749#endif
6655 6750
6656
6657/** 6751/**
6658 * Start a webserver on the given port. 6752 * Start a webserver on the given port.
6659 * 6753 *
@@ -6775,12 +6869,6 @@ MHD_start_daemon_va (unsigned int flags,
6775 /* try to open listen socket */ 6869 /* try to open listen socket */
6776#ifdef HTTPS_SUPPORT 6870#ifdef HTTPS_SUPPORT
6777 daemon->priority_cache = NULL; 6871 daemon->priority_cache = NULL;
6778 if (0 != (*pflags & MHD_USE_TLS))
6779 {
6780 gnutls_priority_init (&daemon->priority_cache,
6781 "NORMAL",
6782 NULL);
6783 }
6784#endif /* HTTPS_SUPPORT */ 6872#endif /* HTTPS_SUPPORT */
6785 daemon->listen_fd = MHD_INVALID_SOCKET; 6873 daemon->listen_fd = MHD_INVALID_SOCKET;
6786 daemon->listen_is_unix = _MHD_NO; 6874 daemon->listen_is_unix = _MHD_NO;
@@ -6857,6 +6945,19 @@ MHD_start_daemon_va (unsigned int flags,
6857 free (daemon); 6945 free (daemon);
6858 return NULL; 6946 return NULL;
6859 } 6947 }
6948#ifdef HTTPS_SUPPORT
6949 if ((0 != (*pflags & MHD_USE_TLS))
6950 && (NULL == daemon->priority_cache)
6951 && ! daemon_tls_priorities_init_default (daemon))
6952 {
6953#ifdef HAVE_MESSAGES
6954 MHD_DLOG (daemon,
6955 _ ("Failed to initialise GnuTLS priorities.\n"));
6956#endif /* HAVE_MESSAGES */
6957 free (daemon);
6958 return NULL;
6959 }
6960#endif /* HTTPS_SUPPORT */
6860 6961
6861#ifdef HAVE_MESSAGES 6962#ifdef HAVE_MESSAGES
6862 if ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) && 6963 if ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) &&