mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-11 03:31:36 +00:00
MINOR: ssl/cli: support crt-list filters
Generate a list of the previous filters when updating a certificate which use filters in crt-list. Then pass this list to the function generating the sni_ctx during the commit. This feature allows the update of the crt-list certificates which uses the filters with "set ssl cert". This function could be probably replaced by creating a new ckch_inst_new_load_store() function which take the previous sni_ctx list as an argument instead of the char **sni_filter, avoiding the allocation/copy during runtime for each filter. But since are still handling the multi-cert bundles, it's better this way to avoid code duplication.
This commit is contained in:
parent
f4629a5346
commit
38df1c8006
@ -111,7 +111,6 @@ struct cert_key_and_chain {
|
|||||||
struct ckch_store {
|
struct ckch_store {
|
||||||
struct cert_key_and_chain *ckch;
|
struct cert_key_and_chain *ckch;
|
||||||
unsigned int multi:1; /* is it a multi-cert bundle ? */
|
unsigned int multi:1; /* is it a multi-cert bundle ? */
|
||||||
unsigned int filters:1;/* one of the instances is using filters, TODO:remove this flag once filters are supported */
|
|
||||||
struct list ckch_inst; /* list of ckch_inst which uses this ckch_node */
|
struct list ckch_inst; /* list of ckch_inst which uses this ckch_node */
|
||||||
struct ebmb_node node;
|
struct ebmb_node node;
|
||||||
char path[0];
|
char path[0];
|
||||||
|
108
src/ssl_sock.c
108
src/ssl_sock.c
@ -3895,6 +3895,84 @@ end:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free a sni filters array generated by ckch_inst_sni_ctx_to_sni_filters()
|
||||||
|
*/
|
||||||
|
static inline void free_sni_filters(char **sni_filter, int fcount)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (sni_filter) {
|
||||||
|
for (i = 0; i < fcount; i++) {
|
||||||
|
if (sni_filter[i]) {
|
||||||
|
free(sni_filter[i]);
|
||||||
|
sni_filter[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(sni_filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill <*sni_filter> with an allocated array of ptr to the existing filters,
|
||||||
|
* The caller should free <*sni_filter>.
|
||||||
|
* Fill <*fcount> with the number of filters
|
||||||
|
* Return an ERR_* code.
|
||||||
|
*/
|
||||||
|
static int ckch_inst_sni_ctx_to_sni_filters(const struct ckch_inst *ckchi, char ***sni_filter, int *fcount, char **err)
|
||||||
|
{
|
||||||
|
struct sni_ctx *sc0;
|
||||||
|
int errcode = 0;
|
||||||
|
int i = 0;
|
||||||
|
char **tmp_filter;
|
||||||
|
int tmp_fcount = 0;
|
||||||
|
|
||||||
|
list_for_each_entry(sc0, &ckchi->sni_ctx, by_ckch_inst) {
|
||||||
|
tmp_fcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tmp_fcount)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
tmp_filter = malloc(sizeof(*tmp_filter) * tmp_fcount);
|
||||||
|
if (!tmp_filter) {
|
||||||
|
errcode |= ERR_FATAL|ERR_ALERT;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(sc0, &ckchi->sni_ctx, by_ckch_inst) {
|
||||||
|
size_t len = strlen((char *)sc0->name.key);
|
||||||
|
|
||||||
|
/* we need to alloc and copy to insert a '!' or/and a '*' */
|
||||||
|
tmp_filter[i] = calloc(1, len + sc0->neg + sc0->wild + 1);
|
||||||
|
if (!tmp_filter[i]) {
|
||||||
|
errcode |= ERR_FATAL|ERR_ALERT;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc0->neg)
|
||||||
|
*tmp_filter[i] = '!';
|
||||||
|
if (sc0->wild)
|
||||||
|
*(tmp_filter[i] + sc0->neg) = '*';
|
||||||
|
|
||||||
|
memcpy(tmp_filter[i] + sc0->neg + sc0->wild, (char *)sc0->name.key, len + 1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
*sni_filter = tmp_filter;
|
||||||
|
*fcount = tmp_fcount;
|
||||||
|
|
||||||
|
return errcode;
|
||||||
|
error:
|
||||||
|
memprintf(err, "%sUnable to generate filters!",
|
||||||
|
err && *err ? *err : "");
|
||||||
|
free_sni_filters(tmp_filter, tmp_fcount);
|
||||||
|
|
||||||
|
return errcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if HA_OPENSSL_VERSION_NUMBER >= 0x1000200fL
|
#if HA_OPENSSL_VERSION_NUMBER >= 0x1000200fL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3949,10 +4027,6 @@ static int ckch_inst_new_load_multi_store(const char *path, struct ckch_store *c
|
|||||||
|
|
||||||
certs_and_keys = ckchs->ckch;
|
certs_and_keys = ckchs->ckch;
|
||||||
|
|
||||||
/* at least one of the instances is using filters during the config
|
|
||||||
* parsing, that's ok to inherit this during loading on CLI */
|
|
||||||
ckchs->filters |= !!fcount;
|
|
||||||
|
|
||||||
/* Process each ckch and update keytypes for each CN/SAN
|
/* Process each ckch and update keytypes for each CN/SAN
|
||||||
* for example, if CN/SAN www.a.com is associated with
|
* for example, if CN/SAN www.a.com is associated with
|
||||||
* certs with keytype 0 and 2, then at the end of the loop,
|
* certs with keytype 0 and 2, then at the end of the loop,
|
||||||
@ -4193,10 +4267,6 @@ static int ckch_inst_new_load_store(const char *path, struct ckch_store *ckchs,
|
|||||||
|
|
||||||
ckch = ckchs->ckch;
|
ckch = ckchs->ckch;
|
||||||
|
|
||||||
/* at least one of the instances is using filters during the config
|
|
||||||
* parsing, that's ok to inherit this during loading on CLI */
|
|
||||||
ckchs->filters |= !!fcount;
|
|
||||||
|
|
||||||
ctx = SSL_CTX_new(SSLv23_server_method());
|
ctx = SSL_CTX_new(SSLv23_server_method());
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
|
memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
|
||||||
@ -10924,6 +10994,8 @@ static int cli_io_handler_commit_cert(struct appctx *appctx)
|
|||||||
/* walk through the old ckch_inst and creates new ckch_inst using the updated ckchs */
|
/* walk through the old ckch_inst and creates new ckch_inst using the updated ckchs */
|
||||||
list_for_each_entry_from(ckchi, &old_ckchs->ckch_inst, by_ckchs) {
|
list_for_each_entry_from(ckchi, &old_ckchs->ckch_inst, by_ckchs) {
|
||||||
struct ckch_inst *new_inst;
|
struct ckch_inst *new_inst;
|
||||||
|
char **sni_filter = NULL;
|
||||||
|
int fcount = 0;
|
||||||
|
|
||||||
/* it takes a lot of CPU to creates SSL_CTXs, so we yield every 10 CKCH instances */
|
/* it takes a lot of CPU to creates SSL_CTXs, so we yield every 10 CKCH instances */
|
||||||
if (y >= 10) {
|
if (y >= 10) {
|
||||||
@ -10932,10 +11004,17 @@ static int cli_io_handler_commit_cert(struct appctx *appctx)
|
|||||||
goto yield;
|
goto yield;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errcode |= ckch_inst_sni_ctx_to_sni_filters(ckchi, &sni_filter, &fcount, &err);
|
||||||
|
if (errcode & ERR_CODE)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (new_ckchs->multi)
|
if (new_ckchs->multi)
|
||||||
errcode |= ckch_inst_new_load_multi_store(new_ckchs->path, new_ckchs, ckchi->bind_conf, ckchi->ssl_conf, NULL, 0, &new_inst, &err);
|
errcode |= ckch_inst_new_load_multi_store(new_ckchs->path, new_ckchs, ckchi->bind_conf, ckchi->ssl_conf, sni_filter, fcount, &new_inst, &err);
|
||||||
else
|
else
|
||||||
errcode |= ckch_inst_new_load_store(new_ckchs->path, new_ckchs, ckchi->bind_conf, ckchi->ssl_conf, NULL, 0, &new_inst, &err);
|
errcode |= ckch_inst_new_load_store(new_ckchs->path, new_ckchs, ckchi->bind_conf, ckchi->ssl_conf, sni_filter, fcount, &new_inst, &err);
|
||||||
|
|
||||||
|
free_sni_filters(sni_filter, fcount);
|
||||||
|
sni_filter = NULL;
|
||||||
|
|
||||||
if (errcode & ERR_CODE)
|
if (errcode & ERR_CODE)
|
||||||
goto error;
|
goto error;
|
||||||
@ -11103,7 +11182,6 @@ error:
|
|||||||
return cli_dynerr(appctx, err);
|
return cli_dynerr(appctx, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parsing function of `set ssl cert`, it updates or creates a temporary ckch.
|
* Parsing function of `set ssl cert`, it updates or creates a temporary ckch.
|
||||||
*/
|
*/
|
||||||
@ -11266,14 +11344,6 @@ static int cli_parse_set_cert(char **args, char *payload, struct appctx *appctx,
|
|||||||
|
|
||||||
old_ckchs = appctx->ctx.ssl.old_ckchs;
|
old_ckchs = appctx->ctx.ssl.old_ckchs;
|
||||||
|
|
||||||
/* TODO: handle filters */
|
|
||||||
if (old_ckchs->filters) {
|
|
||||||
memprintf(&err, "%sCertificates used in crt-list with filters are not supported!\n",
|
|
||||||
err ? err : "");
|
|
||||||
errcode |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* duplicate the ckch store */
|
/* duplicate the ckch store */
|
||||||
new_ckchs = ckchs_dup(old_ckchs);
|
new_ckchs = ckchs_dup(old_ckchs);
|
||||||
if (!new_ckchs) {
|
if (!new_ckchs) {
|
||||||
|
Loading…
Reference in New Issue
Block a user