From: Emeric Brun Date: Tue, 2 Oct 2012 16:42:10 +0000 (+0200) Subject: MINOR: ssl: add 'crt-base' and 'ca-base' global statements. X-Git-Tag: v1.5-dev13~189 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8e8d122575af413bfaf91fcbcc2708a86c7d90f;p=thirdparty%2Fhaproxy.git MINOR: ssl: add 'crt-base' and 'ca-base' global statements. 'crt-base' sets root directory used for relative certificates paths. 'ca-base' sets root directory used for relative CAs and CRLs paths. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 3d8bbfdb65..60e2477a59 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -434,7 +434,9 @@ of them have command-line equivalents. The following keywords are supported in the "global" section : * Process management and security + - ca-base - chroot + - crt-base - daemon - gid - group @@ -481,6 +483,11 @@ The following keywords are supported in the "global" section : 3.1. Process management and security ------------------------------------ +ca-base + Assigns a default directory to fetch SSL CA certificates and CRLs from when a + relative path is used with "cafile" or "crlfile" directives. Absolute + locations specified in "cafile" and "crlfile" prevail and ignore "ca-base". + chroot Changes current directory to and performs a chroot() there before dropping privileges. This increases the security level in case an unknown @@ -489,6 +496,11 @@ chroot with superuser privileges. It is important to ensure that is both empty and unwritable to anyone. +crt-base + Assigns a default directory to fetch SSL certificates from when a relative + path is used with "crtfile" directives. Absolute locations specified after + "crtfile" prevail and ignore "crt-base". + daemon Makes the process fork into background. This is the recommended mode of operation. It is equivalent to the command line "-D" argument. It can be diff --git a/include/types/global.h b/include/types/global.h index 2d4d016793..3efe933e57 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -30,6 +30,10 @@ #include #include +#ifndef UNIX_MAX_PATH +#define UNIX_MAX_PATH 108 +#endif + /* modes of operation (global.mode) */ #define MODE_DEBUG 0x01 #define MODE_DAEMON 0x02 @@ -62,6 +66,10 @@ /* FIXME : this will have to be redefined correctly */ struct global { +#ifdef USE_OPENSSL + char *crt_base; /* base directory path for certificates */ + char *ca_base; /* base directory path for CAs and CRLs */ +#endif int uid; int gid; int nbproc; diff --git a/src/cfgparse.c b/src/cfgparse.c index 9d1a6fd14e..ed3157b30e 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -465,6 +465,44 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) /* no option, nothing special to do */ goto out; } + else if (!strcmp(args[0], "ca-base")) { +#ifdef USE_OPENSSL + if (global.ca_base != NULL) { + Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]); + err_code |= ERR_ALERT; + goto out; + } + if (*(args[1]) == 0) { + Alert("parsing [%s:%d] : '%s' expects a directory path as an argument.\n", file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + global.ca_base = strdup(args[1]); +#else + Alert("parsing [%s:%d] : '%s' is not implemented.\n", file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; +#endif + } + else if (!strcmp(args[0], "crt-base")) { +#ifdef USE_OPENSSL + if (global.crt_base != NULL) { + Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]); + err_code |= ERR_ALERT; + goto out; + } + if (*(args[1]) == 0) { + Alert("parsing [%s:%d] : '%s' expects a directory path as an argument.\n", file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + global.crt_base = strdup(args[1]); +#else + Alert("parsing [%s:%d] : '%s' is not implemented.\n", file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; +#endif + } else if (!strcmp(args[0], "daemon")) { global.mode |= MODE_DAEMON; } diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 9f61198655..df09f9ad5d 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -1107,6 +1107,13 @@ static int bind_parse_cafile(char **args, int cur_arg, struct proxy *px, struct return ERR_ALERT | ERR_FATAL; } + if ((*args[cur_arg + 1] != '/') && global.ca_base) { + conf->cafile = malloc(strlen(global.ca_base) + 1 + strlen(args[cur_arg + 1]) + 1); + if (conf->cafile) + sprintf(conf->cafile, "%s/%s", global.ca_base, args[cur_arg + 1]); + return 0; + } + conf->cafile = strdup(args[cur_arg + 1]); return 0; } @@ -1126,11 +1133,24 @@ static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct /* parse the "crt" bind keyword */ static int bind_parse_crt(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) { + char path[PATH_MAX]; if (!*args[cur_arg + 1]) { memprintf(err, "'%s' : missing certificate location", args[cur_arg]); return ERR_ALERT | ERR_FATAL; } + if ((*args[cur_arg + 1] != '/' ) && global.crt_base) { + if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > PATH_MAX) { + memprintf(err, "'%s' : path too long", args[cur_arg]); + return ERR_ALERT | ERR_FATAL; + } + sprintf(path, "%s/%s", global.crt_base, args[cur_arg + 1]); + if (ssl_sock_load_cert(path, conf, px, err) > 0) + return ERR_ALERT | ERR_FATAL; + + return 0; + } + if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0) return ERR_ALERT | ERR_FATAL; @@ -1151,6 +1171,13 @@ static int bind_parse_crlfile(char **args, int cur_arg, struct proxy *px, struct return ERR_ALERT | ERR_FATAL; } + if ((*args[cur_arg + 1] != '/') && global.ca_base) { + conf->crlfile = malloc(strlen(global.ca_base) + 1 + strlen(args[cur_arg + 1]) + 1); + if (conf->crlfile) + sprintf(conf->crlfile, "%s/%s", global.ca_base, args[cur_arg + 1]); + return 0; + } + conf->crlfile = strdup(args[cur_arg + 1]); return 0; #endif