From: William Lallemand Date: Fri, 6 Mar 2020 21:12:35 +0000 (+0100) Subject: CLEANUP: ssl: separate the directory loading in a new function X-Git-Tag: v2.2-dev5~88 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2d232c2131e97ba9e021974cb992ac2e6b03797b;p=thirdparty%2Fhaproxy.git CLEANUP: ssl: separate the directory loading in a new function In order to store and cache the directory loading, the directory loading was separated from ssl_sock_load_cert() and put in a new function ssl_sock_load_cert_dir() to be more readable. This patch only splits the function in two. --- diff --git a/src/ssl_sock.c b/src/ssl_sock.c index ef3091e3c3..1a98e2ab82 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -4427,9 +4427,9 @@ static int ssl_sock_load_ckchs(const char *path, struct ckch_store *ckchs, return errcode; } - -/* Returns a set of ERR_* flags possibly with an error in . */ -int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err) +/* Read a directory and open its certificates + * Returns a set of ERR_* flags possibly with an error in . */ +static int ssl_sock_load_cert_dir(char *path, struct bind_conf *bind_conf, char **err) { struct dirent **de_list; int i, n; @@ -4442,106 +4442,115 @@ int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err) int is_bundle; int j; #endif - if ((ckchs = ckchs_lookup(path))) { - /* we found the ckchs in the tree, we can use it directly */ - return ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, err); - } - if (stat(path, &buf) == 0) { - if (S_ISDIR(buf.st_mode) == 0) { - ckchs = ckchs_load_cert_file(path, 0, err); - if (!ckchs) - return ERR_ALERT | ERR_FATAL; - - return ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, err); - } - - /* strip trailing slashes, including first one */ - for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--) - *end = 0; + /* strip trailing slashes, including first one */ + for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--) + *end = 0; - n = scandir(path, &de_list, 0, alphasort); - if (n < 0) { - memprintf(err, "%sunable to scan directory '%s' : %s.\n", - err && *err ? *err : "", path, strerror(errno)); - cfgerr |= ERR_ALERT | ERR_FATAL; - } - else { - for (i = 0; i < n; i++) { - struct dirent *de = de_list[i]; + n = scandir(path, &de_list, 0, alphasort); + if (n < 0) { + memprintf(err, "%sunable to scan directory '%s' : %s.\n", + err && *err ? *err : "", path, strerror(errno)); + cfgerr |= ERR_ALERT | ERR_FATAL; + } + else { + for (i = 0; i < n; i++) { + struct dirent *de = de_list[i]; - end = strrchr(de->d_name, '.'); - if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl") || !strcmp(end, ".key"))) - goto ignore_entry; + end = strrchr(de->d_name, '.'); + if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl") || !strcmp(end, ".key"))) + goto ignore_entry; - snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name); - if (stat(fp, &buf) != 0) { - memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n", - err && *err ? *err : "", fp, strerror(errno)); - cfgerr |= ERR_ALERT | ERR_FATAL; - goto ignore_entry; - } - if (!S_ISREG(buf.st_mode)) - goto ignore_entry; + snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name); + if (stat(fp, &buf) != 0) { + memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n", + err && *err ? *err : "", fp, strerror(errno)); + cfgerr |= ERR_ALERT | ERR_FATAL; + goto ignore_entry; + } + if (!S_ISREG(buf.st_mode)) + goto ignore_entry; #if HA_OPENSSL_VERSION_NUMBER >= 0x1000200fL - is_bundle = 0; - /* Check if current entry in directory is part of a multi-cert bundle */ + is_bundle = 0; + /* Check if current entry in directory is part of a multi-cert bundle */ - if ((global_ssl.extra_files & SSL_GF_BUNDLE) && end) { - for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) { - if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) { - is_bundle = 1; - break; - } + if ((global_ssl.extra_files & SSL_GF_BUNDLE) && end) { + for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) { + if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) { + is_bundle = 1; + break; } + } - if (is_bundle) { - int dp_len; - - dp_len = end - de->d_name; + if (is_bundle) { + int dp_len; - /* increment i and free de until we get to a non-bundle cert - * Note here that we look at de_list[i + 1] before freeing de - * this is important since ignore_entry will free de. This also - * guarantees that de->d_name continues to hold the same prefix. - */ - while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, de->d_name, dp_len)) { - free(de); - i++; - de = de_list[i]; - } + dp_len = end - de->d_name; - snprintf(fp, sizeof(fp), "%s/%.*s", path, dp_len, de->d_name); - if ((ckchs = ckchs_lookup(fp)) == NULL) - ckchs = ckchs_load_cert_file(fp, 1, err); - if (!ckchs) - cfgerr |= ERR_ALERT | ERR_FATAL; - else - cfgerr |= ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, err); - /* Successfully processed the bundle */ - goto ignore_entry; + /* increment i and free de until we get to a non-bundle cert + * Note here that we look at de_list[i + 1] before freeing de + * this is important since ignore_entry will free de. This also + * guarantees that de->d_name continues to hold the same prefix. + */ + while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, de->d_name, dp_len)) { + free(de); + i++; + de = de_list[i]; } + + snprintf(fp, sizeof(fp), "%s/%.*s", path, dp_len, de->d_name); + if ((ckchs = ckchs_lookup(fp)) == NULL) + ckchs = ckchs_load_cert_file(fp, 1, err); + if (!ckchs) + cfgerr |= ERR_ALERT | ERR_FATAL; + else + cfgerr |= ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, err); + /* Successfully processed the bundle */ + goto ignore_entry; } + } #endif - if ((ckchs = ckchs_lookup(fp)) == NULL) - ckchs = ckchs_load_cert_file(fp, 0, err); - if (!ckchs) - cfgerr |= ERR_ALERT | ERR_FATAL; - else - cfgerr |= ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, err); + if ((ckchs = ckchs_lookup(fp)) == NULL) + ckchs = ckchs_load_cert_file(fp, 0, err); + if (!ckchs) + cfgerr |= ERR_ALERT | ERR_FATAL; + else + cfgerr |= ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, err); ignore_entry: - free(de); - } - free(de_list); + free(de); } - return cfgerr; + free(de_list); + } + return cfgerr; +} - } else { - /* stat failed */ +/* Returns a set of ERR_* flags possibly with an error in . */ +int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err) +{ + struct stat buf; + char fp[MAXPATHLEN+1]; + int cfgerr = 0; + struct ckch_store *ckchs; + + if ((ckchs = ckchs_lookup(path))) { + /* we found the ckchs in the tree, we can use it directly */ + return ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, err); + } + if (stat(path, &buf) == 0) { + if (S_ISDIR(buf.st_mode) == 0) { + ckchs = ckchs_load_cert_file(path, 0, err); + if (!ckchs) + return ERR_ALERT | ERR_FATAL; + return ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, err); + } else { + return ssl_sock_load_cert_dir(path, bind_conf, err); + } + } else { + /* stat failed, could be a bundle */ if (global_ssl.extra_files & SSL_GF_BUNDLE) { /* try to load a bundle if it is permitted */ ckchs = ckchs_load_cert_file(path, 1, err);