Blame modules/md/md.h

Packit 90a5c9
/* Licensed to the Apache Software Foundation (ASF) under one or more
Packit 90a5c9
 * contributor license agreements.  See the NOTICE file distributed with
Packit 90a5c9
 * this work for additional information regarding copyright ownership.
Packit 90a5c9
 * The ASF licenses this file to You under the Apache License, Version 2.0
Packit 90a5c9
 * (the "License"); you may not use this file except in compliance with
Packit 90a5c9
 * the License.  You may obtain a copy of the License at
Packit 90a5c9
 *
Packit 90a5c9
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 90a5c9
 *
Packit 90a5c9
 * Unless required by applicable law or agreed to in writing, software
Packit 90a5c9
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 90a5c9
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 90a5c9
 * See the License for the specific language governing permissions and
Packit 90a5c9
 * limitations under the License.
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
#ifndef mod_md_md_h
Packit 90a5c9
#define mod_md_md_h
Packit 90a5c9
Packit 90a5c9
#include "md_version.h"
Packit 90a5c9
Packit 90a5c9
struct apr_array_header_t;
Packit 90a5c9
struct apr_hash_t;
Packit 90a5c9
struct md_json_t;
Packit 90a5c9
struct md_cert_t;
Packit 90a5c9
struct md_pkey_t;
Packit 90a5c9
struct md_store_t;
Packit 90a5c9
struct md_srv_conf_t;
Packit 90a5c9
struct md_pkey_spec_t;
Packit 90a5c9
Packit 90a5c9
#define MD_TLSSNI01_DNS_SUFFIX     ".acme.invalid"
Packit 90a5c9
Packit 90a5c9
#define MD_PKEY_RSA_BITS_MIN       2048
Packit 90a5c9
#define MD_PKEY_RSA_BITS_DEF       2048
Packit 90a5c9
Packit 90a5c9
/* Minimum age for the HSTS header (RFC 6797), considered appropriate by Mozilla Security */
Packit 90a5c9
#define MD_HSTS_HEADER             "Strict-Transport-Security"
Packit 90a5c9
#define MD_HSTS_MAX_AGE_DEFAULT    15768000
Packit 90a5c9
Packit 90a5c9
typedef enum {
Packit 90a5c9
    MD_S_UNKNOWN,                   /* MD has not been analysed yet */
Packit 90a5c9
    MD_S_INCOMPLETE,                /* MD is missing necessary information, cannot go live */
Packit 90a5c9
    MD_S_COMPLETE,                  /* MD has all necessary information, can go live */
Packit 90a5c9
    MD_S_EXPIRED,                   /* MD is complete, but credentials have expired */
Packit 90a5c9
    MD_S_ERROR,                     /* MD data is flawed, unable to be processed as is */ 
Packit 90a5c9
    MD_S_MISSING,                   /* MD is missing config information, cannot proceed */
Packit 90a5c9
} md_state_t;
Packit 90a5c9
Packit 90a5c9
typedef enum {
Packit 90a5c9
    MD_REQUIRE_UNSET = -1,
Packit 90a5c9
    MD_REQUIRE_OFF,
Packit 90a5c9
    MD_REQUIRE_TEMPORARY,
Packit 90a5c9
    MD_REQUIRE_PERMANENT,
Packit 90a5c9
} md_require_t;
Packit 90a5c9
Packit 90a5c9
typedef enum {
Packit 90a5c9
    MD_SV_TEXT,
Packit 90a5c9
    MD_SV_JSON,
Packit 90a5c9
    MD_SV_CERT,
Packit 90a5c9
    MD_SV_PKEY,
Packit 90a5c9
    MD_SV_CHAIN,
Packit 90a5c9
} md_store_vtype_t;
Packit 90a5c9
Packit 90a5c9
typedef enum {
Packit 90a5c9
    MD_SG_NONE,
Packit 90a5c9
    MD_SG_ACCOUNTS,
Packit 90a5c9
    MD_SG_CHALLENGES,
Packit 90a5c9
    MD_SG_DOMAINS,
Packit 90a5c9
    MD_SG_STAGING,
Packit 90a5c9
    MD_SG_ARCHIVE,
Packit 90a5c9
    MD_SG_TMP,
Packit 90a5c9
    MD_SG_COUNT,
Packit 90a5c9
} md_store_group_t;
Packit 90a5c9
Packit 90a5c9
typedef enum {
Packit 90a5c9
    MD_DRIVE_DEFAULT = -1,          /* default value */
Packit 90a5c9
    MD_DRIVE_MANUAL,                /* manually triggered transmission of credentials */
Packit 90a5c9
    MD_DRIVE_AUTO,                  /* automatic process performed by httpd */
Packit 90a5c9
    MD_DRIVE_ALWAYS,                /* always driven by httpd, even if not used in any vhost */
Packit 90a5c9
} md_drive_mode_t;
Packit 90a5c9
Packit 90a5c9
typedef struct md_t md_t;
Packit 90a5c9
struct md_t {
Packit 90a5c9
    const char *name;               /* unique name of this MD */
Packit 90a5c9
    struct apr_array_header_t *domains; /* all DNS names this MD includes */
Packit 90a5c9
    struct apr_array_header_t *contacts;   /* list of contact uris, e.g. mailto:xxx */
Packit 90a5c9
Packit 90a5c9
    int transitive;                 /* != 0 iff VirtualHost names/aliases are auto-added */
Packit 90a5c9
    md_require_t require_https;     /* Iff https: is required for this MD */
Packit 90a5c9
    
Packit 90a5c9
    int drive_mode;                 /* mode of obtaining credentials */
Packit 90a5c9
    struct md_pkey_spec_t *pkey_spec;/* specification for generating new private keys */
Packit 90a5c9
    int must_staple;                /* certificates should set the OCSP Must Staple extension */
Packit 90a5c9
    apr_interval_time_t renew_norm; /* if > 0, normalized cert lifetime */
Packit 90a5c9
    apr_interval_time_t renew_window;/* time before expiration that starts renewal */
Packit 90a5c9
    
Packit 90a5c9
    const char *ca_url;             /* url of CA certificate service */
Packit 90a5c9
    const char *ca_proto;           /* protocol used vs CA (e.g. ACME) */
Packit 90a5c9
    const char *ca_account;         /* account used at CA */
Packit 90a5c9
    const char *ca_agreement;       /* accepted agreement uri between CA and user */ 
Packit 90a5c9
    struct apr_array_header_t *ca_challenges; /* challenge types configured for this MD */
Packit 90a5c9
Packit 90a5c9
    md_state_t state;               /* state of this MD */
Packit 90a5c9
    apr_time_t valid_from;          /* When the credentials start to be valid. 0 if unknown */
Packit 90a5c9
    apr_time_t expires;             /* When the credentials expire. 0 if unknown */
Packit 90a5c9
    const char *cert_url;           /* url where cert has been created, remember during drive */ 
Packit 90a5c9
    
Packit 90a5c9
    const struct md_srv_conf_t *sc; /* server config where it was defined or NULL */
Packit 90a5c9
    const char *defn_name;          /* config file this MD was defined */
Packit 90a5c9
    unsigned defn_line_number;      /* line number of definition */
Packit 90a5c9
};
Packit 90a5c9
Packit 90a5c9
#define MD_KEY_ACCOUNT          "account"
Packit 90a5c9
#define MD_KEY_AGREEMENT        "agreement"
Packit 90a5c9
#define MD_KEY_BITS             "bits"
Packit 90a5c9
#define MD_KEY_CA               "ca"
Packit 90a5c9
#define MD_KEY_CA_URL           "ca-url"
Packit 90a5c9
#define MD_KEY_CERT             "cert"
Packit 90a5c9
#define MD_KEY_CHALLENGES       "challenges"
Packit 90a5c9
#define MD_KEY_CONTACT          "contact"
Packit 90a5c9
#define MD_KEY_CONTACTS         "contacts"
Packit 90a5c9
#define MD_KEY_CSR              "csr"
Packit 90a5c9
#define MD_KEY_DETAIL           "detail"
Packit 90a5c9
#define MD_KEY_DISABLED         "disabled"
Packit 90a5c9
#define MD_KEY_DIR              "dir"
Packit 90a5c9
#define MD_KEY_DOMAIN           "domain"
Packit 90a5c9
#define MD_KEY_DOMAINS          "domains"
Packit 90a5c9
#define MD_KEY_DRIVE_MODE       "drive-mode"
Packit 90a5c9
#define MD_KEY_ERRORS           "errors"
Packit 90a5c9
#define MD_KEY_EXPIRES          "expires"
Packit 90a5c9
#define MD_KEY_HTTP             "http"
Packit 90a5c9
#define MD_KEY_HTTPS            "https"
Packit 90a5c9
#define MD_KEY_ID               "id"
Packit 90a5c9
#define MD_KEY_IDENTIFIER       "identifier"
Packit 90a5c9
#define MD_KEY_KEY              "key"
Packit 90a5c9
#define MD_KEY_KEYAUTHZ         "keyAuthorization"
Packit 90a5c9
#define MD_KEY_LOCATION         "location"
Packit 90a5c9
#define MD_KEY_MUST_STAPLE      "must-staple"
Packit 90a5c9
#define MD_KEY_NAME             "name"
Packit 90a5c9
#define MD_KEY_PERMANENT        "permanent"
Packit 90a5c9
#define MD_KEY_PKEY             "privkey"
Packit 90a5c9
#define MD_KEY_PROCESSED        "processed"
Packit 90a5c9
#define MD_KEY_PROTO            "proto"
Packit 90a5c9
#define MD_KEY_REGISTRATION     "registration"
Packit 90a5c9
#define MD_KEY_RENEW            "renew"
Packit 90a5c9
#define MD_KEY_RENEW_WINDOW     "renew-window"
Packit 90a5c9
#define MD_KEY_REQUIRE_HTTPS    "require-https"
Packit 90a5c9
#define MD_KEY_RESOURCE         "resource"
Packit 90a5c9
#define MD_KEY_STATE            "state"
Packit 90a5c9
#define MD_KEY_STATUS           "status"
Packit 90a5c9
#define MD_KEY_STORE            "store"
Packit 90a5c9
#define MD_KEY_TEMPORARY        "temporary"
Packit 90a5c9
#define MD_KEY_TOKEN            "token"
Packit 90a5c9
#define MD_KEY_TRANSITIVE       "transitive"
Packit 90a5c9
#define MD_KEY_TYPE             "type"
Packit 90a5c9
#define MD_KEY_URL              "url"
Packit 90a5c9
#define MD_KEY_URI              "uri"
Packit 90a5c9
#define MD_KEY_VALID_FROM       "validFrom"
Packit 90a5c9
#define MD_KEY_VALUE            "value"
Packit 90a5c9
#define MD_KEY_VERSION          "version"
Packit 90a5c9
Packit 90a5c9
#define MD_FN_MD                "md.json"
Packit 90a5c9
#define MD_FN_JOB               "job.json"
Packit 90a5c9
#define MD_FN_PRIVKEY           "privkey.pem"
Packit 90a5c9
#define MD_FN_PUBCERT           "pubcert.pem"
Packit 90a5c9
#define MD_FN_CERT              "cert.pem"
Packit 90a5c9
#define MD_FN_CHAIN             "chain.pem"
Packit 90a5c9
#define MD_FN_HTTPD_JSON        "httpd.json"
Packit 90a5c9
Packit 90a5c9
#define MD_FN_FALLBACK_PKEY     "fallback-privkey.pem"
Packit 90a5c9
#define MD_FN_FALLBACK_CERT     "fallback-cert.pem"
Packit 90a5c9
Packit 90a5c9
/* Check if a string member of a new MD (n) has 
Packit 90a5c9
 * a value and if it differs from the old MD o
Packit 90a5c9
 */
