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 3d8bbfd..60e2477 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -434,7 +434,9 @@
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 @@
3.1. Process management and security
------------------------------------
+ca-base <dir>
+ 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 <jail dir>
Changes current directory to <jail dir> and performs a chroot() there before
dropping privileges. This increases the security level in case an unknown
@@ -489,6 +496,11 @@
with superuser privileges. It is important to ensure that <jail_dir> is both
empty and unwritable to anyone.
+crt-base <dir>
+ 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 2d4d016..3efe933 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -30,6 +30,10 @@
#include <types/proxy.h>
#include <types/task.h>
+#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 9d1a6fd..ed3157b 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -465,6 +465,44 @@
/* 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 9f61198..df09f9a 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1107,6 +1107,13 @@
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 @@
/* 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 @@
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