Compare commits
5 Commits
master
...
20250217-c
Author | SHA1 | Date | |
---|---|---|---|
|
a69203a3a9 | ||
|
af32dc61f4 | ||
|
5316923f6b | ||
|
5821eb062a | ||
|
6e91a7872e |
@ -5783,6 +5783,7 @@ clitcpka-idle X X X -
|
|||||||
clitcpka-intvl X X X -
|
clitcpka-intvl X X X -
|
||||||
compression X X X X
|
compression X X X X
|
||||||
cookie X - X X
|
cookie X - X X
|
||||||
|
crt - X X -
|
||||||
declare capture - X X -
|
declare capture - X X -
|
||||||
default-server X - X X
|
default-server X - X X
|
||||||
default_backend X X X -
|
default_backend X X X -
|
||||||
@ -7009,6 +7010,62 @@ cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
|
|||||||
|
|
||||||
See also : "balance source", "capture cookie", "server" and "ignore-persist".
|
See also : "balance source", "capture cookie", "server" and "ignore-persist".
|
||||||
|
|
||||||
|
crt <crtname> [<sslbindconf> ...]*
|
||||||
|
Assignate a certificate to the current frontend.
|
||||||
|
|
||||||
|
May be used in the following contexts: tcp, http
|
||||||
|
|
||||||
|
May be used in sections : defaults | frontend | listen | backend
|
||||||
|
no | yes | yes | no
|
||||||
|
|
||||||
|
Arguments :
|
||||||
|
<sslbindconf> supports the following keywords from the bind line
|
||||||
|
(see Section 5.1. Bind options):
|
||||||
|
|
||||||
|
- allow-0rtt
|
||||||
|
- alpn
|
||||||
|
- ca-file
|
||||||
|
- ca-verify-file
|
||||||
|
- ciphers
|
||||||
|
- ciphersuites
|
||||||
|
- client-sigalgs
|
||||||
|
- crl-file
|
||||||
|
- curves
|
||||||
|
- ecdhe
|
||||||
|
- no-alpn
|
||||||
|
- no-ca-names
|
||||||
|
- npn
|
||||||
|
- sigalgs
|
||||||
|
- ssl-min-ver
|
||||||
|
- ssl-max-ver
|
||||||
|
- verify
|
||||||
|
|
||||||
|
sslbindconf also supports the following keywords from the crt-store load
|
||||||
|
keyword (see Section 3.12.1. Load options):
|
||||||
|
|
||||||
|
- key
|
||||||
|
- ocsp
|
||||||
|
- issuer
|
||||||
|
- sctl
|
||||||
|
- ocsp-update
|
||||||
|
|
||||||
|
Assignate a certificate <crtname> to a crt-list created automatically with the
|
||||||
|
frontend name and prefixed by @ (ex: '@frontend1').
|
||||||
|
|
||||||
|
This implicit crt-list will be assigned to every "ssl" bind lines in a
|
||||||
|
frontend that does not already have the "crt" or the "crt-list" line.
|
||||||
|
crt-list commands from the stats socket are effective with this crt-list, so
|
||||||
|
one could replace, remove or add certificates and SSL options to it.
|
||||||
|
|
||||||
|
Example :
|
||||||
|
|
||||||
|
frontend https
|
||||||
|
bind :443 ssl
|
||||||
|
crt foobar.pem.rsa sigalgs "RSA-PSS+SHA256"
|
||||||
|
crt test.foobar.pem
|
||||||
|
crt test2.foobar.crt key test2.foobar.key ocsp test2.foobar.ocsp ocsp-update on
|
||||||
|
|
||||||
|
See also : "crt-list" and "crt".
|
||||||
|
|
||||||
declare capture [ request | response ] len <length>
|
declare capture [ request | response ] len <length>
|
||||||
Declares a capture slot.
|
Declares a capture slot.
|
||||||
|
@ -41,6 +41,7 @@ struct crtlist *crtlist_new(const char *filename, int unique);
|
|||||||
int crtlist_parse_line(char *line, char **crt_path, struct crtlist_entry *entry, struct ckch_conf *conf, const char *file, int linenum, int from_cli, char **err);
|
int crtlist_parse_line(char *line, char **crt_path, struct crtlist_entry *entry, struct ckch_conf *conf, const char *file, int linenum, int from_cli, char **err);
|
||||||
int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, struct crtlist **crtlist, char **err);
|
int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, struct crtlist **crtlist, char **err);
|
||||||
int crtlist_load_cert_dir(char *path, struct bind_conf *bind_conf, struct crtlist **crtlist, char **err);
|
int crtlist_load_cert_dir(char *path, struct bind_conf *bind_conf, struct crtlist **crtlist, char **err);
|
||||||
|
int crtlist_load_crt(char *crt_path, struct ckch_conf *cc, struct crtlist *newlist, struct crtlist_entry *entry, char *file, int linenum, char **err);
|
||||||
|
|
||||||
void crtlist_deinit();
|
void crtlist_deinit();
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <import/ebsttree.h>
|
||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/base64.h>
|
#include <haproxy/base64.h>
|
||||||
#include <haproxy/cfgparse.h>
|
#include <haproxy/cfgparse.h>
|
||||||
@ -40,7 +42,9 @@
|
|||||||
#include <haproxy/ssl_utils.h>
|
#include <haproxy/ssl_utils.h>
|
||||||
#include <haproxy/tools.h>
|
#include <haproxy/tools.h>
|
||||||
#include <haproxy/ssl_ckch.h>
|
#include <haproxy/ssl_ckch.h>
|
||||||
|
#include <haproxy/ssl_crtlist.h>
|
||||||
#include <haproxy/ssl_ocsp.h>
|
#include <haproxy/ssl_ocsp.h>
|
||||||
|
#include <haproxy/ssl_sock.h>
|
||||||
|
|
||||||
|
|
||||||
/****************** Global Section Parsing ********************************************/
|
/****************** Global Section Parsing ********************************************/
|
||||||
@ -2153,7 +2157,205 @@ static int ssl_parse_skip_self_issued_ca(char **args, int section_type, struct p
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cfg_crt_node {
|
||||||
|
int linenum;
|
||||||
|
char *filename;
|
||||||
|
struct ssl_bind_conf *ssl_conf;
|
||||||
|
struct ckch_conf *ckch_conf;
|
||||||
|
struct list list;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* list used for inline crt-list initialization */
|
||||||
|
static struct list cur_crtlist = LIST_HEAD_INIT(cur_crtlist);
|
||||||
|
/*
|
||||||
|
* Parse a "crt" line in a frontend.
|
||||||
|
*/
|
||||||
|
static int proxy_parse_crt(char **args, int section_type, struct proxy *curpx,
|
||||||
|
const struct proxy *defpx, const char *file, int linenum,
|
||||||
|
char **err)
|
||||||
|
{
|
||||||
|
int cfgerr = 0;
|
||||||
|
struct ssl_bind_conf *ssl_conf = NULL;
|
||||||
|
struct ckch_conf *ckch_conf = NULL;
|
||||||
|
struct cfg_crt_node *cfg_crt_node = NULL;
|
||||||
|
int cur_arg = 2;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!*args[1]) {
|
||||||
|
memprintf(err, "parsing [%s:%d] : '%s' : expects a certificate name", file, linenum, args[0]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_crt_node = calloc(1, sizeof *cfg_crt_node);
|
||||||
|
if (!cfg_crt_node) {
|
||||||
|
memprintf(err, "not enough memory!");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ckch_conf = calloc(1, sizeof *ckch_conf);
|
||||||
|
if (!ckch_conf) {
|
||||||
|
memprintf(err, "not enough memory!");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ckch_conf->crt = strdup(args[1]);
|
||||||
|
if (!ckch_conf->crt) {
|
||||||
|
memprintf(err, "not enough memory!");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*args[cur_arg]) {
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
/* first look for crt-list keywords */
|
||||||
|
for (i = 0; ssl_crtlist_kws[i].kw != NULL; i++) {
|
||||||
|
if (strcmp(ssl_crtlist_kws[i].kw, args[cur_arg]) == 0) {
|
||||||
|
|
||||||
|
if (!ssl_conf)
|
||||||
|
ssl_conf = calloc(1, sizeof *ssl_conf);
|
||||||
|
if (!ssl_conf) {
|
||||||
|
memprintf(err, "not enough memory!");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgerr |= ssl_crtlist_kws[i].parse(args, cur_arg, NULL, ssl_conf, 0, err);
|
||||||
|
if (cfgerr & ERR_CODE)
|
||||||
|
goto error;
|
||||||
|
cur_arg += 1 + ssl_crtlist_kws[i].skip;
|
||||||
|
found = 1;
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* then look for ckch_conf keywords */
|
||||||
|
cfgerr |= ckch_conf_parse(args, cur_arg, ckch_conf, &found, file, linenum, err);
|
||||||
|
if (cfgerr & ERR_CODE)
|
||||||
|
goto error;
|
||||||
|
if (found) {
|
||||||
|
cur_arg += 2; /* skip 2 words if the keyword was found */
|
||||||
|
ckch_conf->used = CKCH_CONF_SET_CRTLIST; /* if they are options they must be used everywhere */
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (!found) {
|
||||||
|
memprintf(err, "unknown crt keyword '%s'", args[cur_arg]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_crt_node->ssl_conf = ssl_conf;
|
||||||
|
cfg_crt_node->ckch_conf = ckch_conf;
|
||||||
|
LIST_INSERT(&cur_crtlist, &cfg_crt_node->list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
ckch_conf_clean(ckch_conf);
|
||||||
|
ha_free(&ckch_conf);
|
||||||
|
ssl_sock_free_ssl_conf(ssl_conf);
|
||||||
|
ha_free(&ssl_conf);
|
||||||
|
ha_free(&cfg_crt_node);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After parsing the crt keywords in a frontend/listen section, create the corresponding crt-list and initialize the
|
||||||
|
* certificates
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int post_section_frontend_crt_init()
|
||||||
|
{
|
||||||
|
struct crtlist *newlist = NULL;
|
||||||
|
struct crtlist_entry *entry = NULL;
|
||||||
|
int err_code = 0;
|
||||||
|
struct cfg_crt_node *n, *r;
|
||||||
|
struct bind_conf *b;
|
||||||
|
char *crtlist_name = NULL;
|
||||||
|
char *err = NULL;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(n, r, &cur_crtlist, list) {
|
||||||
|
|
||||||
|
/* create a new crt-list with the frontend name or a specified name */
|
||||||
|
if (!crtlist_name)
|
||||||
|
memprintf(&crtlist_name, "@%s", curproxy->id);
|
||||||
|
if (!crtlist_name) {
|
||||||
|
memprintf(&err, "Not enough memory!");
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newlist)
|
||||||
|
newlist = crtlist_new(crtlist_name, 0);
|
||||||
|
if (!newlist) {
|
||||||
|
memprintf(&err, "Not enough memory!");
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = crtlist_entry_new();
|
||||||
|
if (entry == NULL) {
|
||||||
|
memprintf(&err, "Not enough memory!");
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must set the ssl_conf in case of duplication of the crtlist_entry */
|
||||||
|
entry->ssl_conf = n->ssl_conf;
|
||||||
|
|
||||||
|
err_code |= crtlist_load_crt(n->ckch_conf->crt, n->ckch_conf, newlist, entry, n->filename, n->linenum, &err);
|
||||||
|
if (err_code & ERR_CODE)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
LIST_DELETE(&n->list);
|
||||||
|
/* n->ssl_conf is reused so we don't free them here */
|
||||||
|
free(n->ckch_conf);
|
||||||
|
free(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newlist) {
|
||||||
|
|
||||||
|
if (ebst_insert(&crtlists_tree, &newlist->node) != &newlist->node) {
|
||||||
|
memprintf(&err, "Couldn't create the crt-list '%s', this name is already used by another crt-list!", crtlist_name);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* look for "ssl" bind lines without any crt nor crt-line */
|
||||||
|
list_for_each_entry(b, &curproxy->conf.bind, by_fe) {
|
||||||
|
if (b->options & BC_O_USE_SSL) {
|
||||||
|
if (eb_is_empty(&b->sni_ctx) && eb_is_empty(&b->sni_w_ctx)) {
|
||||||
|
err_code |= ssl_sock_load_cert_list_file(crtlist_name, 0, b, curproxy, &err);
|
||||||
|
if (err_code & ERR_CODE)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err_code;
|
||||||
|
error:
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
ha_alert("%s.\n", err);
|
||||||
|
free(err);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(n, r, &cur_crtlist, list) {
|
||||||
|
ckch_conf_clean(n->ckch_conf);
|
||||||
|
ha_free(&n->ckch_conf);
|
||||||
|
ssl_sock_free_ssl_conf(n->ssl_conf);
|
||||||
|
ha_free(&n->ssl_conf);
|
||||||
|
LIST_DELETE(&n->list);
|
||||||
|
ha_free(&n);
|
||||||
|
}
|
||||||
|
|
||||||
|
ha_free(&crtlist_name);
|
||||||
|
crtlist_entry_free(entry);
|
||||||
|
crtlist_free(newlist);
|
||||||
|
return err_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_CONFIG_POST_SECTION("listen", post_section_frontend_crt_init);
|
||||||
|
REGISTER_CONFIG_POST_SECTION("frontend", post_section_frontend_crt_init);
|
||||||
|
|
||||||
|
|
||||||
/* Note: must not be declared <const> as its list will be overwritten.
|
/* Note: must not be declared <const> as its list will be overwritten.
|
||||||
@ -2343,6 +2545,9 @@ static struct cfg_kw_list cfg_kws = {ILH, {
|
|||||||
{ CFG_GLOBAL, "ssl-default-server-ciphersuites", ssl_parse_global_ciphersuites },
|
{ CFG_GLOBAL, "ssl-default-server-ciphersuites", ssl_parse_global_ciphersuites },
|
||||||
{ CFG_GLOBAL, "ssl-load-extra-files", ssl_parse_global_extra_files },
|
{ CFG_GLOBAL, "ssl-load-extra-files", ssl_parse_global_extra_files },
|
||||||
{ CFG_GLOBAL, "ssl-load-extra-del-ext", ssl_parse_global_extra_noext },
|
{ CFG_GLOBAL, "ssl-load-extra-del-ext", ssl_parse_global_extra_noext },
|
||||||
|
|
||||||
|
{ CFG_LISTEN, "crt", proxy_parse_crt },
|
||||||
|
|
||||||
{ 0, NULL, NULL },
|
{ 0, NULL, NULL },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -4841,6 +4841,9 @@ out:
|
|||||||
/* freeing the content of a ckch_conf structure */
|
/* freeing the content of a ckch_conf structure */
|
||||||
void ckch_conf_clean(struct ckch_conf *conf)
|
void ckch_conf_clean(struct ckch_conf *conf)
|
||||||
{
|
{
|
||||||
|
if (!conf)
|
||||||
|
return;
|
||||||
|
|
||||||
free(conf->crt);
|
free(conf->crt);
|
||||||
free(conf->key);
|
free(conf->key);
|
||||||
free(conf->ocsp);
|
free(conf->ocsp);
|
||||||
|
@ -501,6 +501,141 @@ error:
|
|||||||
return cfgerr;
|
return cfgerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look for a ckch_store <crt_path> which is a compatible with <cc>
|
||||||
|
* Or create a new ckch_store if none exists with this name.
|
||||||
|
*
|
||||||
|
* If the file is a bundle, then duplicate the entries
|
||||||
|
* Then insert the entries in the list
|
||||||
|
*/
|
||||||
|
int crtlist_load_crt(char *crt_path, struct ckch_conf *cc, struct crtlist *newlist, struct crtlist_entry *entry, char *file, int linenum, char **err)
|
||||||
|
{
|
||||||
|
struct ckch_store *ckchs;
|
||||||
|
int found = 0;
|
||||||
|
struct stat st;
|
||||||
|
int cfgerr = 0;
|
||||||
|
|
||||||
|
/* Look for a ckch_store or create one */
|
||||||
|
ckchs = ckchs_lookup(crt_path);
|
||||||
|
if (ckchs == NULL) {
|
||||||
|
if (stat(crt_path, &st) == 0) {
|
||||||
|
found++;
|
||||||
|
|
||||||
|
if (crt_path != cc->crt) {
|
||||||
|
free(cc->crt);
|
||||||
|
cc->crt = strdup(crt_path);
|
||||||
|
if (cc->crt == NULL) {
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ckchs = ckch_store_new_load_files_conf(crt_path, cc, err);
|
||||||
|
if (ckchs == NULL) {
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ckchs->conf = *cc;
|
||||||
|
|
||||||
|
entry->node.key = ckchs;
|
||||||
|
entry->crtlist = newlist;
|
||||||
|
ebpt_insert(&newlist->entries, &entry->node);
|
||||||
|
LIST_APPEND(&newlist->ord_entries, &entry->by_crtlist);
|
||||||
|
LIST_APPEND(&ckchs->crtlist_entry, &entry->by_ckch_store);
|
||||||
|
|
||||||
|
} else if (global_ssl.extra_files & SSL_GF_BUNDLE) {
|
||||||
|
/* If we didn't find the file, this could be a
|
||||||
|
bundle, since 2.3 we don't support multiple
|
||||||
|
certificate in the same OpenSSL store, so we
|
||||||
|
emulate it by loading each file separately. To
|
||||||
|
do so we need to duplicate the entry in the
|
||||||
|
crt-list because it becomes independent */
|
||||||
|
char fp[MAXPATHLEN+1] = {0};
|
||||||
|
int n = 0;
|
||||||
|
struct crtlist_entry *entry_dup = entry; /* use the previous created entry */
|
||||||
|
|
||||||
|
for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = snprintf(fp, sizeof(fp), "%s.%s", crt_path, SSL_SOCK_KEYTYPE_NAMES[n]);
|
||||||
|
if (ret > sizeof(fp))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ckchs = ckchs_lookup(fp);
|
||||||
|
if (!ckchs) {
|
||||||
|
if (stat(fp, &st) == 0) {
|
||||||
|
|
||||||
|
if (cc->used) {
|
||||||
|
memprintf(err, "%sCan't load '%s'. Using crt-store keyword is not compatible with multi certificates bundle.\n",
|
||||||
|
err && *err ? *err : "", crt_path);
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
}
|
||||||
|
ckchs = ckch_store_new_load_files_path(fp, err);
|
||||||
|
if (!ckchs) {
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue; /* didn't find this extension, skip */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found++;
|
||||||
|
linenum++; /* we duplicate the line for this entry in the bundle */
|
||||||
|
if (!entry_dup) { /* if the entry was used, duplicate one */
|
||||||
|
linenum++;
|
||||||
|
entry_dup = crtlist_entry_dup(entry);
|
||||||
|
if (!entry_dup) {
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
entry_dup->linenum = linenum;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_dup->node.key = ckchs;
|
||||||
|
entry_dup->crtlist = newlist;
|
||||||
|
|
||||||
|
ebpt_insert(&newlist->entries, &entry_dup->node);
|
||||||
|
LIST_APPEND(&newlist->ord_entries, &entry_dup->by_crtlist);
|
||||||
|
LIST_APPEND(&ckchs->crtlist_entry, &entry_dup->by_ckch_store);
|
||||||
|
|
||||||
|
entry_dup = NULL; /* the entry was used, we need a new one next round */
|
||||||
|
}
|
||||||
|
#if HA_OPENSSL_VERSION_NUMBER < 0x10101000L
|
||||||
|
if (found) {
|
||||||
|
memprintf(err, "%sCan't load '%s'. Loading a multi certificates bundle requires OpenSSL >= 1.1.1\n",
|
||||||
|
err && *err ? *err : "", crt_path);
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
|
||||||
|
err && *err ? *err : "", crt_path, strerror(errno));
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (ckch_conf_cmp(&ckchs->conf, cc, err) != 0) {
|
||||||
|
memprintf(err, "'%s' in crt-list '%s' line %d, is already defined with incompatible parameters:\n %s", crt_path, file, linenum, err ? *err : "");
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->node.key = ckchs;
|
||||||
|
entry->crtlist = newlist;
|
||||||
|
|
||||||
|
ebpt_insert(&newlist->entries, &entry->node);
|
||||||
|
LIST_APPEND(&newlist->ord_entries, &entry->by_crtlist);
|
||||||
|
LIST_APPEND(&ckchs->crtlist_entry, &entry->by_ckch_store);
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
entry = NULL;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return cfgerr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function parse a crt-list file and store it in a struct crtlist, each line is a crtlist_entry structure
|
/* This function parse a crt-list file and store it in a struct crtlist, each line is a crtlist_entry structure
|
||||||
@ -514,7 +649,6 @@ int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *cu
|
|||||||
struct crtlist_entry *entry = NULL;
|
struct crtlist_entry *entry = NULL;
|
||||||
char thisline[CRT_LINESIZE];
|
char thisline[CRT_LINESIZE];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
struct stat buf;
|
|
||||||
int linenum = 0;
|
int linenum = 0;
|
||||||
int cfgerr = 0;
|
int cfgerr = 0;
|
||||||
int missing_lf = -1;
|
int missing_lf = -1;
|
||||||
@ -536,9 +670,7 @@ int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *cu
|
|||||||
char *line = thisline;
|
char *line = thisline;
|
||||||
char *crt_path;
|
char *crt_path;
|
||||||
char path[MAXPATHLEN+1];
|
char path[MAXPATHLEN+1];
|
||||||
struct ckch_store *ckchs;
|
|
||||||
struct ckch_conf cc = {};
|
struct ckch_conf cc = {};
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
if (missing_lf != -1) {
|
if (missing_lf != -1) {
|
||||||
memprintf(err, "parsing [%s:%d]: Stray NUL character at position %d.\n",
|
memprintf(err, "parsing [%s:%d]: Stray NUL character at position %d.\n",
|
||||||
@ -601,120 +733,10 @@ int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *cu
|
|||||||
crt_path = path;
|
crt_path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look for a ckch_store or create one */
|
cfgerr |= crtlist_load_crt(crt_path, &cc, newlist, entry, file, linenum, err);
|
||||||
ckchs = ckchs_lookup(crt_path);
|
if (cfgerr & ERR_CODE)
|
||||||
if (ckchs == NULL) {
|
goto error;
|
||||||
if (stat(crt_path, &buf) == 0) {
|
|
||||||
found++;
|
|
||||||
free(cc.crt);
|
|
||||||
cc.crt = strdup(crt_path);
|
|
||||||
if (cc.crt == NULL) {
|
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ckchs = ckch_store_new_load_files_conf(crt_path, &cc, err);
|
|
||||||
if (ckchs == NULL) {
|
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ckchs->conf = cc;
|
|
||||||
|
|
||||||
entry->node.key = ckchs;
|
|
||||||
entry->crtlist = newlist;
|
|
||||||
ebpt_insert(&newlist->entries, &entry->node);
|
|
||||||
LIST_APPEND(&newlist->ord_entries, &entry->by_crtlist);
|
|
||||||
LIST_APPEND(&ckchs->crtlist_entry, &entry->by_ckch_store);
|
|
||||||
|
|
||||||
} else if (global_ssl.extra_files & SSL_GF_BUNDLE) {
|
|
||||||
/* If we didn't find the file, this could be a
|
|
||||||
bundle, since 2.3 we don't support multiple
|
|
||||||
certificate in the same OpenSSL store, so we
|
|
||||||
emulate it by loading each file separately. To
|
|
||||||
do so we need to duplicate the entry in the
|
|
||||||
crt-list because it becomes independent */
|
|
||||||
char fp[MAXPATHLEN+1] = {0};
|
|
||||||
int n = 0;
|
|
||||||
struct crtlist_entry *entry_dup = entry; /* use the previous created entry */
|
|
||||||
|
|
||||||
for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
|
|
||||||
struct stat buf;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = snprintf(fp, sizeof(fp), "%s.%s", crt_path, SSL_SOCK_KEYTYPE_NAMES[n]);
|
|
||||||
if (ret > sizeof(fp))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ckchs = ckchs_lookup(fp);
|
|
||||||
if (!ckchs) {
|
|
||||||
if (stat(fp, &buf) == 0) {
|
|
||||||
|
|
||||||
if (cc.used) {
|
|
||||||
memprintf(err, "%sCan't load '%s'. Using crt-store keyword is not compatible with multi certificates bundle.\n",
|
|
||||||
err && *err ? *err : "", crt_path);
|
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
|
||||||
}
|
|
||||||
ckchs = ckch_store_new_load_files_path(fp, err);
|
|
||||||
if (!ckchs) {
|
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue; /* didn't find this extension, skip */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
found++;
|
|
||||||
linenum++; /* we duplicate the line for this entry in the bundle */
|
|
||||||
if (!entry_dup) { /* if the entry was used, duplicate one */
|
|
||||||
linenum++;
|
|
||||||
entry_dup = crtlist_entry_dup(entry);
|
|
||||||
if (!entry_dup) {
|
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
entry_dup->linenum = linenum;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry_dup->node.key = ckchs;
|
|
||||||
entry_dup->crtlist = newlist;
|
|
||||||
|
|
||||||
ebpt_insert(&newlist->entries, &entry_dup->node);
|
|
||||||
LIST_APPEND(&newlist->ord_entries, &entry_dup->by_crtlist);
|
|
||||||
LIST_APPEND(&ckchs->crtlist_entry, &entry_dup->by_ckch_store);
|
|
||||||
|
|
||||||
entry_dup = NULL; /* the entry was used, we need a new one next round */
|
|
||||||
}
|
|
||||||
#if HA_OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
||||||
if (found) {
|
|
||||||
memprintf(err, "%sCan't load '%s'. Loading a multi certificates bundle requires OpenSSL >= 1.1.1\n",
|
|
||||||
err && *err ? *err : "", crt_path);
|
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
|
|
||||||
err && *err ? *err : "", crt_path, strerror(errno));
|
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (ckch_conf_cmp(&ckchs->conf, &cc, err) != 0) {
|
|
||||||
memprintf(err, "'%s' in crt-list '%s' line %d, is already defined with incompatible parameters:\n %s", crt_path, file, linenum, err ? *err : "");
|
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry->node.key = ckchs;
|
|
||||||
entry->crtlist = newlist;
|
|
||||||
|
|
||||||
ebpt_insert(&newlist->entries, &entry->node);
|
|
||||||
LIST_APPEND(&newlist->ord_entries, &entry->by_crtlist);
|
|
||||||
LIST_APPEND(&ckchs->crtlist_entry, &entry->by_ckch_store);
|
|
||||||
found++;
|
|
||||||
}
|
|
||||||
entry = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (missing_lf != -1) {
|
if (missing_lf != -1) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user