diff --git a/doc/configuration.txt b/doc/configuration.txt index 338863e9d..37bac688c 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -4741,7 +4741,23 @@ every certificate of this store must be referenced using "@/" or Files in the certificate storage can also be updated dynamically with the CLI. See "set ssl cert" in the section 9.3 of the management guide. -Currently only the "load" keyword is supported in the "crt-store" section: + +The following keywords are supported in the "crt-store" section : + - crt-base + - key-base + - load + +crt-base + Assigns a default directory to fetch SSL certificates from when a relative + path is used with "crt" directives. Absolute locations specified prevail and + ignore "crt-base". When used in a crt-store, the crt-base of the global + section is ignored. + +key-base + Assigns a default directory to fetch SSL private keys from when a relative + path is used with "key" directives. Absolute locations specified prevail and + ignore "key-base". When used in a crt-store, the key-base of the global + section is ignored. load [crt ] [param*] Load SSL files in the certificate storage. @@ -4788,6 +4804,8 @@ Example: bind *:443 ssl crt "@/site1" crt "site2.crt" crt-store web + crt-base /etc/ssl/certs/ + key-base /etc/ssl/private/ load crt "site3.crt" alias "site3" load crt "site4.crt" key "site4.key" diff --git a/src/ssl_ckch.c b/src/ssl_ckch.c index 8f9c8cacb..3e6917b44 100644 --- a/src/ssl_ckch.c +++ b/src/ssl_ckch.c @@ -3996,14 +3996,18 @@ static struct cli_kw_list cli_kws = {{ },{ INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws); +static char *current_crtbase = NULL; +static char *current_keybase = NULL; +static int crtstore_load = 0; /* did we already load in this crt-store */ + struct ckch_conf_kws ckch_conf_kws[] = { { "alias", -1, PARSE_TYPE_NONE, NULL, NULL }, - { "crt", offsetof(struct ckch_conf, crt), PARSE_TYPE_STR, ssl_sock_load_pem_into_ckch, &global_ssl.crt_base }, - { "key", offsetof(struct ckch_conf, key), PARSE_TYPE_STR, ssl_sock_load_key_into_ckch, &global_ssl.key_base }, - { "ocsp", offsetof(struct ckch_conf, ocsp), PARSE_TYPE_STR, ssl_sock_load_ocsp_response_from_file, &global_ssl.crt_base }, - { "issuer", offsetof(struct ckch_conf, issuer), PARSE_TYPE_STR, ssl_sock_load_issuer_file_into_ckch, &global_ssl.crt_base }, - { "sctl", offsetof(struct ckch_conf, sctl), PARSE_TYPE_STR, ssl_sock_load_sctl_from_file, &global_ssl.crt_base }, - { NULL, -1, PARSE_TYPE_STR, NULL, NULL } + { "crt", offsetof(struct ckch_conf, crt), PARSE_TYPE_STR, ssl_sock_load_pem_into_ckch, ¤t_crtbase }, + { "key", offsetof(struct ckch_conf, key), PARSE_TYPE_STR, ssl_sock_load_key_into_ckch, ¤t_keybase }, + { "ocsp", offsetof(struct ckch_conf, ocsp), PARSE_TYPE_STR, ssl_sock_load_ocsp_response_from_file, ¤t_crtbase }, + { "issuer", offsetof(struct ckch_conf, issuer), PARSE_TYPE_STR, ssl_sock_load_issuer_file_into_ckch, ¤t_crtbase }, + { "sctl", offsetof(struct ckch_conf, sctl), PARSE_TYPE_STR, ssl_sock_load_sctl_from_file, ¤t_crtbase }, + { NULL, -1, PARSE_TYPE_STR, NULL, NULL } }; /* crt-store does not try to find files, but use the stored filename */ @@ -4065,6 +4069,40 @@ int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, char **err) return err_code; } +/* Parse a local crt-base or key-base for a crt-store */ +static int crtstore_parse_path_base(char **args, int section_type, struct proxy *curpx, const struct proxy *defpx, + const char *file, int linenum, char **err) +{ + int err_code = ERR_NONE; + + if (!*args[1]) { + memprintf(err, "parsing [%s:%d] : '%s' requires a argument.", + file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + + if (crtstore_load) { + memprintf(err, "parsing [%s:%d] : '%s' can't be used after a load line, use it at the beginning of the section.", + file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + + if (args[0][1] == 'r') { + /* crt-base */ + free(current_crtbase); + current_crtbase = strdup(args[1]); + } else if (args[0][1] == 'e') { + /* key-base */ + free(current_keybase); + current_keybase = strdup(args[1]); + } + +out: + return err_code; +} + static char current_crtstore_name[PATH_MAX] = {}; static int crtstore_parse_load(char **args, int section_type, struct proxy *curpx, const struct proxy *defpx, @@ -4159,6 +4197,8 @@ static int crtstore_parse_load(char **args, int section_type, struct proxy *curp goto out; } + crtstore_load = 1; + if (!final_name) { final_name = f.crt; @@ -4255,6 +4295,15 @@ static int cfg_parse_crtstore(const char *file, int linenum, char **args, int kw err_code |= ERR_ALERT | ERR_FATAL | ERR_ABORT; goto out; } + /* copy the crt_base and key_base */ + ha_free(¤t_crtbase); + if (global_ssl.crt_base) + current_crtbase = strdup(global_ssl.crt_base); + ha_free(¤t_keybase); + if (global_ssl.key_base) + current_keybase = strdup(global_ssl.key_base); + crtstore_load = 0; + goto out; } @@ -4304,12 +4353,17 @@ static int cfg_parse_crtstore(const char *file, int linenum, char **args, int kw static int cfg_post_parse_crtstore() { current_crtstore_name[0] = '\0'; + ha_free(¤t_crtbase); + ha_free(¤t_keybase); + return ERR_NONE; } REGISTER_CONFIG_SECTION("crt-store", cfg_parse_crtstore, cfg_post_parse_crtstore); static struct cfg_kw_list cfg_kws = {ILH, { + { CFG_CRTSTORE, "crt-base", crtstore_parse_path_base }, + { CFG_CRTSTORE, "key-base", crtstore_parse_path_base }, { CFG_CRTSTORE, "load", crtstore_parse_load }, { 0, NULL, NULL }, }};