summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorStefan Eissing <icing@apache.org>2023-03-05 09:59:34 +0000
committerStefan Eissing <icing@apache.org>2023-03-05 09:59:34 +0000
commita47ee08073efc0a607039ddb3cc230c81203529a (patch)
tree141f1bb0cb3ee5ea3a19dbe6ee52cfdb50b8ead0 /modules
parentd3607972c842eb2945f61f89259a9e4cd416a24d (diff)
downloadhttpd-a47ee08073efc0a607039ddb3cc230c81203529a.tar.gz
*) mod_md:
- Enabling ED25519 support and certificate transparency information when building with libressl v3.5.0 and newer. Thanks to Giovanni Bechis. - MDChallengeDns01 can now be configured for individual domains. Thanks to Jérôme Billiras (@bilhackmac) for the initial PR. - Fixed a bug found by Jérôme Billiras (@bilhackmac) that caused the challenge teardown not being invoked as it should. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908080 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/md/md.h3
-rw-r--r--modules/md/md_acme_authz.c58
-rw-r--r--modules/md/md_acme_authz.h4
-rw-r--r--modules/md/md_acme_drive.c12
-rw-r--r--modules/md/md_acme_order.c19
-rw-r--r--modules/md/md_acme_order.h2
-rw-r--r--modules/md/md_acmev2_drive.c6
-rw-r--r--modules/md/md_core.c4
-rw-r--r--modules/md/md_crypt.c13
-rw-r--r--modules/md/md_version.h4
-rw-r--r--modules/md/mod_md_config.c15
-rw-r--r--modules/md/mod_md_config.h2
12 files changed, 84 insertions, 58 deletions
diff --git a/modules/md/md.h b/modules/md/md.h
index af695f1458..1d75d102c8 100644
--- a/modules/md/md.h
+++ b/modules/md/md.h
@@ -103,7 +103,8 @@ struct md_t {
struct apr_array_header_t *acme_tls_1_domains; /* domains supporting "acme-tls/1" protocol */
int stapling; /* if OCSP stapling is enabled */
-
+ const char *dns01_cmd; /* DNS challenge command, override global command */
+
int watched; /* if certificate is supervised (renew or expiration warning) */
const struct md_srv_conf_t *sc; /* server config where it was defined or NULL */
const char *defn_name; /* config file this MD was defined */
diff --git a/modules/md/md_acme_authz.c b/modules/md/md_acme_authz.c
index 1e9aa76278..a55804e468 100644
--- a/modules/md/md_acme_authz.c
+++ b/modules/md/md_acme_authz.c
@@ -243,7 +243,7 @@ static apr_status_t setup_key_authz(md_acme_authz_cha_t *cha, md_acme_authz_t *a
static apr_status_t cha_http_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
md_acme_t *acme, md_store_t *store,
md_pkeys_spec_t *key_specs,
- apr_array_header_t *acme_tls_1_domains, const char *mdomain,
+ apr_array_header_t *acme_tls_1_domains, const md_t *md,
apr_table_t *env, md_result_t *result, apr_pool_t *p)
{
const char *data;
@@ -253,7 +253,7 @@ static apr_status_t cha_http_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t
(void)key_specs;
(void)env;
(void)acme_tls_1_domains;
- (void)mdomain;
+ (void)md;
if (APR_SUCCESS != (rv = setup_key_authz(cha, authz, acme, p, &notify_server))) {
goto out;
@@ -301,7 +301,7 @@ void tls_alpn01_fnames(apr_pool_t *p, md_pkey_spec_t *kspec, char **keyfn, char
static apr_status_t cha_tls_alpn_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
md_acme_t *acme, md_store_t *store,
md_pkeys_spec_t *key_specs,
- apr_array_header_t *acme_tls_1_domains, const char *mdomain,
+ apr_array_header_t *acme_tls_1_domains, const md_t *md,
apr_table_t *env, md_result_t *result, apr_pool_t *p)
{
const char *acme_id, *token;
@@ -311,7 +311,7 @@ static apr_status_t cha_tls_alpn_01_setup(md_acme_authz_cha_t *cha, md_acme_auth
int i;
(void)env;
- (void)mdomain;
+ (void)md;
if (md_array_str_index(acme_tls_1_domains, authz->domain, 0, 0) < 0) {
rv = APR_ENOTIMPL;
if (acme_tls_1_domains->nelts) {
@@ -413,7 +413,7 @@ out:
static apr_status_t cha_dns_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
md_acme_t *acme, md_store_t *store,
md_pkeys_spec_t *key_specs,
- apr_array_header_t *acme_tls_1_domains, const char *mdomain,
+ apr_array_header_t *acme_tls_1_domains, const md_t *md,
apr_table_t *env, md_result_t *result, apr_pool_t *p)
{
const char *token;
@@ -429,7 +429,9 @@ static apr_status_t cha_dns_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *
(void)key_specs;
(void)acme_tls_1_domains;
- dns01_cmd = apr_table_get(env, MD_KEY_CMD_DNS01);
+ dns01_cmd = md->dns01_cmd;
+ if (!dns01_cmd)
+ dns01_cmd = apr_table_get(env, MD_KEY_CMD_DNS01);
if (!dns01_cmd) {
rv = APR_ENOTIMPL;
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "%s: dns-01 command not set",
@@ -445,7 +447,7 @@ static apr_status_t cha_dns_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *
rv = md_crypt_sha256_digest64(&token, p, &data);
if (APR_SUCCESS != rv) {
md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: create dns-01 token for %s",
- mdomain, authz->domain);
+ md->name, authz->domain);
goto out;
}
@@ -456,13 +458,13 @@ static apr_status_t cha_dns_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *
apr_tokenize_to_argv(cmdline, (char***)&argv, p);
if (APR_SUCCESS != (rv = md_util_exec(p, argv[0], argv, NULL, &exit_code))) {
md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p,
- "%s: dns-01 setup command failed to execute for %s", mdomain, authz->domain);
+ "%s: dns-01 setup command failed to execute for %s", md->name, authz->domain);
goto out;
}
if (exit_code) {
rv = APR_EGENERAL;
md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, p,
- "%s: dns-01 setup command returns %d for %s", mdomain, exit_code, authz->domain);
+ "%s: dns-01 setup command returns %d for %s", md->name, exit_code, authz->domain);
goto out;
}
@@ -478,7 +480,7 @@ static apr_status_t cha_dns_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *
}
/* challenge is setup, tell ACME server so it may (re)try verification */
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "%s: dns-01 setup succeeded for %s",
- mdomain, authz->domain);
+ md->name, authz->domain);
authz_req_ctx_init(&ctx, acme, NULL, authz, p);
ctx.challenge = cha;
rv = md_acme_POST(acme, cha->uri, on_init_authz_resp, authz_http_set, NULL, NULL, &ctx);
@@ -487,7 +489,7 @@ out:
return rv;
}
-static apr_status_t cha_dns_01_teardown(md_store_t *store, const char *domain, const char *mdomain,
+static apr_status_t cha_dns_01_teardown(md_store_t *store, const char *domain, const md_t *md,
apr_table_t *env, apr_pool_t *p)
{
const char * const *argv;
@@ -496,12 +498,14 @@ static apr_status_t cha_dns_01_teardown(md_store_t *store, const char *domain, c
int exit_code;
(void)store;
-
- dns01_cmd = apr_table_get(env, MD_KEY_CMD_DNS01);
+
+ dns01_cmd = md->dns01_cmd;
+ if (!dns01_cmd)
+ dns01_cmd = apr_table_get(env, MD_KEY_CMD_DNS01);
if (!dns01_cmd) {
rv = APR_ENOTIMPL;
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "%s: dns-01 command not set for %s",
- mdomain, domain);
+ md->name, domain);
goto out;
}
@@ -510,27 +514,27 @@ static apr_status_t cha_dns_01_teardown(md_store_t *store, const char *domain, c
if (APR_SUCCESS != (rv = md_util_exec(p, argv[0], argv, NULL, &exit_code)) || exit_code) {
md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p,
"%s: dns-01 teardown command failed (exit code=%d) for %s",
- mdomain, exit_code, domain);
+ md->name, exit_code, domain);
}
out:
return rv;
}
-static apr_status_t cha_teardown_dir(md_store_t *store, const char *domain, const char *mdomain,
+static apr_status_t cha_teardown_dir(md_store_t *store, const char *domain, const md_t *md,
apr_table_t *env, apr_pool_t *p)
{
+ (void)md;
(void)env;
- (void)mdomain;
return md_store_purge(store, p, MD_SG_CHALLENGES, domain);
}
typedef apr_status_t cha_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
md_acme_t *acme, md_store_t *store,
md_pkeys_spec_t *key_specs,
- apr_array_header_t *acme_tls_1_domains, const char *mdomain,
+ apr_array_header_t *acme_tls_1_domains, const md_t *md,
apr_table_t *env, md_result_t *result, apr_pool_t *p);
-typedef apr_status_t cha_teardown(md_store_t *store, const char *domain, const char *mdomain,
+typedef apr_status_t cha_teardown(md_store_t *store, const char *domain, const md_t *md,
apr_table_t *env, apr_pool_t *p);
typedef struct {
@@ -579,7 +583,7 @@ static apr_status_t find_type(void *baton, size_t index, md_json_t *json)
apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, md_acme_t *acme, md_store_t *store,
apr_array_header_t *challenges, md_pkeys_spec_t *key_specs,
- apr_array_header_t *acme_tls_1_domains, const char *mdomain,
+ apr_array_header_t *acme_tls_1_domains, const md_t *md,
apr_table_t *env, apr_pool_t *p, const char **psetup_token,
md_result_t *result)
{
@@ -616,7 +620,7 @@ apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, md_acme_t *acme, md_s
md_json_itera(find_type, &fctx, authz->resource, MD_KEY_CHALLENGES, NULL);
md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, p,
"%s: challenge type '%s' for %s: %s",
- authz->domain, fctx.type, mdomain,
+ authz->domain, fctx.type, md->name,
fctx.accepted? "maybe acceptable" : "not applicable");
if (fctx.accepted) {
@@ -625,17 +629,17 @@ apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, md_acme_t *acme, md_s
md_result_activity_printf(result, "Setting up challenge '%s' for domain %s",
fctx.accepted->type, authz->domain);
rv = CHA_TYPES[j].setup(fctx.accepted, authz, acme, store, key_specs,
- acme_tls_1_domains, mdomain, env, result, p);
+ acme_tls_1_domains, md, env, result, p);
if (APR_SUCCESS == rv) {
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
"%s: set up challenge '%s' for %s",
- authz->domain, fctx.accepted->type, mdomain);
- challenge_setup = CHA_TYPES[i].name;
+ authz->domain, fctx.accepted->type, md->name);
+ challenge_setup = CHA_TYPES[j].name;
goto out;
}
md_result_printf(result, rv, "error setting up challenge '%s' for %s, "
"for domain %s, looking for other option",
- fctx.accepted->type, authz->domain, mdomain);
+ fctx.accepted->type, authz->domain, md->name);
md_result_log(result, MD_LOG_INFO);
}
}
@@ -670,7 +674,7 @@ out:
}
apr_status_t md_acme_authz_teardown(struct md_store_t *store, const char *token,
- const char *mdomain, apr_table_t *env, apr_pool_t *p)
+ const md_t *md, apr_table_t *env, apr_pool_t *p)
{
char *challenge, *domain;
int i;
@@ -682,7 +686,7 @@ apr_status_t md_acme_authz_teardown(struct md_store_t *store, const char *token,
for (i = 0; i < (int)CHA_TYPES_LEN; ++i) {
if (!apr_strnatcasecmp(CHA_TYPES[i].name, challenge)) {
if (CHA_TYPES[i].teardown) {
- return CHA_TYPES[i].teardown(store, domain, mdomain, env, p);
+ return CHA_TYPES[i].teardown(store, domain, md, env, p);
}
break;
}
diff --git a/modules/md/md_acme_authz.h b/modules/md/md_acme_authz.h
index 90193af14c..d74beebab6 100644
--- a/modules/md/md_acme_authz.h
+++ b/modules/md/md_acme_authz.h
@@ -68,12 +68,12 @@ apr_status_t md_acme_authz_update(md_acme_authz_t *authz, struct md_acme_t *acme
apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, struct md_acme_t *acme,
struct md_store_t *store, apr_array_header_t *challenges,
struct md_pkeys_spec_t *key_spec,
- apr_array_header_t *acme_tls_1_domains, const char *mdomain,
+ apr_array_header_t *acme_tls_1_domains, const md_t *md,
struct apr_table_t *env,
apr_pool_t *p, const char **setup_token,
struct md_result_t *result);
apr_status_t md_acme_authz_teardown(struct md_store_t *store, const char *setup_token,
- const char *mdomain, struct apr_table_t *env, apr_pool_t *p);
+ const md_t *md, struct apr_table_t *env, apr_pool_t *p);
#endif /* md_acme_authz_h */
diff --git a/modules/md/md_acme_drive.c b/modules/md/md_acme_drive.c
index abe7d644e6..4bb04f321c 100644
--- a/modules/md/md_acme_drive.c
+++ b/modules/md/md_acme_drive.c
@@ -587,7 +587,9 @@ static apr_status_t acme_driver_init(md_proto_driver_t *d, md_result_t *result)
ad->ca_challenges = md_array_str_remove(d->p, ad->ca_challenges, MD_AUTHZ_TYPE_TLSALPN01, 0);
dis_alpn_acme = 1;
}
- if (!apr_table_get(d->env, MD_KEY_CMD_DNS01) && md_array_str_index(ad->ca_challenges, MD_AUTHZ_TYPE_DNS01, 0, 1) >= 0) {
+ if (!apr_table_get(d->env, MD_KEY_CMD_DNS01)
+ && NULL == d->md->dns01_cmd
+ && md_array_str_index(ad->ca_challenges, MD_AUTHZ_TYPE_DNS01, 0, 1) >= 0) {
ad->ca_challenges = md_array_str_remove(d->p, ad->ca_challenges, MD_AUTHZ_TYPE_DNS01, 0);
dis_dns = 1;
}
@@ -832,7 +834,7 @@ static apr_status_t acme_renew(md_proto_driver_t *d, md_result_t *result)
md_result_printf(result, rv, "Certificate and private key do not match.");
/* Delete the order */
- md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md->name, d->env);
+ md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
goto out;
}
@@ -849,7 +851,7 @@ static apr_status_t acme_renew(md_proto_driver_t *d, md_result_t *result)
}
/* Clean up the order, so the next pkey spec sets up a new one */
- md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md->name, d->env);
+ md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
}
}
}
@@ -857,7 +859,7 @@ static apr_status_t acme_renew(md_proto_driver_t *d, md_result_t *result)
/* As last step, cleanup any order we created so that challenge data
* may be removed asap. */
- md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md->name, d->env);
+ md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
/* first time this job ran through */
first = 1;
@@ -998,7 +1000,7 @@ static apr_status_t acme_preload(md_proto_driver_t *d, md_store_group_t load_gro
}
md_result_activity_setn(result, "purging order information");
- md_acme_order_purge(d->store, d->p, MD_SG_STAGING, name, d->env);
+ md_acme_order_purge(d->store, d->p, MD_SG_STAGING, md, d->env);
md_result_activity_setn(result, "purging store tmp space");
rv = md_store_purge(d->store, d->p, load_group, name);
diff --git a/modules/md/md_acme_order.c b/modules/md/md_acme_order.c
index 8037c762f6..9e25e84c3a 100644
--- a/modules/md/md_acme_order.c
+++ b/modules/md/md_acme_order.c
@@ -226,32 +226,33 @@ static apr_status_t p_purge(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_li
md_store_t *store = baton;
md_acme_order_t *order;
md_store_group_t group;
- const char *md_name, *setup_token;
+ const md_t *md;
+ const char *setup_token;
apr_table_t *env;
int i;
group = (md_store_group_t)va_arg(ap, int);
- md_name = va_arg(ap, const char *);
+ md = va_arg(ap, const md_t *);
env = va_arg(ap, apr_table_t *);
- if (APR_SUCCESS == md_acme_order_load(store, group, md_name, &order, p)) {
- md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "order loaded for %s", md_name);
+ if (APR_SUCCESS == md_acme_order_load(store, group, md->name, &order, p)) {
+ md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "order loaded for %s", md->name);
for (i = 0; i < order->challenge_setups->nelts; ++i) {
setup_token = APR_ARRAY_IDX(order->challenge_setups, i, const char*);
if (setup_token) {
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p,
"order teardown setup %s", setup_token);
- md_acme_authz_teardown(store, setup_token, md_name, env, p);
+ md_acme_authz_teardown(store, setup_token, md, env, p);
}
}
}
- return md_store_remove(store, group, md_name, MD_FN_ORDER, ptemp, 1);
+ return md_store_remove(store, group, md->name, MD_FN_ORDER, ptemp, 1);
}
apr_status_t md_acme_order_purge(md_store_t *store, apr_pool_t *p, md_store_group_t group,
- const char *md_name, apr_table_t *env)
+ const md_t *md, apr_table_t *env)
{
- return md_util_pool_vdo(p_purge, store, p, group, md_name, env, NULL);
+ return md_util_pool_vdo(p_purge, store, p, group, md, env, NULL);
}
/**************************************************************************************************/
@@ -465,7 +466,7 @@ apr_status_t md_acme_order_start_challenges(md_acme_order_t *order, md_acme_t *a
md->name, authz->domain);
rv = md_acme_authz_respond(authz, acme, store, challenge_types,
md->pks,
- md->acme_tls_1_domains, md->name,
+ md->acme_tls_1_domains, md,
env, p, &setup_token, result);
if (APR_SUCCESS != rv) {
goto leave;
diff --git a/modules/md/md_acme_order.h b/modules/md/md_acme_order.h
index 868fb56b13..417044018f 100644
--- a/modules/md/md_acme_order.h
+++ b/modules/md/md_acme_order.h
@@ -60,7 +60,7 @@ apr_status_t md_acme_order_save(struct md_store_t *store, apr_pool_t *p,
md_acme_order_t *authz_set, int create);
apr_status_t md_acme_order_purge(struct md_store_t *store, apr_pool_t *p,
- md_store_group_t group, const char *md_name,
+ md_store_group_t group, const md_t *md,
apr_table_t *env);
apr_status_t md_acme_order_start_challenges(md_acme_order_t *order, md_acme_t *acme,
diff --git a/modules/md/md_acmev2_drive.c b/modules/md/md_acmev2_drive.c
index 7ee4790b37..9dfca96714 100644
--- a/modules/md/md_acmev2_drive.c
+++ b/modules/md/md_acmev2_drive.c
@@ -73,7 +73,7 @@ static apr_status_t ad_setup_order(md_proto_driver_t *d, md_result_t *result, in
}
else if (!APR_STATUS_IS_ENOENT(rv)) {
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "%s: loading order", md->name);
- md_acme_order_purge(d->store, d->p, MD_SG_STAGING, md->name, d->env);
+ md_acme_order_purge(d->store, d->p, MD_SG_STAGING, md, d->env);
}
md_result_activity_setn(result, "Creating new order");
@@ -128,7 +128,7 @@ apr_status_t md_acmev2_drive_renew(md_acme_driver_t *ad, md_proto_driver_t *d, m
|| MD_ACME_ORDER_ST_INVALID == ad->order->status) {
/* order is invalid or no longer known at the ACME server */
ad->order = NULL;
- md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md->name, d->env);
+ md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
}
else if (APR_SUCCESS != rv) {
goto leave;
@@ -145,7 +145,7 @@ retry:
if (!is_new_order && APR_STATUS_IS_EINVAL(rv)) {
/* found 'invalid' domains in previous order, need to start over */
ad->order = NULL;
- md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md->name, d->env);
+ md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
goto retry;
}
if (APR_SUCCESS != rv) goto leave;
diff --git a/modules/md/md_core.c b/modules/md/md_core.c
index 8c7c453625..7aacff0497 100644
--- a/modules/md/md_core.c
+++ b/modules/md/md_core.c
@@ -255,6 +255,7 @@ md_t *md_clone(apr_pool_t *p, const md_t *src)
}
md->acme_tls_1_domains = md_array_str_compact(p, src->acme_tls_1_domains, 0);
md->stapling = src->stapling;
+ if (src->dns01_cmd) md->dns01_cmd = apr_pstrdup(p, src->dns01_cmd);
if (src->cert_files) md->cert_files = md_array_str_clone(p, src->cert_files);
if (src->pkey_files) md->pkey_files = md_array_str_clone(p, src->pkey_files);
}
@@ -311,6 +312,7 @@ md_json_t *md_to_json(const md_t *md, apr_pool_t *p)
if (md->cert_files) md_json_setsa(md->cert_files, json, MD_KEY_CERT_FILES, NULL);
if (md->pkey_files) md_json_setsa(md->pkey_files, json, MD_KEY_PKEY_FILES, NULL);
md_json_setb(md->stapling > 0, json, MD_KEY_STAPLING, NULL);
+ if (md->dns01_cmd) md_json_sets(md->dns01_cmd, json, MD_KEY_CMD_DNS01, NULL);
if (md->ca_eab_kid && strcmp("none", md->ca_eab_kid)) {
md_json_sets(md->ca_eab_kid, json, MD_KEY_EAB, MD_KEY_KID, NULL);
if (md->ca_eab_hmac) md_json_sets(md->ca_eab_hmac, json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
@@ -376,7 +378,7 @@ md_t *md_from_json(md_json_t *json, apr_pool_t *p)
md_json_dupsa(md->pkey_files, p, json, MD_KEY_PKEY_FILES, NULL);
}
md->stapling = (int)md_json_getb(json, MD_KEY_STAPLING, NULL);
-
+ md->dns01_cmd = md_json_dups(p, json, MD_KEY_CMD_DNS01, NULL);
if (md_json_has_key(json, MD_KEY_EAB, NULL)) {
md->ca_eab_kid = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_KID, NULL);
md->ca_eab_hmac = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
diff --git a/modules/md/md_crypt.c b/modules/md/md_crypt.c
index 8baab51c8b..f2b0cd5487 100644
--- a/modules/md/md_crypt.c
+++ b/modules/md/md_crypt.c
@@ -61,8 +61,8 @@
#define MD_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
#endif
-#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L)
-/* Missing from LibreSSL and only available since OpenSSL v1.1.x */
+#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x3050000fL)) || (OPENSSL_VERSION_NUMBER < 0x10100000L)
+/* Missing from LibreSSL < 3.5.0 and only available since OpenSSL v1.1.x */
#ifndef OPENSSL_NO_CT
#define OPENSSL_NO_CT
#endif
@@ -210,7 +210,8 @@ static int pem_passwd(char *buf, int size, int rwflag, void *baton)
*/
static apr_time_t md_asn1_time_get(const ASN1_TIME* time)
{
-#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER < 0x10002000L || (defined(LIBRESSL_VERSION_NUMBER) && \
+ LIBRESSL_VERSION_NUMBER < 0x3060000fL)
/* courtesy: https://stackoverflow.com/questions/10975542/asn1-time-to-time-t-conversion#11263731
* all bugs are mine */
apr_time_exp_t t;
@@ -854,7 +855,8 @@ static apr_status_t gen_ec(md_pkey_t **ppkey, apr_pool_t *p, const char *curve)
curve = EC_curve_nid2nist(curve_nid);
}
#endif
-#if defined(NID_X25519) && !defined(LIBRESSL_VERSION_NUMBER)
+#if defined(NID_X25519) && (!defined(LIBRESSL_VERSION_NUMBER) || \
+ LIBRESSL_VERSION_NUMBER >= 0x3070000fL)
if (NID_undef == curve_nid && !apr_strnatcasecmp("X25519", curve)) {
curve_nid = NID_X25519;
curve = EC_curve_nid2nist(curve_nid);
@@ -872,7 +874,8 @@ static apr_status_t gen_ec(md_pkey_t **ppkey, apr_pool_t *p, const char *curve)
*ppkey = make_pkey(p);
switch (curve_nid) {
-#if defined(NID_X25519) && !defined(LIBRESSL_VERSION_NUMBER)
+#if defined(NID_X25519) && (!defined(LIBRESSL_VERSION_NUMBER) || \
+ LIBRESSL_VERSION_NUMBER >= 0x3070000fL)
case NID_X25519:
/* no parameters */
if (NULL == (ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL))
diff --git a/modules/md/md_version.h b/modules/md/md_version.h
index 9a8d588263..a8f3ef22f7 100644
--- a/modules/md/md_version.h
+++ b/modules/md/md_version.h
@@ -27,7 +27,7 @@
* @macro
* Version number of the md module as c string
*/
-#define MOD_MD_VERSION "2.4.19"
+#define MOD_MD_VERSION "2.4.21"
/**
* @macro
@@ -35,7 +35,7 @@
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
-#define MOD_MD_VERSION_NUM 0x020413
+#define MOD_MD_VERSION_NUM 0x020415
#define MD_ACME_DEF_URL "https://acme-v02.api.letsencrypt.org/directory"
#define MD_TAILSCALE_DEF_URL "file://localhost/var/run/tailscale/tailscaled.sock"
diff --git a/modules/md/mod_md_config.c b/modules/md/mod_md_config.c
index 2f19300584..e117b16009 100644
--- a/modules/md/mod_md_config.c
+++ b/modules/md/mod_md_config.c
@@ -120,6 +120,7 @@ static md_srv_conf_t defconf = {
NULL, /* ca eab hmac */
0, /* stapling */
1, /* staple others */
+ NULL, /* dns01_cmd */
NULL, /* currently defined md */
NULL, /* assigned md, post config */
0, /* is_ssl, set during mod_ssl post_config */
@@ -174,6 +175,7 @@ static void srv_conf_props_clear(md_srv_conf_t *sc)
sc->ca_eab_hmac = NULL;
sc->stapling = DEF_VAL;
sc->staple_others = DEF_VAL;
+ sc->dns01_cmd = NULL;
}
static void srv_conf_props_copy(md_srv_conf_t *to, const md_srv_conf_t *from)
@@ -194,6 +196,7 @@ static void srv_conf_props_copy(md_srv_conf_t *to, const md_srv_conf_t *from)
to->ca_eab_hmac = from->ca_eab_hmac;
to->stapling = from->stapling;
to->staple_others = from->staple_others;
+ to->dns01_cmd = from->dns01_cmd;
}
static void srv_conf_props_apply(md_t *md, const md_srv_conf_t *from, apr_pool_t *p)
@@ -217,6 +220,7 @@ static void srv_conf_props_apply(md_t *md, const md_srv_conf_t *from, apr_pool_t
if (from->ca_eab_kid) md->ca_eab_kid = from->ca_eab_kid;
if (from->ca_eab_hmac) md->ca_eab_hmac = from->ca_eab_hmac;
if (from->stapling != DEF_VAL) md->stapling = from->stapling;
+ if (from->dns01_cmd) md->dns01_cmd = from->dns01_cmd;
}
void *md_config_create_svr(apr_pool_t *pool, server_rec *s)
@@ -262,6 +266,7 @@ static void *md_config_merge(apr_pool_t *pool, void *basev, void *addv)
nsc->ca_eab_hmac = add->ca_eab_hmac? add->ca_eab_hmac : base->ca_eab_hmac;
nsc->stapling = (add->stapling != DEF_VAL)? add->stapling : base->stapling;
nsc->staple_others = (add->staple_others != DEF_VAL)? add->staple_others : base->staple_others;
+ nsc->dns01_cmd = (add->dns01_cmd)? add->dns01_cmd : base->dns01_cmd;
nsc->current = NULL;
return nsc;
@@ -966,10 +971,16 @@ static const char *md_config_set_dns01_cmd(cmd_parms *cmd, void *mconfig, const
md_srv_conf_t *sc = md_config_get(cmd->server);
const char *err;
- if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
+ if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
return err;
}
- apr_table_set(sc->mc->env, MD_KEY_CMD_DNS01, arg);
+
+ if (inside_md_section(cmd)) {
+ sc->dns01_cmd = arg;
+ } else {
+ apr_table_set(sc->mc->env, MD_KEY_CMD_DNS01, arg);
+ }
+
(void)mconfig;
return NULL;
}
diff --git a/modules/md/mod_md_config.h b/modules/md/mod_md_config.h
index b34b92e14c..de42169c97 100644
--- a/modules/md/mod_md_config.h
+++ b/modules/md/mod_md_config.h
@@ -100,6 +100,8 @@ typedef struct md_srv_conf_t {
int stapling; /* OCSP stapling enabled */
int staple_others; /* Provide OCSP stapling for non-MD certificates */
+ const char *dns01_cmd; /* DNS challenge command, override global command */
+
md_t *current; /* md currently defined in <MDomainSet xxx> section */
struct apr_array_header_t *assigned; /* post_config: MDs that apply to this server */
int is_ssl; /* SSLEngine is enabled here */