You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2023/03/05 10:13:27 UTC

svn commit: r1908081 - in /httpd/httpd/branches/2.4.x: ./ changes-entries/ docs/manual/mod/ modules/md/

Author: icing
Date: Sun Mar  5 10:13:26 2023
New Revision: 1908081

URL: http://svn.apache.org/viewvc?rev=1908081&view=rev
Log:
Merge of r1908080 from trunk:

  *) 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.


Added:
    httpd/httpd/branches/2.4.x/changes-entries/md_v2.4.21.txt
      - copied unchanged from r1908080, httpd/httpd/trunk/changes-entries/md_v2.4.21.txt
Modified:
    httpd/httpd/branches/2.4.x/   (props changed)
    httpd/httpd/branches/2.4.x/docs/manual/mod/mod_md.xml
    httpd/httpd/branches/2.4.x/modules/md/md.h
    httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.c
    httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.h
    httpd/httpd/branches/2.4.x/modules/md/md_acme_drive.c
    httpd/httpd/branches/2.4.x/modules/md/md_acme_order.c
    httpd/httpd/branches/2.4.x/modules/md/md_acme_order.h
    httpd/httpd/branches/2.4.x/modules/md/md_acmev2_drive.c
    httpd/httpd/branches/2.4.x/modules/md/md_core.c
    httpd/httpd/branches/2.4.x/modules/md/md_crypt.c
    httpd/httpd/branches/2.4.x/modules/md/md_version.h
    httpd/httpd/branches/2.4.x/modules/md/mod_md_config.c
    httpd/httpd/branches/2.4.x/modules/md/mod_md_config.h

Propchange: httpd/httpd/branches/2.4.x/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk:r1908080

Modified: httpd/httpd/branches/2.4.x/docs/manual/mod/mod_md.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/docs/manual/mod/mod_md.xml?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/docs/manual/mod/mod_md.xml (original)
+++ httpd/httpd/branches/2.4.x/docs/manual/mod/mod_md.xml Sun Mar  5 10:13:26 2023
@@ -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>

Modified: httpd/httpd/branches/2.4.x/modules/md/md.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md.h?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md.h (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md.h Sun Mar  5 10:13:26 2023
@@ -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 */

Modified: httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.c?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.c (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.c Sun Mar  5 10:13:26 2023
@@ -243,7 +243,7 @@ static apr_status_t setup_key_authz(md_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
     (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
 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_setu
     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_
     (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_
     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_
     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_
     }
     /* 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(
     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(
     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 *bato
 
 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_ac
         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_ac
                     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(stru
         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;
             }

Modified: httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.h?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.h (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_acme_authz.h Sun Mar  5 10:13:26 2023
@@ -68,12 +68,12 @@ apr_status_t md_acme_authz_update(md_acm
 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 */

Modified: httpd/httpd/branches/2.4.x/modules/md/md_acme_drive.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_acme_drive.c?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_acme_drive.c (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_acme_drive.c Sun Mar  5 10:13:26 2023
@@ -587,7 +587,9 @@ static apr_status_t acme_driver_init(md_
             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_
                                 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_
                 }
                 
                 /* 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_
     
     /* 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_prot
     }
 
     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);

Modified: httpd/httpd/branches/2.4.x/modules/md/md_acme_order.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_acme_order.c?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_acme_order.c (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_acme_order.c Sun Mar  5 10:13:26 2023
@@ -226,32 +226,33 @@ static apr_status_t p_purge(void *baton,
     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_challen
                               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;

Modified: httpd/httpd/branches/2.4.x/modules/md/md_acme_order.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_acme_order.h?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_acme_order.h (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_acme_order.h Sun Mar  5 10:13:26 2023
@@ -60,7 +60,7 @@ apr_status_t md_acme_order_save(struct m
                                     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,

Modified: httpd/httpd/branches/2.4.x/modules/md/md_acmev2_drive.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_acmev2_drive.c?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_acmev2_drive.c (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_acmev2_drive.c Sun Mar  5 10:13:26 2023
@@ -73,7 +73,7 @@ static apr_status_t ad_setup_order(md_pr
     }
     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_ac
         || 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;

Modified: httpd/httpd/branches/2.4.x/modules/md/md_core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_core.c?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_core.c (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_core.c Sun Mar  5 10:13:26 2023
@@ -255,6 +255,7 @@ md_t *md_clone(apr_pool_t *p, const md_t
         }
         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, ap
         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_
             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);

Modified: httpd/httpd/branches/2.4.x/modules/md/md_crypt.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_crypt.c?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_crypt.c (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_crypt.c Sun Mar  5 10:13:26 2023
@@ -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 siz
  */
 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 **p
         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 **p
     *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))

Modified: httpd/httpd/branches/2.4.x/modules/md/md_version.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/md_version.h?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/md_version.h (original)
+++ httpd/httpd/branches/2.4.x/modules/md/md_version.h Sun Mar  5 10:13:26 2023
@@ -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"

Modified: httpd/httpd/branches/2.4.x/modules/md/mod_md_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/mod_md_config.c?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/mod_md_config.c (original)
+++ httpd/httpd/branches/2.4.x/modules/md/mod_md_config.c Sun Mar  5 10:13:26 2023
@@ -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_
     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_c
     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 *m
     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
     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_c
     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;
 }

Modified: httpd/httpd/branches/2.4.x/modules/md/mod_md_config.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/md/mod_md_config.h?rev=1908081&r1=1908080&r2=1908081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/md/mod_md_config.h (original)
+++ httpd/httpd/branches/2.4.x/modules/md/mod_md_config.h Sun Mar  5 10:13:26 2023
@@ -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 */