diff options
-rw-r--r-- | changes-entries/md_v2.4.21.txt | 8 | ||||
-rw-r--r-- | docs/manual/mod/mod_md.xml | 4 | ||||
-rw-r--r-- | modules/md/md.h | 3 | ||||
-rw-r--r-- | modules/md/md_acme_authz.c | 58 | ||||
-rw-r--r-- | modules/md/md_acme_authz.h | 4 | ||||
-rw-r--r-- | modules/md/md_acme_drive.c | 12 | ||||
-rw-r--r-- | modules/md/md_acme_order.c | 19 | ||||
-rw-r--r-- | modules/md/md_acme_order.h | 2 | ||||
-rw-r--r-- | modules/md/md_acmev2_drive.c | 6 | ||||
-rw-r--r-- | modules/md/md_core.c | 4 | ||||
-rw-r--r-- | modules/md/md_crypt.c | 13 | ||||
-rw-r--r-- | modules/md/md_version.h | 4 | ||||
-rw-r--r-- | modules/md/mod_md_config.c | 15 | ||||
-rw-r--r-- | modules/md/mod_md_config.h | 2 |
14 files changed, 96 insertions, 58 deletions
diff --git a/changes-entries/md_v2.4.21.txt b/changes-entries/md_v2.4.21.txt new file mode 100644 index 0000000000..2a3faa886c --- /dev/null +++ b/changes-entries/md_v2.4.21.txt @@ -0,0 +1,8 @@ + *) 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. + [Stefan Eissing]
\ No newline at end of file diff --git a/docs/manual/mod/mod_md.xml b/docs/manual/mod/mod_md.xml index d972611768..454cb7fff4 100644 --- a/docs/manual/mod/mod_md.xml +++ b/docs/manual/mod/mod_md.xml @@ -1040,6 +1040,10 @@ MDRequireHttps permanent challenge available for wildcard certificates. If you require one of those, you need to configure this. </p><p> + It is now possible to use this directive inside a <directive module="mod_md">MDomain</directive> + section to specify a specific command for that domain. This allows to configure + a script specific for the particular DNS provider involved. + </p><p> See the section about wildcard certificates above for more details. </p> </usage> 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, ¬ify_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 */ |