Skip to content
This repository has been archived by the owner on Sep 16, 2021. It is now read-only.

Commit

Permalink
Merge branch 'feature/CRL' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Ellzey committed Apr 24, 2013
2 parents 94c3b9f + 18c6cc4 commit d287232
Show file tree
Hide file tree
Showing 5 changed files with 531 additions and 20 deletions.
28 changes: 28 additions & 0 deletions README.markdown
Expand Up @@ -240,6 +240,7 @@ incoming connections as SSL.
cache-enabled = true
cache-timeout = 1024
cache-size = 65535
crl = {}
}

* __enabled__
Expand Down Expand Up @@ -292,6 +293,33 @@ incoming connections as SSL.

Timeout for (OpenSSL >= 1.0) session timeouts.

## Server::SSL::CRL Configuration

A server / vhost can be configured to use a CRL list or file which can be
reloaded without restarting or signals. This configuration is turned off by
default.

ssl {
crl {
file = "/path/to/crl.pem"
dir = "/path/to/crldir/"
reload = { 10, 0 }
}
}

* __file__

Read from a specific file for CRLs.

* __dir__

Read from a specific directory for CRLs

* __reload__

A timer (in secuds, useconds) to check for changes and reload the CRL
configuration if changes have been mae.

## Server::Vhost Configuration

## Server::Vhost::Rule Configuration
Expand Down
49 changes: 49 additions & 0 deletions src/cfg.c
Expand Up @@ -30,6 +30,13 @@
*/
static rproxy_rusage_t _rusage = { 0, 0, 0 };

static cfg_opt_t ssl_crl_opts[] = {
CFG_STR("file", NULL, CFGF_NONE),
CFG_STR("dir", NULL, CFGF_NONE),
CFG_INT_LIST("reload", "{ 10, 0 }", CFGF_NONE),
CFG_END()
};