Packit 90a5c9
#define MD_VAL_UPDATE(n,o,s)    ((n)->s != (o)->s)
Packit 90a5c9
#define MD_SVAL_UPDATE(n,o,s)   ((n)->s && (!(o)->s || strcmp((n)->s, (o)->s)))
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Determine if the Managed Domain contains a specific domain name.
Packit 90a5c9
 */
Packit 90a5c9
int md_contains(const md_t *md, const char *domain, int case_sensitive);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Determine if the names of the two managed domains overlap.
Packit 90a5c9
 */
Packit 90a5c9
int md_domains_overlap(const md_t *md1, const md_t *md2);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Determine if the domain names are equal.
Packit 90a5c9
 */
Packit 90a5c9
int md_equal_domains(const md_t *md1, const md_t *md2, int case_sensitive);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Determine if the domains in md1 contain all domains of md2.
Packit 90a5c9
 */
Packit 90a5c9
int md_contains_domains(const md_t *md1, const md_t *md2);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Get one common domain name of the two managed domains or NULL.
Packit 90a5c9
 */
Packit 90a5c9
const char *md_common_name(const md_t *md1, const md_t *md2);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Get the number of common domains.
Packit 90a5c9
 */
Packit 90a5c9
apr_size_t md_common_name_count(const md_t *md1, const md_t *md2);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Look up a managed domain by its name.
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_get_by_name(struct apr_array_header_t *mds, const char *name);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Look up a managed domain by a DNS name it contains.
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_get_by_domain(struct apr_array_header_t *mds, const char *domain);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Find a managed domain, different from the given one, that has overlaps
Packit 90a5c9
 * in the domain list.
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_get_by_dns_overlap(struct apr_array_header_t *mds, const md_t *md);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Find the managed domain in the list that, for the given md, 
Packit 90a5c9
 * has the same name, or the most number of overlaps in domains
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_find_closest_match(apr_array_header_t *mds, const md_t *md);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Create and empty md record, structures initialized.
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_create_empty(apr_pool_t *p);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Create a managed domain, given a list of domain names.
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_create(apr_pool_t *p, struct apr_array_header_t *domains);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Deep copy an md record into another pool.
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_clone(apr_pool_t *p, const md_t *src);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Shallow copy an md record into another pool.
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_copy(apr_pool_t *p, const md_t *src);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Create a merged md with the settings of add overlaying the ones from base.
Packit 90a5c9
 */
