diff --git a/doc/sample.config b/doc/sample.config index fbb564b8..d1250e21 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -473,6 +473,12 @@ no-route = 192.168.5.0/255.255.255.0 # --removeall. This option can be set globally or in the per-user configuration. #restrict-user-to-routes = true +# This option implies restrict-user-to-routes set to true. If set, the +# script /usr/bin/ocserv-fw will be called to restrict the user to its +# to accessing specific ports in the network. This option can be set globally +# or in the per-user configuration. +#restrict-user-to-ports = "tcp(443), tcp(80), udp(443), sctp(99), tcp(583), icmp(), icmpv6()" + # When set to true, all client's iroutes are made visible to all # connecting clients except for the ones offering them. This option # only makes sense if config-per-user is set. @@ -501,7 +507,9 @@ no-route = 192.168.5.0/255.255.255.0 # ipv?-network, ipv4-netmask, rx/tx-per-sec, iroute, route, no-route, # explicit-ipv4, explicit-ipv6, net-priority, deny-roaming, no-udp, # keepalive, dpd, mobile-dpd, max-same-clients, tunnel-all-dns, -# user-profile, cgroup, stats-report-time, and session-timeout. +# restrict-user-to-routes, user-profile, cgroup, stats-report-time, +# mtu, idle-timeout, mobile-idle-timeout, restrict-user-to-ports, +# and session-timeout. # # 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/Makefile.am b/src/Makefile.am index 181f9da9..27a4a9fc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,7 +60,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \ sup-config/file.c sup-config/file.h main-sec-mod-cmd.c \ sup-config/radius.c sup-config/radius.h \ worker-bandwidth.c worker-bandwidth.h main-ctl.h \ - vasprintf.c vasprintf.h worker-proxyproto.c \ + vasprintf.c vasprintf.h worker-proxyproto.c config-ports.c \ proc-search.c proc-search.h http-heads.h ip-util.c ip-util.h \ main-ban.c main-ban.h common-config.h base64-helper.c base64-helper.h \ str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \ diff --git a/src/common-config.h b/src/common-config.h index 0b06d006..40be8703 100644 --- a/src/common-config.h +++ b/src/common-config.h @@ -24,10 +24,12 @@ #include #include #include +#include int add_multi_line_val(void *pool, const char *name, char ***s_name, size_t *num, tOptionValue const *pov, const tOptionValue *val); +int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const char *str); #define MAX_SUBOPTIONS 5 diff --git a/src/config-ports.c b/src/config-ports.c new file mode 100644 index 00000000..58d041be --- /dev/null +++ b/src/config-ports.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +static int append_port(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, int port, fw_proto_t proto) +{ + FwPortSt *current; + + *fw_ports = talloc_realloc(pool, *fw_ports, FwPortSt*, (*n_fw_ports)+1); + if (*fw_ports == NULL) + return -1; + + current = talloc(pool, FwPortSt); + fw_port_st__init(current); + + current->port = port; + current->proto = proto; + + (*fw_ports)[*n_fw_ports] = current; + (*n_fw_ports)++; + + return 0; +} + +/* Parse strings of the format tcp(443), udp(111), and fill in + * allowed_tcp_ports and allowed_udp_ports. + */ +int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const char *str) +{ + const char *p, *p2; + unsigned finish = 0; + int port, ret; + fw_proto_t proto; + + if (str == NULL) + return 0; + + p = str; + + do { + while (c_isspace(*p)) + p++; + + if (strncasecmp(p, "tcp", 3) == 0) { + proto = PROTO_TCP; + p += 3; + } else if (strncasecmp(p, "udp", 3) == 0) { + proto = PROTO_UDP; + p += 3; + } else if (strncasecmp(p, "sctp", 4) == 0) { + proto = PROTO_SCTP; + p += 4; + } else if (strncasecmp(p, "icmpv6", 6) == 0) { + proto = PROTO_ICMPv6; + p += 6; + } else if (strncasecmp(p, "icmp", 4) == 0) { + proto = PROTO_ICMP; + p += 4; + } else if (strncasecmp(p, "esp", 3) == 0) { + proto = PROTO_ESP; + p += 3; + } else { + syslog(LOG_ERR, "unknown protocol on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p-str), str); + return -1; + } + + while (c_isspace(*p)) + p++; + + if (*p != '(') { + syslog(LOG_ERR, "expected parenthesis on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p-str), str); + return -1; + } + + p++; + port = atoi(p); + + ret = append_port(pool, fw_ports, n_fw_ports, port, proto); + if (ret < 0) { + syslog(LOG_ERR, "memory error"); + return -1; + } + + p2 = strchr(p, ')'); + if (p2 == NULL) { + syslog(LOG_ERR, "expected closing parenthesis on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p2-str), str); + return -1; + } + + p2++; + while (c_isspace(*p2)) + p2++; + + if (*p2 == 0) { + finish = 1; + } else if (*p2 != ',') { + syslog(LOG_ERR, "expected comma or end of line on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p2-str), str); + return -1; + } + p=p2; + p++; + } while(finish == 0); + + return 0; +} diff --git a/src/config.c b/src/config.c index 893416f4..411a169f 100644 --- a/src/config.c +++ b/src/config.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2013, 2014 Nikos Mavrogiannopoulos + * Copyright (C) 2013, 2014, 2015 Nikos Mavrogiannopoulos + * Copyright (C) 2014, 2015 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 @@ -134,6 +135,7 @@ static struct cfg_options available_options[] = { { .name = "use-occtl", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "try-mtu-discovery", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "restrict-user-to-routes", .type = OPTION_BOOLEAN, .mandatory = 0 }, + { .name = "restrict-user-to-ports", .type = OPTION_STRING, .mandatory = 0 }, { .name = "ping-leases", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "tls-priorities", .type = OPTION_STRING, .mandatory = 0 }, { .name = "chroot-dir", .type = OPTION_STRING, .mandatory = 0 }, @@ -635,7 +637,7 @@ static void parse_cfg_file(void *pool, const char* file, struct perm_cfg_st *per { tOptionValue const * pov; const tOptionValue* val, *prev; -unsigned j, i, mand; +unsigned j, i, mand, ret; char** auth = NULL; size_t auth_size = 0; unsigned prefix = 0, auto_select_group = 0; @@ -834,8 +836,20 @@ size_t urlfw_size = 0; READ_TF("try-mtu-discovery", config->try_mtu, 0); READ_TF("ping-leases", config->ping_leases, 0); + READ_TF("restrict-user-to-routes", config->restrict_user_to_routes, 0); + tmp = NULL; + READ_STRING("restrict-user-to-ports", tmp); + if (tmp) { + ret = cfg_parse_ports(pool, &config->fw_ports, &config->n_fw_ports, tmp); + if (ret < 0) { + fprintf(stderr, "error parsing restrict-user-to-ports\n"); + exit(1); + } + talloc_free(tmp); + } + READ_STRING("tls-priorities", config->priorities); READ_NUMERIC("mtu", config->default_mtu); diff --git a/src/ipc.proto b/src/ipc.proto index 9ad12b7e..85afa54d 100644 --- a/src/ipc.proto +++ b/src/ipc.proto @@ -13,6 +13,13 @@ message auth_cookie_request_msg required bytes cookie = 1; } +message fw_port_st +{ + required uint32 port = 1; + /* fw_proto_t */ + required uint32 proto = 2; +} + /* This is a structure for per-user/group supplemental configuration. */ message group_cfg_st @@ -49,6 +56,7 @@ message group_cfg_st optional uint32 mtu = 36; optional uint32 idle_timeout = 37; optional uint32 mobile_idle_timeout = 38; + repeated fw_port_st fw_ports = 39; } /* AUTH_REP */ diff --git a/src/main-sec-mod-cmd.c b/src/main-sec-mod-cmd.c index 3f59bfa8..69f4077d 100644 --- a/src/main-sec-mod-cmd.c +++ b/src/main-sec-mod-cmd.c @@ -407,7 +407,13 @@ void apply_default_config(main_server_st *s, proc_st *proc, GroupCfgSt *gc) gc->mobile_idle_timeout = s->config->mobile_idle_timeout; gc->has_mobile_idle_timeout = 1; } + + if (gc->n_fw_ports == 0 && s->config->n_fw_ports > 0) { + gc->n_fw_ports = s->config->n_fw_ports; + gc->fw_ports = s->config->fw_ports; + } } + int session_open(main_server_st * s, struct proc_st *proc, const uint8_t *cookie, unsigned cookie_size) { int ret, e; diff --git a/src/main-user.c b/src/main-user.c index 8c1f1486..6152806e 100644 --- a/src/main-user.c +++ b/src/main-user.c @@ -56,7 +56,7 @@ exit(1); \ } -static void export_dns_route_info(main_server_st *s, struct proc_st* proc) +static void export_fw_info(main_server_st *s, struct proc_st* proc) { str_st str4; str_st str6; @@ -135,6 +135,12 @@ static void export_dns_route_info(main_server_st *s, struct proc_st* proc) exit(1); } + if (proc->config->restrict_user_to_routes) { + if (setenv("OCSERV_RESTRICT_TO_ROUTES", "1", 1) == -1) { + mslog(s, proc, LOG_ERR, "could not export OCSERV_RESTRICT_TO_ROUTES\n"); + exit(1); + } + } /* export the DNS servers */ str_reset(&str4); @@ -174,6 +180,47 @@ static void export_dns_route_info(main_server_st *s, struct proc_st* proc) str_clear(&str4); str_clear(&str6); str_clear(&str_common); + + /* export the ports to reject */ + + str_reset(&str_common); + + if (proc->config->n_fw_ports > 0) { + for (i=0;iconfig->n_fw_ports;i++) { + switch(proc->config->fw_ports[i]->proto) { + case PROTO_UDP: + ret = str_append_printf(&str_common, "udp %u ", proc->config->fw_ports[i]->port); + break; + case PROTO_TCP: + ret = str_append_printf(&str_common, "tcp %u ", proc->config->fw_ports[i]->port); + break; + case PROTO_SCTP: + ret = str_append_printf(&str_common, "sctp %u ", proc->config->fw_ports[i]->port); + break; + case PROTO_ICMP: + ret = str_append_printf(&str_common, "icmp all "); + break; + case PROTO_ESP: + ret = str_append_printf(&str_common, "esp all "); + break; + case PROTO_ICMPv6: + ret = str_append_printf(&str_common, "icmpv6 all "); + break; + } + + if (ret < 0) { + mslog(s, proc, LOG_ERR, "could not append value to environment\n"); + exit(1); + } + } + } + + if (str_common.length > 0 && setenv("OCSERV_PORTS", (char*)str_common.data, 1) == -1) { + mslog(s, proc, LOG_ERR, "could not export PORTS\n"); + exit(1); + } + + str_clear(&str_common); } static @@ -188,7 +235,7 @@ const char* script, *next_script = NULL; else script = s->config->disconnect_script; - if (proc->config->restrict_user_to_routes) { + if (proc->config->restrict_user_to_routes || proc->config->n_fw_ports > 0) { next_script = script; script = OCSERV_FW_SCRIPT; } @@ -283,7 +330,7 @@ const char* script, *next_script = NULL; } /* export DNS and route info */ - export_dns_route_info(s, proc); + export_fw_info(s, proc); /* set stdout to be stderr to avoid confusing scripts - note we have stdout closed */ if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) { diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 205b91bc..e4942a53 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -561,6 +561,12 @@ no-route = 192.168.5.0/255.255.255.0 # --removeall. This option can be set globally or in the per-user configuration. #restrict-user-to-routes = true +# This option implies restrict-user-to-routes set to true. If set, the +# script /usr/bin/ocserv-fw will be called to restrict the user to its +# to accessing specific ports in the network. This option can be set globally +# or in the per-user configuration. +#restrict-user-to-ports = "tcp(443), tcp(80), udp(443), sctp(99), tcp(583), icmp(), icmpv6()" + # When set to true, all client's iroutes are made visible to all # connecting clients except for the ones offering them. This option # only makes sense if config-per-user is set. @@ -596,7 +602,8 @@ no-route = 192.168.5.0/255.255.255.0 # explicit-ipv4, explicit-ipv6, net-priority, deny-roaming, no-udp, # keepalive, dpd, mobile-dpd, max-same-clients, tunnel-all-dns, # restrict-user-to-routes, user-profile, cgroup, stats-report-time, -# mtu, idle-timeout, mobile-idle-timeout, and session-timeout. +# mtu, idle-timeout, mobile-idle-timeout, restrict-user-to-ports, +# and session-timeout. # # 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/ocserv-fw b/src/ocserv-fw index 64ade0af..d99ef348 100755 --- a/src/ocserv-fw +++ b/src/ocserv-fw @@ -3,22 +3,45 @@ PATH=/sbin:/usr/sbin:$PATH COMMENT="ocserv-fw" +INPUT_CHAIN="INPUT" +SEC_INPUT_CHAIN="INPUT-${COMMENT}-${DEVICE}" if test "$1" = "--removeall";then eval "$(iptables -S | grep "comment ${COMMENT}" | sed -e 's/-A/-D/g' -e 's/^-/iptables -/g')" eval "$(ip6tables -S | grep "comment ${COMMENT}" | sed -e 's/-A/-D/g' -e 's/^-/ip6tables -/g')" + + #delete chains + eval "$(iptables -S | grep "INPUT-${COMMENT}" | sed -e 's/-N/-X/g' -e 's/^-/iptables -/g')" + eval "$(ip6tables -S | grep "INPUT-${COMMENT}" | sed -e 's/-N/-X/g' -e 's/^-/ip6tables -/g')" exit 0 fi +execute_next_script() { + if test -n "${OCSERV_NEXT_SCRIPT}";then + TMP_SCRIPT="${OCSERV_NEXT_SCRIPT}" + unset OCSERV_NEXT_SCRIPT + /bin/sh "${TMP_SCRIPT}" + fi +} + +clean_all_rules() { + eval "$(iptables -S | grep "comment ${COMMENT}" | grep -e "-[io] ${DEVICE}" | sed -e 's/-A/-D/g' -e 's/^-/iptables -/g')" 2>/dev/null + eval "$(ip6tables -S | grep "comment ${COMMENT}" | grep -e "-[io] ${DEVICE}" | sed -e 's/-A/-D/g' -e 's/^-/ip6tables -/g')" 2>/dev/null + iptables -X ${SEC_INPUT_CHAIN} 2>/dev/null + ip6tables -X ${SEC_INPUT_CHAIN} 2>/dev/null +} + if test "${REASON}" = "connect";then MOD="-A" - #clear any leftover rules for thus device - eval "$(iptables -S | grep "comment ${COMMENT}" | grep -e "-[io] ${DEVICE}" | sed -e 's/-A/-D/g' -e 's/^-/iptables -/g')" 2>/dev/null - eval "$(ip6tables -S | grep "comment ${COMMENT}" | grep -e "-[io] ${DEVICE}" | sed -e 's/-A/-D/g' -e 's/^-/ip6tables -/g')" 2>/dev/null + #clear any leftover rules for this device + clean_all_rules else if test "${REASON}" = "disconnect";then - MOD="-D" + clean_all_rules + set -e + execute_next_script + exit 0 else logger -t ocserv-fw "unknown reason ${REASON}" exit 1 @@ -28,11 +51,11 @@ fi set -e allow_dns() { - "$1" ${MOD} INPUT -i ${DEVICE} -p udp -d "$2" --dport 53 -j ACCEPT --match comment --comment "${COMMENT}" - "$1" ${MOD} OUTPUT -o ${DEVICE} -p udp -s "$2" --sport 53 -j ACCEPT --match comment --comment "${COMMENT}" + "$1" -A ${INPUT_CHAIN} -i ${DEVICE} -p udp -d "$2" --dport 53 -j ACCEPT --match comment --comment "${COMMENT}" + "$1" -A OUTPUT -o ${DEVICE} -p udp -s "$2" --sport 53 -j ACCEPT --match comment --comment "${COMMENT}" - "$1" ${MOD} INPUT -i ${DEVICE} -p tcp -d "$2" --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT --match comment --comment "${COMMENT}" - "$1" ${MOD} OUTPUT -o ${DEVICE} -p tcp -s "$2" --sport 53 -m state --state ESTABLISHED -j ACCEPT --match comment --comment "${COMMENT}" + "$1" -A ${INPUT_CHAIN} -i ${DEVICE} -p tcp -d "$2" --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT --match comment --comment "${COMMENT}" + "$1" -A OUTPUT -o ${DEVICE} -p tcp -s "$2" --sport 53 -m state --state ESTABLISHED -j ACCEPT --match comment --comment "${COMMENT}" } allow_dns4() { @@ -44,8 +67,8 @@ allow_dns6() { } allow_route() { - "$1" ${MOD} INPUT -i ${DEVICE} -s "$2" -j ACCEPT --match comment --comment "${COMMENT}" - "$1" ${MOD} OUTPUT -o ${DEVICE} -d "$2" -j ACCEPT --match comment --comment "${COMMENT}" + "$1" -A ${INPUT_CHAIN} -i ${DEVICE} -s "$2" -j ACCEPT --match comment --comment "${COMMENT}" + "$1" -A OUTPUT -o ${DEVICE} -d "$2" -j ACCEPT --match comment --comment "${COMMENT}" } allow_route4() { @@ -57,8 +80,8 @@ allow_route6() { } disallow_route() { - "$1" ${MOD} INPUT -i ${DEVICE} -s "$2" -j DROP --match comment --comment "${COMMENT}" - "$1" ${MOD} OUTPUT -o ${DEVICE} -d "$2" -j DROP --match comment --comment "${COMMENT}" + "$1" -A ${INPUT_CHAIN} -i ${DEVICE} -s "$2" -j DROP --match comment --comment "${COMMENT}" + "$1" -A OUTPUT -o ${DEVICE} -d "$2" -j DROP --match comment --comment "${COMMENT}" } disallow_route4() { @@ -70,17 +93,40 @@ disallow_route6() { } disallow_all() { - iptables ${MOD} INPUT -i ${DEVICE} -j DROP --match comment --comment "${COMMENT}" - iptables ${MOD} OUTPUT -o ${DEVICE} -j DROP --match comment --comment "${COMMENT}" - ip6tables ${MOD} INPUT -i ${DEVICE} -j DROP --match comment --comment "${COMMENT}" - ip6tables ${MOD} OUTPUT -o ${DEVICE} -j DROP --match comment --comment "${COMMENT}" + iptables -A ${INPUT_CHAIN} -i ${DEVICE} -j DROP --match comment --comment "${COMMENT}" + iptables -A OUTPUT -o ${DEVICE} -j DROP --match comment --comment "${COMMENT}" + ip6tables -A ${INPUT_CHAIN} -i ${DEVICE} -j DROP --match comment --comment "${COMMENT}" + ip6tables -A OUTPUT -o ${DEVICE} -j DROP --match comment --comment "${COMMENT}" } allow_all() { - iptables ${MOD} INPUT -i ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}" - iptables ${MOD} OUTPUT -o ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}" - ip6tables ${MOD} INPUT -i ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}" - ip6tables ${MOD} OUTPUT -o ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}" + iptables -A ${INPUT_CHAIN} -i ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}" + iptables -A OUTPUT -o ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}" + ip6tables -A ${INPUT_CHAIN} -i ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}" + ip6tables -A OUTPUT -o ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}" +} + +allow_port() { + proto=$1 + port=$2 + + case "$proto" in + icmp) + iptables -A INPUT -i ${DEVICE} -p $proto -j ${INPUT_CHAIN} --match comment --comment "${COMMENT}" + ;; + icmpv6) + ip6tables -A INPUT -i ${DEVICE} -p $proto -j ${INPUT_CHAIN} --match comment --comment "${COMMENT}" + ;; + *) + iptables -A INPUT -i ${DEVICE} -p $proto --dport $port -j ${INPUT_CHAIN} --match comment --comment "${COMMENT}" + ip6tables -A INPUT -i ${DEVICE} -p $proto --dport $port -j ${INPUT_CHAIN} --match comment --comment "${COMMENT}" + ;; + esac +} + +disallow_all_ports() { + iptables -A INPUT -i ${DEVICE} -j REJECT --match comment --comment "${COMMENT}" + ip6tables -A INPUT -i ${DEVICE} -j REJECT --match comment --comment "${COMMENT}" } # Allow DNS lookups @@ -88,38 +134,58 @@ for i in $OCSERV_DNS4;do allow_dns4 $i done +# block or allow routes for i in $OCSERV_DNS6;do allow_dns6 $i done -for i in $OCSERV_NO_ROUTES4;do - disallow_route4 $i -done +# block ports - if needed +if test -n "${OCSERV_PORTS}";then + INPUT_CHAIN="${SEC_INPUT_CHAIN}" + iptables -N "${INPUT_CHAIN}" + ip6tables -N "${INPUT_CHAIN}" -for i in $OCSERV_NO_ROUTES6;do - disallow_route6 $i -done + set ${OCSERV_PORTS} + while test $# -gt 1; do + proto=$1 + port=$2 -if test -n "$OCSERV_ROUTES";then - - for i in $OCSERV_ROUTES4;do - allow_route4 $i + allow_port $proto $port + if test $# -gt 1;then + shift 2 + else + break + fi done - - for i in $OCSERV_ROUTES6;do - allow_route6 $i - done - - # no default route, don't allow anything except the configured routes - disallow_all -else - allow_all + disallow_all_ports fi -if test -n "${OCSERV_NEXT_SCRIPT}";then - TMP_SCRIPT="${OCSERV_NEXT_SCRIPT}" - unset OCSERV_NEXT_SCRIPT - /bin/sh "${TMP_SCRIPT}" +if test "${OCSERV_RESTRICT_TO_ROUTES}" = "1";then + for i in $OCSERV_NO_ROUTES4;do + disallow_route4 $i + done + + for i in $OCSERV_NO_ROUTES6;do + disallow_route6 $i + done + + if test -n "$OCSERV_ROUTES";then + + for i in $OCSERV_ROUTES4;do + allow_route4 $i + done + + for i in $OCSERV_ROUTES6;do + allow_route6 $i + done + + # no default route, don't allow anything except the configured routes + disallow_all + else + allow_all + fi fi +execute_next_script + exit 0 diff --git a/src/sup-config/file.c b/src/sup-config/file.c index cad2ffb5..199a2767 100644 --- a/src/sup-config/file.c +++ b/src/sup-config/file.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Nikos Mavrogiannopoulos - * Copyright (C) 2014 Red Hat, Inc. + * Copyright (C) 2014, 2015 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 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -64,6 +65,7 @@ static struct cfg_options available_options[] = { { .name = "ipv6-subnet-prefix", .type = OPTION_NUMERIC }, { .name = "explicit-ipv4", .type = OPTION_STRING }, { .name = "explicit-ipv6", .type = OPTION_STRING }, + { .name = "restrict-user-to-ports", .type = OPTION_STRING }, { .name = "rx-data-per-sec", .type = OPTION_NUMERIC }, { .name = "tx-data-per-sec", .type = OPTION_NUMERIC }, { .name = "net-priority", .type = OPTION_STRING }, @@ -138,7 +140,7 @@ static struct cfg_options available_options[] = { static int handle_option(const tOptionValue* val) { -unsigned j; + unsigned j; for (j=0;jpzName, available_options[j].name) == 0) { @@ -149,6 +151,7 @@ unsigned j; return 0; } + /* This will parse the configuration file and append/replace data into * config. The provided config must either be memset to zero, or be * already allocated using this function. @@ -160,6 +163,7 @@ int parse_group_cfg_file(struct cfg_st *global_config, { tOptionValue const * pov; const tOptionValue* val, *prev; +char *tmp; unsigned prefix = 0; int ret; unsigned j; @@ -272,6 +276,16 @@ unsigned j; READ_RAW_STRING("user-profile", msg->config->xml_config_file); + tmp = NULL; + READ_RAW_STRING("restrict-user-to-ports", tmp); + if (tmp) { + ret = cfg_parse_ports(pool, &msg->config->fw_ports, &msg->config->n_fw_ports, tmp); + if (ret < 0) { + goto fail; + } + talloc_free(tmp); + } + ret = 0; fail: optionUnloadNested(pov); diff --git a/src/vpn.h b/src/vpn.h index e2682940..eb32a996 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -34,6 +34,8 @@ #include #include +#include + #ifdef __GNUC__ # define _OCSERV_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) # if _OCSERV_GCC_VERSION >= 30000 @@ -63,7 +65,9 @@ typedef enum fw_proto_t { PROTO_UDP, PROTO_TCP, PROTO_SCTP, - PROTO_ALL + PROTO_ESP, + PROTO_ICMP, + PROTO_ICMPv6 } fw_proto_t; /* Banning works with a point system. A wrong password @@ -363,6 +367,9 @@ struct cfg_st { char **known_iroutes; size_t known_iroutes_size; + FwPortSt **fw_ports; + size_t n_fw_ports; + /* the tun network */ struct vpn_st network; };