Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions hitch.conf.man.rst
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,18 @@ Default is none (match any).
pem-dir-glob = "*.pem"


pem-dir-subdir-glob = <string>
------------------------------

Match filter for subdirectories of ``pem-dir`` to load files from.

Default is none (do not match any subdirectories).

::

pem-dir-subdir-glob = "*"


prefer-server-ciphers = on|off
------------------------------

Expand Down
1 change: 1 addition & 0 deletions src/cfg_lex.l
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ char input_line[512];
"ocsp-dir" { return (TOK_OCSP_DIR); }
"pem-dir" { return (TOK_PEM_DIR); }
"pem-dir-glob" { return (TOK_PEM_DIR_GLOB); }
"pem-dir-subdir-glob" { return (TOK_PEM_DIR_SUBDIR_GLOB); }
"session-cache" { return (TOK_SESSION_CACHE); }
"shared-cache-listen" { return (TOK_SHARED_CACHE_LISTEN); }
"shared-cache-peer" { return (TOK_SHARED_CACHE_PEER); }
Expand Down
44 changes: 43 additions & 1 deletion src/cfg_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ extern char input_line[512];
%token TOK_TLSv1_3
%token TOK_SESSION_CACHE TOK_SHARED_CACHE_LISTEN TOK_SHARED_CACHE_PEER
%token TOK_SHARED_CACHE_IF TOK_PRIVATE_KEY TOK_BACKEND_REFRESH
%token TOK_OCSP_REFRESH_INTERVAL TOK_PEM_DIR TOK_PEM_DIR_GLOB
%token TOK_OCSP_REFRESH_INTERVAL TOK_PEM_DIR TOK_PEM_DIR_GLOB TOK_PEM_DIR_SUBDIR_GLOB
%token TOK_LOG_LEVEL TOK_PROXY_TLV

%parse-param { hitch_config *cfg }
Expand Down Expand Up @@ -107,6 +107,7 @@ CFG_RECORD
| OCSP_DIR
| PEM_DIR
| PEM_DIR_GLOB
| PEM_DIR_SUBDIR_GLOB
| SESSION_CACHE_REC
| SHARED_CACHE_LISTEN_REC
| SHARED_CACHE_PEER_REC
Expand Down Expand Up @@ -148,6 +149,9 @@ FB_REC
: FB_HOST
| FB_PORT
| FB_CERT
| FB_PEM_DIR
| FB_PEM_DIR_GLOB
| FB_PEM_DIR_SUBDIR_GLOB
| FB_MATCH_GLOBAL
| FB_SNI_NOMATCH_ABORT
| FB_TLS
Expand Down Expand Up @@ -227,6 +231,14 @@ PEM_DIR_GLOB: TOK_PEM_DIR_GLOB '=' STRING

};

PEM_DIR_SUBDIR_GLOB: TOK_PEM_DIR_SUBDIR_GLOB '=' STRING
{
if ($3)
cfg->PEM_DIR_SUBDIR_GLOB = strdup($3);
else
cfg->PEM_DIR_SUBDIR_GLOB = NULL;
};

OCSP_DIR: TOK_OCSP_DIR '=' STRING
{
if ($3)
Expand Down Expand Up @@ -282,6 +294,36 @@ FB_CERT: TOK_PEM_FILE '=' STRING
cur_pem = NULL;
};

FB_PEM_DIR: TOK_PEM_DIR '=' STRING
{
if ($3) {
size_t l;
l = strlen($3);
cur_fa->pem_dir = malloc(l + 2);
strcpy(cur_fa->pem_dir, $3);
if (cur_fa->pem_dir[l-1] != '/')
strcat(cur_fa->pem_dir, "/");
}
else
cur_fa->pem_dir = NULL;
};

FB_PEM_DIR_GLOB: TOK_PEM_DIR_GLOB '=' STRING
{
if ($3)
cur_fa->pem_dir_glob = strdup($3);
else
cur_fa->pem_dir_glob = NULL;
};

FB_PEM_DIR_SUBDIR_GLOB: TOK_PEM_DIR_SUBDIR_GLOB '=' STRING
{
if ($3)
cur_fa->pem_dir_subdir_glob = strdup($3);
else
cur_fa->pem_dir_subdir_glob = NULL;
};

FB_MATCH_GLOBAL: TOK_MATCH_GLOBAL '=' BOOL { cur_fa->match_global_certs = $3; };

FB_SNI_NOMATCH_ABORT:TOK_SNI_NOMATCH_ABORT '=' BOOL
Expand Down
73 changes: 64 additions & 9 deletions src/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ front_arg_new(void)

