diff --git a/configuration.c b/configuration.c index d5b1d23..1e8c375 100644 --- a/configuration.c +++ b/configuration.c @@ -30,6 +30,7 @@ #define CFG_CIPHERS "ciphers" #define CFG_SSL_ENGINE "ssl-engine" #define CFG_PREFER_SERVER_CIPHERS "prefer-server-ciphers" +#define CFG_PEER_CRT_VRFY_DPTH "peer-cert-verify" #define CFG_BACKEND "backend" #define CFG_FRONTEND "frontend" #define CFG_WORKERS "workers" @@ -145,6 +146,7 @@ stud_config * config_new (void) { r->TCP_KEEPALIVE_TIME = 3600; r->DAEMONIZE = 0; r->PREFER_SERVER_CIPHERS = 0; + r->PEER_CRT_VRFY_DPTH = 0; return r; } @@ -547,6 +549,9 @@ void config_param_validate (char *k, char *v, stud_config *cfg, char *file, int else if (strcmp(k, CFG_PREFER_SERVER_CIPHERS) == 0) { r = config_param_val_bool(v, &cfg->PREFER_SERVER_CIPHERS); } + else if (strcmp(k, CFG_PEER_CRT_VRFY_DPTH) == 0) { + r = config_param_val_int(v, &cfg->PEER_CRT_VRFY_DPTH); + } else if (strcmp(k, CFG_FRONTEND) == 0) { r = config_param_host_port_wildcard(v, &cfg->FRONT_IP, &cfg->FRONT_PORT, 1); } @@ -854,6 +859,8 @@ void config_print_usage_fd (char *prog, stud_config *cfg, FILE *out) { fprintf(out, " -c --ciphers=SUITE Sets allowed ciphers (Default: \"%s\")\n", config_disp_str(cfg->CIPHER_SUITE)); fprintf(out, " -e --ssl-engine=NAME Sets OpenSSL engine (Default: \"%s\")\n", config_disp_str(cfg->ENGINE)); fprintf(out, " -O --prefer-server-ciphers Prefer server list order\n"); + fprintf(out, " -p --peer-cert-verify=DEPTH\n"); + fprintf(out, " Require & verify peer certificates (Default: \"%d\")\n", cfg->PEER_CRT_VRFY_DPTH); fprintf(out, "\n"); fprintf(out, "SOCKET:\n"); fprintf(out, "\n"); @@ -962,6 +969,12 @@ void config_print_default (FILE *fd, stud_config *cfg) { fprintf(fd, FMT_STR, CFG_PREFER_SERVER_CIPHERS, config_disp_bool(cfg->PREFER_SERVER_CIPHERS)); fprintf(fd, "\n"); + fprintf(fd, "# Require peer to send a valid certificate and verify to this depth\n"); + fprintf(fd, "#\n"); + fprintf(fd, "# type: integer\n"); + fprintf(fd, FMT_ISTR, CFG_PEER_CRT_VRFY_DPTH, cfg->PEER_CRT_VRFY_DPTH); + fprintf(fd, "\n"); + fprintf(fd, "# Use specified SSL engine\n"); fprintf(fd, "#\n"); fprintf(fd, "# type: string\n"); @@ -1114,6 +1127,7 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) { { "client", 0, &client, 1}, { CFG_CIPHERS, 1, NULL, 'c' }, { CFG_PREFER_SERVER_CIPHERS, 0, NULL, 'O' }, + { CFG_PEER_CRT_VRFY_DPTH, 1, NULL, 'p' }, { CFG_BACKEND, 1, NULL, 'b' }, { CFG_FRONTEND, 1, NULL, 'f' }, { CFG_WORKERS, 1, NULL, 'n' }, @@ -1145,7 +1159,7 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) { int option_index = 0; c = getopt_long( argc, argv, - "c:e:Ob:f:n:B:C:U:P:M:k:r:u:g:qstVh", + "c:e:Op:b:f:n:B:C:U:P:M:k:r:u:g:qstVh", long_options, &option_index ); @@ -1177,6 +1191,9 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) { case 'O': config_param_validate(CFG_PREFER_SERVER_CIPHERS, CFG_BOOL_ON, cfg, NULL, 0); break; + case 'p': + config_param_validate(CFG_PEER_CRT_VRFY_DPTH, optarg, cfg, NULL, 0); + break; case 'b': config_param_validate(CFG_BACKEND, optarg, cfg, NULL, 0); break; diff --git a/configuration.h b/configuration.h index 13768ff..2198394 100644 --- a/configuration.h +++ b/configuration.h @@ -63,6 +63,7 @@ struct __stud_config { int TCP_KEEPALIVE_TIME; int DAEMONIZE; int PREFER_SERVER_CIPHERS; + int PEER_CRT_VRFY_DPTH; }; typedef struct __stud_config stud_config; diff --git a/stud.c b/stud.c index b623e83..0935a9d 100644 --- a/stud.c +++ b/stud.c @@ -583,6 +583,13 @@ SSL_CTX * init_openssl() { if (CONFIG->PREFER_SERVER_CIPHERS) SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + if (CONFIG->PEER_CRT_VRFY_DPTH) { + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | + SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, NULL); + SSL_CTX_set_verify_depth(ctx, CONFIG->PEER_CRT_VRFY_DPTH); + // TODO: Make configurable + SSL_CTX_load_verify_locations(ctx, CONFIG->CERT_FILE, NULL); + } if (CONFIG->PMODE == SSL_CLIENT) return ctx;