mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
Implemented initialisation of daemon's GnuTLS data
This commit is contained in:
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user