Packit 90a5c9
md_t *md_merge(apr_pool_t *p, const md_t *add, const md_t *base);
Packit 90a5c9
Packit 90a5c9
/** 
Packit 90a5c9
 * Convert the managed domain into a JSON representation and vice versa. 
Packit 90a5c9
 *
Packit 90a5c9
 * This reads and writes the following information: name, domains, ca_url, ca_proto and state.
Packit 90a5c9
 */
Packit 90a5c9
struct md_json_t *md_to_json (const md_t *md, apr_pool_t *p);
Packit 90a5c9
md_t *md_from_json(struct md_json_t *json, apr_pool_t *p);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Determine if MD should renew its cert (if it has one)
Packit 90a5c9
 */
Packit 90a5c9
int md_should_renew(const md_t *md);
Packit 90a5c9
Packit 90a5c9
/**************************************************************************************************/
Packit 90a5c9
/* domain credentials */
Packit 90a5c9
Packit 90a5c9
typedef struct md_creds_t md_creds_t;
Packit 90a5c9
struct md_creds_t {
Packit 90a5c9
    struct md_pkey_t *privkey;
Packit 90a5c9
    struct apr_array_header_t *pubcert;    /* complete md_cert* chain */
Packit 90a5c9
    struct md_cert_t *cert;
Packit 90a5c9
    int expired;
Packit 90a5c9
};
Packit 90a5c9
Packit 90a5c9
/* TODO: not sure this is a good idea, testing some readability and debuggabiltiy of
Packit 90a5c9
 * cascaded apr_status_t checks. */
Packit 90a5c9
#define MD_CHK_VARS                 const char *md_chk_
Packit 90a5c9
#define MD_LAST_CHK                 md_chk_
Packit 90a5c9
#define MD_CHK_STEP(c, status, s)   (md_chk_ = s, (void)md_chk_, status == (rv = (c)))
Packit 90a5c9
#define MD_CHK(c, status)           MD_CHK_STEP(c, status, #c)
Packit 90a5c9
#define MD_IS_ERR(c, err)           (md_chk_ = #c, APR_STATUS_IS_##err((rv = (c))))
Packit 90a5c9
#define MD_CHK_SUCCESS(c)           MD_CHK(c, APR_SUCCESS)
Packit 90a5c9
#define MD_OK(c)                    MD_CHK_SUCCESS(c)
Packit 90a5c9
Packit 90a5c9
#endif /* mod_md_md_h */