diff --git a/doc/sample.config b/doc/sample.config index d825abe2..bafbf3b2 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -2,7 +2,7 @@ # all should succeed. # Options: certificate, pam. #auth = "certificate" -#auth = "plain[./sample.passwd]" +auth = "plain[./sample.passwd]" #auth = "pam" # The gid-min option is used by auto-select-group option, in order to @@ -133,6 +133,11 @@ auth-timeout = 40 # of that cookie. cookie-validity = 10800 +# Whether roaming is allowed, i.e., if true a cookie is +# restricted to a single IP address and cannot be re-used +# from a different IP. +deny-roaming = false + # ReKey time (in seconds) # ocserv will ask the client to refresh keys periodically once # this amount of seconds is elapsed. Set to zero to disable. diff --git a/src/config.c b/src/config.c index e04a9bf1..48ccca80 100644 --- a/src/config.c +++ b/src/config.c @@ -89,6 +89,7 @@ static struct cfg_options available_options[] = { /* this is alias for cisco-client-compat */ { .name = "always-require-cert", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "cisco-client-compat", .type = OPTION_BOOLEAN, .mandatory = 0 }, + { .name = "deny-roaming", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "use-utmp", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "use-dbus", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "use-occtl", .type = OPTION_BOOLEAN, .mandatory = 0 }, @@ -474,6 +475,7 @@ unsigned force_cert_auth; config->rx_per_sec /= 1000; /* in kb */ config->tx_per_sec /= 1000; + READ_TF("deny-roaming", config->deny_roaming, 1); READ_NUMERIC("cookie-validity", config->cookie_validity); config->rekey_time = -1; diff --git a/src/main-auth.c b/src/main-auth.c index 3fac4420..1a39d126 100644 --- a/src/main-auth.c +++ b/src/main-auth.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "str.h" #include @@ -150,6 +151,12 @@ 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) +{ + proc->config.deny_roaming = config->deny_roaming; + proc->config.no_udp = (config->udp_port!=0)?0:1; +} + int handle_auth_cookie_req(main_server_st* s, struct proc_st* proc, const AuthCookieRequestMsg * req) { @@ -183,16 +190,6 @@ PROTOBUF_ALLOCATOR(pa, proc); return -1; snprintf(proc->username, sizeof(proc->username), "%s", cmsg->username); - /* check whether the IP matches */ - if (cmsg->ip == NULL || human_addr2((struct sockaddr *)&proc->remote_addr, proc->remote_addr_len, - str_ip, sizeof(str_ip), 0) == NULL) - return -1; - if (strcmp(str_ip, cmsg->ip) != 0) { - mslog(s, proc, LOG_INFO, "user '%s' is re-using cookie from different IP (prev: %s, current: %s); rejecting", - cmsg->username, cmsg->ip, str_ip); - return -1; - } - if (cmsg->groupname) snprintf(proc->groupname, sizeof(proc->groupname), "%s", cmsg->groupname); @@ -207,6 +204,41 @@ PROTOBUF_ALLOCATOR(pa, proc); memcpy(proc->ipv4_seed, &cmsg->ipv4_seed, sizeof(proc->ipv4_seed)); + /* cookie is good so far, now read config */ + 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; + } + + if (proc->config.cgroup != NULL) { + put_into_cgroup(s, proc->config.cgroup, proc->pid); + } + } + + /* check whether the cookie IP matches */ + if (proc->config.deny_roaming != 0) { + if (cmsg->ip == NULL) { + return -1; + } + + if (human_addr2((struct sockaddr *)&proc->remote_addr, proc->remote_addr_len, + str_ip, sizeof(str_ip), 0) == NULL) + return -1; + + if (strcmp(str_ip, cmsg->ip) != 0) { + mslog(s, proc, LOG_INFO, "user '%s' is re-using cookie from different IP (prev: %s, current: %s); rejecting", + cmsg->username, cmsg->ip, str_ip); + return -1; + } + } + + return 0; } diff --git a/src/main-misc.c b/src/main-misc.c index 672cbb80..b9a8f147 100644 --- a/src/main-misc.c +++ b/src/main-misc.c @@ -213,19 +213,6 @@ static int accept_user(main_server_st * s, struct proc_st *proc, unsigned cmd) return ret; } - 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; - } - - if (proc->config.cgroup != NULL) { - put_into_cgroup(s, proc->config.cgroup, proc->pid); - } - } - ret = open_tun(s, proc); if (ret < 0) { return -1; diff --git a/src/ocserv-args.def b/src/ocserv-args.def index f3fc3802..e96b6a37 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -214,6 +214,11 @@ auth-timeout = 40 # of that cookie. cookie-validity = 10800 +# Whether roaming is allowed, i.e., if true a cookie is +# restricted to a single IP address and cannot be re-used +# from a different IP. +deny-roaming = false + # ReKey time (in seconds) # ocserv will ask the client to refresh keys periodically once # this amount of seconds is elapsed. Set to zero to disable. @@ -370,7 +375,7 @@ route = 192.168.5.0/255.255.255.0 # or the groupname. # The options allowed in the configuration files are dns, nbns, # ipv?-network, ipv4-netmask, ipv6-prefix, rx/tx-per-sec, iroute, route, -# net-priority, no-udp and cgroup. +# net-priority, deny-roaming, no-udp and cgroup. # # Note that the 'iroute' option allows to add routes on the server # based on a user or group. The syntax depends on the input accepted diff --git a/src/sup-config/file.c b/src/sup-config/file.c index 2913b819..20a97f2d 100644 --- a/src/sup-config/file.c +++ b/src/sup-config/file.c @@ -42,6 +42,7 @@ struct cfg_options { static struct cfg_options available_options[] = { { .name = "no-udp", .type = OPTION_BOOLEAN }, + { .name = "deny-roaming", .type = OPTION_BOOLEAN }, { .name = "route", .type = OPTION_MULTI_LINE }, { .name = "iroute", .type = OPTION_MULTI_LINE }, { .name = "dns", .type = OPTION_MULTI_LINE }, @@ -169,6 +170,7 @@ struct group_cfg_st *sconfig = &proc->config; } 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_RAW_MULTI_LINE("route", sconfig->routes, sconfig->routes_size); READ_RAW_MULTI_LINE("iroute", sconfig->iroutes, sconfig->iroutes_size); @@ -249,8 +251,6 @@ static int get_sup_config(struct cfg_st *global_config, struct proc_st *proc) char file[_POSIX_PATH_MAX]; int ret; - memset(&proc->config, 0, sizeof(proc->config)); - if (global_config->per_group_dir != NULL && proc->groupname[0] != 0) { snprintf(file, sizeof(file), "%s/%s", global_config->per_group_dir, proc->groupname); diff --git a/src/vpn.h b/src/vpn.h index 8c6b36c6..ef6130ff 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -147,7 +147,8 @@ struct group_cfg_st { size_t rx_per_sec; size_t tx_per_sec; - + + unsigned deny_roaming; /* whether the user is allowed to re-use cookies from another IP */ unsigned net_priority; unsigned no_udp; /* whether to disable UDP for this user */ }; @@ -213,6 +214,8 @@ struct cfg_st { unsigned split_dns_size;; char* socket_file_prefix; + + unsigned deny_roaming; /* whether a cookie is restricted to a single IP */ time_t cookie_validity; /* in seconds */ time_t rekey_time; /* in seconds */