commit cd822104183907286bc20e3d5b11886478f033fe
parent 0469d08820522ca62916c5f963d12f256c270608
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Thu, 18 Dec 2025 15:55:14 +0100
GnuTLS backend: implemented support for custom profile in the configuration file
Diffstat:
1 file changed, 72 insertions(+), 26 deletions(-)
diff --git a/src/mhd2/tls_gnu_funcs.c b/src/mhd2/tls_gnu_funcs.c
@@ -56,6 +56,7 @@
#endif
#include "mhd_assert.h"
+#include "mhd_assume.h"
#include "mhd_socket_type.h"
#include "mhd_str_types.h"
@@ -63,6 +64,7 @@
#include "mhd_str_macros.h"
#include "mhd_arr_num_elems.h"
+#include "mhd_str.h"
#include "mhd_conn_socket.h"
#include "mhd_tls_internal.h"
@@ -368,9 +370,40 @@ daemon_deinit_credentials (struct mhd_TlsGnuDaemonData *restrict d_tls)
}
+/**
+ * Try to set specified GnuTLS priorities string
+ * @param prio_string the priorities string
+ * @param d_tls the daemon TLS settings
+ * @return GNUTLS_E_SUCCESS on success,
+ * GnuTLS error code otherwise
+ */
+static MHD_FN_PAR_CSTR_ (1) MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_INOUT_ (2) int
+try_prio_string (const char *restrict prio_string,
+ struct mhd_TlsGnuDaemonData *restrict d_tls)
+{
+ int res;
+ mhd_DBG_PRINT_TLS_INFO_PARAM1 ("Trying '%s' priorities",
+ prio_string ? prio_string : "[NULL]");
+
+ res = gnutls_priority_init (&(d_tls->pri_cache),
+ prio_string,
+ NULL);
+
+ if (GNUTLS_E_SUCCESS == res)
+ {
+ mhd_DBG_PRINT_TLS_INFO_PARAM1 ("Initialised with '%s' priorities",
+ prio_string ? prio_string : "[NULL]");
+ return res;
+ }
+
+ mhd_DBG_PRINT_TLS_INFO_PARAM1 ("Failed initialise priorities: %s",
+ gnutls_strerror (res));
+
+ return res;
+}
+
+
static const struct MHD_StringNullable tlsgnulib_base_priorities[] = {
- {0, NULL} /* Replaced with app-defined name */
- ,
/* Do not use "multi-keyword": if the first configuration is found, but has
some error, the next configuration is not tried. */
#if 0 /* ifdef mhd_TLS_GNU_SUPPORTS_MULTI_KEYWORDS_PRIORITY */
@@ -401,49 +434,62 @@ daemon_init_priorities_cache (struct MHD_Daemon *restrict d,
{
size_t i;
- (void) s; // TODO: support app-defined name for TLS backend profile
-
- for (i = 0; i < mhd_ARR_NUM_ELEMS (tlsgnulib_base_priorities); ++i)
+ if (NULL != s->tls_app_name.v_app_name)
{
+ char app_name_uc[128u + 1u] = { '@' };
+ const size_t app_name_len = strlen (s->tls_app_name.v_app_name);
int res;
- if (0 == i)
- continue; // TODO: support app-defined name for TLS backend profile
+ mhd_ASSUME (128u > app_name_len);
+
+ mhd_str_to_uppercase_bin_n (app_name_len + 1u, /* '+1' for zero-termination */
+ s->tls_app_name.v_app_name,
+ app_name_uc + 1u);
+
+ res = try_prio_string (app_name_uc,
+ d_tls);
+ if (GNUTLS_E_SUCCESS == res)
+ return MHD_SC_OK;
+ else if (GNUTLS_E_MEMORY_ERROR == res)
+ return MHD_SC_DAEMON_MEM_ALLOC_FAILURE;
+
+ mhd_LOG_PRINT (d, \
+ s->tls_app_name.v_disable_fallback ?
+ MHD_SC_TLS_DAEMON_INIT_FAILED :
+ MHD_SC_TLS_LIB_CONF_WARNING, \
+ mhd_LOG_FMT ("Failed to initialise '%s' priorities"),
+ gnutls_strerror (res));
+
+ if (s->tls_app_name.v_disable_fallback)
+ return MHD_SC_TLS_DAEMON_INIT_FAILED;
+ }
- mhd_DBG_PRINT_TLS_INFO_PARAM1 ("Trying '%s' priorities",
- NULL == tlsgnulib_base_priorities[i].cstr ?
- "[NULL]" :
- tlsgnulib_base_priorities[i].cstr);
+ for (i = 0; i < mhd_ARR_NUM_ELEMS (tlsgnulib_base_priorities); ++i)
+ {
+ int res;
#if ! defined(mhd_TLS_GNU_TREATS_NULL_AS_DEF_PRIORITY)
if (NULL == tlsgnulib_base_priorities[i].cstr)
{
/* GnuTLS default priorities */
# if defined(mhd_TLS_GNU_NULL_PRIO_CACHE_MEANS_DEF_PRIORITY)
d_tls->pri_cache = NULL;
- break;
+ mhd_DBG_PRINT_TLS_INFO_MSG ("Using NULL pointer as default "
+ "GnuTLS priorities");
+ return MHD_SC_OK;
# else
continue; /* "default" priorities cannot be used */
# endif
}
#endif /* ! mhd_TLS_GNU_TREATS_NULL_AS_DEF_PRIORITY */
- res = gnutls_priority_init (&(d_tls->pri_cache),
- tlsgnulib_base_priorities[i].cstr,
- NULL);
+ res = try_prio_string (tlsgnulib_base_priorities[i].cstr,
+ d_tls);
+
if (GNUTLS_E_SUCCESS == res)
- {
- mhd_DBG_PRINT_TLS_INFO_PARAM1 ("Initialised with '%s' priorities",
- NULL == tlsgnulib_base_priorities[i].cstr
- ? "[NULL]" :
- tlsgnulib_base_priorities[i].cstr);
- break;
- }
- if (GNUTLS_E_MEMORY_ERROR == res)
+ return MHD_SC_OK;
+ else if (GNUTLS_E_MEMORY_ERROR == res)
return MHD_SC_DAEMON_MEM_ALLOC_FAILURE;
}
- if (i < mhd_ARR_NUM_ELEMS (tlsgnulib_base_priorities))
- return MHD_SC_OK; /* Success exit point */
-
mhd_LOG_MSG (d, MHD_SC_TLS_DAEMON_INIT_FAILED, \
"Failed to initialise TLS priorities cache");
return MHD_SC_TLS_DAEMON_INIT_FAILED;