ALLOC_OBJ(fa, FRONT_ARG_MAGIC);
AN(fa);
fa->pem_dir = NULL;
fa->pem_dir_glob = NULL;
fa->pem_dir_subdir_glob = NULL;
fa->match_global_certs = -1;
fa->sni_nomatch_abort = -1;
fa->selected_protos = 0;
Expand All @@ -156,6 +159,9 @@ front_arg_destroy(struct front_arg *fa)
free(fa->ip);
free(fa->port);
free(fa->pspec);
free(fa->pem_dir);
free(fa->pem_dir_glob);
free(fa->pem_dir_subdir_glob);
free(fa->ciphers);
HASH_ITER(hh, fa->certs, cf, cftmp) {
CHECK_OBJ_NOTNULL(cf, CFG_CERT_FILE_MAGIC);
Expand Down Expand Up @@ -202,6 +208,8 @@ config_new(void)
r->CERT_FILES = NULL;
r->LISTEN_ARGS = NULL;
r->PEM_DIR = NULL;
r->PEM_DIR_GLOB = NULL;
r->PEM_DIR_SUBDIR_GLOB = NULL;
fa = front_arg_new();
fa->port = strdup("8443");
fa->pspec = strdup("default");
Expand Down Expand Up @@ -284,6 +292,7 @@ config_destroy(hitch_config *cfg)
free(cfg->ALPN_PROTOS_LV);
free(cfg->PEM_DIR);
free(cfg->PEM_DIR_GLOB);
free(cfg->PEM_DIR_SUBDIR_GLOB);
#ifdef USE_SHARED_CACHE
int i;
free(cfg->SHCUPD_IP);
Expand Down Expand Up @@ -743,6 +752,8 @@ check_frontend_uniqueness(struct front_arg *cur_fa, hitch_config *cfg)
return(1);
}

static int front_scan_pem_dir(struct front_arg *fa);

int
front_arg_add(hitch_config *cfg, struct front_arg *fa)
{
Expand Down Expand Up @@ -779,6 +790,11 @@ front_arg_add(hitch_config *cfg, struct front_arg *fa)
HASH_ADD_KEYPTR(hh, cfg->LISTEN_ARGS, fa->pspec,
strlen(fa->pspec), fa);

if (fa->pem_dir != NULL) {
if (front_scan_pem_dir(fa))
return (0);
}

if (fa->match_global_certs == -1) {
if (HASH_CNT(hh, fa->certs) == 0)
fa->match_global_certs = 1;
Expand Down Expand Up @@ -1117,11 +1133,16 @@ config_disp_log_facility (int facility)
}
}

int
config_scan_pem_dir(char *pemdir, hitch_config *cfg)
static int
scan_pem_dir(const char *pemdir, \
const char *dir_glob, \
const char *subdir_glob, \
struct cfg_cert_file **cert_files, \
struct cfg_cert_file **cert_default)
{
int n, i;
struct dirent **d;
int retval = 0;

n = scandir(pemdir, &d, NULL, alphasort);
if (n < 0) {
Expand All @@ -1133,8 +1154,21 @@ config_scan_pem_dir(char *pemdir, hitch_config *cfg)
struct cfg_cert_file *cert;
char fpath[PATH_MAX + NAME_MAX];

if (cfg->PEM_DIR_GLOB != NULL) {
if (fnmatch(cfg->PEM_DIR_GLOB, d[i]->d_name, 0))
if (d[i]->d_type == DT_DIR) {
if (subdir_glob != NULL &&
strcmp(d[i]->d_name, ".") && \
strcmp(d[i]->d_name, "..") && \
fnmatch(subdir_glob, d[i]->d_name, 0) == 0) {
snprintf(fpath, PATH_MAX + NAME_MAX, "%s/%s/", pemdir, d[i]->d_name);
retval = scan_pem_dir(fpath, dir_glob, subdir_glob, cert_files, cert_default);
if (retval != 0)
break;
}
continue;
}

if (dir_glob != NULL) {
if (fnmatch(dir_glob, d[i]->d_name, 0))
continue;
}
if (d[i]->d_type != DT_REG)
Expand All @@ -1150,20 +1184,41 @@ config_scan_pem_dir(char *pemdir, hitch_config *cfg)
if (r != 0) {
/* If no default has been set, use the first
* match according to alphasort */
if (cfg->CERT_DEFAULT == NULL)
cfg->CERT_DEFAULT = cert;
if ((cert_default != NULL) && (*cert_default == NULL))
*cert_default = cert;
else
cfg_cert_add(cert, &cfg->CERT_FILES);
cfg_cert_add(cert, cert_files);
} else {
cfg_cert_file_free(&cert);
}
free(d[i]);
}

free(d);
return (0);
return(retval);
}

static int
config_scan_pem_dir(hitch_config *cfg)
{
return scan_pem_dir(cfg->PEM_DIR, \
cfg->PEM_DIR_GLOB, \
cfg->PEM_DIR_SUBDIR_GLOB, \
&cfg->CERT_FILES, \
&cfg->CERT_DEFAULT);
}

static int
front_scan_pem_dir(struct front_arg *fa)
{
return scan_pem_dir(fa->pem_dir, \
fa->pem_dir_glob, \
fa->pem_dir_subdir_glob, \
&fa->certs, \
NULL);
}


void
config_print_usage_fd(char *prog, FILE *out)
{
Expand Down Expand Up @@ -1597,7 +1652,7 @@ CFG_ON('s', CFG_SYSLOG);
}

if (cfg->PEM_DIR != NULL) {
if (config_scan_pem_dir(cfg->PEM_DIR, cfg))
if (config_scan_pem_dir(cfg))
return (1);
}

Expand Down
4 changes: 4 additions & 0 deletions src/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ struct front_arg {
char *port;
struct cfg_cert_file *certs;
char *pspec;
char *pem_dir;
char *pem_dir_glob;
char *pem_dir_subdir_glob;
int match_global_certs;
int sni_nomatch_abort;
int prefer_server_ciphers;
Expand Down Expand Up @@ -148,6 +151,7 @@ struct __hitch_config {
int TEST;
char *PEM_DIR;
char *PEM_DIR_GLOB;
char *PEM_DIR_SUBDIR_GLOB;
int OCSP_VFY;
char *OCSP_DIR;
double OCSP_RESP_TMO;
Expand Down