diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-10-11 09:41:15 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-10-13 09:07:02 +0300 |
commit | 6e95c305e4f0a3b0c33d8d4db7db8058f998e089 (patch) | |
tree | bcdef304d833a5dd25b64471f20cf63f09a86a3c | |
parent | ce538bc10254dbe52ea8ae66aeb0bc77605d1547 (diff) | |
download | libmicrohttpd-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.h | 13 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 117 |
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 | */ | ||
5899 | enum 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 | |||
5909 | static 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 | */ | ||
5923 | static bool | ||
5924 | daemon_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)) && |