Skip to content

Commit

Permalink
config: prioritize cli options to config file
Browse files Browse the repository at this point in the history
Parse config file and command line arguments in two different variables
and merge them appropriately.

Future work could make the merge function behave differently depending
on environmental circumstances (e.g. openfortivpn run as a setuid
program probably would want to refuse some cli options)

Fixes adrienverge#258.
  • Loading branch information
martinetd committed Jul 19, 2018
1 parent f4f9e01 commit 194dc86
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 60 deletions.
132 changes: 132 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,35 @@
#include <ctype.h>
#include <sys/stat.h>


const struct vpn_config invalid_cfg = {
.gateway_host = {'\0'},
.gateway_port = 0,
.username = {'\0'},
.password = {'\0'},
.otp = {'\0'},
.cookie = {'\0'},
.realm = {'\0'},
.set_routes = -1,
.set_dns = -1,
.pppd_use_peerdns = -1,
.use_syslog = -1,
.half_internet_routes = -1,
.persistent = -1,
.pppd_log = NULL,
.pppd_plugin = NULL,
.pppd_ipparam = NULL,
.pppd_ifname = NULL,
.pppd_call = NULL,
.ca_file = NULL,
.user_cert = NULL,
.user_key = NULL,
.verify_cert = -1,
.insecure_ssl = -1,
.cipher_list = NULL,
.cert_whitelist = NULL
};

/*
* Adds a sha256 digest to the list of trusted certificates.
*/
Expand Down Expand Up @@ -217,14 +246,19 @@ int load_config(struct vpn_config *cfg, const char *filename)
}
cfg->pppd_use_peerdns = pppd_use_peerdns;
} else if (strcmp(key, "pppd-log") == 0) {
free(cfg->pppd_log);
cfg->pppd_log = strdup(val);
} else if (strcmp(key, "pppd-plugin") == 0) {
free(cfg->pppd_plugin);
cfg->pppd_plugin = strdup(val);
} else if (strcmp(key, "pppd-ipparam") == 0) {
free(cfg->pppd_ipparam);
cfg->pppd_ipparam = strdup(val);
} else if (strcmp(key, "pppd-ifname") == 0) {
free(cfg->pppd_ifname);
cfg->pppd_ifname = strdup(val);
} else if (strcmp(key, "pppd-call") == 0) {
free(cfg->pppd_call);
cfg->pppd_call = strdup(val);
} else if (strcmp(key, "use-syslog") == 0) {
int use_syslog = strtob(val);
Expand All @@ -244,10 +278,13 @@ int load_config(struct vpn_config *cfg, const char *filename)
log_warn("Could not add certificate digest to whitelist.\n");

} else if (strcmp(key, "ca-file") == 0) {
free(cfg->ca_file);
cfg->ca_file = strdup(val);
} else if (strcmp(key, "user-cert") == 0) {
free(cfg->user_cert);
cfg->user_cert = strdup(val);
} else if (strcmp(key, "user-key") == 0) {
free(cfg->user_key);
cfg->user_key = strdup(val);
} else if (strcmp(key, "insecure-ssl") == 0) {
int insecure_ssl = strtob(val);
Expand All @@ -258,6 +295,7 @@ int load_config(struct vpn_config *cfg, const char *filename)
}
cfg->insecure_ssl = insecure_ssl;
} else if (strcmp(key, "cipher-list") == 0) {
free(cfg->cipher_list);
cfg->cipher_list = strdup(val);
} else {
log_warn("Bad key in config file: \"%s\".\n", key);
Expand All @@ -274,3 +312,97 @@ int load_config(struct vpn_config *cfg, const char *filename)

return ret;
}

void destroy_vpn_config(struct vpn_config *cfg)
{
free(cfg->pppd_log);
free(cfg->pppd_plugin);
free(cfg->pppd_ipparam);
free(cfg->pppd_ifname);
free(cfg->pppd_call);
free(cfg->ca_file);
free(cfg->user_cert);
free(cfg->user_key);
free(cfg->cipher_list);
while (cfg->cert_whitelist != NULL) {
struct x509_digest *tmp = cfg->cert_whitelist->next;
free(cfg->cert_whitelist);
cfg->cert_whitelist = tmp;
}
}

void merge_config(struct vpn_config *dst, struct vpn_config *src)
{
if (src->gateway_host[0])
strcpy(dst->gateway_host, src->gateway_host);
if (src->gateway_port != invalid_cfg.gateway_port)
dst->gateway_port = src->gateway_port;
if (src->username[0])
strcpy(dst->username, src->username);
if (src->password[0])
strcpy(dst->password, src->password);
if (src->otp[0])
strcpy(dst->otp, src->otp);
if (src->realm[0])
strcpy(dst->realm, src->realm);
if (src->set_routes != invalid_cfg.set_routes)
dst->set_routes = src->set_routes;
if (src->set_dns != invalid_cfg.set_dns)
dst->set_dns = src->set_dns;
if (src->pppd_use_peerdns != invalid_cfg.pppd_use_peerdns)
dst->pppd_use_peerdns = src->pppd_use_peerdns;
if (src->use_syslog != invalid_cfg.use_syslog)
dst->use_syslog = src->use_syslog;
if (src->half_internet_routes != invalid_cfg.half_internet_routes)
dst->half_internet_routes = src->half_internet_routes;
if (src->persistent != invalid_cfg.persistent)
dst->persistent = src->persistent;
if (src->pppd_log) {
free(dst->pppd_log);
dst->pppd_log = src->pppd_log;
}
if (src->pppd_plugin) {
free(dst->pppd_plugin);
dst->pppd_plugin = src->pppd_plugin;
}
if (src->pppd_ipparam) {
free(dst->pppd_ipparam);
dst->pppd_ipparam = src->pppd_ipparam;
}
if (src->pppd_ifname) {
free(dst->pppd_ifname);
dst->pppd_ifname = src->pppd_ifname;
}
if (src->pppd_call) {
free(dst->pppd_call);
dst->pppd_call = src->pppd_call;
}
if (src->ca_file) {
free(dst->ca_file);
dst->ca_file = src->ca_file;
}
if (src->user_cert) {
free(dst->user_cert);
dst->user_cert = src->user_cert;
}
if (src->user_key) {
free(dst->user_key);
dst->user_key = src->user_key;
}
if (src->verify_cert != invalid_cfg.verify_cert)
dst->verify_cert = src->verify_cert;
if (src->insecure_ssl != invalid_cfg.insecure_ssl)
dst->insecure_ssl = src->insecure_ssl;
if (src->cipher_list) {
free(dst->cipher_list);
dst->cipher_list = src->cipher_list;
}
if (src->cert_whitelist) {
while (dst->cert_whitelist != NULL) {
struct x509_digest *tmp = dst->cert_whitelist->next;
free(dst->cert_whitelist);
dst->cert_whitelist = tmp;
}
dst->cert_whitelist = src->cert_whitelist;
}
}
10 changes: 10 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,15 @@ int add_trusted_cert(struct vpn_config *cfg, const char *digest);
int strtob(const char *str);

int load_config(struct vpn_config *cfg, const char *filename);
void destroy_vpn_config(struct vpn_config *cfg);

/** merge source config into dest
*
* memory allocated dynamically is transferred with this function
* e.g. ownership goes to dest config
*/
void merge_config(struct vpn_config *dest, struct vpn_config *source);

extern const struct vpn_config invalid_cfg;

#endif
Loading

0 comments on commit 194dc86

Please sign in to comment.