MINOR: ssl: directories are loaded like crt-list
Generate a directory cache with the crtlist and crtlist_entry structures. With this new model, directories are a special case of the crt-lists. A directory is a crt-list which allows only one occurence of each file, without SSL configuration (ssl_bind_conf) and without filters.
This commit is contained in:
parent
2954c478eb
commit
6be66ec7a9
|
@ -4429,10 +4429,15 @@ static int ssl_sock_load_ckchs(const char *path, struct ckch_store *ckchs,
|
||||||
return errcode;
|
return errcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a directory and open its certificates
|
|
||||||
* Returns a set of ERR_* flags possibly with an error in <err>. */
|
/* This function reads a directory and stores it in a struct crtlist, each file is a crtlist_entry structure
|
||||||
static int ssl_sock_load_cert_dir(char *path, struct bind_conf *bind_conf, char **err)
|
* Fill the <crtlist> argument with a pointer to a new crtlist struct
|
||||||
|
*
|
||||||
|
* This function tries to open and store certificate files.
|
||||||
|
*/
|
||||||
|
static int crtlist_load_cert_dir(char *path, struct bind_conf *bind_conf, struct crtlist **crtlist, char **err)
|
||||||
{
|
{
|
||||||
|
struct crtlist *dir;
|
||||||
struct dirent **de_list;
|
struct dirent **de_list;
|
||||||
int i, n;
|
int i, n;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
@ -4449,6 +4454,14 @@ static int ssl_sock_load_cert_dir(char *path, struct bind_conf *bind_conf, char
|
||||||
for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
|
for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
|
||||||
*end = 0;
|
*end = 0;
|
||||||
|
|
||||||
|
dir = malloc(sizeof(*dir) + strlen(path) + 1);
|
||||||
|
if (dir == NULL) {
|
||||||
|
memprintf(err, "not enough memory");
|
||||||
|
return ERR_ALERT | ERR_FATAL;
|
||||||
|
}
|
||||||
|
memcpy(dir->node.key, path, strlen(path) + 1);
|
||||||
|
dir->entries = EB_ROOT_UNIQUE; /* it's a directory, files are unique */
|
||||||
|
|
||||||
n = scandir(path, &de_list, 0, alphasort);
|
n = scandir(path, &de_list, 0, alphasort);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
memprintf(err, "%sunable to scan directory '%s' : %s.\n",
|
memprintf(err, "%sunable to scan directory '%s' : %s.\n",
|
||||||
|
@ -4457,13 +4470,20 @@ static int ssl_sock_load_cert_dir(char *path, struct bind_conf *bind_conf, char
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
struct crtlist_entry *entry;
|
||||||
struct dirent *de = de_list[i];
|
struct dirent *de = de_list[i];
|
||||||
struct ckch_inst *ckch_inst = NULL;
|
|
||||||
|
|
||||||
end = strrchr(de->d_name, '.');
|
end = strrchr(de->d_name, '.');
|
||||||
if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl") || !strcmp(end, ".key")))
|
if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl") || !strcmp(end, ".key")))
|
||||||
goto ignore_entry;
|
goto ignore_entry;
|
||||||
|
|
||||||
|
entry = malloc(sizeof(*entry));
|
||||||
|
if (entry == NULL) {
|
||||||
|
memprintf(err, "not enough memory '%s'", fp);
|
||||||
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto ignore_entry;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
|
snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
|
||||||
if (stat(fp, &buf) != 0) {
|
if (stat(fp, &buf) != 0) {
|
||||||
memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
|
memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
|
||||||
|
@ -4503,31 +4523,64 @@ static int ssl_sock_load_cert_dir(char *path, struct bind_conf *bind_conf, char
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(fp, sizeof(fp), "%s/%.*s", path, dp_len, de->d_name);
|
snprintf(fp, sizeof(fp), "%s/%.*s", path, dp_len, de->d_name);
|
||||||
if ((ckchs = ckchs_lookup(fp)) == NULL)
|
ckchs = ckchs_lookup(fp);
|
||||||
ckchs = ckchs_load_cert_file(fp, 1, err);
|
if (ckchs == NULL)
|
||||||
if (!ckchs)
|
ckchs = ckchs_load_cert_file(fp, 1, err);
|
||||||
|
if (ckchs == NULL) {
|
||||||
|
free(de);
|
||||||
|
free(entry);
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
else
|
goto end;
|
||||||
cfgerr |= ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, &ckch_inst, err);
|
}
|
||||||
|
|
||||||
|
entry->node.key = ckchs;
|
||||||
|
entry->ssl_conf = NULL; /* directories don't use ssl_conf */
|
||||||
|
ebpt_insert(&dir->entries, &entry->node);
|
||||||
|
|
||||||
/* Successfully processed the bundle */
|
/* Successfully processed the bundle */
|
||||||
goto ignore_entry;
|
goto ignore_entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
if ((ckchs = ckchs_lookup(fp)) == NULL)
|
ckchs = ckchs_lookup(fp);
|
||||||
ckchs = ckchs_load_cert_file(fp, 0, err);
|
if (ckchs == NULL)
|
||||||
if (!ckchs)
|
ckchs = ckchs_load_cert_file(fp, 0, err);
|
||||||
|
if (ckchs == NULL) {
|
||||||
|
free(de);
|
||||||
|
free(entry);
|
||||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||||
else
|
goto end;
|
||||||
cfgerr |= ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, &ckch_inst, err);
|
}
|
||||||
|
entry->node.key = ckchs;
|
||||||
|
entry->ssl_conf = NULL; /* directories don't use ssl_conf */
|
||||||
|
ebpt_insert(&dir->entries, &entry->node);
|
||||||
|
|
||||||
ignore_entry:
|
ignore_entry:
|
||||||
free(de);
|
free(de);
|
||||||
}
|
}
|
||||||
|
end:
|
||||||
free(de_list);
|
free(de_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cfgerr & ERR_CODE) {
|
||||||
|
/* free the dir and entries on error */
|
||||||
|
struct ebpt_node *node;
|
||||||
|
|
||||||
|
node = ebpt_first(&dir->entries);
|
||||||
|
while (node) {
|
||||||
|
struct crtlist_entry *entry;
|
||||||
|
|
||||||
|
entry = ebpt_entry(node, typeof(*entry), node);
|
||||||
|
node = ebpt_next(node);
|
||||||
|
ebpt_delete(&entry->node);
|
||||||
|
free(entry);
|
||||||
|
}
|
||||||
|
free(dir);
|
||||||
|
}
|
||||||
|
|
||||||
return cfgerr;
|
return cfgerr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4835,7 +4888,7 @@ static int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct pr
|
||||||
*
|
*
|
||||||
* Returns a set of ERR_* flags possibly with an error in <err>.
|
* Returns a set of ERR_* flags possibly with an error in <err>.
|
||||||
*/
|
*/
|
||||||
int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
|
int ssl_sock_load_cert_list_file(char *file, int dir, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
|
||||||
{
|
{
|
||||||
struct crtlist *crtlist = NULL;
|
struct crtlist *crtlist = NULL;
|
||||||
struct ebmb_node *eb;
|
struct ebmb_node *eb;
|
||||||
|
@ -4849,7 +4902,12 @@ int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct
|
||||||
if (eb) {
|
if (eb) {
|
||||||
crtlist = ebmb_entry(eb, struct crtlist, node);
|
crtlist = ebmb_entry(eb, struct crtlist, node);
|
||||||
} else {
|
} else {
|
||||||
cfgerr |= crtlist_parse_file(file, bind_conf, curproxy, &crtlist, err);
|
/* load a crt-list OR a directory */
|
||||||
|
if (dir)
|
||||||
|
cfgerr |= crtlist_load_cert_dir(file, bind_conf, &crtlist, err);
|
||||||
|
else
|
||||||
|
cfgerr |= crtlist_parse_file(file, bind_conf, curproxy, &crtlist, err);
|
||||||
|
|
||||||
if (!(cfgerr & ERR_CODE))
|
if (!(cfgerr & ERR_CODE))
|
||||||
ebst_insert(&crtlists_tree, &crtlist->node);
|
ebst_insert(&crtlists_tree, &crtlist->node);
|
||||||
}
|
}
|
||||||
|
@ -4917,7 +4975,7 @@ int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
|
||||||
|
|
||||||
return ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, &ckch_inst, err);
|
return ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, &ckch_inst, err);
|
||||||
} else {
|
} else {
|
||||||
return ssl_sock_load_cert_dir(path, bind_conf, err);
|
return ssl_sock_load_cert_list_file(path, 1, bind_conf, bind_conf->frontend, err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* stat failed, could be a bundle */
|
/* stat failed, could be a bundle */
|
||||||
|
@ -9021,7 +9079,7 @@ static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struc
|
||||||
return ERR_ALERT | ERR_FATAL;
|
return ERR_ALERT | ERR_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err_code = ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err);
|
err_code = ssl_sock_load_cert_list_file(args[cur_arg + 1], 0, conf, px, err);
|
||||||
if (err_code)
|
if (err_code)
|
||||||
memprintf(err, "'%s' : %s", args[cur_arg], *err);
|
memprintf(err, "'%s' : %s", args[cur_arg], *err);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue