mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
separated permanent configuration options from the reloaded ones
This commit is contained in:
20
src/cfg.h
20
src/cfg.h
@@ -46,22 +46,12 @@ typedef struct pam_cfg_st {
|
||||
int gid_min;
|
||||
} pam_cfg_st;
|
||||
|
||||
unsigned expand_brackets_string(struct cfg_st *config, const char *str, subcfg_val_st out[MAX_SUBOPTIONS]);
|
||||
inline static void free_expanded_brackets_string(subcfg_val_st out[MAX_SUBOPTIONS], unsigned size)
|
||||
{
|
||||
unsigned i;
|
||||
for (i=0;i<size;i++) {
|
||||
talloc_free(out[i].name);
|
||||
talloc_free(out[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECK_TRUE(str) (str != NULL && (c_strcasecmp(str, "true") == 0 || c_strcasecmp(str, "yes") == 0))?1:0
|
||||
|
||||
void *get_brackets_string1(struct cfg_st *config, const char *str);
|
||||
void *gssapi_get_brackets_string(struct cfg_st *config, const char *str);
|
||||
void *radius_get_brackets_string(struct cfg_st *config, const char *str);
|
||||
void *pam_get_brackets_string(struct cfg_st *config, const char *str);
|
||||
void *plain_get_brackets_string(struct cfg_st *config, const char *str);
|
||||
void *get_brackets_string1(struct perm_cfg_st *config, const char *str);
|
||||
void *gssapi_get_brackets_string(struct perm_cfg_st *config, const char *str);
|
||||
void *radius_get_brackets_string(struct perm_cfg_st *config, const char *str);
|
||||
void *pam_get_brackets_string(struct perm_cfg_st *config, const char *str);
|
||||
void *plain_get_brackets_string(struct perm_cfg_st *config, const char *str);
|
||||
|
||||
#endif
|
||||
|
||||
354
src/config.c
354
src/config.c
@@ -240,15 +240,18 @@ unsigned j;
|
||||
exit(1); \
|
||||
}}
|
||||
|
||||
#define READ_STRING(name, s_name) { \
|
||||
#define PREAD_STRING(pool, name, s_name) { \
|
||||
val = get_option(name, &mand); \
|
||||
if (val != NULL && val->valType == OPARG_TYPE_STRING) \
|
||||
s_name = talloc_strdup(config, val->v.strVal); \
|
||||
s_name = talloc_strdup(pool, val->v.strVal); \
|
||||
else if (mand != 0) { \
|
||||
fprintf(stderr, "Configuration option %s is mandatory.\n", name); \
|
||||
exit(1); \
|
||||
}}
|
||||
|
||||
#define READ_STRING(name, s_name) \
|
||||
PREAD_STRING(config, name, s_name)
|
||||
|
||||
#define READ_STATIC_STRING(name, s_name) { \
|
||||
val = get_option(name, &mand); \
|
||||
if (val != NULL && val->valType == OPARG_TYPE_STRING) \
|
||||
@@ -353,7 +356,7 @@ typedef struct auth_types_st {
|
||||
unsigned name_size;
|
||||
const struct auth_mod_st *mod;
|
||||
unsigned type;
|
||||
void *(*get_brackets_string)(struct cfg_st *config, const char *);
|
||||
void *(*get_brackets_string)(struct perm_cfg_st *config, const char *);
|
||||
} auth_types_st;
|
||||
|
||||
#define NAME(x) (x),(sizeof(x)-1)
|
||||
@@ -372,7 +375,7 @@ static auth_types_st avail_auth_types[] =
|
||||
{NAME("certificate"), NULL, AUTH_TYPE_CERTIFICATE, NULL},
|
||||
};
|
||||
|
||||
static void figure_auth_funcs(struct cfg_st *config, char **auth, unsigned auth_size,
|
||||
static void figure_auth_funcs(struct perm_cfg_st *config, char **auth, unsigned auth_size,
|
||||
unsigned primary)
|
||||
{
|
||||
unsigned j, i;
|
||||
@@ -386,7 +389,7 @@ static void figure_auth_funcs(struct cfg_st *config, char **auth, unsigned auth_
|
||||
if (c_strncasecmp(auth[j], avail_auth_types[i].name, avail_auth_types[i].name_size) == 0) {
|
||||
if (avail_auth_types[i].get_brackets_string)
|
||||
config->auth[0].additional = avail_auth_types[i].get_brackets_string(config, auth[j]+avail_auth_types[i].name_size);
|
||||
|
||||
|
||||
if (config->auth[0].amod != NULL && avail_auth_types[i].mod != NULL) {
|
||||
fprintf(stderr, "%s: You cannot mix multiple authentication methods of this type\n", auth[j]);
|
||||
exit(1);
|
||||
@@ -459,7 +462,7 @@ typedef struct acct_types_st {
|
||||
const char *name;
|
||||
unsigned name_size;
|
||||
const struct acct_mod_st *mod;
|
||||
void *(*get_brackets_string)(struct cfg_st *config, const char *);
|
||||
void *(*get_brackets_string)(struct perm_cfg_st *config, const char *);
|
||||
} acct_types_st;
|
||||
|
||||
static acct_types_st avail_acct_types[] =
|
||||
@@ -472,7 +475,7 @@ static acct_types_st avail_acct_types[] =
|
||||
#endif
|
||||
};
|
||||
|
||||
static void figure_acct_funcs(struct cfg_st *config, const char *acct)
|
||||
static void figure_acct_funcs(struct perm_cfg_st *config, const char *acct)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned found = 0;
|
||||
@@ -604,7 +607,7 @@ static void parse_kkdcp(struct cfg_st *config, char **urlfw, unsigned urlfw_size
|
||||
}
|
||||
#endif
|
||||
|
||||
static void parse_cfg_file(const char* file, struct cfg_st *config, unsigned reload)
|
||||
static void parse_cfg_file(void *pool, const char* file, struct perm_cfg_st *perm_config, unsigned reload)
|
||||
{
|
||||
tOptionValue const * pov;
|
||||
const tOptionValue* val, *prev;
|
||||
@@ -615,6 +618,7 @@ unsigned prefix = 0, auto_select_group = 0;
|
||||
unsigned prefix4 = 0;
|
||||
char *tmp;
|
||||
unsigned force_cert_auth;
|
||||
struct cfg_st *config = perm_config->config;
|
||||
#ifdef HAVE_GSSAPI
|
||||
char **urlfw = NULL;
|
||||
unsigned urlfw_size = 0;
|
||||
@@ -644,36 +648,61 @@ unsigned urlfw_size = 0;
|
||||
prev = val;
|
||||
} while((val = optionNextValue(pov, prev)) != NULL);
|
||||
|
||||
config->sup_config_type = SUP_CONFIG_FILE;
|
||||
if (reload == 0) {
|
||||
perm_config->sup_config_type = SUP_CONFIG_FILE;
|
||||
|
||||
READ_MULTI_LINE("auth", auth, auth_size);
|
||||
figure_auth_funcs(config, auth, auth_size, 1);
|
||||
auth = NULL;
|
||||
auth_size = 0;
|
||||
READ_MULTI_LINE("auth", auth, auth_size);
|
||||
figure_auth_funcs(perm_config, auth, auth_size, 1);
|
||||
auth = NULL;
|
||||
auth_size = 0;
|
||||
|
||||
READ_MULTI_LINE("enable-auth", auth, auth_size);
|
||||
figure_auth_funcs(config, auth, auth_size, 0);
|
||||
auth = NULL;
|
||||
auth_size = 0;
|
||||
READ_MULTI_LINE("enable-auth", auth, auth_size);
|
||||
figure_auth_funcs(perm_config, auth, auth_size, 0);
|
||||
auth = NULL;
|
||||
auth_size = 0;
|
||||
|
||||
if (config->auth[0].enabled == 0) {
|
||||
fprintf(stderr, "No authentication method was specified!\n");
|
||||
exit(1);
|
||||
}
|
||||
if (perm_config->auth[0].enabled == 0) {
|
||||
fprintf(stderr, "No authentication method was specified!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tmp = NULL;
|
||||
READ_STRING("acct", tmp);
|
||||
if (tmp != NULL) {
|
||||
figure_acct_funcs(config, tmp);
|
||||
talloc_free(tmp);
|
||||
tmp = NULL;
|
||||
READ_STRING("acct", tmp);
|
||||
if (tmp != NULL) {
|
||||
figure_acct_funcs(perm_config, tmp);
|
||||
talloc_free(tmp);
|
||||
}
|
||||
|
||||
PREAD_STRING(pool, "listen-host", perm_config->listen_host);
|
||||
PREAD_STRING(pool, "listen-clear-file", perm_config->unix_conn_file);
|
||||
READ_NUMERIC("tcp-port", perm_config->port);
|
||||
READ_NUMERIC("udp-port", perm_config->udp_port);
|
||||
|
||||
val = get_option("run-as-user", NULL);
|
||||
if (val != NULL && val->valType == OPARG_TYPE_STRING) {
|
||||
const struct passwd* pwd = getpwnam(val->v.strVal);
|
||||
if (pwd == NULL) {
|
||||
fprintf(stderr, "Unknown user: %s\n", val->v.strVal);
|
||||
exit(1);
|
||||
}
|
||||
perm_config->uid = pwd->pw_uid;
|
||||
}
|
||||
|
||||
val = get_option("run-as-group", NULL);
|
||||
if (val != NULL && val->valType == OPARG_TYPE_STRING) {
|
||||
const struct group *grp = getgrnam(val->v.strVal);
|
||||
if (grp == NULL) {
|
||||
fprintf(stderr, "Unknown group: %s\n", val->v.strVal);
|
||||
exit(1);
|
||||
}
|
||||
perm_config->gid = grp->gr_gid;
|
||||
}
|
||||
}
|
||||
|
||||
/* When adding allocated data, remember to modify
|
||||
* reload_cfg_file();
|
||||
*/
|
||||
READ_STRING("listen-host", config->listen_host);
|
||||
READ_TF("listen-host-is-dyndns", config->is_dyndns, 0);
|
||||
READ_STRING("listen-clear-file", config->unix_conn_file);
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
READ_MULTI_LINE("kkdcp", urlfw, urlfw_size);
|
||||
@@ -683,8 +712,6 @@ unsigned urlfw_size = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
READ_NUMERIC("tcp-port", config->port);
|
||||
READ_NUMERIC("udp-port", config->udp_port);
|
||||
READ_NUMERIC("keepalive", config->keepalive);
|
||||
READ_NUMERIC("dpd", config->dpd);
|
||||
if (config->dpd == 0)
|
||||
@@ -841,26 +868,6 @@ unsigned urlfw_size = 0;
|
||||
|
||||
READ_NUMERIC("max-same-clients", config->max_same_clients);
|
||||
|
||||
val = get_option("run-as-user", NULL);
|
||||
if (val != NULL && val->valType == OPARG_TYPE_STRING) {
|
||||
const struct passwd* pwd = getpwnam(val->v.strVal);
|
||||
if (pwd == NULL) {
|
||||
fprintf(stderr, "Unknown user: %s\n", val->v.strVal);
|
||||
exit(1);
|
||||
}
|
||||
config->uid = pwd->pw_uid;
|
||||
}
|
||||
|
||||
val = get_option("run-as-group", NULL);
|
||||
if (val != NULL && val->valType == OPARG_TYPE_STRING) {
|
||||
const struct group *grp = getgrnam(val->v.strVal);
|
||||
if (grp == NULL) {
|
||||
fprintf(stderr, "Unknown group: %s\n", val->v.strVal);
|
||||
exit(1);
|
||||
}
|
||||
config->gid = grp->gr_gid;
|
||||
}
|
||||
|
||||
READ_STATIC_STRING("device", config->network.name);
|
||||
READ_STRING("cgroup", config->cgroup);
|
||||
READ_STRING("proxy-url", config->proxy_url);
|
||||
@@ -910,8 +917,8 @@ unsigned urlfw_size = 0;
|
||||
READ_STRING("default-select-group", config->default_select_group);
|
||||
READ_TF("auto-select-group", auto_select_group, 0);
|
||||
|
||||
if (auto_select_group != 0 && config->auth[0].amod != NULL && config->auth[0].amod->group_list != NULL) {
|
||||
config->auth[0].amod->group_list(config, config->auth[0].additional, &config->group_list, &config->group_list_size);
|
||||
if (auto_select_group != 0 && perm_config->auth[0].amod != NULL && perm_config->auth[0].amod->group_list != NULL) {
|
||||
perm_config->auth[0].amod->group_list(config, perm_config->auth[0].additional, &config->group_list, &config->group_list_size);
|
||||
} else {
|
||||
READ_MULTI_BRACKET_LINE("select-group",
|
||||
config->group_list,
|
||||
@@ -953,109 +960,114 @@ unsigned urlfw_size = 0;
|
||||
|
||||
|
||||
/* sanity checks on config */
|
||||
static void check_cfg(struct cfg_st *config)
|
||||
static void check_cfg(struct perm_cfg_st *perm_config)
|
||||
{
|
||||
if (config->network.ipv4 == NULL && config->network.ipv6 == NULL) {
|
||||
if (perm_config->config->network.ipv4 == NULL && perm_config->config->network.ipv6 == NULL) {
|
||||
fprintf(stderr, "No ipv4-network or ipv6-network options set.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (config->network.ipv4 != NULL && config->network.ipv4_netmask == NULL) {
|
||||
if (perm_config->config->network.ipv4 != NULL && perm_config->config->network.ipv4_netmask == NULL) {
|
||||
fprintf(stderr, "No mask found for IPv4 network.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (config->network.ipv6 != NULL && config->network.ipv6_prefix == 0) {
|
||||
if (perm_config->config->network.ipv6 != NULL && perm_config->config->network.ipv6_prefix == 0) {
|
||||
fprintf(stderr, "No prefix found for IPv6 network.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (config->banner && strlen(config->banner) > MAX_BANNER_SIZE) {
|
||||
if (perm_config->config->banner && strlen(perm_config->config->banner) > MAX_BANNER_SIZE) {
|
||||
fprintf(stderr, "Banner size is too long\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (config->cert_size != config->key_size) {
|
||||
if (perm_config->config->cert_size != perm_config->config->key_size) {
|
||||
fprintf(stderr, "The specified number of keys doesn't match the certificates\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (config->auth[0].type & AUTH_TYPE_CERTIFICATE) {
|
||||
if (config->cisco_client_compat == 0)
|
||||
config->cert_req = GNUTLS_CERT_REQUIRE;
|
||||
if (perm_config->auth[0].type & AUTH_TYPE_CERTIFICATE) {
|
||||
if (perm_config->config->cisco_client_compat == 0)
|
||||
perm_config->config->cert_req = GNUTLS_CERT_REQUIRE;
|
||||
else
|
||||
config->cert_req = GNUTLS_CERT_REQUEST;
|
||||
perm_config->config->cert_req = GNUTLS_CERT_REQUEST;
|
||||
} else {
|
||||
unsigned i;
|
||||
for (i=1;i<config->auth_methods;i++) {
|
||||
if (config->auth[i].type & AUTH_TYPE_CERTIFICATE) {
|
||||
config->cert_req = GNUTLS_CERT_REQUEST;
|
||||
for (i=1;i<perm_config->auth_methods;i++) {
|
||||
if (perm_config->auth[i].type & AUTH_TYPE_CERTIFICATE) {
|
||||
perm_config->config->cert_req = GNUTLS_CERT_REQUEST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config->cert_req != 0 && config->cert_user_oid == NULL) {
|
||||
if (perm_config->config->cert_req != 0 && perm_config->config->cert_user_oid == NULL) {
|
||||
fprintf(stderr, "A certificate is requested by the option 'cert-user-oid' is not set\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (config->unix_conn_file != NULL && (config->cert_req != 0)) {
|
||||
if (perm_config->unix_conn_file != NULL && (perm_config->config->cert_req != 0)) {
|
||||
fprintf(stderr, "The option 'listen-clear-file' cannot be combined with 'auth=certificate'\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef ANYCONNECT_CLIENT_COMPAT
|
||||
if (config->cert) {
|
||||
config->cert_hash = calc_sha1_hash(config, config->cert[0], 1);
|
||||
if (perm_config->config->cert) {
|
||||
perm_config->config->cert_hash = calc_sha1_hash(perm_config->config, perm_config->config->cert[0], 1);
|
||||
}
|
||||
|
||||
if (config->xml_config_file) {
|
||||
config->xml_config_hash = calc_sha1_hash(config, config->xml_config_file, 0);
|
||||
if (config->xml_config_hash == NULL && config->chroot_dir != NULL) {
|
||||
if (perm_config->config->xml_config_file) {
|
||||
perm_config->config->xml_config_hash = calc_sha1_hash(perm_config->config, perm_config->config->xml_config_file, 0);
|
||||
if (perm_config->config->xml_config_hash == NULL && perm_config->config->chroot_dir != NULL) {
|
||||
char path[_POSIX_PATH_MAX];
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s", config->chroot_dir, config->xml_config_file);
|
||||
config->xml_config_hash = calc_sha1_hash(config, path, 0);
|
||||
snprintf(path, sizeof(path), "%s/%s", perm_config->config->chroot_dir, perm_config->config->xml_config_file);
|
||||
perm_config->config->xml_config_hash = calc_sha1_hash(perm_config->config, path, 0);
|
||||
|
||||
if (config->xml_config_hash == NULL) {
|
||||
if (perm_config->config->xml_config_hash == NULL) {
|
||||
fprintf(stderr, "Cannot open file '%s'\n", path);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (config->xml_config_hash == NULL) {
|
||||
fprintf(stderr, "Cannot open file '%s'\n", config->xml_config_file);
|
||||
if (perm_config->config->xml_config_hash == NULL) {
|
||||
fprintf(stderr, "Cannot open file '%s'\n", perm_config->config->xml_config_file);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (config->keepalive == 0)
|
||||
config->keepalive = 3600;
|
||||
if (perm_config->config->keepalive == 0)
|
||||
perm_config->config->keepalive = 3600;
|
||||
|
||||
if (config->dpd == 0)
|
||||
config->keepalive = 60;
|
||||
if (perm_config->config->dpd == 0)
|
||||
perm_config->config->keepalive = 60;
|
||||
|
||||
if (config->priorities == NULL)
|
||||
config->priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT";
|
||||
if (perm_config->config->priorities == NULL)
|
||||
perm_config->config->priorities = talloc_strdup(perm_config->config, "NORMAL:%SERVER_PRECEDENCE:%COMPAT");
|
||||
}
|
||||
|
||||
int cmd_parser (void *pool, int argc, char **argv, struct cfg_st** config)
|
||||
int cmd_parser (void *pool, int argc, char **argv, struct perm_cfg_st** config)
|
||||
{
|
||||
*config = talloc_zero(pool, struct perm_cfg_st);
|
||||
if (*config == NULL)
|
||||
exit(1);
|
||||
|
||||
*config = talloc_zero(pool, struct cfg_st);
|
||||
(*config)->config = talloc_zero(*config, struct cfg_st);
|
||||
if ((*config)->config == NULL)
|
||||
exit(1);
|
||||
|
||||
optionProcess( &ocservOptions, argc, argv);
|
||||
|
||||
if (HAVE_OPT(FOREGROUND))
|
||||
(*config)->foreground = 1;
|
||||
(*config)->config->foreground = 1;
|
||||
|
||||
if (HAVE_OPT(PID_FILE)) {
|
||||
strlcpy(pid_file, OPT_ARG(PID_FILE), sizeof(pid_file));
|
||||
}
|
||||
|
||||
if (HAVE_OPT(DEBUG))
|
||||
(*config)->debug = OPT_VALUE_DEBUG;
|
||||
(*config)->config->debug = OPT_VALUE_DEBUG;
|
||||
|
||||
if (HAVE_OPT(CONFIG)) {
|
||||
cfg_file = OPT_ARG(CONFIG);
|
||||
@@ -1064,7 +1076,7 @@ int cmd_parser (void *pool, int argc, char **argv, struct cfg_st** config)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parse_cfg_file(cfg_file, *config, 0);
|
||||
parse_cfg_file(pool, cfg_file, *config, 0);
|
||||
|
||||
check_cfg(*config);
|
||||
|
||||
@@ -1073,87 +1085,82 @@ int cmd_parser (void *pool, int argc, char **argv, struct cfg_st** config)
|
||||
}
|
||||
|
||||
#define DEL(x) {talloc_free(x);x=NULL;}
|
||||
void clear_cfg_file(struct cfg_st* config)
|
||||
void clear_cfg_file(struct perm_cfg_st* perm_config)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
#ifdef ANYCONNECT_CLIENT_COMPAT
|
||||
DEL(config->xml_config_file);
|
||||
DEL(config->xml_config_hash);
|
||||
DEL(config->cert_hash);
|
||||
DEL(perm_config->config->xml_config_file);
|
||||
DEL(perm_config->config->xml_config_hash);
|
||||
DEL(perm_config->config->cert_hash);
|
||||
#endif
|
||||
DEL(config->cgroup);
|
||||
DEL(config->route_add_cmd);
|
||||
DEL(config->route_del_cmd);
|
||||
DEL(config->per_user_dir);
|
||||
DEL(config->per_group_dir);
|
||||
DEL(config->socket_file_prefix);
|
||||
DEL(config->default_domain);
|
||||
DEL(perm_config->config->cgroup);
|
||||
DEL(perm_config->config->route_add_cmd);
|
||||
DEL(perm_config->config->route_del_cmd);
|
||||
DEL(perm_config->config->per_user_dir);
|
||||
DEL(perm_config->config->per_group_dir);
|
||||
DEL(perm_config->config->socket_file_prefix);
|
||||
DEL(perm_config->config->default_domain);
|
||||
|
||||
DEL(config->ocsp_response);
|
||||
DEL(config->banner);
|
||||
DEL(config->dh_params_file);
|
||||
DEL(config->listen_host);
|
||||
DEL(config->pin_file);
|
||||
DEL(config->srk_pin_file);
|
||||
DEL(config->ca);
|
||||
DEL(config->crl);
|
||||
DEL(config->cert_user_oid);
|
||||
DEL(config->cert_group_oid);
|
||||
DEL(config->priorities);
|
||||
DEL(config->chroot_dir);
|
||||
DEL(config->connect_script);
|
||||
DEL(config->disconnect_script);
|
||||
DEL(config->proxy_url);
|
||||
DEL(perm_config->config->ocsp_response);
|
||||
DEL(perm_config->config->banner);
|
||||
DEL(perm_config->config->dh_params_file);
|
||||
DEL(perm_config->config->pin_file);
|
||||
DEL(perm_config->config->srk_pin_file);
|
||||
DEL(perm_config->config->ca);
|
||||
DEL(perm_config->config->crl);
|
||||
DEL(perm_config->config->cert_user_oid);
|
||||
DEL(perm_config->config->cert_group_oid);
|
||||
DEL(perm_config->config->priorities);
|
||||
DEL(perm_config->config->chroot_dir);
|
||||
DEL(perm_config->config->connect_script);
|
||||
DEL(perm_config->config->disconnect_script);
|
||||
DEL(perm_config->config->proxy_url);
|
||||
|
||||
for (i=0;i<config->auth_methods;i++) {
|
||||
if (config->auth[i].enabled)
|
||||
talloc_free(config->auth[i].name);
|
||||
}
|
||||
#ifdef HAVE_GSSAPI
|
||||
for (i=0;i<config->kkdcp_size;i++) {
|
||||
for (i=0;i<perm_config->config->kkdcp_size;i++) {
|
||||
unsigned j;
|
||||
DEL(config->kkdcp[i].url);
|
||||
for (j=0;j<config->kkdcp[i].realms_size;j++) {
|
||||
DEL(config->kkdcp[i].realms[j].realm);
|
||||
DEL(perm_config->config->kkdcp[i].url);
|
||||
for (j=0;j<perm_config->config->kkdcp[i].realms_size;j++) {
|
||||
DEL(perm_config->config->kkdcp[i].realms[j].realm);
|
||||
}
|
||||
}
|
||||
DEL(config->kkdcp);
|
||||
DEL(perm_config->config->kkdcp);
|
||||
#endif
|
||||
|
||||
DEL(config->network.ipv4);
|
||||
DEL(config->network.ipv4_netmask);
|
||||
DEL(config->network.ipv6);
|
||||
for (i=0;i<config->network.routes_size;i++)
|
||||
DEL(config->network.routes[i]);
|
||||
DEL(config->network.routes);
|
||||
for (i=0;i<config->network.dns_size;i++)
|
||||
DEL(config->network.dns[i]);
|
||||
DEL(config->network.dns);
|
||||
for (i=0;i<config->network.nbns_size;i++)
|
||||
DEL(config->network.nbns[i]);
|
||||
DEL(config->network.nbns);
|
||||
for (i=0;i<config->key_size;i++)
|
||||
DEL(config->key[i]);
|
||||
DEL(config->key);
|
||||
for (i=0;i<config->cert_size;i++)
|
||||
DEL(config->cert[i]);
|
||||
DEL(config->cert);
|
||||
for (i=0;i<config->custom_header_size;i++)
|
||||
DEL(config->custom_header[i]);
|
||||
DEL(config->custom_header);
|
||||
for (i=0;i<config->split_dns_size;i++)
|
||||
DEL(config->split_dns[i]);
|
||||
DEL(config->split_dns);
|
||||
for (i=0;i<config->group_list_size;i++)
|
||||
DEL(config->group_list[i]);
|
||||
DEL(config->group_list);
|
||||
DEL(config->default_select_group);
|
||||
DEL(perm_config->config->network.ipv4);
|
||||
DEL(perm_config->config->network.ipv4_netmask);
|
||||
DEL(perm_config->config->network.ipv6);
|
||||
for (i=0;i<perm_config->config->network.routes_size;i++)
|
||||
DEL(perm_config->config->network.routes[i]);
|
||||
DEL(perm_config->config->network.routes);
|
||||
for (i=0;i<perm_config->config->network.dns_size;i++)
|
||||
DEL(perm_config->config->network.dns[i]);
|
||||
DEL(perm_config->config->network.dns);
|
||||
for (i=0;i<perm_config->config->network.nbns_size;i++)
|
||||
DEL(perm_config->config->network.nbns[i]);
|
||||
DEL(perm_config->config->network.nbns);
|
||||
for (i=0;i<perm_config->config->key_size;i++)
|
||||
DEL(perm_config->config->key[i]);
|
||||
DEL(perm_config->config->key);
|
||||
for (i=0;i<perm_config->config->cert_size;i++)
|
||||
DEL(perm_config->config->cert[i]);
|
||||
DEL(perm_config->config->cert);
|
||||
for (i=0;i<perm_config->config->custom_header_size;i++)
|
||||
DEL(perm_config->config->custom_header[i]);
|
||||
DEL(perm_config->config->custom_header);
|
||||
for (i=0;i<perm_config->config->split_dns_size;i++)
|
||||
DEL(perm_config->config->split_dns[i]);
|
||||
DEL(perm_config->config->split_dns);
|
||||
for (i=0;i<perm_config->config->group_list_size;i++)
|
||||
DEL(perm_config->config->group_list[i]);
|
||||
DEL(perm_config->config->group_list);
|
||||
DEL(perm_config->config->default_select_group);
|
||||
#ifdef HAVE_LIBTALLOC
|
||||
/* our included talloc don't include that */
|
||||
talloc_free_children(config);
|
||||
talloc_free_children(perm_config->config);
|
||||
#endif
|
||||
memset(config, 0, sizeof(*config));
|
||||
memset(perm_config->config, 0, sizeof(*perm_config->config));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1201,48 +1208,15 @@ void print_version(tOptions *opts, tOptDesc *desc)
|
||||
}
|
||||
|
||||
|
||||
void reload_cfg_file(void *pool, struct cfg_st* config)
|
||||
void reload_cfg_file(void *pool, struct perm_cfg_st* perm_config)
|
||||
{
|
||||
auth_struct_st auth_bak[MAX_AUTH_METHODS];
|
||||
acct_struct_st acct_bak;
|
||||
unsigned auth_bak_size, i;
|
||||
clear_cfg_file(perm_config);
|
||||
|
||||
/* authentication and accounting methods can't change on reload */
|
||||
memcpy(auth_bak, config->auth, sizeof(config->auth));
|
||||
memcpy(&acct_bak, &config->acct, sizeof(config->acct));
|
||||
auth_bak_size = config->auth_methods;
|
||||
parse_cfg_file(pool, cfg_file, perm_config, 1);
|
||||
|
||||
clear_cfg_file(config);
|
||||
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
parse_cfg_file(cfg_file, config, 1);
|
||||
|
||||
/* check if the authentication methods remained the same */
|
||||
if (config->acct.amod != acct_bak.amod) {
|
||||
goto auth_fail;
|
||||
}
|
||||
|
||||
if (config->auth_methods != auth_bak_size) {
|
||||
goto auth_fail;
|
||||
}
|
||||
|
||||
for (i=0;i<config->auth_methods;i++) {
|
||||
if (config->auth[i].enabled != auth_bak[i].enabled) {
|
||||
goto auth_fail;
|
||||
}
|
||||
|
||||
if (config->auth[i].type != auth_bak[i].type) {
|
||||
goto auth_fail;
|
||||
}
|
||||
}
|
||||
|
||||
check_cfg(config);
|
||||
check_cfg(perm_config);
|
||||
|
||||
return;
|
||||
auth_fail:
|
||||
syslog(LOG_ERR, "you cannot switch authentication or accounting methods on reload");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void write_pid_file(void)
|
||||
|
||||
@@ -159,9 +159,9 @@ int send_cookie_auth_reply(main_server_st* s, struct proc_st* proc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apply_default_sup_config(struct cfg_st *config, struct proc_st *proc)
|
||||
static void apply_default_sup_config(struct perm_cfg_st *config, struct proc_st *proc)
|
||||
{
|
||||
proc->config.deny_roaming = config->deny_roaming;
|
||||
proc->config.deny_roaming = config->config->deny_roaming;
|
||||
proc->config.no_udp = (config->udp_port!=0)?0:1;
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ struct proc_st *old_proc;
|
||||
/* cookie is good so far, now read config (in order to know
|
||||
* whether roaming is allowed or not */
|
||||
memset(&proc->config, 0, sizeof(proc->config));
|
||||
apply_default_sup_config(s->config, proc);
|
||||
apply_default_sup_config(s->perm_config, proc);
|
||||
|
||||
/* loads sup config */
|
||||
ret = session_open(s, proc, req->cookie.data, req->cookie.len);
|
||||
|
||||
@@ -136,7 +136,7 @@ int ctl_handler_init(main_server_st * s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = chown(s->config->occtl_socket_file, s->config->uid, s->config->gid);
|
||||
ret = chown(s->config->occtl_socket_file, s->perm_config->uid, s->perm_config->gid);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "could not chown socket '%s': %s",
|
||||
|
||||
@@ -632,7 +632,7 @@ int run_sec_mod(main_server_st * s)
|
||||
#endif
|
||||
setproctitle(PACKAGE_NAME "-secmod");
|
||||
close(fd[1]);
|
||||
sec_mod_server(s->main_pool, s->config, p, s->cookie_key, fd[0]);
|
||||
sec_mod_server(s->main_pool, s->perm_config, p, s->cookie_key, fd[0]);
|
||||
exit(0);
|
||||
} else if (pid > 0) { /* parent */
|
||||
close(fd[0]);
|
||||
|
||||
@@ -83,7 +83,7 @@ int handle_sec_mod_commands(main_server_st * s)
|
||||
|
||||
if (ret == 0) {
|
||||
mslog(s, NULL, LOG_DEBUG, "command socket closed");
|
||||
return ERR_WORKER_TERMINATED;
|
||||
return ERR_BAD_COMMAND;
|
||||
}
|
||||
|
||||
if (ret < 3) {
|
||||
|
||||
62
src/main.c
62
src/main.c
@@ -95,10 +95,10 @@ static void add_listener(void *pool, struct listen_list_st *list,
|
||||
list->total++;
|
||||
}
|
||||
|
||||
static void set_udp_socket_options(struct cfg_st* config, int fd, int family)
|
||||
static void set_udp_socket_options(struct perm_cfg_st* config, int fd, int family)
|
||||
{
|
||||
int y;
|
||||
if (config->try_mtu) {
|
||||
if (config->config->try_mtu) {
|
||||
#if defined(IP_DONTFRAG)
|
||||
y = 1;
|
||||
if (setsockopt(fd, SOL_IP, IP_DONTFRAG,
|
||||
@@ -139,7 +139,7 @@ static void set_common_socket_options(int fd)
|
||||
}
|
||||
|
||||
static
|
||||
int _listen_ports(void *pool, struct cfg_st* config,
|
||||
int _listen_ports(void *pool, struct perm_cfg_st* config,
|
||||
struct addrinfo *res, struct listen_list_st *list)
|
||||
{
|
||||
struct addrinfo *ptr;
|
||||
@@ -158,7 +158,7 @@ int _listen_ports(void *pool, struct cfg_st* config,
|
||||
else
|
||||
continue;
|
||||
|
||||
if (config->foreground != 0)
|
||||
if (config->config->foreground != 0)
|
||||
fprintf(stderr, "listening (%s) on %s...\n",
|
||||
type, human_addr(ptr->ai_addr, ptr->ai_addrlen,
|
||||
buf, sizeof(buf)));
|
||||
@@ -218,7 +218,7 @@ int _listen_ports(void *pool, struct cfg_st* config,
|
||||
}
|
||||
|
||||
static
|
||||
int _listen_unix_ports(void *pool, struct cfg_st* config,
|
||||
int _listen_unix_ports(void *pool, struct perm_cfg_st* config,
|
||||
struct listen_list_st *list)
|
||||
{
|
||||
int s, e, ret;
|
||||
@@ -231,7 +231,7 @@ int _listen_unix_ports(void *pool, struct cfg_st* config,
|
||||
strlcpy(sa.sun_path, config->unix_conn_file, sizeof(sa.sun_path));
|
||||
remove(sa.sun_path);
|
||||
|
||||
if (config->foreground != 0)
|
||||
if (config->config->foreground != 0)
|
||||
fprintf(stderr, "listening (UNIX) on %s...\n",
|
||||
sa.sun_path);
|
||||
|
||||
@@ -276,7 +276,7 @@ int _listen_unix_ports(void *pool, struct cfg_st* config,
|
||||
/* Returns 0 on success or negative value on error.
|
||||
*/
|
||||
static int
|
||||
listen_ports(void *pool, struct cfg_st* config,
|
||||
listen_ports(void *pool, struct perm_cfg_st* config,
|
||||
struct listen_list_st *list)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
@@ -352,7 +352,7 @@ listen_ports(void *pool, struct cfg_st* config,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (config->foreground != 0)
|
||||
if (config->config->foreground != 0)
|
||||
fprintf(stderr, "listening on %d systemd sockets...\n", list->total);
|
||||
|
||||
return 0;
|
||||
@@ -536,30 +536,30 @@ static void drop_privileges(main_server_st* s)
|
||||
}
|
||||
}
|
||||
|
||||
if (s->config->gid != -1 && (getgid() == 0 || getegid() == 0)) {
|
||||
ret = setgid(s->config->gid);
|
||||
if (s->perm_config->gid != -1 && (getgid() == 0 || getegid() == 0)) {
|
||||
ret = setgid(s->perm_config->gid);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "cannot set gid to %d: %s\n",
|
||||
(int) s->config->gid, strerror(e));
|
||||
(int) s->perm_config->gid, strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = setgroups(1, &s->config->gid);
|
||||
ret = setgroups(1, &s->perm_config->gid);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "cannot set groups to %d: %s\n",
|
||||
(int) s->config->gid, strerror(e));
|
||||
(int) s->perm_config->gid, strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->config->uid != -1 && (getuid() == 0 || geteuid() == 0)) {
|
||||
ret = setuid(s->config->uid);
|
||||
if (s->perm_config->uid != -1 && (getuid() == 0 || geteuid() == 0)) {
|
||||
ret = setuid(s->perm_config->uid);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "cannot set uid to %d: %s\n",
|
||||
(int) s->config->uid, strerror(e));
|
||||
(int) s->perm_config->uid, strerror(e));
|
||||
exit(1);
|
||||
|
||||
}
|
||||
@@ -691,7 +691,7 @@ int sfd = -1;
|
||||
ret = oc_recvfrom_at(listener->fd, buffer, sizeof(buffer), 0,
|
||||
(struct sockaddr*)&cli_addr, &cli_addr_size,
|
||||
(struct sockaddr*)&our_addr, &our_addr_size,
|
||||
s->config->udp_port);
|
||||
s->perm_config->udp_port);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_INFO, "error receiving in UDP socket");
|
||||
return -1;
|
||||
@@ -733,7 +733,7 @@ int sfd = -1;
|
||||
match_ip_only = 1;
|
||||
|
||||
/* don't bother IP matching when the listen-clear-file is in use */
|
||||
if (s->config->unix_conn_file)
|
||||
if (s->perm_config->unix_conn_file)
|
||||
goto fail;
|
||||
} else {
|
||||
/* read session_id */
|
||||
@@ -827,7 +827,7 @@ unsigned total = 10;
|
||||
|
||||
if (reload_conf != 0) {
|
||||
mslog(s, NULL, LOG_INFO, "reloading configuration");
|
||||
reload_cfg_file(s->main_pool, s->config);
|
||||
reload_cfg_file(s->main_pool, s->perm_config);
|
||||
tls_reload_crl(s, s->creds);
|
||||
reload_conf = 0;
|
||||
kill(s->sec_mod_pid, SIGHUP);
|
||||
@@ -858,8 +858,8 @@ unsigned total = 10;
|
||||
*/
|
||||
clear_lists(s);
|
||||
tls_global_deinit(s->creds);
|
||||
clear_cfg_file(s->config);
|
||||
talloc_free(s->config);
|
||||
clear_cfg_file(s->perm_config);
|
||||
talloc_free(s->perm_config);
|
||||
talloc_free(s->main_pool);
|
||||
closelog();
|
||||
exit(0);
|
||||
@@ -972,11 +972,12 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
/* load configuration */
|
||||
ret = cmd_parser(main_pool, argc, argv, &s->config);
|
||||
ret = cmd_parser(main_pool, argc, argv, &s->perm_config);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error in arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
s->config = s->perm_config->config;
|
||||
|
||||
setproctitle(PACKAGE_NAME"-main");
|
||||
|
||||
@@ -986,7 +987,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
/* Listen to network ports */
|
||||
ret = listen_ports(s, s->config, &s->listen_list);
|
||||
ret = listen_ports(s, s->perm_config, &s->listen_list);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot listen to specified ports\n");
|
||||
exit(1);
|
||||
@@ -1107,7 +1108,7 @@ int main(int argc, char** argv)
|
||||
#ifdef HAVE_PSELECT
|
||||
ts.tv_nsec = 0;
|
||||
ts.tv_sec = 30;
|
||||
ret = pselect(n + 1, &rd_set, &wr_set, NULL, &ts, &emptyset);
|
||||
ret = pselect(n + 1, &rd_set, NULL/*&wr_set*/, NULL, &ts, &emptyset);
|
||||
#else
|
||||
ts.tv_usec = 0;
|
||||
ts.tv_sec = 30;
|
||||
@@ -1115,6 +1116,7 @@ int main(int argc, char** argv)
|
||||
ret = select(n + 1, &rd_set, &wr_set, NULL, &ts);
|
||||
sigprocmask(SIG_BLOCK, &blockset, NULL);
|
||||
#endif
|
||||
|
||||
if (ret == -1 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
@@ -1136,7 +1138,7 @@ int main(int argc, char** argv)
|
||||
fd = accept(ltmp->fd, (void*)&ws->remote_addr, &ws->remote_addr_len);
|
||||
if (fd < 0) {
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"Error in accept(): %s", strerror(errno));
|
||||
"error in accept(): %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
set_cloexec_flag (fd, 1);
|
||||
@@ -1147,7 +1149,7 @@ int main(int argc, char** argv)
|
||||
|
||||
if (s->config->max_clients > 0 && s->active_clients >= s->config->max_clients) {
|
||||
close(fd);
|
||||
mslog(s, NULL, LOG_INFO, "Reached maximum client limit (active: %u)", s->active_clients);
|
||||
mslog(s, NULL, LOG_INFO, "reached maximum client limit (active: %u)", s->active_clients);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1191,6 +1193,7 @@ int main(int argc, char** argv)
|
||||
|
||||
ws->main_pool = main_pool;
|
||||
ws->config = s->config;
|
||||
ws->perm_config = s->perm_config;
|
||||
ws->cmd_fd = cmd_fd[1];
|
||||
ws->tun_fd = -1;
|
||||
ws->dtls_tptr.fd = -1;
|
||||
@@ -1254,7 +1257,12 @@ fork_failed:
|
||||
}
|
||||
|
||||
if (FD_ISSET(s->sec_mod_fd, &rd_set)) {
|
||||
handle_sec_mod_commands(s);
|
||||
ret = handle_sec_mod_commands(s);
|
||||
if (ret < 0) { /* bad commands from sec-mod are unacceptable */
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"error command from sec-mod");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for pending control commands */
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
#define COOKIE_KEY_SIZE 16
|
||||
|
||||
extern sigset_t sig_default_set;
|
||||
int cmd_parser (void *pool, int argc, char **argv, struct cfg_st** config);
|
||||
void reload_cfg_file(void *pool, struct cfg_st* config);
|
||||
void clear_cfg_file(struct cfg_st* config);
|
||||
int cmd_parser (void *pool, int argc, char **argv, struct perm_cfg_st** config);
|
||||
void reload_cfg_file(void *pool, struct perm_cfg_st* config);
|
||||
void clear_cfg_file(struct perm_cfg_st* config);
|
||||
void write_pid_file(void);
|
||||
void remove_pid_file(void);
|
||||
|
||||
@@ -163,7 +163,8 @@ struct proc_hash_db_st {
|
||||
};
|
||||
|
||||
typedef struct main_server_st {
|
||||
struct cfg_st *config;
|
||||
struct cfg_st *config; /* pointer inside perm_config */
|
||||
struct perm_cfg_st *perm_config;
|
||||
|
||||
struct ip_lease_db_st ip_leases;
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
#define SESSION_STR "(session: %.5s)"
|
||||
|
||||
void sec_auth_init(sec_mod_st * sec, struct cfg_st *config)
|
||||
void sec_auth_init(sec_mod_st * sec, struct perm_cfg_st *config)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
@@ -448,8 +448,8 @@ int handle_sec_auth_session_open(int cfd, sec_mod_st *sec, const SecAuthSessionM
|
||||
return send_failed_session_open_reply(cfd, sec);
|
||||
}
|
||||
|
||||
if (sec->config->acct.amod != NULL && sec->config->acct.amod->open_session != NULL && e->session_is_open == 0) {
|
||||
ret = sec->config->acct.amod->open_session(e->module->type, e->auth_ctx, &e->auth_info, req->sid.data, req->sid.len);
|
||||
if (sec->perm_config->acct.amod != NULL && sec->perm_config->acct.amod->open_session != NULL && e->session_is_open == 0) {
|
||||
ret = sec->perm_config->acct.amod->open_session(e->module->type, e->auth_ctx, &e->auth_info, req->sid.data, req->sid.len);
|
||||
if (ret < 0) {
|
||||
e->status = PS_AUTH_FAILED;
|
||||
seclog(sec, LOG_INFO, "denied session for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid);
|
||||
@@ -587,7 +587,7 @@ int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req)
|
||||
if (req->uptime > e->stats.uptime)
|
||||
e->stats.uptime = req->uptime;
|
||||
|
||||
if (sec->config->acct.amod == NULL || sec->config->acct.amod->session_stats == NULL)
|
||||
if (sec->perm_config->acct.amod == NULL || sec->perm_config->acct.amod->session_stats == NULL)
|
||||
return 0;
|
||||
|
||||
stats_add_to(&totals, &e->stats, &e->saved_stats);
|
||||
@@ -598,7 +598,7 @@ int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req)
|
||||
if (req->ipv6)
|
||||
strlcpy(e->auth_info.ipv6, req->ipv6, sizeof(e->auth_info.ipv6));
|
||||
|
||||
sec->config->acct.amod->session_stats(e->module->type, e->auth_ctx, &e->auth_info, &totals);
|
||||
sec->perm_config->acct.amod->session_stats(e->module->type, e->auth_ctx, &e->auth_info, &totals);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -667,12 +667,12 @@ int set_module(sec_mod_st * sec, client_entry_st *e, unsigned auth_type)
|
||||
|
||||
/* Find the first configured authentication method which contains
|
||||
* the method asked by the worker, and use that. */
|
||||
for (i=0;i<sec->config->auth_methods;i++) {
|
||||
if (sec->config->auth[i].enabled && (sec->config->auth[i].type & auth_type) == auth_type) {
|
||||
e->module = sec->config->auth[i].amod;
|
||||
e->auth_type = sec->config->auth[i].type;
|
||||
for (i=0;i<sec->perm_config->auth_methods;i++) {
|
||||
if (sec->perm_config->auth[i].enabled && (sec->perm_config->auth[i].type & auth_type) == auth_type) {
|
||||
e->module = sec->perm_config->auth[i].amod;
|
||||
e->auth_type = sec->perm_config->auth[i].type;
|
||||
|
||||
seclog(sec, LOG_INFO, "using '%s' authentication to authenticate user "SESSION_STR, sec->config->auth[i].name, e->auth_info.psid);
|
||||
seclog(sec, LOG_INFO, "using '%s' authentication to authenticate user "SESSION_STR, sec->perm_config->auth[i].name, e->auth_info.psid);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -776,8 +776,8 @@ void sec_auth_user_deinit(sec_mod_st * sec, client_entry_st * e)
|
||||
|
||||
seclog(sec, LOG_DEBUG, "permamently closing session of user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid);
|
||||
if (e->auth_ctx != NULL) {
|
||||
if (sec->config->acct.amod != NULL && sec->config->acct.amod->close_session != NULL && e->session_is_open != 0) {
|
||||
sec->config->acct.amod->close_session(e->module->type, e->auth_ctx, &e->auth_info, &e->saved_stats);
|
||||
if (sec->perm_config->acct.amod != NULL && sec->perm_config->acct.amod->close_session != NULL && e->session_is_open != 0) {
|
||||
sec->perm_config->acct.amod->close_session(e->module->type, e->auth_ctx, &e->auth_info, &e->saved_stats);
|
||||
}
|
||||
e->module->auth_deinit(e->auth_ctx);
|
||||
e->auth_ctx = NULL;
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
|
||||
void sup_config_init(sec_mod_st *sec)
|
||||
{
|
||||
if (sec->config->sup_config_type == SUP_CONFIG_FILE) {
|
||||
if (sec->perm_config->sup_config_type == SUP_CONFIG_FILE) {
|
||||
sec->config_module = &file_sup_config;
|
||||
#ifdef HAVE_RADIUS
|
||||
} else if (sec->config->sup_config_type == SUP_CONFIG_RADIUS) {
|
||||
} else if (sec->perm_config->sup_config_type == SUP_CONFIG_RADIUS) {
|
||||
sec->config_module = &radius_sup_config;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
* proc->username/proc->groupname and save it in proc->config.
|
||||
*/
|
||||
struct config_mod_st {
|
||||
int (*get_sup_config)(struct cfg_st *global_config, client_entry_st *entry,
|
||||
int (*get_sup_config)(struct cfg_st *perm_config, client_entry_st *entry,
|
||||
SecAuthSessionReplyMsg *msg, void *pool);
|
||||
};
|
||||
|
||||
|
||||
@@ -374,7 +374,7 @@ static void check_other_work(sec_mod_st *sec)
|
||||
|
||||
if (need_reload) {
|
||||
seclog(sec, LOG_DEBUG, "reloading configuration");
|
||||
reload_cfg_file(sec, sec->config);
|
||||
reload_cfg_file(sec, sec->perm_config);
|
||||
need_reload = 0;
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ int serve_request(sec_mod_st *sec, int cfd, unsigned is_main, uint8_t *buffer, u
|
||||
* clients fast without becoming a bottleneck due to private
|
||||
* key operations.
|
||||
*/
|
||||
void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_file,
|
||||
void sec_mod_server(void *main_pool, struct perm_cfg_st *perm_config, const char *socket_file,
|
||||
uint8_t cookie_key[COOKIE_KEY_SIZE], int cmd_fd)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
@@ -509,7 +509,8 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
|
||||
memcpy(sec->cookie_key, cookie_key, COOKIE_KEY_SIZE);
|
||||
sec->dcookie_key.data = sec->cookie_key;
|
||||
sec->dcookie_key.size = COOKIE_KEY_SIZE;
|
||||
sec->config = talloc_steal(sec, config);
|
||||
sec->perm_config = talloc_steal(sec, perm_config);
|
||||
sec->config = sec->perm_config->config;
|
||||
|
||||
sup_config_init(sec);
|
||||
|
||||
@@ -528,8 +529,7 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
|
||||
ocsignal(SIGTERM, handle_sigterm);
|
||||
ocsignal(SIGALRM, handle_alarm);
|
||||
|
||||
|
||||
sec_auth_init(sec, config);
|
||||
sec_auth_init(sec, perm_config);
|
||||
sec->cmd_fd = cmd_fd;
|
||||
|
||||
#ifdef HAVE_PKCS11
|
||||
@@ -562,7 +562,7 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = chown(SOCKET_FILE, config->uid, config->gid);
|
||||
ret = chown(SOCKET_FILE, perm_config->uid, perm_config->gid);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
seclog(sec, LOG_INFO, "could not chown socket '%s': %s", SOCKET_FILE,
|
||||
@@ -577,15 +577,15 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = load_pins(config, &pins);
|
||||
ret = load_pins(sec->config, &pins);
|
||||
if (ret < 0) {
|
||||
seclog(sec, LOG_ERR, "error loading PIN files");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* FIXME: the private key isn't reloaded on reload */
|
||||
sec->key_size = config->key_size;
|
||||
sec->key = talloc_size(sec, sizeof(*sec->key) * config->key_size);
|
||||
sec->key_size = sec->config->key_size;
|
||||
sec->key = talloc_size(sec, sizeof(*sec->key) * sec->config->key_size);
|
||||
if (sec->key == NULL) {
|
||||
seclog(sec, LOG_ERR, "error in memory allocation");
|
||||
exit(1);
|
||||
@@ -597,19 +597,19 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
|
||||
/* load the private key */
|
||||
if (gnutls_url_is_supported(config->key[i]) != 0) {
|
||||
if (gnutls_url_is_supported(sec->config->key[i]) != 0) {
|
||||
gnutls_privkey_set_pin_function(sec->key[i],
|
||||
pin_callback, &pins);
|
||||
ret =
|
||||
gnutls_privkey_import_url(sec->key[i],
|
||||
config->key[i], 0);
|
||||
sec->config->key[i], 0);
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
} else {
|
||||
gnutls_datum_t data;
|
||||
ret = gnutls_load_file(config->key[i], &data);
|
||||
ret = gnutls_load_file(sec->config->key[i], &data);
|
||||
if (ret < 0) {
|
||||
seclog(sec, LOG_ERR, "error loading file '%s'",
|
||||
config->key[i]);
|
||||
sec->config->key[i]);
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
}
|
||||
|
||||
@@ -686,7 +686,7 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
|
||||
|
||||
/* do not allow unauthorized processes to issue commands
|
||||
*/
|
||||
ret = check_upeer_id("sec-mod", config->debug, cfd, config->uid, config->gid, &uid);
|
||||
ret = check_upeer_id("sec-mod", sec->config->debug, cfd, perm_config->uid, perm_config->gid, &uid);
|
||||
if (ret < 0) {
|
||||
seclog(sec, LOG_INFO, "rejected unauthorized connection");
|
||||
} else {
|
||||
|
||||
@@ -31,6 +31,7 @@ typedef struct sec_mod_st {
|
||||
uint8_t cookie_key[COOKIE_KEY_SIZE];
|
||||
|
||||
struct cfg_st *config;
|
||||
struct perm_cfg_st *perm_config;
|
||||
gnutls_privkey_t *key;
|
||||
unsigned key_size;
|
||||
struct htable *client_db;
|
||||
@@ -116,7 +117,7 @@ void cleanup_client_entries(sec_mod_st *sec);
|
||||
void seclog_hex(const struct sec_mod_st* sec, int priority,
|
||||
const char *prefix, uint8_t* bin, unsigned bin_size, unsigned b64);
|
||||
|
||||
void sec_auth_init(sec_mod_st *sec, struct cfg_st *config);
|
||||
void sec_auth_init(sec_mod_st *sec, struct perm_cfg_st *config);
|
||||
|
||||
int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg * req);
|
||||
int handle_sec_auth_cont(int cfd, sec_mod_st *sec, const SecAuthContMsg * req);
|
||||
@@ -124,7 +125,7 @@ int handle_sec_auth_session_cmd(int cfd, sec_mod_st *sec, const SecAuthSessionMs
|
||||
int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req);
|
||||
void sec_auth_user_deinit(sec_mod_st * sec, client_entry_st * e);
|
||||
|
||||
void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_file,
|
||||
void sec_mod_server(void *main_pool, struct perm_cfg_st *config, const char *socket_file,
|
||||
uint8_t cookie_key[COOKIE_KEY_SIZE], int cmd_fd);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,9 +30,19 @@
|
||||
#include <vpn.h>
|
||||
#include "cfg.h"
|
||||
|
||||
static void free_expanded_brackets_string(subcfg_val_st out[MAX_SUBOPTIONS], unsigned size)
|
||||
{
|
||||
unsigned i;
|
||||
for (i=0;i<size;i++) {
|
||||
talloc_free(out[i].name);
|
||||
talloc_free(out[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the number of suboptions processed.
|
||||
*/
|
||||
unsigned expand_brackets_string(struct cfg_st *config, const char *str, subcfg_val_st out[MAX_SUBOPTIONS])
|
||||
static
|
||||
unsigned expand_brackets_string(void *pool, const char *str, subcfg_val_st out[MAX_SUBOPTIONS])
|
||||
{
|
||||
char *p, *p2, *p3;
|
||||
unsigned len, len2;
|
||||
@@ -79,8 +89,8 @@ unsigned expand_brackets_string(struct cfg_st *config, const char *str, subcfg_v
|
||||
while (c_isspace(p2[len2-1]))
|
||||
len2--;
|
||||
|
||||
out[pos].name = talloc_strndup(config, p, len);
|
||||
out[pos].value = talloc_strndup(config, p2, len2);
|
||||
out[pos].name = talloc_strndup(pool, p, len);
|
||||
out[pos].value = talloc_strndup(pool, p2, len2);
|
||||
pos++;
|
||||
|
||||
} while(finish == 0 && pos < MAX_SUBOPTIONS);
|
||||
@@ -89,7 +99,7 @@ unsigned expand_brackets_string(struct cfg_st *config, const char *str, subcfg_v
|
||||
}
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
void *gssapi_get_brackets_string(struct cfg_st *config, const char *str)
|
||||
void *gssapi_get_brackets_string(struct perm_cfg_st *config, const char *str)
|
||||
{
|
||||
subcfg_val_st vals[MAX_SUBOPTIONS];
|
||||
unsigned vals_size, i;
|
||||
@@ -117,7 +127,7 @@ void *gssapi_get_brackets_string(struct cfg_st *config, const char *str)
|
||||
}
|
||||
#endif
|
||||
|
||||
void *get_brackets_string1(struct cfg_st *config, const char *str)
|
||||
void *get_brackets_string1(struct perm_cfg_st *config, const char *str)
|
||||
{
|
||||
char *p, *p2;
|
||||
unsigned len;
|
||||
@@ -145,7 +155,7 @@ void *get_brackets_string1(struct cfg_st *config, const char *str)
|
||||
}
|
||||
|
||||
#ifdef HAVE_RADIUS
|
||||
static void *get_brackets_string2(struct cfg_st *config, const char *str)
|
||||
static void *get_brackets_string2(struct perm_cfg_st *config, const char *str)
|
||||
{
|
||||
char *p, *p2;
|
||||
unsigned len;
|
||||
@@ -179,7 +189,7 @@ static void *get_brackets_string2(struct cfg_st *config, const char *str)
|
||||
return talloc_strndup(config, p, len);
|
||||
}
|
||||
|
||||
void *radius_get_brackets_string(struct cfg_st *config, const char *str)
|
||||
void *radius_get_brackets_string(struct perm_cfg_st *config, const char *str)
|
||||
{
|
||||
char *p;
|
||||
subcfg_val_st vals[MAX_SUBOPTIONS];
|
||||
@@ -235,7 +245,7 @@ void *radius_get_brackets_string(struct cfg_st *config, const char *str)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PAM
|
||||
void *pam_get_brackets_string(struct cfg_st *config, const char *str)
|
||||
void *pam_get_brackets_string(struct perm_cfg_st *config, const char *str)
|
||||
{
|
||||
subcfg_val_st vals[MAX_SUBOPTIONS];
|
||||
unsigned vals_size, i;
|
||||
@@ -266,7 +276,7 @@ void *pam_get_brackets_string(struct cfg_st *config, const char *str)
|
||||
}
|
||||
#endif
|
||||
|
||||
void *plain_get_brackets_string(struct cfg_st *config, const char *str)
|
||||
void *plain_get_brackets_string(struct perm_cfg_st *config, const char *str)
|
||||
{
|
||||
subcfg_val_st vals[MAX_SUBOPTIONS];
|
||||
unsigned vals_size, i;
|
||||
|
||||
@@ -430,8 +430,8 @@ int open_tun(main_server_st * s, struct proc_st *proc)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (s->config->uid != -1) {
|
||||
t = s->config->uid;
|
||||
if (s->perm_config->uid != -1) {
|
||||
t = s->perm_config->uid;
|
||||
ret = ioctl(tunfd, TUNSETOWNER, t);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
@@ -441,8 +441,8 @@ int open_tun(main_server_st * s, struct proc_st *proc)
|
||||
}
|
||||
}
|
||||
#ifdef TUNSETGROUP
|
||||
if (s->config->gid != -1) {
|
||||
t = s->config->uid;
|
||||
if (s->perm_config->gid != -1) {
|
||||
t = s->perm_config->uid;
|
||||
ret = ioctl(tunfd, TUNSETGROUP, t);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
|
||||
30
src/vpn.h
30
src/vpn.h
@@ -263,12 +263,7 @@ typedef struct kkdcp_st {
|
||||
} kkdcp_st;
|
||||
|
||||
struct cfg_st {
|
||||
char *listen_host;
|
||||
unsigned int port;
|
||||
unsigned int udp_port;
|
||||
unsigned int is_dyndns;
|
||||
char* unix_conn_file;
|
||||
unsigned int sup_config_type; /* one of SUP_CONFIG_ */
|
||||
unsigned int stats_report_time;
|
||||
|
||||
kkdcp_st *kkdcp;
|
||||
@@ -287,9 +282,6 @@ struct cfg_st {
|
||||
char *cert_user_oid; /* The OID that will be used to extract the username */
|
||||
char *cert_group_oid; /* The OID that will be used to extract the groupname */
|
||||
|
||||
auth_struct_st auth[MAX_AUTH_METHODS];
|
||||
unsigned auth_methods;
|
||||
acct_struct_st acct;
|
||||
|
||||
gnutls_certificate_request_t cert_req;
|
||||
char *priorities;
|
||||
@@ -376,9 +368,6 @@ struct cfg_st {
|
||||
char *cert_hash;
|
||||
#endif
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
|
||||
/* additional configuration files */
|
||||
char *per_group_dir;
|
||||
char *per_user_dir;
|
||||
@@ -391,6 +380,25 @@ struct cfg_st {
|
||||
struct vpn_st network;
|
||||
};
|
||||
|
||||
struct perm_cfg_st {
|
||||
/* gets reloaded */
|
||||
struct cfg_st *config;
|
||||
|
||||
/* stuff here don't change on reload */
|
||||
auth_struct_st auth[MAX_AUTH_METHODS];
|
||||
unsigned auth_methods;
|
||||
acct_struct_st acct;
|
||||
unsigned int sup_config_type; /* one of SUP_CONFIG_ */
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
|
||||
char *listen_host;
|
||||
char* unix_conn_file;
|
||||
unsigned int port;
|
||||
unsigned int udp_port;
|
||||
};
|
||||
|
||||
/* generic thing to stop complaints */
|
||||
struct worker_st;
|
||||
struct main_server_st;
|
||||
|
||||
@@ -97,9 +97,9 @@ int ws_switch_auth_to(struct worker_st *ws, unsigned auth)
|
||||
ws->selected_auth->type & auth)
|
||||
return 1;
|
||||
|
||||
for (i=0;i<ws->config->auth_methods;i++) {
|
||||
if (ws->config->auth[i].enabled && (ws->config->auth[i].type & auth) != 0) {
|
||||
ws->selected_auth = &ws->config->auth[i];
|
||||
for (i=0;i<ws->perm_config->auth_methods;i++) {
|
||||
if (ws->perm_config->auth[i].enabled && (ws->perm_config->auth[i].type & auth) != 0) {
|
||||
ws->selected_auth = &ws->perm_config->auth[i];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -110,9 +110,9 @@ void ws_disable_auth(struct worker_st *ws, unsigned auth)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i=0;i<ws->config->auth_methods;i++) {
|
||||
if ((ws->config->auth[i].type & auth) != 0) {
|
||||
ws->config->auth[i].enabled = 0;
|
||||
for (i=0;i<ws->perm_config->auth_methods;i++) {
|
||||
if ((ws->perm_config->auth[i].type & auth) != 0) {
|
||||
ws->perm_config->auth[i].enabled = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,7 +611,7 @@ static int recv_cookie_auth_reply(worker_st * ws)
|
||||
ws->config->net_priority = msg->net_priority;
|
||||
|
||||
if (msg->has_no_udp && msg->no_udp != 0)
|
||||
ws->config->udp_port = 0;
|
||||
ws->perm_config->udp_port = 0;
|
||||
|
||||
if (msg->xml_config_file) {
|
||||
talloc_free(ws->config->xml_config_file);
|
||||
@@ -1106,7 +1106,7 @@ int basic_auth_handler(worker_st * ws, unsigned http_ver, const char *msg)
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
if (ws->config->auth_methods > 1) {
|
||||
if (ws->perm_config->auth_methods > 1) {
|
||||
ret = cstp_puts(ws, "X-HTTP-Auth-Support: fallback\r\n");
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
@@ -439,7 +439,7 @@ void vpn_server(struct worker_st *ws)
|
||||
|
||||
memset(&settings, 0, sizeof(settings));
|
||||
|
||||
ws->selected_auth = &ws->config->auth[0];
|
||||
ws->selected_auth = &ws->perm_config->auth[0];
|
||||
if (ws->cert_auth_ok)
|
||||
ws_switch_auth_to(ws, AUTH_TYPE_CERTIFICATE);
|
||||
|
||||
@@ -1325,7 +1325,7 @@ static int connect_handler(worker_st * ws)
|
||||
}
|
||||
|
||||
ws->udp_state = UP_DISABLED;
|
||||
if (ws->config->udp_port != 0 && req->master_secret_set != 0) {
|
||||
if (ws->perm_config->udp_port != 0 && req->master_secret_set != 0) {
|
||||
memcpy(ws->master_secret, req->master_secret, TLS_MASTER_SIZE);
|
||||
ws->udp_state = UP_WAIT_FD;
|
||||
} else {
|
||||
@@ -1616,7 +1616,7 @@ static int connect_handler(worker_st * ws)
|
||||
|
||||
ret =
|
||||
cstp_printf(ws, "X-DTLS-Port: %u\r\n",
|
||||
ws->config->udp_port);
|
||||
ws->perm_config->udp_port);
|
||||
SEND_ERR(ret);
|
||||
|
||||
if (ws->config->rekey_time > 0) {
|
||||
|
||||
@@ -172,6 +172,8 @@ typedef struct worker_st {
|
||||
|
||||
http_parser *parser;
|
||||
struct cfg_st *config;
|
||||
struct perm_cfg_st *perm_config;
|
||||
|
||||
unsigned int auth_state; /* S_AUTH */
|
||||
|
||||
struct sockaddr_un secmod_addr; /* sec-mod unix address */
|
||||
|
||||
Reference in New Issue
Block a user