aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-10-12 18:13:52 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-10-13 09:07:02 +0300
commit0b9776811f2d8bd1041b759bd84733754bba7b3e (patch)
tree8f818713adda4a8d00c2e24bee3c48951df9d49d
parentc8b0bf5627c20f6681ec9207ad4b30d84ef825e9 (diff)
downloadlibmicrohttpd-0b9776811f2d8bd1041b759bd84733754bba7b3e.tar.gz
libmicrohttpd-0b9776811f2d8bd1041b759bd84733754bba7b3e.zip
Added new MHD option to append TLS priorities string
The string is appended to default GnuTLS priorities. This way application may control priorities details, while leaving the basic settings to system's defaults.
-rw-r--r--src/include/microhttpd.h16
-rw-r--r--src/microhttpd/daemon.c190
2 files changed, 204 insertions, 2 deletions
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 94e6095c..13bfa554 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 0x00097541 99#define MHD_VERSION 0x00097542
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',
@@ -2025,7 +2025,19 @@ enum MHD_OPTION
2025 * When not specified, default value #MHD_DAUTH_BIND_NONCE_NONE is used. 2025 * When not specified, default value #MHD_DAUTH_BIND_NONCE_NONE is used.
2026 * @note Available since #MHD_VERSION 0x00097531 2026 * @note Available since #MHD_VERSION 0x00097531
2027 */ 2027 */
2028 MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE = 36 2028 MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE = 36,
2029
2030 /**
2031 * Memory pointer to a `const char *` specifying the GnuTLS priorities to be
2032 * appended to default priorities.
2033 * This allow some specific options to be enabled/disabled, while leaving
2034 * the rest of the settings to their defaults.
2035 * The string does not have to start with a colon ':' character.
2036 * See #MHD_OPTION_HTTPS_PRIORITIES description for details of automatic
2037 * default priorities.
2038 * @note Available since #MHD_VERSION 0x00097542
2039 */
2040 MHD_OPTION_HTTPS_PRIORITIES_APPEND = 37
2029} _MHD_FIXED_ENUM; 2041} _MHD_FIXED_ENUM;
2030 2042
2031 2043
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index a12bbadb..9135af8c 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -5983,6 +5983,175 @@ daemon_tls_priorities_init_default (struct MHD_Daemon *daemon)
5983} 5983}
5984 5984
5985 5985
5986/**
5987 * The inner helper function for #daemon_tls_priorities_init_app().
5988 * @param daemon the daemon to use
5989 * @param prio the appication-specified appendix for default priorities
5990 * @param prio_len the length of @a prio
5991 * @param buf the temporal buffer for string manipulations
5992 * @param buf_size the size of the @a buf
5993 * @return true on success, false on error
5994 */
5995static bool
5996daemon_tls_priorities_init_append_inner_ (struct MHD_Daemon *daemon,
5997 const char *prio,
5998 size_t prio_len,
5999 char *buf,
6000 const size_t buf_size)
6001{
6002 unsigned int p;
6003 int res;
6004 const char *err_pos;
6005
6006 (void) buf_size; /* Mute compiler warning for non-Debug builds */
6007 mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS));
6008 mhd_assert (NULL == daemon->priority_cache);
6009 mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \
6010 sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]));
6011
6012 for (p = 0;
6013 p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]);
6014 ++p)
6015 {
6016
6017#if GNUTLS_VERSION_NUMBER >= 0x030300
6018#if GNUTLS_VERSION_NUMBER >= 0x030603
6019 if (NULL == MHD_TlsBasePriotities[p].str)
6020 res = gnutls_priority_init2 (&daemon->priority_cache, prio, &err_pos,
6021 GNUTLS_PRIORITY_INIT_DEF_APPEND);
6022 else
6023#else \
6024 /* 0x030300 <= GNUTLS_VERSION_NUMBER && GNUTLS_VERSION_NUMBER < 0x030603 */
6025 if (NULL == MHD_TlsBasePriotities[p].str)
6026 continue; /* Skip the value, no way to append priorities to the default string */
6027 else
6028#endif /* GNUTLS_VERSION_NUMBER < 0x030603 */
6029#endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
6030 if (1)
6031 {
6032 size_t buf_pos;
6033
6034 mhd_assert (NULL != MHD_TlsBasePriotities[p].str);
6035 buf_pos = 0;
6036 memcpy (buf + buf_pos, MHD_TlsBasePriotities[p].str,
6037 MHD_TlsBasePriotities[p].len);
6038 buf_pos += MHD_TlsBasePriotities[p].len;
6039 buf[buf_pos++] = ':';
6040 memcpy (buf + buf_pos, prio, prio_len + 1);
6041#ifdef _DEBUG
6042 buf_pos += prio_len + 1;
6043 mhd_assert (buf_size >= buf_pos);
6044#endif /* _DEBUG */
6045 res = gnutls_priority_init (&daemon->priority_cache, buf, &err_pos);
6046 }
6047 if (GNUTLS_E_SUCCESS == res)
6048 {
6049#ifdef _DEBUG
6050#ifdef HAVE_MESSAGES
6051 switch ((enum MHD_TlsPrioritiesBaseType) p)
6052 {
6053 case MHD_TLS_PRIO_BASE_LIBMHD:
6054 MHD_DLOG (daemon,
6055 _ ("GnuTLS priorities have been initialised with " \
6056 "priorities specified by application appended to " \
6057 "@LIBMICROHTTPD application-specific system-wide " \
6058 "configuration.\n") );
6059 break;
6060 case MHD_TLS_PRIO_BASE_SYSTEM:
6061 MHD_DLOG (daemon,
6062 _ ("GnuTLS priorities have been initialised with " \
6063 "priorities specified by application appended to " \
6064 "@SYSTEM system-wide configuration.\n") );
6065 break;
6066#if GNUTLS_VERSION_NUMBER >= 0x030300
6067 case MHD_TLS_PRIO_BASE_DEFAULT:
6068 MHD_DLOG (daemon,
6069 _ ("GnuTLS priorities have been initialised with " \
6070 "priorities specified by application appended to " \
6071 "GnuTLS default configuration.\n") );
6072 break;
6073#endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
6074 case MHD_TLS_PRIO_BASE_NORMAL:
6075 MHD_DLOG (daemon,
6076 _ ("GnuTLS priorities have been initialised with " \
6077 "priorities specified by application appended to " \
6078 "NORMAL configuration.\n") );
6079 break;
6080 default:
6081 mhd_assert (0);
6082 }
6083#endif /* HAVE_MESSAGES */
6084#endif /* _DEBUG */
6085 return true;
6086 }
6087 }
6088#ifdef HAVE_MESSAGES
6089 MHD_DLOG (daemon,
6090 _ ("Failed to set GnuTLS priorities. Last error: %s. " \
6091 "The problematic part starts at: %s\n"),
6092 gnutls_strerror (res), err_pos);
6093#endif /* HAVE_MESSAGES */
6094 return false;
6095}
6096
6097
6098#define LOCAL_BUFF_SIZE 128
6099
6100/**
6101 * Initialise TLS priorities with default settings with application-specified
6102 * appended string.
6103 * @param daemon the daemon to initialise TLS priorities
6104 * @param prio the application specified priorities to be appended to
6105 * the GnuTLS standard priorities string
6106 * @return true on success, false on error
6107 */
6108static bool
6109daemon_tls_priorities_init_append (struct MHD_Daemon *daemon, const char *prio)
6110{
6111 static const size_t longest_base_prio = MHD_TlsBasePriotities[0].len;
6112 bool ret;
6113 size_t prio_len;
6114 size_t buf_size_needed;
6115
6116 if (NULL == prio)
6117 return daemon_tls_priorities_init_default (daemon);
6118
6119 if (':' == prio[0])
6120 ++prio;
6121
6122 prio_len = strlen (prio);
6123
6124 buf_size_needed = longest_base_prio + 1 + prio_len + 1;
6125
6126 if (LOCAL_BUFF_SIZE >= buf_size_needed)
6127 {
6128 char local_buffer[LOCAL_BUFF_SIZE];
6129 ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len,
6130 local_buffer,
6131 LOCAL_BUFF_SIZE);
6132 }
6133 else
6134 {
6135 char *allocated_buffer;
6136 allocated_buffer = (char *) malloc (buf_size_needed);
6137 if (NULL == allocated_buffer)
6138 {
6139#ifdef HAVE_MESSAGES
6140 MHD_DLOG (daemon,
6141 _ ("Error allocating memory: %s\n"),
6142 MHD_strerror_ (errno));
6143#endif
6144 return false;
6145 }
6146 ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len,
6147 allocated_buffer,
6148 buf_size_needed);
6149 free (allocated_buffer);
6150 }
6151 return ret;
6152}
6153
6154
5986#endif /* HTTPS_SUPPORT */ 6155#endif /* HTTPS_SUPPORT */
5987 6156
5988 6157
@@ -6277,6 +6446,26 @@ parse_options_va (struct MHD_Daemon *daemon,
6277 opt); 6446 opt);
6278#endif 6447#endif
6279 break; 6448 break;
6449 case MHD_OPTION_HTTPS_PRIORITIES_APPEND:
6450 pstr = va_arg (ap,
6451 const char *);
6452 if (0 != (daemon->options & MHD_USE_TLS))
6453 {
6454 if (NULL != daemon->priority_cache)
6455 gnutls_priority_deinit (daemon->priority_cache);
6456 daemon->priority_cache = NULL;
6457 /* The next function log error messages if needed */
6458 if (! daemon_tls_priorities_init_append (daemon, pstr))
6459 return MHD_NO;
6460 }
6461#ifdef HAVE_MESSAGES
6462 else
6463 MHD_DLOG (daemon,
6464 _ ("MHD HTTPS option %d passed to MHD but " \
6465 "MHD_USE_TLS not set.\n"),
6466 opt);
6467#endif
6468 break;
6280 case MHD_OPTION_HTTPS_CERT_CALLBACK: 6469 case MHD_OPTION_HTTPS_CERT_CALLBACK:
6281#if GNUTLS_VERSION_MAJOR < 3 6470#if GNUTLS_VERSION_MAJOR < 3
6282#ifdef HAVE_MESSAGES 6471#ifdef HAVE_MESSAGES
@@ -6514,6 +6703,7 @@ parse_options_va (struct MHD_Daemon *daemon,
6514 case MHD_OPTION_HTTPS_MEM_TRUST: 6703 case MHD_OPTION_HTTPS_MEM_TRUST:
6515 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 6704 case MHD_OPTION_HTTPS_MEM_DHPARAMS:
6516 case MHD_OPTION_HTTPS_PRIORITIES: 6705 case MHD_OPTION_HTTPS_PRIORITIES:
6706 case MHD_OPTION_HTTPS_PRIORITIES_APPEND:
6517 case MHD_OPTION_ARRAY: 6707 case MHD_OPTION_ARRAY:
6518 case MHD_OPTION_HTTPS_CERT_CALLBACK: 6708 case MHD_OPTION_HTTPS_CERT_CALLBACK:
6519 case MHD_OPTION_HTTPS_CERT_CALLBACK2: 6709 case MHD_OPTION_HTTPS_CERT_CALLBACK2: