From 62a1913e00b420e80735663d215984a9d4a5c32b Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 21 Jun 2023 13:55:36 +0200 Subject: [PATCH] Add experimental option --tun Switch from pppd/ppp to a tun device and internal PPP code. --- src/config.c | 1 + src/config.h | 1 + src/http.c | 2 +- src/io.c | 8 ++++---- src/main.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/tunnel.c | 5 ++--- src/tunnel.h | 1 - 7 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/config.c b/src/config.c index 7257e269..b3eee897 100644 --- a/src/config.c +++ b/src/config.c @@ -51,6 +51,7 @@ const struct vpn_config invalid_cfg = { .no_ftm_push = -1, .pinentry = NULL, .realm = {'\0'}, + .tun = -1, .iface_name = {'\0'}, .set_routes = -1, .set_dns = -1, diff --git a/src/config.h b/src/config.h index 445d89c3..1a7bc97b 100644 --- a/src/config.h +++ b/src/config.h @@ -95,6 +95,7 @@ struct vpn_config { unsigned int otp_delay; int no_ftm_push; char *pinentry; + int tun; char iface_name[IF_NAMESIZE]; char realm[REALM_SIZE + 1]; diff --git a/src/http.c b/src/http.c index 7a9212d6..4e31d41a 100644 --- a/src/http.c +++ b/src/http.c @@ -833,7 +833,7 @@ static int parse_xml_config(struct tunnel *tunnel, const char *buffer) if (!gateway) log_warn("No gateway address, using interface for routing\n"); - if (tunnel->use_tun) { + if (tunnel->config->tun) { tunnel->ipv4.ip_addr.s_addr = inet_addr(gateway); tunnel->ipv4.peer_addr.s_addr = inet_addr("192.0.2.1"); } diff --git a/src/io.c b/src/io.c index cabb10b8..3122c16d 100644 --- a/src/io.c +++ b/src/io.c @@ -1087,7 +1087,7 @@ static void *pppd_read(void *arg) log_debug("%s thread\n", __func__); - if (tunnel->use_tun) { + if (tunnel->config->tun) { switch (tunnel->tun_state) { case TUN_PPP_LCP: conf_request(tunnel); @@ -1124,7 +1124,7 @@ static void *pppd_read(void *arg) SEM_POST(&sem_pppd_ready); first_time = 0; } - if (tunnel->use_tun) { + if (tunnel->config->tun) { ssize_t pktsize = n + 2; struct ppp_packet *packet = NULL; @@ -1237,7 +1237,7 @@ static void *pppd_write(void *arg) // This waits until a packet has arrived from the gateway packet = pool_pop(&tunnel->ssl_to_pty_pool); - if (tunnel->use_tun) { + if (tunnel->config->tun) { void *pkt_type = pkt_data(packet); hdlc_bufsize = len = packet->len; @@ -1455,7 +1455,7 @@ static void *ssl_read(void *arg) set_tunnel_ips(tunnel, packet); - if (tunnel->use_tun) + if (tunnel->config->tun) tun_ifup(tunnel->tun_iface, tunnel->ipv4.ip_addr.s_addr, 0); strcpy(line, "["); diff --git a/src/main.c b/src/main.c index 4ebefc98..62067cb3 100644 --- a/src/main.c +++ b/src/main.c @@ -81,7 +81,7 @@ " [--cookie=] [--cookie-on-stdin]\n" \ " [--otp=] [--otp-delay=] [--otp-prompt=]\n" \ " [--pinentry=] [--realm=]\n" \ -" [--ifname=] [--set-routes=<0|1>]\n" \ +" [--tun=<0|1>] [--ifname=] [--set-routes=<0|1>]\n" \ " [--half-internet-routes=<0|1>] [--set-dns=<0|1>]\n" \ PPPD_USAGE \ " " RESOLVCONF_USAGE "[--ca-file=]\n" \ @@ -124,6 +124,7 @@ PPPD_USAGE \ " --no-ftm-push Do not use FTM push if the server provides the option.\n" \ " --pinentry= Use the program to supply a secret instead of asking for it.\n" \ " --realm= Use specified authentication realm.\n" \ +" --tun=[01] Create a TUN device and use internal PPP code (experimental).\n" \ " --ifname= Bind to interface.\n" \ " --set-routes=[01] Set if openfortivpn should configure routes\n" \ " when tunnel is up.\n" \ @@ -284,6 +285,7 @@ int main(int argc, char **argv) {"otp-prompt", required_argument, NULL, 0}, {"otp-delay", required_argument, NULL, 0}, {"no-ftm-push", no_argument, &cli_cfg.no_ftm_push, 1}, + {"tun", required_argument, NULL, 0}, {"ifname", required_argument, NULL, 0}, {"set-routes", required_argument, NULL, 0}, {"no-routes", no_argument, &cli_cfg.set_routes, 0}, @@ -489,6 +491,18 @@ int main(int argc, char **argv) cli_cfg.otp_prompt = strdup(optarg); break; } + if (strcmp(long_options[option_index].name, + "tun") == 0) { + int tun = strtob(optarg); + + if (tun < 0) { + log_warn("Bad tun option: \"%s\"\n", + optarg); + break; + } + cli_cfg.tun = tun; + break; + } if (strcmp(long_options[option_index].name, "ifname") == 0) { strncpy(cli_cfg.iface_name, optarg, IF_NAMESIZE - 1); @@ -646,6 +660,41 @@ int main(int argc, char **argv) merge_config(&cfg, &cli_cfg); set_syslog(cfg.use_syslog); + if (cfg.tun) { +#if HAVE_USR_SBIN_PPPD + if (cfg.pppd_use_peerdns) { + log_error("Option pppd_use_peerdns is not compatible with option tun\n"); + exit(EXIT_FAILURE); + } + if (cfg.pppd_plugin) { + log_error("Option pppd_plugin is not compatible with option tun\n"); + exit(EXIT_FAILURE); + } + if (cfg.pppd_ifname) { + log_error("Option pppd_ifname is not compatible with option tun\n"); + exit(EXIT_FAILURE); + } + if (cfg.pppd_ipparam) { + log_error("Option pppd_ipparam is not compatible with option tun\n"); + exit(EXIT_FAILURE); + } + if (cfg.pppd_call) { + log_error("Option pppd_call is not compatible with option tun\n"); + exit(EXIT_FAILURE); + } + if (cfg.pppd_plugin) { + log_error("Option pppd_plugin is not compatible with option tun\n"); + exit(EXIT_FAILURE); + } +#endif +#if HAVE_USR_SBIN_PPP + if (cfg.ppp_system) { + log_error("Option ppp_system is not compatible with option tun\n"); + exit(EXIT_FAILURE); + } +#endif + } + // Set default UA if (cfg.user_agent == NULL) cfg.user_agent = strdup("Mozilla/5.0 SV1"); diff --git a/src/tunnel.c b/src/tunnel.c index 036c487c..ac9c2403 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -1481,7 +1481,6 @@ int run_tunnel(struct vpn_config *config) goto err_tunnel; // Step 3: get configuration - tunnel.use_tun = 1; log_info("Retrieving configuration\n"); ret = auth_get_config(&tunnel); if (ret != 1) { @@ -1493,7 +1492,7 @@ int run_tunnel(struct vpn_config *config) // Step 4: run a pppd process log_info("Establishing the tunnel\n"); - if (tunnel.use_tun) + if (config->tun) ret = tun_setup(&tunnel); else ret = pppd_run(&tunnel); @@ -1526,7 +1525,7 @@ int run_tunnel(struct vpn_config *config) tunnel.state = STATE_DISCONNECTING; err_start_tunnel: - if (!tunnel.use_tun) { + if (!config->tun) { ret = pppd_terminate(&tunnel); log_info("Terminated %s.\n", PPP_DAEMON); } diff --git a/src/tunnel.h b/src/tunnel.h index bc900f80..6cca06d4 100644 --- a/src/tunnel.h +++ b/src/tunnel.h @@ -72,7 +72,6 @@ struct tunnel { pid_t pppd_pid; pid_t pppd_pty; - int use_tun; char tun_iface[ROUTE_IFACE_LEN]; char ppp_iface[ROUTE_IFACE_LEN];