diff --git a/src/config.c b/src/config.c index 87469854..0772294b 100644 --- a/src/config.c +++ b/src/config.c @@ -59,6 +59,7 @@ const struct vpn_config invalid_cfg = { #endif .use_syslog = -1, .half_internet_routes = -1, + .set_default_route = -1, .persistent = -1, #if HAVE_USR_SBIN_PPPD .pppd_log = NULL, @@ -320,6 +321,15 @@ int load_config(struct vpn_config *cfg, const char *filename) continue; } cfg->half_internet_routes = half_internet_routes; + } else if (strcmp(key, "set-default-route") == 0) { + int set_default_route = strtob(val); + + if (set_default_route < 0) { + log_warn("Bad set_default_route in config file: \"%s\".\n", + val); + continue; + } + cfg->set_default_route = set_default_route; } else if (strcmp(key, "persistent") == 0) { unsigned long persistent = strtoul(val, NULL, 0); @@ -528,6 +538,8 @@ void merge_config(struct vpn_config *dst, struct vpn_config *src) dst->use_syslog = src->use_syslog; if (src->half_internet_routes != invalid_cfg.half_internet_routes) dst->half_internet_routes = src->half_internet_routes; + if (src->set_default_route != invalid_cfg.set_default_route) + dst->set_default_route = src->set_default_route; if (src->persistent != invalid_cfg.persistent) dst->persistent = src->persistent; #if HAVE_USR_SBIN_PPPD diff --git a/src/config.h b/src/config.h index c27b8dfd..d5e02335 100644 --- a/src/config.h +++ b/src/config.h @@ -97,6 +97,7 @@ struct vpn_config { int use_resolvconf; #endif int half_internet_routes; + int set_default_route; unsigned int persistent; diff --git a/src/ipv4.c b/src/ipv4.c index 0e473d86..f4f7d34c 100644 --- a/src/ipv4.c +++ b/src/ipv4.c @@ -884,6 +884,7 @@ int ipv4_add_split_vpn_route(struct tunnel *tunnel, char *dest, char *mask, static int ipv4_set_split_routes(struct tunnel *tunnel) { int i; + struct vpn_config *cfg = tunnel->config; for (i = 0; i < tunnel->ipv4.split_routes; i++) { struct rtentry *route; @@ -901,10 +902,19 @@ static int ipv4_set_split_routes(struct tunnel *tunnel) route_iface(route) = strdup(tunnel->ppp_iface); if (!route_iface(route)) return ERR_IPV4_NO_MEM; + // in case of manually configured default route into the server, and default route disabled, ignore + if (!cfg->set_default_route && route_dest(route).s_addr == 0) + continue; if (route_gtw(route).s_addr == tunnel->ipv4.ip_addr.s_addr) route_gtw(route).s_addr = 0; - if (route_gtw(route).s_addr == 0) + if (route_gtw(route).s_addr == 0) { + // when default route disabled, gateway must be set. + // use the local address instead of remote gateway to avoid trouble + // with vpn dup configurations + if (!cfg->set_default_route) + route_gtw(route).s_addr = tunnel->ipv4.ip_addr.s_addr; route->rt_flags &= ~RTF_GATEWAY; + } if (route_gtw(route).s_addr != 0) route->rt_flags |= RTF_GATEWAY; ret = ipv4_set_route(route); @@ -1000,15 +1010,20 @@ static int ipv4_set_default_routes(struct tunnel *tunnel) int ipv4_set_tunnel_routes(struct tunnel *tunnel) { - int ret = ipv4_protect_tunnel_route(tunnel); + int ret = 0; + struct vpn_config *cfg = tunnel->config; + + if (cfg->set_default_route) + ret = ipv4_protect_tunnel_route(tunnel); if (tunnel->ipv4.split_routes) // try even if ipv4_protect_tunnel_route has failed return ipv4_set_split_routes(tunnel); - else if (ret == 0) - return ipv4_set_default_routes(tunnel); - else - return ret; + else if (ret == 0) { + if (cfg->set_default_route) + return ipv4_set_default_routes(tunnel); + } + return ret; } int ipv4_restore_routes(struct tunnel *tunnel) @@ -1034,10 +1049,12 @@ int ipv4_restore_routes(struct tunnel *tunnel) // Restore the default route. It seems not to be // automatically restored on all linux distributions - ret = ipv4_set_route(def_rt); - if (ret != 0) { - log_warn("Could not restore default route (%s). Already restored?\n", - err_ipv4_str(ret)); + if (cfg->set_default_route) { + ret = ipv4_set_route(def_rt); + if (ret != 0) { + log_warn("Could not restore default route (%s). Already restored?\n", + err_ipv4_str(ret)); + } } } } else { diff --git a/src/main.c b/src/main.c index 1415fb81..a0bf7906 100644 --- a/src/main.c +++ b/src/main.c @@ -86,6 +86,7 @@ PPPD_USAGE \ " [--user-cert=] [--user-key=]\n" \ " [--trusted-cert=] [--use-syslog]\n" \ " [--persistent=] [-c ] [-v|-q]\n" \ +" [--set-default-route=<0|1>]" \ " openfortivpn --help\n" \ " openfortivpn --version\n" \ "\n" @@ -122,6 +123,8 @@ PPPD_USAGE \ " --realm= Use specified authentication realm.\n" \ " --set-routes=[01] Set if openfortivpn should configure routes\n" \ " when tunnel is up.\n" \ +" --set-default-route=[01] Configure the default route through the VPN when set to 1\n" \ +" Default is 1.\n" \ " --no-routes Do not configure routes, same as --set-routes=0.\n" \ " --half-internet-routes=[01] Add two 0.0.0.0/1 and 128.0.0.0/1 routes with higher\n" \ " priority instead of replacing the default route.\n" \ @@ -205,6 +208,7 @@ int main(int argc, char **argv) .set_dns = 1, .use_syslog = 0, .half_internet_routes = 0, + .set_default_route = 1, .persistent = 0, #if HAVE_RESOLVCONF .use_resolvconf = USE_RESOLVCONF, @@ -252,6 +256,7 @@ int main(int argc, char **argv) {"set-routes", required_argument, NULL, 0}, {"no-routes", no_argument, &cli_cfg.set_routes, 0}, {"half-internet-routes", required_argument, NULL, 0}, + {"set-default-route", required_argument, NULL, 0}, {"set-dns", required_argument, NULL, 0}, {"no-dns", no_argument, &cli_cfg.set_dns, 0}, {"use-syslog", no_argument, &cli_cfg.use_syslog, 1}, @@ -454,6 +459,18 @@ int main(int argc, char **argv) cli_cfg.half_internet_routes = half_internet_routes; break; } + if (strcmp(long_options[option_index].name, + "set-default-route") == 0) { + int set_default_route = strtob(optarg); + + if (set_default_route < 0) { + log_warn("Bad set-default-route option: \"%s\"\n", + optarg); + break; + } + cli_cfg.set_default_route = set_default_route; + break; + } if (strcmp(long_options[option_index].name, "otp-delay") == 0) { long otp_delay = strtol(optarg, NULL, 0);