Implemented initialisation of daemon's GnuTLS data

This commit is contained in:
Evgeny Grin (Karlson2k)
2024-11-19 10:52:16 +03:00
parent 86170adff2
commit cd6fda427c
18 changed files with 1110 additions and 94 deletions
+54 -5
View File
@@ -149,18 +149,67 @@ Argument1: enum MHD_TlsBackend backend
Description1: the TLS backend to use,
+ #MHD_TLS_BACKEND_NONE for non-TLS (plain TCP) connections
Name: tls_key_cert
Name: tls_cert_key
Value: 121
Comment: Provide TLS key and certificate data in-memory.
+ Works only if TLS mode is enabled.
Type: struct MHD_DaemonOptionValueTlsCert
Argument1: const char *mem_key
Description1: the private key loaded into memory (not a filename)
Argument2: const char *mem_cert
Description2: the certificate loaded into memory (not a filename)
Argument1: /* const */ char *mem_cert
Description1: The X.509 certificates chain in PEM format loaded into memory (not a filename).
+ The first certificate must be the server certificate, following by the chain of signing
+ certificates up to (but not including) CA root certificate.
Argument2: const char *mem_key
Description2: the private key in PEM format loaded into memory (not a filename)
Argument3: const char *mem_pass
Description3: the option passphrase phrase to decrypt the private key,
+ could be NULL is private does not need a password
CustomSetter: /* custom setter */
+ if ((NULL == option->val.tls_cert_key.v_mem_cert)
+ || (NULL == option->val.tls_cert_key.v_mem_key))
+ return MHD_SC_TLS_CONF_BAD_CERT;
+ else
+ {
+ size_t cert_size;
+ size_t key_size;
+ size_t pass_size;
+ cert_size = strlen (option->val.tls_cert_key.v_mem_cert);
+ key_size = strlen (option->val.tls_cert_key.v_mem_key);
+ if ((0 == cert_size)
+ || (0 == key_size))
+ return MHD_SC_TLS_CONF_BAD_CERT;
+ ++cert_size; /* Space for zero-termination */
+ ++key_size; /* Space for zero-termination */
+ if (NULL != option->val.tls_cert_key.v_mem_pass)
+ pass_size = strlen (option->val.tls_cert_key.v_mem_cert);
+ else
+ pass_size = 0;
+ if (0 != pass_size)
+ ++pass_size; /* Space for zero-termination */
+ if (NULL != settings->tls_cert_key.v_mem_cert)
+ free (settings->tls_cert_key.v_mem_cert); // TODO: Support multiple certificates!!
+ settings->tls_cert_key.v_mem_cert = malloc (cert_size + key_size + pass_size);
+ if (NULL == settings->tls_cert_key.v_mem_cert)
+ return MHD_SC_DAEMON_MALLOC_FAILURE;
+ memcpy (settings->tls_cert_key.v_mem_cert,
+ option->val.tls_cert_key.v_mem_cert,
+ cert_size);
+ memcpy (settings->tls_cert_key.v_mem_cert + cert_size,
+ option->val.tls_cert_key.v_mem_key,
+ key_size);
+ settings->tls_cert_key.v_mem_key =
+ settings->tls_cert_key.v_mem_cert + cert_size;
+ if (0 != pass_size)
+ {
+ memcpy (settings->tls_cert_key.v_mem_cert + cert_size + key_size,
+ option->val.tls_cert_key.v_mem_pass,
+ pass_size);
+ settings->tls_cert_key.v_mem_pass =
+ settings->tls_cert_key.v_mem_cert + cert_size + key_size;
+ }
+ else
+ settings->tls_cert_key.v_mem_pass = NULL;
+ }
Name: tls_client_ca
Value: 122
+40 -21
View File
@@ -459,6 +459,7 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
,
/**
* Failed to allocate memory for the daemon resources.
* TODO: combine similar error codes for daemon
*/
MHD_SC_DAEMON_MALLOC_FAILURE = 30081
,
@@ -713,12 +714,6 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_TLS_DISABLED = 50000
,
/**
* The application attempted to setup TLS parameters before
* enabling TLS.
*/
MHD_SC_TLS_BACKEND_UNINITIALIZED = 50003
,
/**
* The selected TLS backend does not yet support this operation.
*/
@@ -1286,6 +1281,11 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_LIB_INIT_GLOBAL_FAILED = 51000
,
/**
* Failed to initialise TLS context for the daemon
*/
MHD_SC_DAEMON_TLS_INIT_FAILED = 51200
,
/**
* Something wrong in the internal MHD logic.
* This error should be never returned if MHD works as expected.
@@ -1309,17 +1309,6 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC = 60001
,
/**
* The application requested an unsupported TLS backend to be used.
*/
MHD_SC_TLS_BACKEND_UNSUPPORTED = 60003
,
/**
* The application requested a TLS cipher suite which is not
* supported by the selected backend.
*/
MHD_SC_TLS_CIPHERS_INVALID = 60004
,
/**
* MHD is closing a connection because the application
* logic to generate the response data failed.
@@ -1390,6 +1379,34 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_CONFIGURATION_CONN_LIMIT_TOO_SMALL = 60016
,
/**
* The application requested an unsupported TLS backend to be used.
*/
MHD_SC_TLS_BACKEND_UNSUPPORTED = 60020
,
/**
* The application attempted to setup TLS parameters before
* enabling TLS.
*/
MHD_SC_TLS_BACKEND_UNINITIALIZED = 60021
,
/**
* The application requested a TLS backend which cannot be used due
* to missing TLS dynamic library or backend initialisation problem.
*/
MHD_SC_TLS_BACKEND_UNAVAILABLE = 60022
,
/**
* Provided TLS certificate and/or private key are incorrect
*/
MHD_SC_TLS_CONF_BAD_CERT = 60023
,
/**
* The application requested a TLS cipher suite which is not
* supported by the selected backend.
*/
MHD_SC_TLS_CIPHERS_INVALID = 60024
,
/**
* The response header name has forbidden characters or token
*/
@@ -3954,16 +3971,18 @@ MHD_D_OPTION_TLS (
/**
* Provide TLS key and certificate data in-memory.
* Works only if TLS mode is enabled.
* @param mem_key the private key loaded into memory (not a filename)
* @param mem_cert the certificate loaded into memory (not a filename)
* @param mem_cert The X.509 certificates chain in PEM format loaded into memory (not a filename).
* The first certificate must be the server certificate, following by the chain of signing
* certificates up to (but not including) CA root certificate.
* @param mem_key the private key in PEM format loaded into memory (not a filename)
* @param mem_pass the option passphrase phrase to decrypt the private key,
* could be NULL is private does not need a password
* @return structure with the requested setting
*/
struct MHD_DaemonOptionAndValue
MHD_D_OPTION_TLS_KEY_CERT (
MHD_D_OPTION_TLS_CERT_KEY (
/* const */ char *mem_cert,
const char *mem_key,
const char *mem_cert,
const char *mem_pass
);
@@ -108,7 +108,7 @@ Works only when #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA() are used.
* Provide TLS key and certificate data in-memory.
* Works only if TLS mode is enabled.
*/
MHD_D_O_TLS_KEY_CERT = 121
MHD_D_O_TLS_CERT_KEY = 121
,
/**
@@ -424,19 +424,21 @@ struct MHD_DaemonOptionValueTFO
};
/**
* Data for #MHD_D_O_TLS_KEY_CERT
* Data for #MHD_D_O_TLS_CERT_KEY
*/
struct MHD_DaemonOptionValueTlsCert
{
/**
* the private key loaded into memory (not a filename)
* The X.509 certificates chain in PEM format loaded into memory (not a filename).
* The first certificate must be the server certificate, following by the chain of signing
* certificates up to (but not including) CA root certificate.
*/
const char *v_mem_key;
/* const */ char *v_mem_cert;
/**
* the certificate loaded into memory (not a filename)
* the private key in PEM format loaded into memory (not a filename)
*/
const char *v_mem_cert;
const char *v_mem_key;
/**
* the option passphrase phrase to decrypt the private key,
@@ -656,10 +658,12 @@ union MHD_DaemonOptionValue
enum MHD_TlsBackend tls;
/**
* Value for #MHD_D_O_TLS_KEY_CERT.
* the private key loaded into memory (not a filename)
* Value for #MHD_D_O_TLS_CERT_KEY.
* The X.509 certificates chain in PEM format loaded into memory (not a filename).
* The first certificate must be the server certificate, following by the chain of signing
* certificates up to (but not including) CA root certificate.
*/
struct MHD_DaemonOptionValueTlsCert tls_key_cert;
struct MHD_DaemonOptionValueTlsCert tls_cert_key;
/**
* Value for #MHD_D_O_TLS_CLIENT_CA.
@@ -1023,20 +1027,22 @@ Works only when #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA() are used.
/**
* Provide TLS key and certificate data in-memory.
* Works only if TLS mode is enabled.
* @param mem_key the private key loaded into memory (not a filename)
* @param mem_cert the certificate loaded into memory (not a filename)
* @param mem_cert The X.509 certificates chain in PEM format loaded into memory (not a filename).
* The first certificate must be the server certificate, following by the chain of signing
* certificates up to (but not including) CA root certificate.
* @param mem_key the private key in PEM format loaded into memory (not a filename)
* @param mem_pass the option passphrase phrase to decrypt the private key,
* could be NULL is private does not need a password
* @return structure with the requested setting
*/
# define MHD_D_OPTION_TLS_KEY_CERT(mem_key,mem_cert,mem_pass) \
# define MHD_D_OPTION_TLS_CERT_KEY(mem_cert,mem_key,mem_pass) \
MHD_NOWARN_COMPOUND_LITERALS_ \
(const struct MHD_DaemonOptionAndValue) \
{ \
.opt = MHD_D_O_TLS_KEY_CERT, \
.val.tls_key_cert.v_mem_key = (mem_key), \
.val.tls_key_cert.v_mem_cert = (mem_cert), \
.val.tls_key_cert.v_mem_pass = (mem_pass) \
.opt = MHD_D_O_TLS_CERT_KEY, \
.val.tls_cert_key.v_mem_cert = (mem_cert), \
.val.tls_cert_key.v_mem_key = (mem_key), \
.val.tls_cert_key.v_mem_pass = (mem_pass) \
} \
MHD_RESTORE_WARN_COMPOUND_LITERALS_
/**
@@ -1740,25 +1746,27 @@ MHD_D_OPTION_TLS (
/**
* Provide TLS key and certificate data in-memory.
* Works only if TLS mode is enabled.
* @param mem_key the private key loaded into memory (not a filename)
* @param mem_cert the certificate loaded into memory (not a filename)
* @param mem_cert The X.509 certificates chain in PEM format loaded into memory (not a filename).
* The first certificate must be the server certificate, following by the chain of signing
* certificates up to (but not including) CA root certificate.
* @param mem_key the private key in PEM format loaded into memory (not a filename)
* @param mem_pass the option passphrase phrase to decrypt the private key,
* could be NULL is private does not need a password
* @return structure with the requested setting
*/
static MHD_INLINE struct MHD_DaemonOptionAndValue
MHD_D_OPTION_TLS_KEY_CERT (
MHD_D_OPTION_TLS_CERT_KEY (
/* const */ char *mem_cert,
const char *mem_key,
const char *mem_cert,
const char *mem_pass
)
{
struct MHD_DaemonOptionAndValue opt_val;
opt_val.opt = MHD_D_O_TLS_KEY_CERT;
opt_val.val.tls_key_cert.v_mem_key = mem_key;
opt_val.val.tls_key_cert.v_mem_cert = mem_cert;
opt_val.val.tls_key_cert.v_mem_pass = mem_pass;
opt_val.opt = MHD_D_O_TLS_CERT_KEY;
opt_val.val.tls_cert_key.v_mem_cert = mem_cert;
opt_val.val.tls_cert_key.v_mem_key = mem_key;
opt_val.val.tls_cert_key.v_mem_pass = mem_pass;
return opt_val;
}
+34 -17
View File
@@ -459,6 +459,7 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
,
/**
* Failed to allocate memory for the daemon resources.
* TODO: combine similar error codes for daemon
*/
MHD_SC_DAEMON_MALLOC_FAILURE = 30081
,
@@ -713,12 +714,6 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_TLS_DISABLED = 50000
,
/**
* The application attempted to setup TLS parameters before
* enabling TLS.
*/
MHD_SC_TLS_BACKEND_UNINITIALIZED = 50003
,
/**
* The selected TLS backend does not yet support this operation.
*/
@@ -1286,6 +1281,11 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_LIB_INIT_GLOBAL_FAILED = 51000
,
/**
* Failed to initialise TLS context for the daemon
*/
MHD_SC_DAEMON_TLS_INIT_FAILED = 51200
,
/**
* Something wrong in the internal MHD logic.
* This error should be never returned if MHD works as expected.
@@ -1309,17 +1309,6 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC = 60001
,
/**
* The application requested an unsupported TLS backend to be used.
*/
MHD_SC_TLS_BACKEND_UNSUPPORTED = 60003
,
/**
* The application requested a TLS cipher suite which is not
* supported by the selected backend.
*/
MHD_SC_TLS_CIPHERS_INVALID = 60004
,
/**
* MHD is closing a connection because the application
* logic to generate the response data failed.
@@ -1390,6 +1379,34 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_CONFIGURATION_CONN_LIMIT_TOO_SMALL = 60016
,
/**
* The application requested an unsupported TLS backend to be used.
*/
MHD_SC_TLS_BACKEND_UNSUPPORTED = 60020
,
/**
* The application attempted to setup TLS parameters before
* enabling TLS.
*/
MHD_SC_TLS_BACKEND_UNINITIALIZED = 60021
,
/**
* The application requested a TLS backend which cannot be used due
* to missing TLS dynamic library or backend initialisation problem.
*/
MHD_SC_TLS_BACKEND_UNAVAILABLE = 60022
,
/**
* Provided TLS certificate and/or private key are incorrect
*/
MHD_SC_TLS_CONF_BAD_CERT = 60023
,
/**
* The application requested a TLS cipher suite which is not
* supported by the selected backend.
*/
MHD_SC_TLS_CIPHERS_INVALID = 60024
,
/**
* The response header name has forbidden characters or token
*/
+2 -1
View File
@@ -108,10 +108,11 @@ upgrade_files = \
tls_common_files = \
mhd_tls_choice.h \
mhd_tls_funcs.h \
mhd_tls_funcs.c mhd_tls_funcs.h \
tls_dh_params.h
tls_gnu_files = \
tls_gnu_tls_lib.h tls_gnu_daemon_data.h tls_gnu_conn_data.h \
tls_gnu_funcs.c tls_gnu_funcs.h
if HAVE_POST_PARSER
+6 -3
View File
@@ -81,9 +81,9 @@ MHD_daemon_create (MHD_RequestCallback req_cb,
/* Any floating point and pointer members must be initialised manually here */
#ifndef HAVE_NULL_PTR_ALL_ZEROS
s->bind_sa.v_sa = NULL;
s->tls_key_cert.v_mem_key = NULL;
s->tls_key_cert.v_mem_cert = NULL;
s->tls_key_cert.v_mem_pass = NULL;
s->tls_cert_key.v_mem_key = NULL;
s->tls_cert_key.v_mem_cert = NULL;
s->tls_cert_key.v_mem_pass = NULL;
s->tls_client_ca = NULL;
s->tls_psk_callback.v_psk_cb = NULL;
s->tls_psk_callback.v_psk_cb_cls = NULL;
@@ -98,6 +98,9 @@ MHD_daemon_create (MHD_RequestCallback req_cb,
s->notify_stream.v_nsc = NULL;
s->notify_stream.v_cls = NULL;
s->random_entropy.v_buf = NULL;
s->tls_cert_key.v_mem_cert = NULL;
s->tls_cert_key.v_mem_key = NULL;
s->tls_cert_key.v_mem_pass = NULL;
d->log_params.v_log_cb = NULL; /* optional */
#endif /* !HAVE_NULL_PTR_ALL_ZEROS */
+5 -3
View File
@@ -94,10 +94,12 @@ struct DaemonOptions
/**
* Value for #MHD_D_O_TLS_KEY_CERT.
* the private key loaded into memory (not a filename)
* Value for #MHD_D_O_TLS_CERT_KEY.
* The X.509 certificates chain in PEM format loaded into memory (not a filename).
* The first certificate must be the server certificate, following by the chain of signing
* certificates up to (but not including) CA root certificate.
*/
struct MHD_DaemonOptionValueTlsCert tls_key_cert;
struct MHD_DaemonOptionValueTlsCert tls_cert_key;
/**
+47 -4
View File
@@ -86,10 +86,53 @@ MHD_daemon_set_options (
case MHD_D_O_TLS:
settings->tls = option->val.tls;
continue;
case MHD_D_O_TLS_KEY_CERT:
settings->tls_key_cert.v_mem_key = option->val.tls_key_cert.v_mem_key;
settings->tls_key_cert.v_mem_cert = option->val.tls_key_cert.v_mem_cert;
settings->tls_key_cert.v_mem_pass = option->val.tls_key_cert.v_mem_pass;
case MHD_D_O_TLS_CERT_KEY:
/* custom setter */
if ((NULL == option->val.tls_cert_key.v_mem_cert)
|| (NULL == option->val.tls_cert_key.v_mem_key))
return MHD_SC_TLS_CONF_BAD_CERT;
else
{
size_t cert_size;
size_t key_size;
size_t pass_size;
cert_size = strlen (option->val.tls_cert_key.v_mem_cert);
key_size = strlen (option->val.tls_cert_key.v_mem_key);
if ((0 == cert_size)
|| (0 == key_size))
return MHD_SC_TLS_CONF_BAD_CERT;
++cert_size; /* Space for zero-termination */
++key_size; /* Space for zero-termination */
if (NULL != option->val.tls_cert_key.v_mem_pass)
pass_size = strlen (option->val.tls_cert_key.v_mem_cert);
else
pass_size = 0;
if (0 != pass_size)
++pass_size; /* Space for zero-termination */
if (NULL != settings->tls_cert_key.v_mem_cert)
free (settings->tls_cert_key.v_mem_cert); // TODO: Support multiple certificates!!
settings->tls_cert_key.v_mem_cert = malloc (cert_size + key_size + pass_size);
if (NULL == settings->tls_cert_key.v_mem_cert)
return MHD_SC_DAEMON_MALLOC_FAILURE;
memcpy (settings->tls_cert_key.v_mem_cert,
option->val.tls_cert_key.v_mem_cert,
cert_size);
memcpy (settings->tls_cert_key.v_mem_cert + cert_size,
option->val.tls_cert_key.v_mem_key,
key_size);
settings->tls_cert_key.v_mem_key =
settings->tls_cert_key.v_mem_cert + cert_size;
if (0 != pass_size)
{
memcpy (settings->tls_cert_key.v_mem_cert + cert_size + key_size,
option->val.tls_cert_key.v_mem_pass,
pass_size);
settings->tls_cert_key.v_mem_pass =
settings->tls_cert_key.v_mem_cert + cert_size + key_size;
}
else
settings->tls_cert_key.v_mem_pass = NULL;
}
continue;
case MHD_D_O_TLS_CLIENT_CA:
settings->tls_client_ca = option->val.tls_client_ca;
+108 -15
View File
@@ -72,6 +72,10 @@
#include "mhd_lib_init.h"
#include "daemon_logger.h"
#ifdef MHD_ENABLE_HTTPS
# include "mhd_tls_funcs.h"
#endif
#ifdef MHD_USE_THREADS
# include "mhd_itc.h"
# include "mhd_threads.h"
@@ -101,6 +105,8 @@ dsettings_release (struct DaemonOptions *s)
mhd_socket_close (s->listen_socket);
if (NULL != s->bind_sa.v_sa)
free (s->bind_sa.v_sa);
if (NULL != s->tls_cert_key.v_mem_cert)
free (s->tls_cert_key.v_mem_cert);
free (s);
}
@@ -1437,6 +1443,88 @@ dauth_init (struct MHD_Daemon *restrict d,
#endif
/**
* Initialise daemon TLS data
* @param d the daemon object
* @param s the user settings
* @return #MHD_SC_OK on success,
* the error code otherwise
*/
static MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) \
MHD_FN_MUST_CHECK_RESULT_ enum MHD_StatusCode
daemon_init_tls (struct MHD_Daemon *restrict d,
struct DaemonOptions *restrict s)
{
mhd_StatusCodeInt ret;
mhd_assert (! d->dbg.tls_inited);
#ifdef MHD_ENABLE_HTTPS
d->tls = NULL;
#endif
if (MHD_TLS_BACKEND_NONE == s->tls)
{
#ifndef NDEBUG
d->dbg.tls_inited = true;
#endif
return MHD_SC_OK;
}
#ifndef MHD_ENABLE_HTTPS
mhd_LOG_MSG (d, \
MHD_SC_TLS_DISABLED, \
"HTTPS is not supported by this MHD build");
return MHD_SC_TLS_DISABLED;
#else /* MHD_ENABLE_HTTPS */
if (1)
{
enum mhd_TlsBackendAvailable tls_avail;
tls_avail = mhd_tls_is_backend_available (s);
if (mhd_TLS_BACKEND_AVAIL_NOT_SUPPORTED == tls_avail)
{
mhd_LOG_MSG (d, \
MHD_SC_TLS_BACKEND_UNSUPPORTED, \
"The requested TLS backend is not supported " \
"by this MHD build");
return MHD_SC_TLS_BACKEND_UNSUPPORTED;
}
else if (mhd_TLS_BACKEND_AVAIL_NOT_AVAILABLE == tls_avail)
{
mhd_LOG_MSG (d, \
MHD_SC_TLS_BACKEND_UNAVAILABLE, \
"The requested TLS backend is not available");
return MHD_SC_TLS_BACKEND_UNAVAILABLE;
}
}
ret = mhd_tls_daemon_init (d,
&(d->tls),
s);
mhd_assert ((MHD_SC_OK == ret) || (NULL == d->tls));
mhd_assert ((MHD_SC_OK != ret) || (NULL != d->tls));
#ifndef NDEBUG
d->dbg.tls_inited = (MHD_SC_OK == ret);
#endif
return (enum MHD_StatusCode) ret;
#endif /* MHD_ENABLE_HTTPS */
}
/**
* Deinitialise daemon TLS data
* @param d the daemon object
*/
MHD_FN_PAR_NONNULL_ (1) static void
daemon_deinit_tls (struct MHD_Daemon *restrict d)
{
mhd_assert (d->dbg.tls_inited);
#ifdef MHD_ENABLE_HTTPS
if (NULL != d->tls)
mhd_tls_daemon_deinit (d->tls);
#endif
}
/**
* Initialise large buffer tracking.
* @param d the daemon object
@@ -2828,32 +2916,35 @@ daemon_start_internal (struct MHD_Daemon *restrict d,
if (MHD_SC_OK != res)
return res;
mhd_assert (d->dbg.net_inited);
res = daemon_init_tls (d, s);
// TODO: Other init
res = daemon_init_threading_and_conn (d, s);
if (MHD_SC_OK == res)
{
mhd_assert (d->dbg.net_inited);
mhd_assert (d->dbg.threading_inited);
mhd_assert (! mhd_D_TYPE_IS_INTERNAL_ONLY (d->threading.d_type));
res = daemon_init_large_buf (d, s);
mhd_assert (d->dbg.tls_inited);
res = daemon_init_threading_and_conn (d, s);
if (MHD_SC_OK == res)
{
res = daemon_start_threads (d);
mhd_assert (d->dbg.threading_inited);
mhd_assert (! mhd_D_TYPE_IS_INTERNAL_ONLY (d->threading.d_type));
res = daemon_init_large_buf (d, s);
if (MHD_SC_OK == res)
{
return MHD_SC_OK;
res = daemon_start_threads (d);
if (MHD_SC_OK == res)
{
return MHD_SC_OK;
}
/* Below is a clean-up path */
daemon_deinit_large_buf (d);
}
/* Below is a clean-up path */
daemon_deinit_large_buf (d);
daemon_deinit_threading_and_conn (d);
}
daemon_deinit_threading_and_conn (d);
daemon_deinit_tls (d);
}
daemon_deinit_net (d);
mhd_assert (MHD_SC_OK != res);
return res;
@@ -2911,6 +3002,8 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
daemon_deinit_large_buf (daemon);
daemon_deinit_tls (daemon);
daemon_deinit_net (daemon);
}
daemon->state = mhd_DAEMON_STATE_STOPPED; /* Useful only for debugging */
+21
View File
@@ -35,6 +35,10 @@
#include "mhd_public_api.h"
#ifdef MHD_ENABLE_HTTPS
# include "mhd_tls_choice.h"
#endif
#ifdef MHD_USE_THREADS
# include "mhd_threads.h"
# include "mhd_itc_types.h"
@@ -873,6 +877,7 @@ struct mhd_daemon_debug
{
bool net_inited;
bool net_deinited;
bool tls_inited;
bool events_allocated;
unsigned int num_events_elements;
bool events_fully_inited;
@@ -913,6 +918,15 @@ struct MHD_Daemon
*/
struct mhd_DaemonNetwork net;
#ifdef MHD_ENABLE_HTTPS
/**
* The pointer to the daemon TLS data.
* If set to non-NULL then HTTPS protocol is used, if set to NULL then
* plain HTTP protocol used.
*/
struct mhd_DaemonTlsData *tls;
#endif
#ifdef MHD_USE_THREADS
/* Threading data */
@@ -1002,4 +1016,11 @@ struct MHD_Daemon
(mhd_D_IS_USING_EPOLL (d) || \
(mhd_WM_INT_EXTERNAL_EVENTS_EDGE ==((d)->wmode_int)))
#ifdef MHD_ENABLE_HTTPS
# define mhd_D_HAS_TLS(d) ((d->tls) ? (! 0) : (0))
#else
# define mhd_D_HAS_TLS(d) (0)
#endif
#endif /* ! MHD_DAEMON_H */
+49
View File
@@ -0,0 +1,49 @@
/*
This file is part of GNU libmicrohttpd
Copyright (C) 2024 Evgeny Grin (Karlson2k)
GNU libmicrohttpd is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
GNU libmicrohttpd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file src/mhd2/mhd_tls_funcs.c
* @brief The TLS backend generic functions
* @author Karlson2k (Evgeny Grin)
*/
#include "mhd_sys_options.h"
#include "mhd_tls_funcs.h"
#include "mhd_assert.h"
#include "mhd_public_api.h"
#include "daemon_options.h"
MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_
enum mhd_TlsBackendAvailable
mhd_tls_is_backend_available (struct DaemonOptions *s)
{
mhd_assert (MHD_TLS_BACKEND_NONE != s->tls);
if (MHD_TLS_BACKEND_ANY == s->tls)
return mhd_tls_gnu_is_inited_fine ()
/* || mhd_tls_other_is_inited_fine() */;
#ifdef MHD_USE_GNUTLS
if (MHD_TLS_BACKEND_GNUTLS == s->tls)
return mhd_tls_gnu_is_inited_fine ();
#endif
return false;
}
+63
View File
@@ -30,6 +30,8 @@
#include "mhd_sys_options.h"
#include "sys_bool_type.h"
#include "mhd_tls_choice.h"
#ifndef MHD_ENABLE_HTTPS
#error This header should be used only if HTTPS is enabled
@@ -39,6 +41,12 @@
# include "tls_gnu_funcs.h"
#endif
#ifndef MHD_USE_GNUTLS
# define mhd_tls_gnu_is_inited_fine() (0)
#endif
/* ** Global initialisation ** */
/**
* Perform one-time global initialisation of TLS backend
*/
@@ -57,5 +65,60 @@
#define mhd_tls_global_re_init() \
mhd_MACRO_CONCAT3 (mhd_tls_,mhd_TLS_FUNC_NAME_ID,_global_re_init)()
/* ** Daemon initialisation ** */
/**
* Set daemon TLS parameters
* @param d the daemon handle
* @param p_d_tls the pointer to variable to set the pointer to
* the daemon's TLS settings (allocated by this function)
* @param s the daemon settings
* @return #MHD_SC_OK on success (p_d_tls set to the allocated settings),
* error code otherwise
*/
#define mhd_tls_daemon_init(d,p_d_tls,s) \
mhd_MACRO_CONCAT3 (mhd_tls_,mhd_TLS_FUNC_NAME_ID,_daemon_init)( \
(d),(p_d_tls),(s))
/**
* De-initialise daemon TLS parameters (and free memory allocated for TLS
* settings)
* @param d_tls the pointer to the daemon's TLS settings
*/
#define mhd_tls_daemon_deinit(d_tls) \
mhd_MACRO_CONCAT3 (mhd_tls_,mhd_TLS_FUNC_NAME_ID,_daemon_deinit)( \
(d_tls))
/**
* Result of TLS backend availablility check
*/
enum mhd_TlsBackendAvailable
{
/**
* The TLS backend is available and can be used
*/
mhd_TLS_BACKEND_AVAIL_OK = 0
,
/**
* The TLS backend support is not enabled in this MHD build
*/
mhd_TLS_BACKEND_AVAIL_NOT_SUPPORTED
,
/**
* The TLS backend supported, but not available
*/
mhd_TLS_BACKEND_AVAIL_NOT_AVAILABLE
};
/**
* Check whether the requested TLS backend is available
* @param s the daemon settings
* @return 'mhd_TLS_BACKEND_AVAIL_OK' if requested backend is available,
* error code otherwise
*/
MHD_INTERNAL enum mhd_TlsBackendAvailable
mhd_tls_is_backend_available (struct DaemonOptions *s)
MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_;
#endif /* ! MHD_TLS_FUNCS_H */
+53
View File
@@ -0,0 +1,53 @@
/*
This file is part of GNU libmicrohttpd
Copyright (C) 2024 Evgeny Grin (Karlson2k)
GNU libmicrohttpd is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
GNU libmicrohttpd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file src/mhd2/tls_dh_params.h
* @brief The Diffie-Hellman parameters for TLS backends without RFC7919
* support
* @author Karlson2k (Evgeny Grin)
*/
#ifndef MHD_TLS_DH_PARAMS_H
#define MHD_TLS_DH_PARAMS_H 1
#include "mhd_sys_options.h"
/**
* The PEM encoded PKCS#3 Diffie-Hellman parameters.
*
* To be used only if TLS backend does not support RFC7919.
* Generated by GnuTLS "certtool --get-dh-params" command.
*/
static const char mhd_tls_dh_params_pkcs3[] =
"-----BEGIN DH PARAMETERS-----\n"
"MIIBjAKCAYEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz\n"
"+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a\n"
"87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7\n"
"YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi\n"
"7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD\n"
"ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3\n"
"7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32\n"
"nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZsYu\n"
"N///////////AgECAgIBFA==\n"
"-----END DH PARAMETERS-----\n";
#endif /* ! MHD_TLS_DH_PARAMS_H */
+49
View File
@@ -0,0 +1,49 @@
/*
This file is part of GNU libmicrohttpd
Copyright (C) 2024 Evgeny Grin (Karlson2k)
GNU libmicrohttpd is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
GNU libmicrohttpd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file src/mhd2/tls_gnu_conn_data.h
* @brief The definition of GnuTLS daemon-specific data structures
* @author Karlson2k (Evgeny Grin)
*/
#ifndef MHD_TLS_GNU_CONN_DATA_H
#define MHD_TLS_GNU_CONN_DATA_H 1
#include "mhd_sys_options.h"
#ifndef MHD_USE_GNUTLS
#error This header can be used only if GnuTLS is enabled
#endif
#include "tls_gnu_tls_lib.h"
/**
* The structure with connection-specific GnuTLS data
*/
struct mhd_ConnTlsGnuData
{
/**
* GnuTLS session data
*/
gnutls_session_t sess;
};
#endif /* ! MHD_TLS_GNU_CONN_DATA_H */
+61
View File
@@ -0,0 +1,61 @@
/*
This file is part of GNU libmicrohttpd
Copyright (C) 2024 Evgeny Grin (Karlson2k)
GNU libmicrohttpd is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
GNU libmicrohttpd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file src/mhd2/tls_gnu_daemon_data.h
* @brief The definition of GnuTLS daemon-specific data structures
* @author Karlson2k (Evgeny Grin)
*/
#ifndef MHD_TLS_GNU_DAEMON_DATA_H
#define MHD_TLS_GNU_DAEMON_DATA_H 1
#include "mhd_sys_options.h"
#ifndef MHD_USE_GNUTLS
#error This header can be used only if GnuTLS is enabled
#endif
#include "tls_gnu_tls_lib.h"
/**
* The structure with daemon-specific GnuTLS data
*/
struct mhd_DaemonTlsGnuData
{
/**
* The credentials
*/
gnutls_certificate_credentials_t cred;
#ifdef mhd_TLS_GNU_DH_PARAMS_NEEDS_PKCS3
/**
* Diffie-Hellman parameters
*/
gnutls_dh_params_t dh_params;
#endif
/**
* TLS priorities cache
*/
gnutls_priority_t pri_cache;
};
#endif /* ! MHD_TLS_GNU_DAEMON_DATA_H */
+345 -1
View File
@@ -29,10 +29,30 @@
#include "sys_bool_type.h"
#include "sys_base_types.h"
#include <gnutls/gnutls.h>
#include <string.h>
#include "mhd_str_types.h"
#include "mhd_str_macros.h"
#include "mhd_arr_num_elems.h"
#include "compat_calloc.h"
#include "sys_malloc.h"
#include "mhd_assert.h"
#include "tls_gnu_tls_lib.h"
#include "tls_gnu_daemon_data.h"
#include "tls_gnu_funcs.h"
#include "daemon_options.h"
#include "mhd_public_api.h"
#include "daemon_logger.h"
#ifdef mhd_TLS_GNU_DH_PARAMS_NEEDS_PKCS3
# include "tls_dh_params.h"
#endif
struct mhd_DaemonTlsGnuData; /* Forward declaration */
struct mhd_ConnTlsGnuData; /* Forward declaration */
@@ -62,3 +82,327 @@ mhd_tls_gnu_global_deinit (void)
gnutls_global_deinit ();
gnutls_lib_inited = false;
}
MHD_INTERNAL bool
mhd_tls_gnu_is_inited_fine (void)
{
return gnutls_lib_inited;
}
/* ** Daemon initialisation ** */
/**
* Check application-provided daemon TLS settings
* @param d the daemon handle
* @param s the application-provided settings
* @return #MHD_SC_OK on success,
* error code otherwise
*/
static MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_ enum MHD_StatusCode
check_app_tls_sessings (struct MHD_Daemon *restrict d,
struct DaemonOptions *restrict s)
{
mhd_assert (MHD_TLS_BACKEND_NONE == s->tls);
mhd_assert ((MHD_TLS_BACKEND_GNUTLS == s->tls) || \
(MHD_TLS_BACKEND_ANY == s->tls));
if (NULL == s->tls_cert_key.v_mem_cert)
{
mhd_LOG_MSG (d, MHD_SC_TLS_CONF_BAD_CERT, \
"No valid TLS certificate is provided");
return MHD_SC_TLS_CONF_BAD_CERT;
}
mhd_assert (NULL != s->tls_cert_key.v_mem_key);
return MHD_SC_OK;
}
/**
* Initialise daemon TLS Diffie-Hellman parameters.
*
* This function initialise Diffie-Hellman parameters for the daemon based
* on GnuTLS recommended defaults.
* With modern GnuTLS versions this function is no-op and always succeed.
*
* This function does not put any messages to the log.
* @param d_tls the daemon TLS data
* @return 'true' if succeed,
* 'false' if failed
*/
static MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_ bool
daemon_init_dh_data (struct mhd_DaemonTlsGnuData *restrict d_tls)
{
#if defined(mhd_TLS_GNU_DH_PARAMS_USE_KNOWN)
/* Rely on reasonable TLS defaults set in the TLS library.
Modern GnuTLS versions relies completely on RFC 7919 and do not need
this function therefore do not bother implementing special
application-defined settings just for limited number of GnuTLS
versions (>= 3.5.6 && < 3.6.0). */
return (GNUTLS_E_SUCCESS ==
gnutls_certificate_set_known_dh_params (d_tls->cred,
GNUTLS_SEC_PARAM_MEDIUM));
#elif defined(mhd_TLS_GNU_DH_PARAMS_NEEDS_PKCS3)
gnutls_datum_t dh_data;
if (GNUTLS_E_SUCCESS !=
gnutls_dh_params_init (&(d_tls->dh_params)))
return false;
dh_data.data = mhd_DROP_CONST (mhd_tls_dh_params_pkcs3);
dh_data.size = sizeof (mhd_tls_dh_params_pkcs3);
if (GNUTLS_E_SUCCESS ==
gnutls_dh_params_import_pkcs3 (d_tls->dh_params,
&dh_data,
GNUTLS_X509_FMT_PEM))
{
gnutls_certificate_set_dh_params (d_tls->cred,
d_tls->dh_params);
return true; /* success exit point */
}
/* Below is a clean-up code path */
gnutls_dh_params_deinit (d_tls->dh_params);
return false;
#else
(void) d_tls; /* Mute compiler warning */
return true;
#endif
}
/**
* De-initialise daemon TLS Diffie-Hellman parameters.
* @param d_tls the daemon TLS data
*/
static MHD_FN_PAR_NONNULL_ALL_ void
daemon_deinit_dh_data (struct mhd_DaemonTlsGnuData *restrict d_tls)
{
#if defined(mhd_TLS_GNU_DH_PARAMS_NEEDS_PKCS3)
mhd_assert (NULL != d_tls->dh_params);
gnutls_dh_params_deinit (d_tls->dh_params);
#else
(void) d_tls; /* Mute compiler warning */
#endif
}
/**
* Set daemon TLS credentials (and Diffie-Hellman parameters).
* This function puts error messages to the log if needed.
* @param d the daemon handle
* @param d_tls the daemon TLS settings
* @param s the application-provided settings
* @return #MHD_SC_OK on success,
* error code otherwise
*/
static MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_ enum MHD_StatusCode
daemon_init_credentials (struct MHD_Daemon *restrict d,
struct mhd_DaemonTlsGnuData *restrict d_tls,
struct DaemonOptions *restrict s)
{
enum MHD_StatusCode res;
size_t cert_len;
size_t key_len;
if (GNUTLS_E_SUCCESS !=
gnutls_certificate_allocate_credentials (&(d_tls->cred)))
{
mhd_LOG_MSG (d, MHD_SC_DAEMON_TLS_INIT_FAILED, \
"Failed to initialise TLS credentials for the daemon");
return MHD_SC_DAEMON_TLS_INIT_FAILED;
}
// TODO: Support multiple certificates
cert_len = strlen (s->tls_cert_key.v_mem_cert) + 1; // TODO: Reuse calculated length
key_len = strlen (s->tls_cert_key.v_mem_key) + 1; // TODO: Reuse calculated length
if (((unsigned int) cert_len != cert_len)
|| ((unsigned int) key_len != key_len))
res = MHD_SC_TLS_CONF_BAD_CERT; /* Very unlikely, do not waste space on special message */
else
{
gnutls_datum_t cert_data;
gnutls_datum_t key_data;
cert_data.data = mhd_DROP_CONST (s->tls_cert_key.v_mem_cert);
cert_data.size = (unsigned int) cert_len;
key_data.data = mhd_DROP_CONST (s->tls_cert_key.v_mem_key);
key_data.size = (unsigned int) key_len;
if (0 >
gnutls_certificate_set_x509_key_mem2 (d_tls->cred,
&cert_data,
&key_data,
GNUTLS_X509_FMT_PEM,
s->tls_cert_key.v_mem_pass,
0))
{
mhd_LOG_MSG (d, MHD_SC_TLS_CONF_BAD_CERT, \
"Failed to set the provided TLS certificate");
res = MHD_SC_TLS_CONF_BAD_CERT;
}
else
{
if (! daemon_init_dh_data (d_tls))
{
mhd_LOG_MSG (d, MHD_SC_DAEMON_TLS_INIT_FAILED, \
"Failed to initialise Diffie-Hellman parameters " \
"for the daemon");
res = MHD_SC_DAEMON_TLS_INIT_FAILED;
}
else
return MHD_SC_OK;
}
}
gnutls_certificate_free_credentials (d_tls->cred);
mhd_assert (MHD_SC_OK != res);
return res; /* Failure exit point */
}
/**
* Free daemon fully allocated credentials (and Diffie-Hellman parameters).
* @param d_tls the daemon TLS settings
*/
static MHD_FN_PAR_NONNULL_ALL_ void
daemon_deinit_credentials (struct mhd_DaemonTlsGnuData *restrict d_tls)
{
mhd_assert (NULL != d_tls->cred);
/* To avoid dangling pointer to DH data in the credentials,
free credentials first and then free DH data. */
gnutls_certificate_free_credentials (d_tls->cred);
daemon_deinit_dh_data (d_tls);
}
static const struct MHD_StringNullable tlsgnulib_base_priorities[] = {
{0, NULL} /* Replaced with app-defined name */
,
#ifdef mhd_TLS_GNU_SUPPORTS_MULTI_KEYWORDS_PRIORITY
mhd_MSTR_INIT ("@LIBMICROHTTPD,@SYSTEM")
#else
mhd_MSTR_INIT ("@LIBMICROHTTPD")
,
mhd_MSTR_INIT ("@SYSTEM")
#endif
,
{0, NULL}
,
mhd_MSTR_INIT ("NORMAL")
};
/**
* Initialise GnuTLS priorities cache
* @param d the daemon handle
* @param d_tls the daemon TLS settings
* @param s the application-provided settings
* @return #MHD_SC_OK on success,
* error code otherwise
*/
static MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_ enum MHD_StatusCode
daemon_init_priorities_cache (struct MHD_Daemon *restrict d,
struct mhd_DaemonTlsGnuData *restrict d_tls,
struct DaemonOptions *restrict s)
{
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 (0 == i)
continue; // TODO: support app-defined name for TLS backend profile
#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;
# else
continue; /* "default" priorities cannot be used */
# endif
}
#endif /* ! mhd_TLS_GNU_TREATS_NULL_AS_DEF_PRIORITY */
if (GNUTLS_E_SUCCESS ==
gnutls_priority_init (&(d_tls->pri_cache),
tlsgnulib_base_priorities[i].cstr,
NULL))
break;
}
if (i < mhd_ARR_NUM_ELEMS (tlsgnulib_base_priorities))
return MHD_SC_OK; /* Success exit point */
mhd_LOG_MSG (d, MHD_SC_DAEMON_TLS_INIT_FAILED, \
"Failed to initialise TLS priorities cache");
return MHD_SC_DAEMON_TLS_INIT_FAILED;
}
/**
* De-initialise priorities cache
* @param d_tls the daemon TLS settings
*/
static MHD_FN_PAR_NONNULL_ALL_ void
daemon_deinit_priorities_cache (struct mhd_DaemonTlsGnuData *restrict d_tls)
{
#if ! defined(mhd_TLS_GNU_NULL_PRIO_CACHE_MEANS_DEF_PRIORITY)
mhd_assert (NULL != d_tls->pri_cache);
#else
if (NULL != d_tls->pri_cache)
#endif
gnutls_priority_deinit (d_tls->pri_cache);
}
MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
MHD_FN_PAR_OUT_ (2) mhd_StatusCodeInt
mhd_tls_gnu_daemon_init (struct MHD_Daemon *restrict d,
struct mhd_DaemonTlsGnuData **restrict p_d_tls,
struct DaemonOptions *restrict s)
{
mhd_StatusCodeInt res;
struct mhd_DaemonTlsGnuData *restrict d_tls;
res = check_app_tls_sessings (d, s);
if (MHD_SC_OK != res)
return res;
d_tls = (struct mhd_DaemonTlsGnuData *)
mhd_calloc (1, sizeof (struct mhd_DaemonTlsGnuData));
*p_d_tls = d_tls;
if (NULL == d_tls)
return MHD_SC_DAEMON_MALLOC_FAILURE;
res = daemon_init_credentials (d,
d_tls,
s);
if (MHD_SC_OK == res)
{
res = daemon_init_priorities_cache (d,
d_tls,
s);
if (MHD_SC_OK == res)
return MHD_SC_OK; /* Success exit point */
/* Below is a clean-up code path */
daemon_deinit_credentials (d_tls);
}
free (d_tls);
*p_d_tls = NULL;
mhd_assert (MHD_SC_OK != res);
return res;
}
MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
MHD_FN_PAR_INOUT_ (1) void
mhd_tls_gnu_daemon_deinit (struct mhd_DaemonTlsGnuData *restrict d_tls)
{
mhd_assert (NULL != d_tls);
daemon_deinit_priorities_cache (d_tls);
daemon_deinit_credentials (d_tls);
free (d_tls);
}
+38
View File
@@ -33,6 +33,8 @@
#error This header can be used only if GnuTLS is enabled
#endif
#include "mhd_status_code_int.h"
/**
* The structure with daemon-specific GnuTLS data
*/
@@ -64,4 +66,40 @@ mhd_tls_gnu_global_init (void);
MHD_INTERNAL void
mhd_tls_gnu_global_deinit (void);
/**
* Check whether GnuTLS backend was successfully initialised globally
*/
MHD_INTERNAL bool
mhd_tls_gnu_is_inited_fine (void);
/* ** Daemon initialisation ** */
struct MHD_Daemon; /* Forward declaration */
struct DaemonOptions; /* Forward declaration */
/**
* Set daemon TLS parameters
* @param d the daemon handle
* @param p_d_tls the pointer to variable to set the pointer to
* the daemon's TLS settings (allocated by this function)
* @param s the daemon settings
* @return #MHD_SC_OK on success (p_d_tls set to the allocated settings),
* error code otherwise
*/
MHD_INTERNAL mhd_StatusCodeInt
mhd_tls_gnu_daemon_init (struct MHD_Daemon *restrict d,
struct mhd_DaemonTlsGnuData **restrict p_d_tls,
struct DaemonOptions *restrict s)
MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (2);
/**
* De-initialise daemon TLS parameters (and free memory allocated for TLS
* settings)
* @param d_tls the pointer to the daemon's TLS settings
*/
MHD_INTERNAL void
mhd_tls_gnu_daemon_deinit (struct mhd_DaemonTlsGnuData *restrict d_tls)
MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1);
#endif /* ! MHD_TLS_GNU_FUNCS_H */
+103
View File
@@ -0,0 +1,103 @@
/*
This file is part of GNU libmicrohttpd
Copyright (C) 2024 Evgeny Grin (Karlson2k)
GNU libmicrohttpd is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
GNU libmicrohttpd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file src/mhd2/tls_gnu_tls_lib.h
* @brief The wrapper for GnuTLS header
* @author Karlson2k (Evgeny Grin)
*/
#ifndef MHD_TLS_GNU_TLS_LIB_H
#define MHD_TLS_GNU_TLS_LIB_H 1
#include "mhd_sys_options.h"
#ifndef MHD_USE_GNUTLS
#error This header can be used only if GnuTLS is enabled
#endif
#include <gnutls/gnutls.h>
#ifndef GNUTLS_VERSION_NUMBER
#error GNUTLS_VERSION_NUMBER is not defined
#endif
#if GNUTLS_VERSION_NUMBER >= 0x030600
/**
* Indicate that RC7919 defaults are used
*/
# define mhd_TLS_GNU_HAS_RFC7919_DEFS 1
#endif
#ifndef mhd_TLS_GNU_HAS_RFC7919_DEFS
# if GNUTLS_VERSION_NUMBER >= 0x030506
/**
* Use gnutls_certificate_set_known_dh_params() function to set DH parameters
*/
# define mhd_TLS_GNU_DH_PARAMS_USE_KNOWN 1
# else
/**
* TLS backend needs encoded Diffie-Hellman parameters
*/
# define mhd_TLS_GNU_DH_PARAMS_NEEDS_PKCS3 1
# endif
#endif
#if GNUTLS_VERSION_NUMBER >= 0x020104
/**
* Defined if gnutls_set_default_priority() function is available
*/
# define mhd_TLS_GNU_HAS_SET_DEF_PRIORITY 1
#endif
#if GNUTLS_VERSION_NUMBER >= 0x030300
/**
* Defined if NULL is treated as "default priorities" when used as "priorities"
* argument for gnutls_priority_init() and gnutls_priority_init2()
*/
# define mhd_TLS_GNU_TREATS_NULL_AS_DEF_PRIORITY 1
#endif
#if ! defined(mhd_TLS_GNU_TREATS_NULL_AS_DEF_PRIORITY) \
&& defined(mhd_TLS_GNU_HAS_SET_DEF_PRIORITY)
/**
* Defined if NULL in priorities cache is treated as indication that default
* priorities must used for connection / session
*/
# define mhd_TLS_GNU_NULL_PRIO_CACHE_MEANS_DEF_PRIORITY 1
#endif
#if GNUTLS_VERSION_NUMBER >= 0x030603
/**
* Defined if gnutls_priority_init2() function and the flag
* GNUTLS_PRIORITY_INIT_DEF_APPEND are available
*/
# define mhd_TLS_GNU_HAS_PRIORITY_INIT2 1
#endif
#if GNUTLS_VERSION_NUMBER >= 0x030501
/**
* Defined if gnutls_priority_init{,2}() functions support "@KEYWORD1,@KEYWORD2"
* to as fallback values.
*/
# define mhd_TLS_GNU_SUPPORTS_MULTI_KEYWORDS_PRIORITY 1
#endif
#endif /* ! MHD_TLS_GNU_TLS_LIB_H */