Commit 647b163d authored by Stefan Eissing's avatar Stefan Eissing
Browse files

On the 2.4.x-mod_md branch:

Merge of r1817777 from trunk.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x-mod_md@1817780 13f79535-47bb-0310-9956-ffa450edef68
parent 596916ad
Loading
Loading
Loading
Loading
+46 −22
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ typedef struct {
    
    md_cert_t *cert;                 /* the new certificate */
    apr_array_header_t *chain;       /* the chain certificates */
    const char *next_up_link;        /* where the next chain cert is */
    
    md_acme_t *acme;
    md_t *md;
@@ -59,8 +60,6 @@ typedef struct {
    const char *csr_der_64;
    apr_interval_time_t cert_poll_timeout;
    
    const char *chain_url;
    
} md_acme_driver_t;

/**************************************************************************************************/
@@ -345,6 +344,16 @@ static apr_status_t ad_monitor_challenges(md_proto_driver_t *d)
/**************************************************************************************************/
/* poll cert */

static void get_up_link(md_proto_driver_t *d, apr_table_t *headers)
{
    md_acme_driver_t *ad = d->baton;

    ad->next_up_link = md_link_find_relation(headers, d->p, "up");
    if (ad->next_up_link) {
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, 
                      "server reports up link as %s", ad->next_up_link);
    }
} 

static apr_status_t read_http_cert(md_cert_t **pcert, apr_pool_t *p,
                                   const md_http_response_t *res)
@@ -371,6 +380,9 @@ static apr_status_t on_got_cert(md_acme_t *acme, const md_http_response_t *res,
        rv = md_store_save(d->store, d->p, MD_SG_STAGING, ad->md->name, MD_FN_CERT, 
                           MD_SV_CERT, ad->cert, 0);
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "cert parsed and saved");
        if (APR_SUCCESS == rv) {
            get_up_link(d, res->headers);
        }
    }
    return rv;
}
@@ -441,9 +453,13 @@ static apr_status_t csr_req(md_acme_t *acme, const md_http_response_t *res, void
    }
    
    /* Check if it already was sent with this response */
    ad->next_up_link = NULL;
    if (APR_SUCCESS == (rv = md_cert_read_http(&ad->cert, d->p, res))) {
        rv = md_cert_save(d->store, d->p, MD_SG_STAGING, ad->md->name, ad->cert, 0);
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "cert parsed and saved");
        if (APR_SUCCESS == rv) {
            get_up_link(d, res->headers);
        }
    }
    else if (APR_STATUS_IS_ENOENT(rv)) {
        rv = APR_SUCCESS;
@@ -523,6 +539,9 @@ static apr_status_t on_add_chain(md_acme_t *acme, const md_http_response_t *res,
    if (APR_SUCCESS == (rv = read_http_cert(&cert, d->p, res))) {
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "chain cert parsed");
        APR_ARRAY_PUSH(ad->chain, md_cert_t *) = cert;
        if (APR_SUCCESS == rv) {
            get_up_link(d, res->headers);
        }
    }
    return rv;
}
@@ -532,7 +551,7 @@ static apr_status_t get_chain(void *baton, int attempt)
    md_proto_driver_t *d = baton;
    md_acme_driver_t *ad = d->baton;
    md_cert_t *cert;
    const char *url, *last_url = NULL;
    const char *prev_link = NULL;
    apr_status_t rv = APR_SUCCESS;

    while (APR_SUCCESS == rv && ad->chain->nelts < 10) {
@@ -544,29 +563,18 @@ static apr_status_t get_chain(void *baton, int attempt)
            cert = ad->cert;
        }
        
        if (APR_SUCCESS == (rv = md_cert_get_issuers_uri(&url, cert, d->p))
            && (!last_url || strcmp(last_url, url))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "next issuer is  %s", url);
