From baa3e4701e3c5787079f0f335a48fe49cde2ebf4 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 8 Dec 2014 12:56:16 +0100 Subject: [PATCH] Supplementary configuration is now read by the security module. That allows sec-mod to handle both authentication and accounting. That deprecates the session-control configuration option. --- src/Makefile.am | 2 +- src/common.h | 3 +- src/config.c | 5 +- src/ip-lease.c | 61 ++++++- src/ipc.proto | 20 +++ src/main-auth.c | 26 ++- src/main-misc.c | 106 +++++++++--- src/main.c | 3 - src/main.h | 1 - src/ocserv-args.def | 6 - src/sec-mod-auth.c | 24 +-- ...main-sup-config.c => sec-mod-sup-config.c} | 6 +- ...main-sup-config.h => sec-mod-sup-config.h} | 8 +- src/sec-mod.c | 24 ++- src/sec-mod.h | 5 +- src/sup-config/file.c | 151 +++++++----------- src/sup-config/file.h | 2 +- src/vpn.h | 6 +- 18 files changed, 289 insertions(+), 170 deletions(-) rename src/{main-sup-config.c => sec-mod-sup-config.c} (89%) rename src/{main-sup-config.h => sec-mod-sup-config.h} (83%) diff --git a/src/Makefile.am b/src/Makefile.am index 1ae8e6f8..080baeac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -73,7 +73,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \ sec-mod.c sec-mod-db.c sec-mod-auth.c sec-mod-auth.h sec-mod.h sec-mod-ban.c \ script-list.h $(COMMON_SOURCES) $(AUTH_SOURCES) \ icmp-ping.c icmp-ping.h \ - main-sup-config.c main-sup-config.h \ + sec-mod-sup-config.c sec-mod-sup-config.h \ sup-config/file.c sup-config/file.h \ worker-bandwidth.c worker-bandwidth.h ctl.h main-ctl.h \ vasprintf.c vasprintf.h \ diff --git a/src/common.h b/src/common.h index f9c71f08..d941a4eb 100644 --- a/src/common.h +++ b/src/common.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2013 Nikos Mavrogiannopoulos + * Copyright (C) 2013, 2014 Nikos Mavrogiannopoulos + * Copyright (C) 2014 Red Hat, Inc. * * Author: Nikos Mavrogiannopoulos * diff --git a/src/config.c b/src/config.c index 8cbfbe44..fd02f718 100644 --- a/src/config.c +++ b/src/config.c @@ -452,8 +452,9 @@ unsigned force_cert_auth; if (config->occtl_socket_file == NULL) config->occtl_socket_file = talloc_strdup(config, OCCTL_UNIX_SOCKET); - if (config->auth_types & AUTH_TYPE_USERNAME_PASS) { - READ_TF("session-control", config->session_control, 0); + val = get_option("session-control", NULL); + if (val != NULL) { + fprintf(stderr, "The option 'session-control' is deprecated\n"); } READ_STRING("banner", config->banner); diff --git a/src/ip-lease.c b/src/ip-lease.c index 24a09f7f..723de428 100644 --- a/src/ip-lease.c +++ b/src/ip-lease.c @@ -141,7 +141,34 @@ int get_ipv4_lease(main_server_st* s, struct proc_st* proc) int ret; const char* c_network, *c_netmask; char buf[64]; + + if (proc->config.explicit_ipv4) { + /* if an explicit IP is given for that client, then + * don't do any IP accounting */ + ret = + inet_pton(AF_INET, proc->config.explicit_ipv4, SA_IN_P(&network)); + + if (ret != 1) { + mslog(s, NULL, LOG_ERR, "error reading explicit IP: %s", proc->config.explicit_ipv4); + return -1; + } + + proc->ipv4 = talloc_zero(proc, struct ip_lease_st); + if (proc->ipv4 == NULL) + return ERR_MEM; + + ((struct sockaddr_in*)&network)->sin_family = AF_INET; + ((struct sockaddr_in*)&network)->sin_port = 0; + memcpy(&proc->ipv4->lip, &network, sizeof(struct sockaddr_in)); + proc->ipv4->lip_len = sizeof(struct sockaddr_in); + memcpy(&proc->ipv4->rip, &network, sizeof(struct sockaddr_in)); + proc->ipv4->rip_len = sizeof(struct sockaddr_in); + + return 0; + } + + /* Our IP accounting */ if (proc->config.ipv4_network && proc->config.ipv4_netmask) { c_network = proc->config.ipv4_network; c_netmask = proc->config.ipv4_netmask; @@ -277,6 +304,32 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc) char *c_netmask = NULL; char buf[64]; + if (proc->config.explicit_ipv6) { + /* if an explicit IP is given for that client, then + * don't do any IP accounting */ + ret = + inet_pton(AF_INET6, proc->config.explicit_ipv6, SA_IN6_P(&network)); + + if (ret != 1) { + mslog(s, NULL, LOG_ERR, "error reading explicit IP: %s", proc->config.explicit_ipv6); + return -1; + } + + proc->ipv6 = talloc_zero(proc, struct ip_lease_st); + if (proc->ipv6 == NULL) + return ERR_MEM; + + ((struct sockaddr_in6*)&network)->sin6_family = AF_INET6; + ((struct sockaddr_in6*)&network)->sin6_port = 0; + memcpy(&proc->ipv6->lip, &network, sizeof(struct sockaddr_in6)); + proc->ipv6->lip_len = sizeof(struct sockaddr_in6); + + memcpy(&proc->ipv6->rip, &network, sizeof(struct sockaddr_in6)); + proc->ipv6->rip_len = sizeof(struct sockaddr_in6); + + return 0; + } + if (proc->config.ipv6_network && proc->config.ipv6_prefix) { c_network = proc->config.ipv6_network; c_netmask = ipv6_prefix_to_mask(proc, proc->config.ipv6_prefix); @@ -401,7 +454,7 @@ fail: } static -int unref_ip_lease(struct ip_lease_st * lease) +int unref_ip_lease(struct ip_lease_st *lease) { if (lease->db) { htable_del(&lease->db->ht, rehash(lease, NULL), lease); @@ -409,7 +462,7 @@ int unref_ip_lease(struct ip_lease_st * lease) return 0; } -int get_ip_leases(main_server_st* s, struct proc_st* proc) +int get_ip_leases(main_server_st *s, struct proc_st *proc) { int ret; char buf[128]; @@ -419,7 +472,7 @@ char buf[128]; if (ret < 0) return ret; - if (proc->ipv4) { + if (proc->ipv4 && proc->ipv4->db) { if (htable_add(&s->ip_leases.ht, rehash(proc->ipv4, NULL), proc->ipv4) == 0) { mslog(s, proc, LOG_ERR, "could not add IPv4 lease to hash table."); return -1; @@ -433,7 +486,7 @@ char buf[128]; if (ret < 0) return ret; - if (proc->ipv6) { + if (proc->ipv6 && proc->ipv4->db) { if (htable_add(&s->ip_leases.ht, rehash(proc->ipv6, NULL), proc->ipv6) == 0) { mslog(s, proc, LOG_ERR, "could not add IPv6 lease to hash table."); return -1; diff --git a/src/ipc.proto b/src/ipc.proto index 9365f6fd..ee805936 100644 --- a/src/ipc.proto +++ b/src/ipc.proto @@ -192,4 +192,24 @@ message sec_auth_session_msg message sec_auth_session_reply_msg { required AUTH_REP reply = 1; + + /* sup - config */ + optional bool no_udp = 10; + optional bool deny_roaming = 11; + optional bool require_cert = 12; + repeated string routes = 13; + repeated string iroutes = 14; + repeated string dns = 15; + repeated string nbns = 16; + optional string ipv4_net = 17; + optional string ipv4_netmask = 18; + optional string ipv6_net = 19; + optional uint32 ipv6_prefix = 20; + optional string cgroup = 21; + optional string xml_config_file = 22; + optional uint32 rx_per_sec = 23; + optional uint32 tx_per_sec = 24; + optional uint32 net_priority = 25; + optional string explicit_ipv4 = 26; + optional string explicit_ipv6 = 27; } diff --git a/src/main-auth.c b/src/main-auth.c index f08f1eed..5520101a 100644 --- a/src/main-auth.c +++ b/src/main-auth.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "str.h" #include @@ -209,17 +208,16 @@ struct cookie_entry_st *old; memset(&proc->config, 0, sizeof(proc->config)); apply_default_sup_config(s->config, proc); - if (s->config_module) { - ret = s->config_module->get_sup_config(s->config, proc); - if (ret < 0) { - mslog(s, proc, LOG_ERR, - "error reading additional configuration"); - return ERR_READ_CONFIG; - } + /* loads sup config */ + ret = session_open(s, proc); + if (ret < 0) { + mslog(s, proc, LOG_INFO, "could not open session"); + return -1; + } - if (proc->config.cgroup != NULL) { - put_into_cgroup(s, proc->config.cgroup, proc->pid); - } + /* Put into right cgroup */ + if (proc->config.cgroup != NULL) { + put_into_cgroup(s, proc->config.cgroup, proc->pid); } /* check whether the cookie IP matches */ @@ -283,12 +281,6 @@ struct cookie_entry_st *old; memcpy(proc->ipv4_seed, &cmsg->ipv4_seed, sizeof(proc->ipv4_seed)); - ret = session_open(s, proc); - if (ret < 0) { - mslog(s, proc, LOG_INFO, "could not open session"); - return -1; - } - /* add the links to proc hash */ proc_table_add(s, proc); diff --git a/src/main-misc.c b/src/main-misc.c index 6f41b40e..b5f9ac8c 100644 --- a/src/main-misc.c +++ b/src/main-misc.c @@ -46,7 +46,6 @@ #include #include #include -#include #ifdef HAVE_MALLOC_TRIM # include @@ -168,10 +167,8 @@ int session_cmd(main_server_st * s, struct proc_st *proc, unsigned open) int sd, ret, e; SecAuthSessionMsg ireq = SEC_AUTH_SESSION_MSG__INIT; SecAuthSessionReplyMsg *msg = NULL; - unsigned type; - - if (s->config->session_control == 0) - return 0; + unsigned type, i; + PROTOBUF_ALLOCATOR(pa, proc); if (open) type = SM_CMD_AUTH_SESSION_OPEN; @@ -227,6 +224,86 @@ int session_cmd(main_server_st * s, struct proc_st *proc, unsigned open) mslog(s, proc, LOG_INFO, "could not initiate session for '%s'", proc->username); return -1; } + + /* fill in group_cfg_st */ + if (msg->has_no_udp) + proc->config.no_udp = msg->no_udp; + + if (msg->has_deny_roaming) + proc->config.deny_roaming = msg->deny_roaming; + + if (msg->has_require_cert) + proc->config.require_cert = msg->require_cert; + + if (msg->has_ipv6_prefix) + proc->config.ipv6_prefix = msg->ipv6_prefix; + + if (msg->rx_per_sec) + proc->config.rx_per_sec = msg->rx_per_sec; + if (msg->tx_per_sec) + proc->config.tx_per_sec = msg->tx_per_sec; + + if (msg->net_priority) + proc->config.net_priority = msg->net_priority; + + if (msg->ipv4_net) { + proc->config.ipv4_network = talloc_strdup(proc, msg->ipv4_net); + } + if (msg->ipv4_netmask) { + proc->config.ipv4_netmask = talloc_strdup(proc, msg->ipv4_netmask); + } + if (msg->ipv6_net) { + proc->config.ipv6_network = talloc_strdup(proc, msg->ipv6_net); + } + + if (msg->cgroup) { + proc->config.cgroup = talloc_strdup(proc, msg->cgroup); + } + + if (msg->xml_config_file) { + proc->config.xml_config_file = talloc_strdup(proc, msg->xml_config_file); + } + + if (msg->explicit_ipv4) { + proc->config.explicit_ipv4 = talloc_strdup(proc, msg->explicit_ipv4); + } + + if (msg->explicit_ipv6) { + proc->config.explicit_ipv6 = talloc_strdup(proc, msg->explicit_ipv6); + } + + if (msg->n_routes > 0) { + proc->config.routes = talloc_size(proc, sizeof(char*)*msg->n_routes); + for (i=0;in_routes;i++) { + proc->config.routes[i] = talloc_strdup(proc, msg->routes[i]); + } + proc->config.routes_size = msg->n_routes; + } + + if (msg->n_iroutes > 0) { + proc->config.iroutes = talloc_size(proc, sizeof(char*)*msg->n_iroutes); + for (i=0;in_iroutes;i++) { + proc->config.iroutes[i] = talloc_strdup(proc, msg->iroutes[i]); + } + proc->config.iroutes_size = msg->n_iroutes; + } + + if (msg->n_dns > 0) { + proc->config.dns = talloc_size(proc, sizeof(char*)*msg->n_dns); + for (i=0;in_dns;i++) { + proc->config.dns[i] = talloc_strdup(proc, msg->dns[i]); + } + proc->config.dns_size = msg->n_dns; + } + + if (msg->n_nbns > 0) { + proc->config.nbns = talloc_size(proc, sizeof(char*)*msg->n_nbns); + for (i=0;in_nbns;i++) { + proc->config.nbns[i] = talloc_strdup(proc, msg->nbns[i]); + } + proc->config.nbns_size = msg->n_nbns; + } + sec_auth_session_reply_msg__free_unpacked(msg, &pa); } else { close(sd); } @@ -262,7 +339,7 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k) } /* close any pending sessions */ - if (s->config->session_control != 0 && proc->active_sid) { + if (proc->active_sid) { session_close(s, proc); } @@ -273,26 +350,17 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k) proc->pid = -1; remove_iroutes(s, proc); - if (s->config_module) { - s->config_module->clear_sup_config(&proc->config); - } if (proc->ipv4 || proc->ipv6) remove_ip_leases(s, proc); /* expire any available cookies */ if (proc->cookie_ptr) { - unsigned timeout = s->config->cookie_timeout; - proc->cookie_ptr->proc = NULL; - if (s->config->session_control != 0) { - /* if we use session control and we closed the session we - * need to invalidate the cookie, so that a new session is - * used on the next connection */ - proc->cookie_ptr->expiration = 1; - } else { - proc->cookie_ptr->expiration = time(0) + timeout; - } + /* if we use session control and we closed the session we + * need to invalidate the cookie, so that a new session is + * used on the next connection */ + proc->cookie_ptr->expiration = 1; } close_tun(s, proc); diff --git a/src/main.c b/src/main.c index 6afc9b20..893c5e21 100644 --- a/src/main.c +++ b/src/main.c @@ -51,7 +51,6 @@ # include #endif #include -#include #include #include #include @@ -987,8 +986,6 @@ int main(int argc, char** argv) run_sec_mod(s); - sup_config_init(s); - ret = ctl_handler_init(s); if (ret < 0) { fprintf(stderr, "Cannot create command handler\n"); diff --git a/src/main.h b/src/main.h index 1a78c11d..107315b2 100644 --- a/src/main.h +++ b/src/main.h @@ -213,7 +213,6 @@ typedef struct main_server_st { time_t start_time; void * auth_extra; - struct config_mod_st *config_module; #ifdef HAVE_DBUS void * ctl_ctx; diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 146e59a9..c4b2a727 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -96,12 +96,6 @@ An example configuration file follows. # to generate password entries. #auth = "plain[/etc/ocserv/ocpasswd]" -# Whether to enable the authentication method's session control (i.e., PAM). -# That requires more resources on the server, and makes cookies one-time-use; -# thus don't enable unless you need it. That should be used when you have an -# accounting system in place with the PAM modules. -#session-control = true - # Whether to enable seccomp worker isolation. That restricts the number of # system calls allowed to a worker process, in order to reduce damage from a # bug in the worker process. It is available on Linux systems at a performance cost. diff --git a/src/sec-mod-auth.c b/src/sec-mod-auth.c index a9d8d2ff..8c13ca01 100644 --- a/src/sec-mod-auth.c +++ b/src/sec-mod-auth.c @@ -49,6 +49,7 @@ #include #include #include +#include static const struct auth_mod_st *module = NULL; @@ -106,6 +107,7 @@ int send_sec_auth_reply(sec_mod_st * sec, client_entry_st * entry, AUTHREP r) { SecAuthReplyMsg msg = SEC_AUTH_REPLY_MSG__INIT; int ret; + void *pool = NULL; if (r == AUTH__REP__OK) { /* fill message */ @@ -135,6 +137,7 @@ int send_sec_auth_reply(sec_mod_st * sec, client_entry_st * entry, AUTHREP r) (pack_size_func) sec_auth_reply_msg__get_packed_size, (pack_func) sec_auth_reply_msg__pack); + talloc_free(pool); } else { msg.reply = AUTH__REP__FAILED; @@ -279,9 +282,6 @@ int handle_sec_auth_res(sec_mod_st * sec, client_entry_st * e, int result) } ret = 0; - if (module != NULL && (sec->config->session_control == 0 || module->open_session == NULL)) { - del_client_entry(sec, e); - } /* else do nothing, and wait for session close/open messages */ } else { e->status = PS_AUTH_FAILED; add_ip_to_ban_list(sec, e->ip, time(0) + sec->config->min_reauth_time); @@ -305,19 +305,12 @@ int handle_sec_auth_res(sec_mod_st * sec, client_entry_st * e, int result) /* opens or closes a session. */ -int handle_sec_auth_session_cmd(sec_mod_st * sec, const SecAuthSessionMsg * req, unsigned cmd) +int handle_sec_auth_session_cmd(sec_mod_st * sec, const SecAuthSessionMsg * req, + unsigned cmd, client_entry_st **r_entry) { client_entry_st *e; int ret; - if (module == NULL || module->open_session == NULL) - return 0; - - if (sec->config->session_control == 0) { - seclog(sec, LOG_ERR, "auth session open/close but session control is disabled!"); - return 0; - } - if (req->sid.len != SID_SIZE) { seclog(sec, LOG_ERR, "auth session open/close but with illegal sid size (%d)!", (int)req->sid.len); @@ -331,6 +324,13 @@ int handle_sec_auth_session_cmd(sec_mod_st * sec, const SecAuthSessionMsg * req, } if (cmd == SM_CMD_AUTH_SESSION_OPEN) { + if (r_entry) { + *r_entry = e; + } + + if (module == NULL || module->open_session == NULL) + return 0; + ret = module->open_session(e->auth_ctx); if (ret < 0) { e->status = PS_AUTH_FAILED; diff --git a/src/main-sup-config.c b/src/sec-mod-sup-config.c similarity index 89% rename from src/main-sup-config.c rename to src/sec-mod-sup-config.c index edc37351..29ce7752 100644 --- a/src/main-sup-config.c +++ b/src/sec-mod-sup-config.c @@ -27,11 +27,11 @@ #include #include #include -#include +#include #include -void sup_config_init(main_server_st *s) +void sup_config_init(sec_mod_st *sec) { - s->config_module = &file_sup_config; + sec->config_module = &file_sup_config; } diff --git a/src/main-sup-config.h b/src/sec-mod-sup-config.h similarity index 83% rename from src/main-sup-config.h rename to src/sec-mod-sup-config.h index 17ea7d45..ef11b041 100644 --- a/src/main-sup-config.h +++ b/src/sec-mod-sup-config.h @@ -21,16 +21,16 @@ #ifndef SUP_CONFIG_H # define SUP_CONFIG_H -#include +#include /* The get_sup_config() should read any additional configuration for * proc->username/proc->groupname and save it in proc->config. */ struct config_mod_st { - int (*get_sup_config)(struct cfg_st *global_config, struct proc_st *proc); - void (*clear_sup_config)(struct group_cfg_st *out); + int (*get_sup_config)(struct cfg_st *global_config, client_entry_st *entry, + SecAuthSessionReplyMsg *msg, void *pool); }; -void sup_config_init(main_server_st *s); +void sup_config_init(sec_mod_st *sec); #endif diff --git a/src/sec-mod.c b/src/sec-mod.c index 66c1b9ed..2b2bd755 100644 --- a/src/sec-mod.c +++ b/src/sec-mod.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -281,7 +282,9 @@ int process_packet(void *pool, sec_mod_st * sec, cmd_request_t cmd, case SM_CMD_AUTH_SESSION_OPEN: case SM_CMD_AUTH_SESSION_CLOSE:{ SecAuthSessionMsg *msg; + void *lpool = NULL; SecAuthSessionReplyMsg rep = SEC_AUTH_SESSION_REPLY_MSG__INIT; + client_entry_st *e = NULL; if (uid != 0) { seclog(sec, LOG_INFO, "received session open/close from unauthorized uid (%u)\n", (unsigned)uid); @@ -296,21 +299,36 @@ int process_packet(void *pool, sec_mod_st * sec, cmd_request_t cmd, return -1; } - ret = handle_sec_auth_session_cmd(sec, msg, cmd); + ret = handle_sec_auth_session_cmd(sec, msg, cmd, &e); sec_auth_session_msg__free_unpacked(msg, &pa); if (cmd == SM_CMD_AUTH_SESSION_OPEN) { - if (ret < 0) + if (ret < 0 || e == NULL) rep.reply = AUTH__REP__FAILED; else rep.reply = AUTH__REP__OK; + if (sec->config_module && e != NULL) { + lpool = talloc_new(e); + if (lpool == NULL) { + return ERR_MEM; + } + + ret = sec->config_module->get_sup_config(sec->config, e, &rep, lpool); + if (ret < 0) { + seclog(sec, LOG_ERR, "error reading additional configuration for '%s'", e->username); + talloc_free(lpool); + return ERR_READ_CONFIG; + } + } + ret = send_msg(pool, sec->fd, SM_CMD_AUTH_SESSION_REPLY, &rep, (pack_size_func) sec_auth_session_reply_msg__get_packed_size, (pack_func) sec_auth_session_reply_msg__pack); if (ret < 0) { seclog(sec, LOG_WARNING, "sec-mod error in sending session reply"); } + talloc_free(lpool); } return ret; @@ -435,6 +453,8 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f sec->dcookie_key.size = COOKIE_KEY_SIZE; sec->config = talloc_steal(sec, config); + sup_config_init(sec); + memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_UNIX; snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", socket_file); diff --git a/src/sec-mod.h b/src/sec-mod.h index 3def32c5..72e3f647 100644 --- a/src/sec-mod.h +++ b/src/sec-mod.h @@ -19,6 +19,7 @@ * along with this program. If not, see */ #ifndef SEC_MOD_H +# define SEC_MOD_H #include #include @@ -34,6 +35,8 @@ typedef struct sec_mod_st { struct htable *client_db; struct htable *ban_db; + struct config_mod_st *config_module; + int fd; } sec_mod_st; @@ -87,7 +90,7 @@ void sec_auth_init(struct cfg_st *config); int handle_sec_auth_init(sec_mod_st *sec, const SecAuthInitMsg * req); int handle_sec_auth_cont(sec_mod_st *sec, const SecAuthContMsg * req); -int handle_sec_auth_session_cmd(sec_mod_st * sec, const SecAuthSessionMsg * req, unsigned cmd); +int handle_sec_auth_session_cmd(sec_mod_st * sec, const SecAuthSessionMsg * req, unsigned cmd, client_entry_st **_e); 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, diff --git a/src/sup-config/file.c b/src/sup-config/file.c index e6a13757..ba9202f4 100644 --- a/src/sup-config/file.c +++ b/src/sup-config/file.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Nikos Mavrogiannopoulos + * Copyright (C) 2014 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +34,7 @@ #include #include -#include +#include struct cfg_options { const char* name; @@ -68,14 +69,14 @@ static struct cfg_options available_options[] = { if (val != NULL && val->valType == OPARG_TYPE_STRING) { \ if (s_name == NULL) { \ num = 0; \ - s_name = talloc_size(proc, sizeof(char*)*MAX_CONFIG_ENTRIES); \ + s_name = talloc_size(pool, sizeof(char*)*MAX_CONFIG_ENTRIES); \ } \ do { \ if (num >= MAX_CONFIG_ENTRIES) \ break; \ if (val && !strcmp(val->pzName, name)==0) \ continue; \ - s_name[num] = talloc_strdup(proc, val->v.strVal); \ + s_name[num] = talloc_strdup(pool, val->v.strVal); \ num++; \ } while((val = optionNextValue(pov, val)) != NULL); \ s_name[num] = NULL; \ @@ -86,28 +87,33 @@ static struct cfg_options available_options[] = { if (val != NULL && val->valType == OPARG_TYPE_STRING) { \ if (s_name != NULL) \ talloc_free(s_name); \ - s_name = talloc_strdup(proc, val->v.strVal); \ + s_name = talloc_strdup(pool, val->v.strVal); \ }} -#define READ_RAW_NUMERIC(name, s_name) { \ +#define READ_RAW_NUMERIC(name, s_name, def) { \ val = optionGetValue(pov, name); \ if (val != NULL) { \ - if (val->valType == OPARG_TYPE_NUMERIC) \ + if (val->valType == OPARG_TYPE_NUMERIC) {\ s_name = val->v.longVal; \ - else if (val->valType == OPARG_TYPE_STRING) \ + def = 1; \ + } else if (val->valType == OPARG_TYPE_STRING) {\ s_name = atoi(val->v.strVal); \ + def = 1; \ + } \ }} -#define READ_RAW_PRIO_TOS(name, s_name) { \ +#define READ_RAW_PRIO_TOS(name, s_name, def) { \ val = optionGetValue(pov, name); \ if (val != NULL) { \ if (val->valType == OPARG_TYPE_STRING) { \ if (strncmp(val->v.strVal, "0x", 2) == 0) { \ s_name = strtol(val->v.strVal, NULL, 16); \ s_name = TOS_PACK(s_name); \ + def = 1; \ } else { \ s_name = atoi(val->v.strVal); \ s_name++; \ + def = 1; \ } \ } \ }} @@ -115,12 +121,13 @@ static struct cfg_options available_options[] = { #define READ_TF(name, s_name, def) { \ { char* tmp_tf = NULL; \ READ_RAW_STRING(name, tmp_tf); \ - if (tmp_tf == NULL) s_name = def; \ - else { \ + if (tmp_tf == NULL) { def = 0; \ + } else { \ if (c_strcasecmp(tmp_tf, "true") == 0 || c_strcasecmp(tmp_tf, "yes") == 0) \ s_name = 1; \ else \ s_name = 0; \ + def = 1; \ } \ talloc_free(tmp_tf); \ }} @@ -143,13 +150,13 @@ unsigned j; * already allocated using this function. */ static -int parse_group_cfg_file(struct cfg_st *global_config, struct proc_st *proc, +int parse_group_cfg_file(struct cfg_st *global_config, + SecAuthSessionReplyMsg *msg, void *pool, const char* file) { tOptionValue const * pov; const tOptionValue* val, *prev; unsigned prefix = 0; -struct group_cfg_st *sconfig = &proc->config; pov = configFileLoad(file); if (pov == NULL) { @@ -171,59 +178,58 @@ struct group_cfg_st *sconfig = &proc->config; prev = val; } while((val = optionNextValue(pov, prev)) != NULL); - READ_TF("no-udp", sconfig->no_udp, (global_config->udp_port!=0)?0:1); - READ_TF("deny-roaming", sconfig->deny_roaming, global_config->deny_roaming); - READ_TF("require-cert", sconfig->require_cert, 0); + READ_TF("no-udp", msg->no_udp, msg->has_no_udp); + READ_TF("deny-roaming", msg->deny_roaming, msg->has_deny_roaming); + READ_TF("require-cert", msg->require_cert, msg->has_require_cert); - READ_RAW_MULTI_LINE("route", sconfig->routes, sconfig->routes_size); - READ_RAW_MULTI_LINE("iroute", sconfig->iroutes, sconfig->iroutes_size); + READ_RAW_MULTI_LINE("route", msg->routes, msg->n_routes); + READ_RAW_MULTI_LINE("iroute", msg->iroutes, msg->n_iroutes); - READ_RAW_MULTI_LINE("dns", sconfig->dns, sconfig->dns_size); - if (sconfig->dns_size == 0) { + READ_RAW_MULTI_LINE("dns", msg->dns, msg->n_dns); + if (msg->n_dns == 0) { /* try aliases */ - READ_RAW_MULTI_LINE("ipv6-dns", sconfig->dns, sconfig->dns_size); - READ_RAW_MULTI_LINE("ipv4-dns", sconfig->dns, sconfig->dns_size); + READ_RAW_MULTI_LINE("ipv6-dns", msg->dns, msg->n_dns); + READ_RAW_MULTI_LINE("ipv4-dns", msg->dns, msg->n_dns); } - READ_RAW_MULTI_LINE("nbns", sconfig->nbns, sconfig->nbns_size); - if (sconfig->nbns_size == 0) { + READ_RAW_MULTI_LINE("nbns", msg->nbns, msg->n_nbns); + if (msg->n_nbns == 0) { /* try aliases */ - READ_RAW_MULTI_LINE("ipv6-nbns", sconfig->nbns, sconfig->nbns_size); - READ_RAW_MULTI_LINE("ipv4-nbns", sconfig->nbns, sconfig->nbns_size); + READ_RAW_MULTI_LINE("ipv6-nbns", msg->nbns, msg->n_nbns); + READ_RAW_MULTI_LINE("ipv4-nbns", msg->nbns, msg->n_nbns); } - READ_RAW_STRING("cgroup", sconfig->cgroup); - READ_RAW_STRING("ipv4-network", sconfig->ipv4_network); - READ_RAW_STRING("ipv6-network", sconfig->ipv6_network); - READ_RAW_STRING("ipv4-netmask", sconfig->ipv4_netmask); + READ_RAW_STRING("cgroup", msg->cgroup); + READ_RAW_STRING("ipv4-network", msg->ipv4_net); + READ_RAW_STRING("ipv6-network", msg->ipv6_net); + READ_RAW_STRING("ipv4-netmask", msg->ipv4_netmask); - READ_RAW_NUMERIC("ipv6-prefix", prefix); - if (prefix > 0) { - sconfig->ipv6_prefix = prefix; - - if (valid_ipv6_prefix(prefix) == 0) { + READ_RAW_NUMERIC("ipv6-prefix", msg->ipv6_prefix, msg->has_ipv6_prefix); + if (msg->has_ipv6_prefix != 0) { + if (valid_ipv6_prefix(msg->ipv6_prefix) == 0) { syslog(LOG_ERR, "unknown ipv6-prefix '%u' in %s", prefix, file); } } - READ_RAW_NUMERIC("rx-data-per-sec", sconfig->rx_per_sec); - READ_RAW_NUMERIC("tx-data-per-sec", sconfig->tx_per_sec); - sconfig->rx_per_sec /= 1000; /* in kb */ - sconfig->tx_per_sec /= 1000; /* in kb */ + READ_RAW_NUMERIC("rx-data-per-sec", msg->rx_per_sec, msg->has_rx_per_sec); + READ_RAW_NUMERIC("tx-data-per-sec", msg->tx_per_sec, msg->has_tx_per_sec); + msg->rx_per_sec /= 1000; /* in kb */ + msg->tx_per_sec /= 1000; /* in kb */ /* net-priority will contain the actual priority + 1, * to allow having zero as uninitialized. */ - READ_RAW_PRIO_TOS("net-priority", sconfig->net_priority); + READ_RAW_PRIO_TOS("net-priority", msg->net_priority, msg->has_net_priority); - READ_RAW_STRING("user-profile", sconfig->xml_config_file); + READ_RAW_STRING("user-profile", msg->xml_config_file); optionUnloadNested(pov); return 0; } -static int read_sup_config_file(struct cfg_st *global_config, struct proc_st *proc, - const char *file, const char *fallback, const char *type) +static int read_sup_config_file(struct cfg_st *global_config, + SecAuthSessionReplyMsg *msg, void *pool, + const char *file, const char *fallback, const char *type) { int ret; @@ -231,44 +237,41 @@ static int read_sup_config_file(struct cfg_st *global_config, struct proc_st *pr syslog(LOG_DEBUG, "Loading %s configuration '%s'", type, file); - ret = parse_group_cfg_file(global_config, proc, file); + ret = parse_group_cfg_file(global_config, msg, pool, file); if (ret < 0) return ERR_READ_CONFIG; } else { if (fallback != NULL) { syslog(LOG_DEBUG, "Loading default %s configuration '%s'", type, fallback); - ret = parse_group_cfg_file(global_config, proc, fallback); + ret = parse_group_cfg_file(global_config, msg, pool, fallback); if (ret < 0) return ERR_READ_CONFIG; - } else { - syslog(LOG_DEBUG, "No %s configuration for '%s'", type, - proc->username); } } return 0; } -static int get_sup_config(struct cfg_st *global_config, struct proc_st *proc) +static int get_sup_config(struct cfg_st *cfg, client_entry_st *entry, + SecAuthSessionReplyMsg *msg, void *pool) { char file[_POSIX_PATH_MAX]; int ret; - if (global_config->per_group_dir != NULL && proc->groupname[0] != 0) { - snprintf(file, sizeof(file), "%s/%s", global_config->per_group_dir, - proc->groupname); + if (cfg->per_group_dir != NULL && entry->groupname[0] != 0) { + snprintf(file, sizeof(file), "%s/%s", cfg->per_group_dir, + entry->groupname); - ret = read_sup_config_file(global_config, proc, file, global_config->default_group_conf, "group"); + ret = read_sup_config_file(cfg, msg, pool, file, cfg->default_group_conf, "group"); if (ret < 0) return ret; } - if (global_config->per_user_dir != NULL) { - snprintf(file, sizeof(file), "%s/%s", global_config->per_user_dir, - proc->username); - - ret = read_sup_config_file(global_config, proc, file, global_config->default_user_conf, "user"); + if (cfg->per_user_dir != NULL) { + snprintf(file, sizeof(file), "%s/%s", cfg->per_user_dir, + entry->username); + ret = read_sup_config_file(cfg, msg, pool, file, cfg->default_user_conf, "user"); if (ret < 0) return ret; } @@ -276,40 +279,6 @@ static int get_sup_config(struct cfg_st *global_config, struct proc_st *proc) return 0; } - -static -void clear_sup_config(struct group_cfg_st* config) -{ -unsigned i; - - for(i=0;iroutes_size;i++) { - talloc_free(config->routes[i]); - } - talloc_free(config->routes); - - for(i=0;iiroutes_size;i++) { - talloc_free(config->iroutes[i]); - } - talloc_free(config->iroutes); - - for(i=0;idns_size;i++) { - talloc_free(config->dns[i]); - } - talloc_free(config->dns); - - for(i=0;inbns_size;i++) { - talloc_free(config->nbns[i]); - } - talloc_free(config->nbns); - - talloc_free(config->cgroup); - talloc_free(config->ipv4_network); - talloc_free(config->ipv6_network); - talloc_free(config->ipv4_netmask); - safe_memset(config, 0, sizeof(*config)); -} - struct config_mod_st file_sup_config = { .get_sup_config = get_sup_config, - .clear_sup_config = clear_sup_config, }; diff --git a/src/sup-config/file.h b/src/sup-config/file.h index fb37ca53..cb1f5c77 100644 --- a/src/sup-config/file.h +++ b/src/sup-config/file.h @@ -21,7 +21,7 @@ #ifndef SUP_CONFIG_FILE_H #define SUP_CONFIG_FILE_H -#include +#include extern struct config_mod_st file_sup_config; diff --git a/src/vpn.h b/src/vpn.h index 0809ffc4..f485efd0 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -145,7 +145,10 @@ struct group_cfg_st { char *ipv6_network; unsigned ipv6_prefix; char *ipv4_netmask; - + + char *explicit_ipv4; + char *explicit_ipv6; + char *cgroup; char *xml_config_file; @@ -202,7 +205,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 */ unsigned int auth_types; /* or'ed sequence of AUTH_TYPE */ - unsigned session_control; /* whether to use the session control part of authentication (PAM) */ char *auth_additional; /* the additional string specified in the auth methode */ gnutls_certificate_request_t cert_req; char *priorities;