Skip to content

Commit 2a01ce2

Browse files
committed
*) mod_md: full squash of all changes in trunk, since people
do changes and miss proposing them for backport. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1923593 13f79535-47bb-0310-9956-ffa450edef68
1 parent 347d7b3 commit 2a01ce2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+842
-371
lines changed

changes-entries/md_v2.5.1.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
*) mod_md: update to version 2.5.1
2+
- Added support for ACME profiles with new directives MDProfile and
3+
MDProfileMandatory.
4+
- When installing a custom CA file via `MDCACertificateFile`, also set the
5+
libcurl option CURLSSLOPT_NO_REVOKE that suppresses complains by Schannel
6+
(when curl is linked with it) about missing CRL/OCSP in certificates.
7+
- Fixed handling of corrupted httpd.json and added test 300_30 for it.
8+
File is removed on error and written again. Fixes #369.
9+
- Added explanation in log for how to proceed when md_store.json could not be
10+
parsed and prevented the server start.
11+
- restored fixed to #336 and #337 which got lost in a sync with Apache svn
12+
- Add Issue Name/Uris to certificate information in md-status handler
13+
- MDomains with static certificate files have MDRenewMode "manual", unless
14+
"always" is configured.

modules/md/md.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ struct md_t {
9292
struct apr_array_header_t *pkey_files; /* != NULL iff privkeys explicitly configured */
9393
const char *ca_eab_kid; /* optional KEYID for external account binding */
9494
const char *ca_eab_hmac; /* optional HMAC for external account binding */
95+
const char *profile; /* optional cert profile to order */
96+
int profile_mandatory; /* if profile, when given, is mandatory */
9597

9698
const char *state_descr; /* description of state of NULL */
9799

@@ -154,6 +156,8 @@ struct md_t {
154156
#define MD_KEY_HTTPS "https"
155157
#define MD_KEY_ID "id"
156158
#define MD_KEY_IDENTIFIER "identifier"
159+
#define MD_KEY_ISSUER_NAME "issuer-name"
160+
#define MD_KEY_ISSUER_URI "issuer-uri"
157161
#define MD_KEY_KEY "key"
158162
#define MD_KEY_KID "kid"
159163
#define MD_KEY_KEYAUTHZ "keyAuthorization"
@@ -175,6 +179,8 @@ struct md_t {
175179
#define MD_KEY_PKEY "privkey"
176180
#define MD_KEY_PKEY_FILES "pkey-files"
177181
#define MD_KEY_PROBLEM "problem"
182+
#define MD_KEY_PROFILE "profile"
183+
#define MD_KEY_PROFILE_MANDATORY "profile-mandatory"
178184
#define MD_KEY_PROTO "proto"
179185
#define MD_KEY_READY "ready"
180186
#define MD_KEY_REGISTRATION "registration"

modules/md/md_acme.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,15 @@ typedef struct {
664664
md_result_t *result;
665665
} update_dir_ctx;
666666

667+
static int collect_profiles(void *baton, const char* key, md_json_t *json)
668+
{
669+
update_dir_ctx *ctx = baton;
670+
(void)json;
671+
APR_ARRAY_PUSH(ctx->acme->api.v2.profiles, const char *) =
672+
apr_pstrdup(ctx->acme->p, key);
673+
return 1;
674+
}
675+
667676
static apr_status_t update_directory(const md_http_response_t *res, void *data)
668677
{
669678
md_http_request_t *req = res->req;
@@ -728,6 +737,20 @@ static apr_status_t update_directory(const md_http_response_t *res, void *data)
728737
acme->new_nonce_fn = acmev2_new_nonce;
729738
acme->req_init_fn = acmev2_req_init;
730739
acme->post_new_account_fn = acmev2_POST_new_account;
740+
741+
if (md_json_has_key(json, "meta", "profiles", NULL)) {
742+
acme->api.v2.profiles = apr_array_make(acme->p, 5, sizeof(const char*));
743+
md_json_iterkey(collect_profiles, data, json, "meta", "profiles", NULL);
744+
md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, req->pool,
745+
"found %d profiles in ACME directory meta",
746+
acme->api.v2.profiles->nelts);
747+
}
748+
else {
749+
acme->api.v2.profiles = NULL;
750+
md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, req->pool,
751+
"no profiles in ACME directory meta");
752+
753+
}
731754
}
732755
else if ((s = md_json_dups(acme->p, json, "new-authz", NULL))) {
733756
acme->api.v1.new_authz = s;

modules/md/md_acme.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ struct md_acme_t {
118118
const char *key_change;
119119
const char *revoke_cert;
120120
const char *new_nonce;
121+
struct apr_array_header_t *profiles;
121122
} v2;
122123
} api;
123124
const char *ca_agreement;

modules/md/md_acme_drive.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,9 @@ static apr_status_t acme_renew(md_proto_driver_t *d, md_result_t *result)
765765
if (!ad->domains) {
766766
ad->domains = md_dns_make_minimal(d->p, ad->md->domains);
767767
}
768-
768+
ad->profile = ad->md->profile;
769+
ad->profile_mandatory = ad->md->profile_mandatory;
770+
769771
md_result_activity_printf(result, "Contacting ACME server for %s at %s",
770772
d->md->name, ca_effective);
771773
if (APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, ca_effective,

modules/md/md_acme_drive.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ typedef struct md_acme_driver_t {
2929
md_t *md;
3030
struct apr_array_header_t *domains;
3131
apr_array_header_t *ca_challenges;
32+
const char *profile;
33+
int profile_mandatory;
3234

3335
int complete;
3436
apr_array_header_t *creds; /* the new md_credentials_t */

modules/md/md_acme_order.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,14 @@ typedef struct {
263263
md_acme_order_t *order;
264264
md_acme_t *acme;
265265
const char *name;
266+
const char *profile;
266267
apr_array_header_t *domains;
267268
md_result_t *result;
268269
} order_ctx_t;
269270

270-
#define ORDER_CTX_INIT(ctx, p, o, a, n, d, r) \
271+
#define ORDER_CTX_INIT(ctx, p, o, a, n, d, pf, r) \
271272
(ctx)->p = (p); (ctx)->order = (o); (ctx)->acme = (a); \
272-
(ctx)->name = (n); (ctx)->domains = d; (ctx)->result = r
273+
(ctx)->name = (n); (ctx)->domains = d; (ctx)->profile = pf; (ctx)->result = r
273274

274275
static apr_status_t identifier_to_json(void *value, md_json_t *json, apr_pool_t *p, void *baton)
275276
{
@@ -289,6 +290,8 @@ static apr_status_t on_init_order_register(md_acme_req_t *req, void *baton)
289290

290291
jpayload = md_json_create(req->p);
291292
md_json_seta(ctx->domains, identifier_to_json, NULL, jpayload, "identifiers", NULL);
293+
if (ctx->profile)
294+
md_json_sets(ctx->profile, jpayload, "profile", NULL);
292295

293296
return md_acme_req_body_init(req, jpayload);
294297
}
@@ -321,13 +324,14 @@ static apr_status_t on_order_upd(md_acme_t *acme, apr_pool_t *p, const apr_table
321324
}
322325

323326
apr_status_t md_acme_order_register(md_acme_order_t **porder, md_acme_t *acme, apr_pool_t *p,
324-
const char *name, apr_array_header_t *domains)
327+
const char *name, apr_array_header_t *domains,
328+
const char *profile)
325329
{
326330
order_ctx_t ctx;
327331
apr_status_t rv;
328332

329333
assert(MD_ACME_VERSION_MAJOR(acme->version) > 1);
330-
ORDER_CTX_INIT(&ctx, p, NULL, acme, name, domains, NULL);
334+
ORDER_CTX_INIT(&ctx, p, NULL, acme, name, domains, profile, NULL);
331335
rv = md_acme_POST(acme, acme->api.v2.new_order, on_init_order_register, on_order_upd, NULL, NULL, &ctx);
332336
*porder = (APR_SUCCESS == rv)? ctx.order : NULL;
333337
return rv;
@@ -340,7 +344,7 @@ apr_status_t md_acme_order_update(md_acme_order_t *order, md_acme_t *acme,
340344
apr_status_t rv;
341345

342346
assert(MD_ACME_VERSION_MAJOR(acme->version) > 1);
343-
ORDER_CTX_INIT(&ctx, p, order, acme, NULL, NULL, result);
347+
ORDER_CTX_INIT(&ctx, p, order, acme, NULL, NULL, NULL, result);
344348
rv = md_acme_GET(acme, order->url, NULL, on_order_upd, NULL, NULL, &ctx);
345349
if (APR_SUCCESS != rv && APR_SUCCESS != acme->last->status) {
346350
md_result_dup(result, acme->last);
@@ -380,7 +384,7 @@ apr_status_t md_acme_order_await_ready(md_acme_order_t *order, md_acme_t *acme,
380384
apr_status_t rv;
381385

382386
assert(MD_ACME_VERSION_MAJOR(acme->version) > 1);
383-
ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, result);
387+
ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, NULL, result);
384388

385389
md_result_activity_setn(result, "Waiting for order to become ready");
386390
rv = md_util_try(await_ready, &ctx, 0, timeout, 0, 0, 1);
@@ -423,7 +427,7 @@ apr_status_t md_acme_order_await_valid(md_acme_order_t *order, md_acme_t *acme,
423427
apr_status_t rv;
424428

425429
assert(MD_ACME_VERSION_MAJOR(acme->version) > 1);
426-
ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, result);
430+
ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, NULL, result);
427431

428432
md_result_activity_setn(result, "Waiting for finalized order to become valid");
429433
rv = md_util_try(await_valid, &ctx, 0, timeout, 0, 0, 1);
@@ -552,7 +556,7 @@ apr_status_t md_acme_order_monitor_authzs(md_acme_order_t *order, md_acme_t *acm
552556
order_ctx_t ctx;
553557
apr_status_t rv;
554558

555-
ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, result);
559+
ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, NULL, result);
556560

557561
md_result_activity_printf(result, "Monitoring challenge status for %s", md->name);
558562
rv = md_util_try(check_challenges, &ctx, 0, timeout, 0, 0, 1);

modules/md/md_acme_order.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ apr_status_t md_acme_order_monitor_authzs(md_acme_order_t *order, md_acme_t *acm
7676
/* ACMEv2 only ************************************************************************************/
7777

7878
apr_status_t md_acme_order_register(md_acme_order_t **porder, md_acme_t *acme, apr_pool_t *p,
79-
const char *name, struct apr_array_header_t *domains);
79+
const char *name, struct apr_array_header_t *domains,
80+
const char *profile);
8081

8182
apr_status_t md_acme_order_update(md_acme_order_t *order, md_acme_t *acme,
8283
struct md_result_t *result, apr_pool_t *p);

modules/md/md_acmev2_drive.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static apr_status_t ad_setup_order(md_proto_driver_t *d, md_result_t *result, in
5656
md_acme_driver_t *ad = d->baton;
5757
apr_status_t rv;
5858
md_t *md = ad->md;
59+
const char *profile = NULL;
5960

6061
assert(ad->md);
6162
assert(ad->acme);
@@ -77,7 +78,33 @@ static apr_status_t ad_setup_order(md_proto_driver_t *d, md_result_t *result, in
7778
}
7879

7980
md_result_activity_setn(result, "Creating new order");
80-
rv = md_acme_order_register(&ad->order, ad->acme, d->p, d->md->name, ad->domains);
81+
if (ad->profile) {
82+
if(ad->acme->api.v2.profiles) {
83+
int i;
84+
for (i = 0; !profile && i < ad->acme->api.v2.profiles->nelts; ++i) {
85+
const char *s = APR_ARRAY_IDX(ad->acme->api.v2.profiles, i, const char*);
86+
if (!apr_strnatcasecmp(s, ad->profile))
87+
profile = s;
88+
}
89+
}
90+
if (profile)
91+
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p,
92+
"%s: ordering ACME profile '%s'", md->name, profile);
93+
else if (ad->profile_mandatory) {
94+
md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p,
95+
"%s: mandatory ACME profile '%s' is not offered by CA",
96+
md->name, ad->profile);
97+
rv = APR_EINVAL;
98+
goto leave;
99+
}
100+
else {
101+
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p,
102+
"%s: ACME profile '%s' is not offered by CA, continuing without",
103+
md->name, ad->profile);
104+
}
105+
}
106+
107+
rv = md_acme_order_register(&ad->order, ad->acme, d->p, d->md->name, ad->domains, profile);
81108
if (APR_SUCCESS !=rv) goto leave;
82109
rv = md_acme_order_save(d->store, d->p, MD_SG_STAGING, d->md->name, ad->order, 0);
83110
if (APR_SUCCESS != rv) {

modules/md/md_core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ md_json_t *md_to_json(const md_t *md, apr_pool_t *p)
317317
md_json_sets(md->ca_eab_kid, json, MD_KEY_EAB, MD_KEY_KID, NULL);
318318
if (md->ca_eab_hmac) md_json_sets(md->ca_eab_hmac, json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
319319
}
320+
if (md->profile) md_json_sets(md->profile, json, MD_KEY_PROFILE, NULL);
321+
md_json_setb(md->profile_mandatory > 0, json, MD_KEY_PROFILE_MANDATORY, NULL);
320322
return json;
321323
}
322324
return NULL;
@@ -383,6 +385,10 @@ md_t *md_from_json(md_json_t *json, apr_pool_t *p)
383385
md->ca_eab_kid = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_KID, NULL);
384386
md->ca_eab_hmac = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
385387
}
388+
389+
md->profile_mandatory = (int)md_json_getb(json, MD_KEY_PROFILE_MANDATORY, NULL);
390+
if (md_json_has_key(json, MD_KEY_PROFILE, NULL))
391+
md->profile = md_json_dups(p, json, MD_KEY_PROFILE, NULL);
386392
return md;
387393
}
388394
return NULL;

0 commit comments

Comments
 (0)