#if MD_EXPERIMENTAL
            if (!strncmp("http://127.0.0.1:", url, sizeof("http://127.0.0.1:")-1)) {
                /* test boulder instance always reports issuer cert on localhost, but we
                 * may use a different address to reach the boulder server */
                apr_uri_t curi, ca;
        if (ad->next_up_link && (!prev_link || strcmp(prev_link, ad->next_up_link))) {
            prev_link = ad->next_up_link;

                if (APR_SUCCESS == apr_uri_parse(d->p, url, &curi)
                    && APR_SUCCESS == apr_uri_parse(d->p, ad->acme->url, &ca)) {
                    url = apr_psprintf(d->p, "%s://%s:%s%s", 
                                       ca.scheme, ca.hostname, ca.port_str, curi.path);
                }
            }
#endif
            rv = md_acme_GET(ad->acme, url, NULL, NULL, on_add_chain, d);
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, 
                          "next issuer is  %s", ad->next_up_link);
            rv = md_acme_GET(ad->acme, ad->next_up_link, NULL, NULL, on_add_chain, d);
            
            if (APR_SUCCESS == rv && nelts == ad->chain->nelts) {
                break;
            }
        }
        else if (APR_STATUS_IS_ENOENT(rv) || !url || !strlen(url)) {
        else {
            rv = APR_SUCCESS;
            break;
        }
@@ -581,6 +589,22 @@ static apr_status_t ad_chain_install(md_proto_driver_t *d)
    md_acme_driver_t *ad = d->baton;
    apr_status_t rv;
    
    /* We should have that from initial cert retrieval, but if we restarted
     * or switched child process, we need to retrieve this again from the 
     * certificate resources. */
    if (!ad->next_up_link) {
        if (APR_SUCCESS != (rv = ad_cert_poll(d, 0))) {
            return rv;
        }
        if (!ad->next_up_link) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p, 
                "server reports no link header 'up' for certificate at %s", ad->md->cert_url);
            return APR_EINVAL;
        }
    }
    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, 
                  "chain starts at %s", ad->next_up_link);
    
    ad->chain = apr_array_make(d->p, 5, sizeof(md_cert_t *));
    if (APR_SUCCESS == (rv = md_util_try(get_chain, d, 0, ad->cert_poll_timeout, 0, 0, 0))) {
        rv = md_store_save(d->store, d->p, MD_SG_STAGING, ad->md->name, MD_FN_CHAIN, 
+1 −1
Original line number Diff line number Diff line
@@ -712,7 +712,7 @@ apr_status_t md_reg_sync(md_reg_t *reg, apr_pool_t *p, apr_pool_t *ptemp,
                 * someone only changed upper/lowercase, we'd like to persist that. */
                if (!md_equal_domains(md, smd, 1)) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, 
                                 "%s: %d domains changed", smd->name);
                                 "%s: domains changed", smd->name);
                    smd->domains = md_array_str_clone(ptemp, md->domains);
                    fields |= MD_UPD_DOMAINS;
                }
+2 −3
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
 * @macro
 * Version number of the md module as c string
 */
#define MOD_MD_VERSION "1.0.5"
#define MOD_MD_VERSION "1.1.0-git"

/**
 * @macro
@@ -34,9 +34,8 @@
 * 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 0x010005
#define MOD_MD_VERSION_NUM 0x010100

#define MD_EXPERIMENTAL 0
#define MD_ACME_DEF_URL    "https://acme-v01.api.letsencrypt.org/directory"

#endif /* mod_md_md_version_h */
+25 −2
Original line number Diff line number Diff line
@@ -30,8 +30,8 @@
#include "mod_md_private.h"
#include "mod_md_config.h"

#define MD_CMD_MD             "ManagedDomain"
#define MD_CMD_MD_SECTION     "<ManagedDomain"
#define MD_CMD_MD             "MDomain"
#define MD_CMD_MD_SECTION     "<MDomainSet"
#define MD_CMD_CA             "MDCertificateAuthority"
#define MD_CMD_CAAGREEMENT    "MDCertificateAgreement"
#define MD_CMD_CACHALLENGES   "MDCAChallenges"
@@ -760,6 +760,21 @@ static const char *md_config_set_notify_cmd(cmd_parms *cmd, void *arg, const cha
    return NULL;
}

static const char *md_config_set_names_old(cmd_parms *cmd, void *dc, 
                                           int argc, char *const argv[])
{
    ap_log_error( APLOG_MARK, APLOG_WARNING, 0, cmd->server,  
                 "mod_md: directive 'ManagedDomain' is deprecated, replace with 'MDomain'.");
    return md_config_set_names(cmd, dc, argc, argv);
}

static const char *md_config_sec_start_old(cmd_parms *cmd, void *mconfig, const char *arg)
{
    ap_log_error( APLOG_MARK, APLOG_WARNING, 0, cmd->server,  
                 "mod_md: directive '<ManagedDomain' is deprecated, replace with '<MDomainSet'.");
    return md_config_sec_start(cmd, mconfig, arg);
}

const command_rec md_cmds[] = {
    AP_INIT_TAKE1(     MD_CMD_CA, md_config_set_ca, NULL, RSRC_CONF, 
                  "URL of CA issuing the certificates"),
@@ -800,6 +815,14 @@ const command_rec md_cmds[] = {
                  "Redirect non-secure requests to the https: equivalent."),
    AP_INIT_TAKE1(     MD_CMD_NOTIFYCMD, md_config_set_notify_cmd, NULL, RSRC_CONF, 
                  "set the command to run when signup/renew of domain is complete."),

/* This will disappear soon */
    AP_INIT_TAKE_ARGV( "ManagedDomain", md_config_set_names_old, NULL, RSRC_CONF, 
                      "Deprecated, replace with 'MDomain'."),
    AP_INIT_RAW_ARGS(  "<ManagedDomain", md_config_sec_start_old, NULL, RSRC_CONF, 
                     "Deprecated, replace with 'MDomainSet'."),
/* */

    AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
};

+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ typedef struct md_srv_conf_t {
    const char *ca_agreement;          /* accepted agreement uri between CA and user */ 
    struct apr_array_header_t *ca_challenges; /* challenge types configured */

    md_t *current;                     /* md currently defined in <ManagedDomain xxx> section */
    md_t *current;                     /* md currently defined in <MDomainSet xxx> section */
    md_t *assigned;                    /* post_config: MD that applies to this server or NULL */
} md_srv_conf_t;