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 2021/03/22 15:09:05 UTC
svn commit: r1887923 - in /httpd/httpd/trunk: ./ modules/md/
Author: icing
Date: Mon Mar 22 15:09:05 2021
New Revision: 1887923
URL: http://svn.apache.org/viewvc?rev=1887923&view=rev
Log:
mod_md:
- MDCertificateFile and MDCertificateKeyFile can now be specified several
times to add multiple, static certificates to a MDomain.
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/modules/md/md.h
httpd/httpd/trunk/modules/md/md_core.c
httpd/httpd/trunk/modules/md/md_crypt.c
httpd/httpd/trunk/modules/md/md_reg.c
httpd/httpd/trunk/modules/md/md_reg.h
httpd/httpd/trunk/modules/md/md_status.c
httpd/httpd/trunk/modules/md/mod_md.c
httpd/httpd/trunk/modules/md/mod_md_config.c
httpd/httpd/trunk/modules/md/mod_md_drive.c
httpd/httpd/trunk/modules/md/mod_md_status.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Mon Mar 22 15:09:05 2021
@@ -60,6 +60,8 @@ Changes with Apache 2.5.1
- Account Update transactions to V2 CAs now use the correct POST-AS-GET method.
Previously, an empty JSON object was sent - which apparently LE accepted,
but others reject.
+ - MDCertificateFile and MDCertificateKeyFile can now be specified several
+ times to add multiple, static certificates to a MDomain.
[Stefan Eissing, @tlhackque, Andreas Ulm]
*) mod_session: Improve session parsing. [Yann Yalvic]
Modified: httpd/httpd/trunk/modules/md/md.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md.h?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md.h (original)
+++ httpd/httpd/trunk/modules/md/md.h Mon Mar 22 15:09:05 2021
@@ -92,8 +92,8 @@ struct md_t {
const char *ca_account; /* account used at CA */
const char *ca_agreement; /* accepted agreement uri between CA and user */
struct apr_array_header_t *ca_challenges; /* challenge types configured for this MD */
- const char *cert_file; /* != NULL iff pubcert file explicitly configured */
- const char *pkey_file; /* != NULL iff privkey file explicitly configured */
+ struct apr_array_header_t *cert_files; /* != NULL iff pubcerts explicitly configured */
+ struct apr_array_header_t *pkey_files; /* != NULL iff privkeys explicitly configured */
md_state_t state; /* state of this MD */
@@ -118,7 +118,7 @@ struct md_t {
#define MD_KEY_CA "ca"
#define MD_KEY_CA_URL "ca-url"
#define MD_KEY_CERT "cert"
-#define MD_KEY_CERT_FILE "cert-file"
+#define MD_KEY_CERT_FILES "cert-files"
#define MD_KEY_CERTIFICATE "certificate"
#define MD_KEY_CHALLENGE "challenge"
#define MD_KEY_CHALLENGES "challenges"
@@ -164,7 +164,7 @@ struct md_t {
#define MD_KEY_ORDERS "orders"
#define MD_KEY_PERMANENT "permanent"
#define MD_KEY_PKEY "privkey"
-#define MD_KEY_PKEY_FILE "pkey-file"
+#define MD_KEY_PKEY_FILES "pkey-files"
#define MD_KEY_PROBLEM "problem"
#define MD_KEY_PROTO "proto"
#define MD_KEY_READY "ready"
@@ -285,6 +285,9 @@ md_t *md_from_json(struct md_json_t *jso
int md_is_covered_by_alt_names(const md_t *md, const struct apr_array_header_t* alt_names);
+/* how many certificates this domain has/will eventually have. */
+int md_cert_count(const md_t *md);
+
#define LE_ACMEv1_PROD "https://acme-v01.api.letsencrypt.org/directory"
#define LE_ACMEv1_STAGING "https://acme-staging.api.letsencrypt.org/directory"
Modified: httpd/httpd/trunk/modules/md/md_core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_core.c?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_core.c (original)
+++ httpd/httpd/trunk/modules/md/md_core.c Mon Mar 22 15:09:05 2021
@@ -183,6 +183,15 @@ md_t *md_get_by_dns_overlap(struct apr_a
return NULL;
}
+int md_cert_count(const md_t *md)
+{
+ /* cert are defined as a list of static files or a list of private key specs */
+ if (md->cert_files && md->cert_files->nelts) {
+ return md->cert_files->nelts;
+ }
+ return md_pkeys_spec_count(md->pks);
+}
+
md_t *md_create(apr_pool_t *p, apr_array_header_t *domains)
{
md_t *md;
@@ -242,8 +251,8 @@ 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->cert_file) md->cert_file = apr_pstrdup(p, src->cert_file);
- if (src->pkey_file) md->pkey_file = apr_pstrdup(p, src->pkey_file);
+ 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);
}
return md;
}
@@ -290,8 +299,8 @@ md_json_t *md_to_json(const md_t *md, ap
}
md_json_setb(md->must_staple > 0, json, MD_KEY_MUST_STAPLE, NULL);
md_json_setsa(md->acme_tls_1_domains, json, MD_KEY_PROTO, MD_KEY_ACME_TLS_1, NULL);
- md_json_sets(md->cert_file, json, MD_KEY_CERT_FILE, NULL);
- md_json_sets(md->pkey_file, json, MD_KEY_PKEY_FILE, NULL);
+ 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);
return json;
}
@@ -337,8 +346,12 @@ md_t *md_from_json(md_json_t *json, apr_
md->must_staple = (int)md_json_getb(json, MD_KEY_MUST_STAPLE, NULL);
md_json_dupsa(md->acme_tls_1_domains, p, json, MD_KEY_PROTO, MD_KEY_ACME_TLS_1, NULL);
- md->cert_file = md_json_dups(p, json, MD_KEY_CERT_FILE, NULL);
- md->pkey_file = md_json_dups(p, json, MD_KEY_PKEY_FILE, NULL);
+ if (md_json_has_key(json, MD_KEY_CERT_FILES, NULL)) {
+ md->cert_files = apr_array_make(p, 3, sizeof(char*));
+ md->pkey_files = apr_array_make(p, 3, sizeof(char*));
+ md_json_dupsa(md->cert_files, p, json, MD_KEY_CERT_FILES, NULL);
+ md_json_dupsa(md->pkey_files, p, json, MD_KEY_PKEY_FILES, NULL);
+ }
md->stapling = (int)md_json_getb(json, MD_KEY_STAPLING, NULL);
return md;
Modified: httpd/httpd/trunk/modules/md/md_crypt.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_crypt.c?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_crypt.c (original)
+++ httpd/httpd/trunk/modules/md/md_crypt.c Mon Mar 22 15:09:05 2021
@@ -22,6 +22,8 @@
#include <apr_buckets.h>
#include <apr_file_io.h>
#include <apr_strings.h>
+#include <httpd.h>
+#include <http_core.h>
#include <openssl/err.h>
#include <openssl/evp.h>
Modified: httpd/httpd/trunk/modules/md/md_reg.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_reg.c?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_reg.c (original)
+++ httpd/httpd/trunk/modules/md/md_reg.c Mon Mar 22 15:09:05 2021
@@ -201,43 +201,40 @@ static apr_status_t state_init(md_reg_t
const md_pubcert_t *pub;
const md_cert_t *cert;
apr_status_t rv = APR_SUCCESS;
- md_pkey_spec_t *spec;
int i;
if (md->renew_window == NULL) md->renew_window = reg->renew_window;
if (md->warn_window == NULL) md->warn_window = reg->warn_window;
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
- spec = md_pkeys_spec_get(md->pks, i);
- if (APR_SUCCESS == (rv = md_reg_get_pubcert(&pub, reg, md, spec, p))) {
+ for (i = 0; i < md_cert_count(md); ++i) {
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, p, "md{%s}: check cert %d", md->name, i);
+ if (APR_SUCCESS == (rv = md_reg_get_pubcert(&pub, reg, md, i, p))) {
cert = APR_ARRAY_IDX(pub->certs, 0, const md_cert_t*);
if (!md_is_covered_by_alt_names(md, pub->alt_names)) {
state = MD_S_INCOMPLETE;
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
- "md{%s}: incomplete, certificate(%s) does not cover all domains.",
- md->name, md_pkey_spec_name(spec));
+ "md{%s}: incomplete, certificate(%d) does not cover all domains.",
+ md->name, i);
goto out;
}
if (!md->must_staple != !md_cert_must_staple(cert)) {
state = MD_S_INCOMPLETE;
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
"md{%s}: incomplete, OCSP Stapling is%s requested, but "
- "certificate(%s) has it%s enabled.",
- md->name, md_pkey_spec_name(spec),
- md->must_staple? "" : " not",
+ "certificate(%d) has it%s enabled.",
+ md->name, md->must_staple? "" : " not", i,
!md->must_staple? "" : " not");
goto out;
}
state = MD_S_COMPLETE;
- md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "md{%s}: certificate(%s) is ok",
- md->name, md_pkey_spec_name(spec));
+ md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "md{%s}: certificate(%d) is ok",
+ md->name, i);
}
else if (APR_STATUS_IS_ENOENT(rv)) {
state = MD_S_INCOMPLETE;
rv = APR_SUCCESS;
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
- "md{%s}: incomplete, certificate(%s) is missing", md->name,
- md_pkey_spec_name(spec));
+ "md{%s}: incomplete, certificate(%d) is missing", md->name, i);
goto out;
}
}
@@ -247,6 +244,7 @@ out:
state = MD_S_ERROR;
md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, "md{%s}: error", md->name);
}
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, p, "md{%s}: state==%d", md->name, state);
md->state = state;
return rv;
}
@@ -532,7 +530,7 @@ static apr_status_t pubcert_load(void *b
apr_array_header_t *certs;
md_pubcert_t *pubcert, **ppubcert;
const md_t *md;
- md_pkey_spec_t *spec;
+ int index;
const md_cert_t *cert;
md_cert_state_t cert_state;
md_store_group_t group;
@@ -541,12 +539,13 @@ static apr_status_t pubcert_load(void *b
ppubcert = va_arg(ap, md_pubcert_t **);
group = (md_store_group_t)va_arg(ap, int);
md = va_arg(ap, const md_t *);
- spec = va_arg(ap, md_pkey_spec_t *);
+ index = va_arg(ap, int);
- if (md->cert_file) {
- rv = md_chain_fload(&certs, p, md->cert_file);
+ if (md->cert_files && md->cert_files->nelts) {
+ rv = md_chain_fload(&certs, p, APR_ARRAY_IDX(md->cert_files, index, const char *));
}
else {
+ md_pkey_spec_t *spec = md_pkeys_spec_get(md->pks, index);;
rv = md_pubcert_load(reg->store, group, md->name, spec, &certs, p);
}
if (APR_SUCCESS != rv) goto leave;
@@ -571,16 +570,16 @@ leave:
}
apr_status_t md_reg_get_pubcert(const md_pubcert_t **ppubcert, md_reg_t *reg,
- const md_t *md, md_pkey_spec_t *spec, apr_pool_t *p)
+ const md_t *md, int i, apr_pool_t *p)
{
apr_status_t rv = APR_SUCCESS;
const md_pubcert_t *pubcert;
const char *name;
- name = apr_pstrcat(p, md->name, "[", md_pkey_spec_name(spec), "]", NULL);
+ name = apr_psprintf(p, "%s[%d]", md->name, i, NULL);
pubcert = apr_hash_get(reg->certs, name, (apr_ssize_t)strlen(name));
if (!pubcert && !reg->domains_frozen) {
- rv = md_util_pool_vdo(pubcert_load, reg, reg->p, &pubcert, MD_SG_DOMAINS, md, spec, NULL);
+ rv = md_util_pool_vdo(pubcert_load, reg, reg->p, &pubcert, MD_SG_DOMAINS, md, i, NULL);
if (APR_STATUS_IS_ENOENT(rv)) {
/* We cache it missing with an empty record */
pubcert = apr_pcalloc(reg->p, sizeof(*pubcert));
@@ -603,12 +602,6 @@ apr_status_t md_reg_get_cred_files(const
{
apr_status_t rv;
- if (md->cert_file) {
- /* With fixed files configured, we use those without further checking them ourself */
- *pcertfile = md->cert_file;
- *pkeyfile = md->pkey_file;
- return APR_SUCCESS;
- }
rv = md_store_get_fname(pkeyfile, reg->store, group, md->name, md_pkey_filename(spec, p), p);
if (APR_SUCCESS != rv) return rv;
if (!md_file_exists(*pkeyfile, p)) return APR_ENOENT;
@@ -622,14 +615,12 @@ apr_time_t md_reg_valid_until(md_reg_t *
{
const md_pubcert_t *pub;
const md_cert_t *cert;
- md_pkey_spec_t *spec;
int i;
apr_time_t t, valid_until = 0;
apr_status_t rv;
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
- spec = md_pkeys_spec_get(md->pks, i);
- rv = md_reg_get_pubcert(&pub, reg, md, spec, p);
+ for (i = 0; i < md_cert_count(md); ++i) {
+ rv = md_reg_get_pubcert(&pub, reg, md, i, p);
if (APR_SUCCESS == rv) {
cert = APR_ARRAY_IDX(pub->certs, 0, const md_cert_t*);
t = md_cert_get_not_after(cert);
@@ -652,9 +643,8 @@ apr_time_t md_reg_renew_at(md_reg_t *reg
apr_status_t rv;
if (md->state == MD_S_INCOMPLETE) return apr_time_now();
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
- spec = md_pkeys_spec_get(md->pks, i);
- rv = md_reg_get_pubcert(&pub, reg, md, spec, p);
+ for (i = 0; i < md_cert_count(md); ++i) {
+ rv = md_reg_get_pubcert(&pub, reg, md, i, p);
if (APR_STATUS_IS_ENOENT(rv)) return apr_time_now();
if (APR_SUCCESS == rv) {
cert = APR_ARRAY_IDX(pub->certs, 0, const md_cert_t*);
@@ -691,14 +681,12 @@ int md_reg_should_warn(md_reg_t *reg, co
const md_pubcert_t *pub;
const md_cert_t *cert;
md_timeperiod_t certlife, warn;
- md_pkey_spec_t *spec;
int i;
apr_status_t rv;
if (md->state == MD_S_INCOMPLETE) return 0;
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
- spec = md_pkeys_spec_get(md->pks, i);
- rv = md_reg_get_pubcert(&pub, reg, md, spec, p);
+ for (i = 0; i < md_cert_count(md); ++i) {
+ rv = md_reg_get_pubcert(&pub, reg, md, i, p);
if (APR_STATUS_IS_ENOENT(rv)) return 0;
if (APR_SUCCESS == rv) {
cert = APR_ARRAY_IDX(pub->certs, 0, const md_cert_t*);
@@ -708,8 +696,8 @@ int md_reg_should_warn(md_reg_t *reg, co
warn = md_timeperiod_slice_before_end(&certlife, md->warn_window);
if (md_log_is_level(p, MD_LOG_TRACE1)) {
md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, p,
- "md[%s]: certificate(%s) life[%s] warn[%s]",
- md->name, md_pkey_spec_name(spec),
+ "md[%s]: certificate(%d) life[%s] warn[%s]",
+ md->name, i,
md_timeperiod_print(p, &certlife),
md_timeperiod_print(p, &warn));
}
@@ -898,8 +886,6 @@ apr_status_t md_reg_sync_finish(md_reg_t
apr_status_t rv;
int changed = 1;
- md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, ptemp, "sync MDs, finish start");
-
if (!md->ca_url) {
md->ca_url = MD_ACME_DEF_URL;
md->ca_proto = MD_PROTO_ACME;
@@ -908,7 +894,9 @@ apr_status_t md_reg_sync_finish(md_reg_t
rv = state_init(reg, ptemp, md);
if (APR_SUCCESS != rv) goto leave;
+ md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "loading md %s", md->name);
if (APR_SUCCESS == md_load(reg->store, MD_SG_DOMAINS, md->name, &old, ptemp)) {
+ md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "loaded md %s", md->name);
/* Some parts are kept from old, lacking new values */
if ((!md->contacts || apr_is_empty_array(md->contacts)) && old->contacts) {
md->contacts = md_array_str_clone(p, old->contacts);
@@ -938,11 +926,14 @@ apr_status_t md_reg_sync_finish(md_reg_t
&& md_array_str_eq(md->acme_tls_1_domains, old->acme_tls_1_domains, 0)
&& !MD_VAL_UPDATE(md, old, stapling)
&& md_array_str_eq(md->contacts, old->contacts, 0)
+ && md_array_str_eq(md->cert_files, old->cert_files, 0)
+ && md_array_str_eq(md->pkey_files, old->pkey_files, 0)
&& md_array_str_eq(md->ca_challenges, old->ca_challenges, 0)) {
changed = 0;
}
}
if (changed) {
+ md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "saving md %s", md->name);
rv = md_save(reg->store, ptemp, MD_SG_DOMAINS, md, 0);
}
leave:
@@ -1202,16 +1193,14 @@ apr_status_t md_reg_freeze_domains(md_re
apr_status_t rv = APR_SUCCESS;
md_t *md;
const md_pubcert_t *pubcert;
- md_pkey_spec_t *spec;
int i, j;
assert(!reg->domains_frozen);
/* prefill the certs cache for all mds */
for (i = 0; i < mds->nelts; ++i) {
md = APR_ARRAY_IDX(mds, i, md_t*);
- for (j = 0; j < md_pkeys_spec_count(md->pks); ++j) {
- spec = md_pkeys_spec_get(md->pks, j);
- rv = md_reg_get_pubcert(&pubcert, reg, md, spec, reg->p);
+ for (j = 0; j < md_cert_count(md); ++j) {
+ rv = md_reg_get_pubcert(&pubcert, reg, md, i, reg->p);
if (APR_SUCCESS != rv && !APR_STATUS_IS_ENOENT(rv)) goto leave;
}
}
Modified: httpd/httpd/trunk/modules/md/md_reg.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_reg.h?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_reg.h (original)
+++ httpd/httpd/trunk/modules/md/md_reg.h Mon Mar 22 15:09:05 2021
@@ -113,7 +113,7 @@ apr_status_t md_reg_update(md_reg_t *reg
* of the domain and going up the issuers. Returns APR_ENOENT when not available.
*/
apr_status_t md_reg_get_pubcert(const md_pubcert_t **ppubcert, md_reg_t *reg,
- const md_t *md, struct md_pkey_spec_t *spec, apr_pool_t *p);
+ const md_t *md, int i, apr_pool_t *p);
/**
* Get the filenames of private key and pubcert of the MD - if they exist.
Modified: httpd/httpd/trunk/modules/md/md_status.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_status.c?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_status.c (original)
+++ httpd/httpd/trunk/modules/md/md_status.c Mon Mar 22 15:09:05 2021
@@ -116,7 +116,7 @@ static apr_status_t status_get_certs_jso
apr_status_t rv = APR_SUCCESS;
json = md_json_create(p);
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
+ for (i = 0; i < md_cert_count(md); ++i) {
spec = md_pkeys_spec_get(md->pks, i);
cert = APR_ARRAY_IDX(certs, i, md_cert_t*);
if (!cert) continue;
@@ -157,7 +157,7 @@ static apr_status_t get_staging_certs_js
apr_status_t rv;
certs = apr_array_make(p, 5, sizeof(md_cert_t*));
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
+ for (i = 0; i < md_cert_count(md); ++i) {
spec = md_pkeys_spec_get(md->pks, i);
cert = NULL;
rv = md_pubcert_load(md_reg_store_get(reg), MD_SG_STAGING, md->name, spec, &chain, p);
@@ -180,15 +180,13 @@ static apr_status_t status_get_md_json(m
apr_array_header_t *certs;
apr_status_t rv = APR_SUCCESS;
apr_time_t renew_at;
- md_pkey_spec_t *spec;
int i;
mdj = md_to_json(md, p);
certs = apr_array_make(p, 5, sizeof(md_cert_t*));
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
- spec = md_pkeys_spec_get(md->pks, i);
+ for (i = 0; i < md_cert_count(md); ++i) {
cert = NULL;
- if (APR_SUCCESS == md_reg_get_pubcert(&pubcert, reg, md, spec, p)) {
+ if (APR_SUCCESS == md_reg_get_pubcert(&pubcert, reg, md, i, p)) {
cert = APR_ARRAY_IDX(pubcert->certs, 0, const md_cert_t*);
}
APR_ARRAY_PUSH(certs, const md_cert_t*) = cert;
Modified: httpd/httpd/trunk/modules/md/mod_md.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md.c?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md.c (original)
+++ httpd/httpd/trunk/modules/md/mod_md.c Mon Mar 22 15:09:05 2021
@@ -671,17 +671,20 @@ static apr_status_t merge_mds_with_conf(
}
}
- if (md->cert_file && !md->pkey_file) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO(10170)
- "The Managed Domain '%s', defined in %s(line %d), "
- "has a MDCertificateFile but no MDCertificateKeyFile.",
- md->name, md->defn_name, md->defn_line_number);
- return APR_EINVAL;
+ if (md->cert_files && md->cert_files->nelts) {
+ if (!md->pkey_files || (md->cert_files->nelts != md->pkey_files->nelts)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO(10170)
+ "The Managed Domain '%s', defined in %s(line %d), "
+ "needs one MDCertificateKeyFile for each MDCertificateFile.",
+ md->name, md->defn_name, md->defn_line_number);
+ return APR_EINVAL;
+ }
}
- if (!md->cert_file && md->pkey_file) {
+ else if (md->pkey_files && md->pkey_files->nelts
+ && (!md->cert_files || !md->cert_files->nelts)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO(10171)
"The Managed Domain '%s', defined in %s(line %d), "
- "has a MDCertificateKeyFile but no MDCertificateFile.",
+ "has MDCertificateKeyFile(s) but no MDCertificateFile.",
md->name, md->defn_name, md->defn_line_number);
return APR_EINVAL;
}
@@ -950,13 +953,16 @@ static apr_status_t md_post_config_after
for (i = 0; i < mc->mds->nelts; ++i) {
md = APR_ARRAY_IDX(mc->mds, i, md_t *);
+ ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "md{%s}: auto_add", md->name);
if (APR_SUCCESS != (rv = auto_add_domains(md, s, p))) {
goto leave;
}
init_acme_tls_1_domains(md, s);
+ ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "md{%s}: check_usage", md->name);
if (APR_SUCCESS != (rv = check_usage(mc, md, s, p, ptemp))) {
goto leave;
}
+ ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "md{%s}: sync_finish", md->name);
if (APR_SUCCESS != (rv = md_reg_sync_finish(mc->reg, md, p, ptemp))) {
ap_log_error( APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10172)
"md[%s]: error syncing to store", md->name);
@@ -964,8 +970,10 @@ static apr_status_t md_post_config_after
}
}
/*8*/
+ ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "init_cert_watch");
watched = init_cert_watch_status(mc, p, ptemp, s);
/*9*/
+ ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "cleanup challenges");
md_reg_cleanup_challenges(mc->reg, p, ptemp, mc->mds);
/* From here on, the domains in the registry are readonly
@@ -990,6 +998,7 @@ static apr_status_t md_post_config_after
rv = md_ocsp_start_watching(mc, s, p);
leave:
+ ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "post_config done");
return rv;
}
@@ -1087,7 +1096,6 @@ static apr_status_t get_certificates(ser
const md_t *md;
apr_array_header_t *key_files, *chain_files;
const char *keyfile, *chainfile;
- md_pkey_spec_t *spec;
int i;
*pkey_files = *pcert_files = NULL;
@@ -1127,53 +1135,61 @@ static apr_status_t get_certificates(ser
}
md = APR_ARRAY_IDX(sc->assigned, 0, const md_t*);
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
- spec = md_pkeys_spec_get(md->pks, i);
- rv = md_reg_get_cred_files(&keyfile, &chainfile, reg, MD_SG_DOMAINS, md, spec, p);
- if (APR_SUCCESS == rv) {
- APR_ARRAY_PUSH(key_files, const char*) = keyfile;
- APR_ARRAY_PUSH(chain_files, const char*) = chainfile;
- }
- else if (!APR_STATUS_IS_ENOENT(rv)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10110)
- "retrieving credentials for MD %s (%s)",
- md->name, md_pkey_spec_name(spec));
- return rv;
- }
+ if (md->cert_files && md->cert_files->nelts) {
+ apr_array_cat(chain_files, md->cert_files);
+ apr_array_cat(key_files, md->pkey_files);
+ rv = APR_SUCCESS;
}
+ else {
+ md_pkey_spec_t *spec;
+
+ for (i = 0; i < md_cert_count(md); ++i) {
+ spec = md_pkeys_spec_get(md->pks, i);
+ rv = md_reg_get_cred_files(&keyfile, &chainfile, reg, MD_SG_DOMAINS, md, spec, p);
+ if (APR_SUCCESS == rv) {
+ APR_ARRAY_PUSH(key_files, const char*) = keyfile;
+ APR_ARRAY_PUSH(chain_files, const char*) = chainfile;
+ }
+ else if (!APR_STATUS_IS_ENOENT(rv)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10110)
+ "retrieving credentials for MD %s (%s)",
+ md->name, md_pkey_spec_name(spec));
+ return rv;
+ }
+ }
- if (md_array_is_empty(key_files)) {
- if (fallback) {
- /* Provide temporary, self-signed certificate as fallback, so that
- * clients do not get obscure TLS handshake errors or will see a fallback
- * virtual host that is not intended to be served here. */
- char *kfn, *cfn;
-
- store = md_reg_store_get(reg);
- assert(store);
-
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
- spec = md_pkeys_spec_get(md->pks, i);
- fallback_fnames(p, spec, &kfn, &cfn);
-
- md_store_get_fname(&keyfile, store, MD_SG_DOMAINS, md->name, kfn, p);
- md_store_get_fname(&chainfile, store, MD_SG_DOMAINS, md->name, cfn, p);
- if (!md_file_exists(keyfile, p) || !md_file_exists(chainfile, p)) {
- if (APR_SUCCESS != (rv = make_fallback_cert(store, md, spec, s, p, kfn, cfn))) {
- return rv;
+ if (md_array_is_empty(key_files)) {
+ if (fallback) {
+ /* Provide temporary, self-signed certificate as fallback, so that
+ * clients do not get obscure TLS handshake errors or will see a fallback
+ * virtual host that is not intended to be served here. */
+ char *kfn, *cfn;
+
+ store = md_reg_store_get(reg);
+ assert(store);
+
+ for (i = 0; i < md_cert_count(md); ++i) {
+ spec = md_pkeys_spec_get(md->pks, i);
+ fallback_fnames(p, spec, &kfn, &cfn);
+
+ md_store_get_fname(&keyfile, store, MD_SG_DOMAINS, md->name, kfn, p);
+ md_store_get_fname(&chainfile, store, MD_SG_DOMAINS, md->name, cfn, p);
+ if (!md_file_exists(keyfile, p) || !md_file_exists(chainfile, p)) {
+ if (APR_SUCCESS != (rv = make_fallback_cert(store, md, spec, s, p, kfn, cfn))) {
+ return rv;
+ }
}
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10116)
+ "%s: providing %s fallback certificate for server %s",
+ md->name, md_pkey_spec_name(spec), s->server_hostname);
+ APR_ARRAY_PUSH(key_files, const char*) = keyfile;
+ APR_ARRAY_PUSH(chain_files, const char*) = chainfile;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10116)
- "%s: providing %s fallback certificate for server %s",
- md->name, md_pkey_spec_name(spec), s->server_hostname);
- APR_ARRAY_PUSH(key_files, const char*) = keyfile;
- APR_ARRAY_PUSH(chain_files, const char*) = chainfile;
+ rv = APR_EAGAIN;
+ goto leave;
}
- rv = APR_EAGAIN;
- goto leave;
}
}
-
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(10077)
"%s[state=%d]: providing certificates for server %s",
md->name, md->state, s->server_hostname);
@@ -1345,7 +1361,8 @@ static int md_http_challenge_pr(request_
return DONE;
}
else if (!md || md->renew_mode == MD_RENEW_MANUAL
- || (md->cert_file && md->renew_mode == MD_RENEW_AUTO)) {
+ || (md->cert_files && md->cert_files->nelts
+ && md->renew_mode == MD_RENEW_AUTO)) {
/* The request hostname is not for a domain - or at least not for
* a domain that we renew ourselves. We are not
* the sole authority here for /.well-known/acme-challenge (see PR62189).
Modified: httpd/httpd/trunk/modules/md/mod_md_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md_config.c?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md_config.c (original)
+++ httpd/httpd/trunk/modules/md/mod_md_config.c Mon Mar 22 15:09:05 2021
@@ -878,27 +878,37 @@ static const char *md_config_set_dns01_c
return NULL;
}
-static const char *md_config_set_cert_file(cmd_parms *cmd, void *mconfig, const char *arg)
+static const char *md_config_add_cert_file(cmd_parms *cmd, void *mconfig, const char *arg)
{
md_srv_conf_t *sc = md_config_get(cmd->server);
- const char *err;
+ const char *err, *fpath;
(void)mconfig;
if ((err = md_conf_check_location(cmd, MD_LOC_MD))) return err;
assert(sc->current);
- sc->current->cert_file = arg;
+ fpath = ap_server_root_relative(cmd->pool, arg);
+ if (!fpath) return apr_psprintf(cmd->pool, "certificate file not found: %s", arg);
+ if (!sc->current->cert_files) {
+ sc->current->cert_files = apr_array_make(cmd->pool, 3, sizeof(char*));
+ }
+ APR_ARRAY_PUSH(sc->current->cert_files, const char*) = fpath;
return NULL;
}
-static const char *md_config_set_key_file(cmd_parms *cmd, void *mconfig, const char *arg)
+static const char *md_config_add_key_file(cmd_parms *cmd, void *mconfig, const char *arg)
{
md_srv_conf_t *sc = md_config_get(cmd->server);
- const char *err;
+ const char *err, *fpath;
(void)mconfig;
if ((err = md_conf_check_location(cmd, MD_LOC_MD))) return err;
assert(sc->current);
- sc->current->pkey_file = arg;
+ fpath = ap_server_root_relative(cmd->pool, arg);
+ if (!fpath) return apr_psprintf(cmd->pool, "certificate key file not found: %s", arg);
+ if (!sc->current->pkey_files) {
+ sc->current->pkey_files = apr_array_make(cmd->pool, 3, sizeof(char*));
+ }
+ APR_ARRAY_PUSH(sc->current->pkey_files, const char*) = fpath;
return NULL;
}
@@ -1049,9 +1059,9 @@ const command_rec md_cmds[] = {
"Allow managing of base server outside virtual hosts."),
AP_INIT_RAW_ARGS("MDChallengeDns01", md_config_set_dns01_cmd, NULL, RSRC_CONF,
"Set the command for setup/teardown of dns-01 challenges"),
- AP_INIT_TAKE1("MDCertificateFile", md_config_set_cert_file, NULL, RSRC_CONF,
+ AP_INIT_TAKE1("MDCertificateFile", md_config_add_cert_file, NULL, RSRC_CONF,
"set the static certificate (chain) file to use for this domain."),
- AP_INIT_TAKE1("MDCertificateKeyFile", md_config_set_key_file, NULL, RSRC_CONF,
+ AP_INIT_TAKE1("MDCertificateKeyFile", md_config_add_key_file, NULL, RSRC_CONF,
"set the static private key file to use for this domain."),
AP_INIT_TAKE1("MDServerStatus", md_config_set_server_status, NULL, RSRC_CONF,
"On to see Managed Domains in server-status."),
Modified: httpd/httpd/trunk/modules/md/mod_md_drive.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md_drive.c?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md_drive.c (original)
+++ httpd/httpd/trunk/modules/md/mod_md_drive.c Mon Mar 22 15:09:05 2021
@@ -173,7 +173,7 @@ int md_will_renew_cert(const md_t *md)
if (md->renew_mode == MD_RENEW_MANUAL) {
return 0;
}
- else if (md->renew_mode == MD_RENEW_AUTO && md->cert_file) {
+ else if (md->renew_mode == MD_RENEW_AUTO && md->cert_files && md->cert_files->nelts) {
return 0;
}
return 1;
Modified: httpd/httpd/trunk/modules/md/mod_md_status.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md_status.c?rev=1887923&r1=1887922&r2=1887923&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md_status.c (original)
+++ httpd/httpd/trunk/modules/md/mod_md_status.c Mon Mar 22 15:09:05 2021
@@ -104,7 +104,7 @@ int md_http_cert_status(request_rec *r)
md_json_setj(md_json_getj(mdj, MD_KEY_CERT, MD_KEY_VALID, NULL), resp, MD_KEY_VALID, NULL);
}
- for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
+ for (i = 0; i < md_cert_count(md); ++i) {
spec = md_pkeys_spec_get(md->pks, i);
keyname = md_pkey_spec_name(spec);
cj = md_json_create(r->pool);