static cfg_opt_t ssl_opts[] = {
CFG_BOOL("enabled", cfg_false, CFGF_NONE),
CFG_STR_LIST("protocols-on", "{ALL}", CFGF_NONE),
Expand All @@ -46,6 +53,7 @@ static cfg_opt_t ssl_opts[] = {
CFG_BOOL("cache-enabled", cfg_true, CFGF_NONE),
CFG_INT("cache-timeout", 1024, CFGF_NONE),
CFG_INT("cache-size", 65535, CFGF_NONE),
CFG_SEC("crl", ssl_crl_opts, CFGF_NODEFAULT),
CFG_END()
};

Expand Down Expand Up @@ -689,6 +697,47 @@ ssl_cfg_parse(cfg_t * cfg) {
scfg->ssl_ctx_timeout = cfg_getint(cfg, "context-timeout");
scfg->ssl_opts = ssl_opts;

if (cfg_getsec(cfg, "crl")) {
ssl_crl_cfg_t * crl_config;
cfg_t * crl_cfg;

crl_cfg = cfg_getsec(cfg, "crl");
assert(crl_cfg != NULL);

if (!(crl_config = calloc(sizeof(ssl_crl_cfg_t), 1))) {
fprintf(stderr, "Could not allocate crl cfg %s\n", strerror(errno));
exit(EXIT_FAILURE);
}

if (cfg_getstr(crl_cfg, "file")) {
crl_config->filename = strdup(cfg_getstr(crl_cfg, "file"));

if (stat(crl_config->filename, &file_stat) == -1 || !S_ISREG(file_stat.st_mode)) {
fprintf(stderr, "Cannot find CRL file '%s'\n", crl_config->filename);
exit(EXIT_FAILURE);
}
}

if (cfg_getstr(crl_cfg, "dir")) {
crl_config->dirname = strdup(cfg_getstr(crl_cfg, "dir"));

if (stat(crl_config->dirname, &file_stat) != 0 || !S_ISDIR(file_stat.st_mode)) {
fprintf(stderr, "Cannot find CRL directory '%s'\n", crl_config->dirname);
exit(EXIT_FAILURE);
}
}

crl_config->reload_timer.tv_sec = cfg_getnint(crl_cfg, "reload", 0);
crl_config->reload_timer.tv_usec = cfg_getnint(crl_cfg, "reload", 1);

/* at the moment evhtp does not give us an area where we can store this
* type of information without breaking the configuration structure. But
* it does have an optional user-supplied arguments, which we use here
* to store our CRL configuration.
*/
scfg->args = (void *)crl_config;
}

return scfg;
} /* ssl_cfg_parse */

Expand Down
27 changes: 27 additions & 0 deletions src/rproxy.c
Expand Up @@ -1348,10 +1348,24 @@ add_vhost(lztq_elem * elem, void * arg) {
if (vcfg->ssl_cfg != NULL) {
/* vhost specific ssl configuration found */
evhtp_ssl_init(htp_vhost, vcfg->ssl_cfg);

/* if CRL checking is enabled, create a new ssl_crl_ent_t and add it
* to the evhtp_t's arguments. XXX: in the future we should create a
* generic wrapper for various things we want to put in the evhtp
* arguments, but for now, the only thing that we care about is the
* CRL context.
*/
if (vcfg->ssl_cfg->args) {
ssl_crl_cfg_t * crl_cfg = vcfg->ssl_cfg->args;

htp->arg = (void *)ssl_crl_ent_new(htp, crl_cfg);
assert(htp->arg != NULL);
}
} else if (htp->ssl_ctx != NULL) {
/* use the global SSL context */
htp_vhost->ssl_ctx = htp->ssl_ctx;
htp_vhost->ssl_cfg = htp->ssl_cfg;
htp_vhost->arg = htp->arg;
}

return 0;
Expand Down Expand Up @@ -1395,6 +1409,19 @@ rproxy_init(evbase_t * evbase, rproxy_cfg_t * cfg) {
if (server->ssl_cfg) {
/* enable SSL support on this server */
evhtp_ssl_init(htp, server->ssl_cfg);

/* if CRL checking is enabled, create a new ssl_crl_ent_t and add it
* to the evhtp_t's arguments. XXX: in the future we should create a
* generic wrapper for various things we want to put in the evhtp
* arguments, but for now, the only thing that we care about is the
* CRL context.
*/
if (server->ssl_cfg->args) {
ssl_crl_cfg_t * crl_cfg = server->ssl_cfg->args;

htp->arg = ssl_crl_ent_new(htp, crl_cfg);
assert(htp->arg != NULL);
}
}

/* for each vhost, create a child virtual host and stick it in our main
Expand Down
56 changes: 42 additions & 14 deletions src/rproxy.h
Expand Up @@ -25,6 +25,7 @@
#include <confuse.h>
#include <event2/dns.h>
#include <evhtp.h>
#include <pthread.h>

#include "lzq.h"
#include "lzlog.h"
Expand Down Expand Up @@ -71,6 +72,7 @@ typedef struct server_cfg server_cfg_t;
typedef struct downstream_cfg downstream_cfg_t;
typedef struct headers_cfg headers_cfg_t;
typedef struct x509_ext_cfg x509_ext_cfg_t;
typedef struct ssl_crl_cfg ssl_crl_cfg_t;
typedef struct logger_cfg logger_cfg_t;

typedef enum rule_type rule_type;
Expand Down Expand Up @@ -112,6 +114,12 @@ struct x509_ext_cfg {
char * oid; /**< the oid of the x509 extension to pull */
};

struct ssl_crl_cfg {
char * filename;
char * dirname;
struct timeval reload_timer;
};

/**
* @brief which headers to add to the downstream request if avail.
*/
Expand Down Expand Up @@ -201,15 +209,15 @@ struct rproxy_rusage {
* @brief main configuration structure.
*/
struct rproxy_cfg {
bool daemonize; /**< should proxy run in background */
bool daemonize; /**< should proxy run in background */
int mem_trimsz;
int max_nofile; /**< max number of open file descriptors */
char * rootdir; /**< root dir to daemonize */
char * user; /**< user to run as */
char * group; /**< group to run as */
lztq * servers; /**< list of server_cfg_t's */
logger_cfg_t * log; /**< generic log configuration */
rproxy_rusage_t rusage; /**< the needed resource totals */
int max_nofile; /**< max number of open file descriptors */
char * rootdir; /**< root dir to daemonize */
char * user; /**< user to run as */
char * group; /**< group to run as */
lztq * servers; /**< list of server_cfg_t's */
logger_cfg_t * log; /**< generic log configuration */
rproxy_rusage_t rusage; /**< the needed resource totals */
};

/********************************************
Expand All @@ -220,10 +228,10 @@ struct rproxy_cfg {
* @brief a downstream's connection status.
*/
enum downstream_status {
downstream_status_nil = 0, /**< connection has never been used */
downstream_status_active, /**< connection is actively processing */
downstream_status_idle, /**< connection is idle and available */
downstream_status_down /**< connection is down and cannot be used */
downstream_status_nil = 0, /**< connection has never been used */
downstream_status_active, /**< connection is actively processing */
downstream_status_idle, /**< connection is idle and available */
downstream_status_down /**< connection is down and cannot be used */
};

enum logger_argtype {
Expand Down Expand Up @@ -255,6 +263,7 @@ typedef struct vhost vhost_t;
typedef struct logger_arg logger_arg_t;
typedef struct logger logger_t;
typedef struct pending_request_q pending_request_q_t;
typedef struct ssl_crl_ent ssl_crl_ent_t;

typedef enum downstream_status downstream_status;
typedef enum logger_argtype logger_argtype;
Expand All @@ -277,6 +286,22 @@ struct logger {
TAILQ_HEAD(logger_args, logger_arg) args;
};

struct ssl_crl_ent {
ssl_crl_cfg_t * cfg;
rproxy_t * rproxy;
evhtp_t * htp;
X509_STORE * crl;
event_t * reload_timer_ev;
#ifdef __APPLE__
struct timespec last_file_mod;
struct timespec last_dir_mod;
#else
time_t last_file_mod;
time_t last_dir_mod;
#endif
pthread_mutex_t lock; /**< lock to make sure we don't overwrite during a verification */
};

struct vhost {
vhost_cfg_t * config;
rproxy_t * rproxy;
Expand Down Expand Up @@ -400,8 +425,11 @@ void downstream_connection_retry(int, short, void *);
/********************************************
* SSL verification callback functions
********************************************/
int ssl_x509_verifyfn(int, X509_STORE_CTX *);
int ssl_x509_issuedcb(X509_STORE_CTX *, X509 *, X509 *);
int ssl_x509_verifyfn(int, X509_STORE_CTX *);
int ssl_x509_issuedcb(X509_STORE_CTX *, X509 *, X509 *);
ssl_crl_ent_t * ssl_crl_ent_new(evhtp_t *, ssl_crl_cfg_t *);



/***********************************************
* Request handling funcs (upstream/downstream)
Expand Down

0 comments on commit d287232

Please sign in to comment.