Skip to content

Commit

Permalink
Add experimental option --tun
Browse files Browse the repository at this point in the history
Switch from pppd/ppp to a tun device and internal PPP code.
  • Loading branch information
DimitriPapadopoulos committed Mar 3, 2024
1 parent 4f710c8 commit e8921f2
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const struct vpn_config invalid_cfg = {
.no_ftm_push = -1,
.pinentry = NULL,
.realm = {'\0'},
.tun = -1,
.iface_name = {'\0'},
.sni = {'\0'},
.set_routes = -1,
Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
2 changes: 1 addition & 1 deletion src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,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");
}
Expand Down
8 changes: 4 additions & 4 deletions src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,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);
Expand Down Expand Up @@ -1120,7 +1120,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;

Expand Down Expand Up @@ -1233,7 +1233,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;
Expand Down Expand Up @@ -1451,7 +1451,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, "[");
Expand Down
51 changes: 50 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
" [--cookie=<cookie>] [--cookie-on-stdin]\n" \
" [--otp=<otp>] [--otp-delay=<delay>] [--otp-prompt=<prompt>]\n" \
" [--pinentry=<program>] [--realm=<realm>]\n" \
" [--ifname=<ifname>] [--set-routes=<0|1>]\n" \
" [--tun=<0|1>] [--ifname=<ifname>] [--set-routes=<0|1>]\n" \
" [--half-internet-routes=<0|1>] [--set-dns=<0|1>]\n" \
PPPD_USAGE \
" " RESOLVCONF_USAGE "[--ca-file=<file>]\n" \
Expand Down Expand Up @@ -123,6 +123,7 @@ PPPD_USAGE \
" --no-ftm-push Do not use FTM push if the server provides the option.\n" \
" --pinentry=<program> Use the program to supply a secret instead of asking for it.\n" \
" --realm=<realm> Use specified authentication realm.\n" \
" --tun=[01] Create a TUN device and use internal PPP code (experimental).\n" \
" --ifname=<interface> Bind to interface.\n" \
" --set-routes=[01] Set if openfortivpn should configure routes\n" \
" when tunnel is up.\n" \
Expand Down Expand Up @@ -290,6 +291,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},
{"sni", required_argument, NULL, 0},
Expand Down Expand Up @@ -514,6 +516,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);
Expand Down Expand Up @@ -677,6 +691,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");
Expand Down
5 changes: 2 additions & 3 deletions src/tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,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) {
Expand All @@ -1434,7 +1433,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);
Expand Down Expand Up @@ -1467,7 +1466,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);
}
Expand Down
1 change: 0 additions & 1 deletion src/tunnel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down

0 comments on commit e8921f2

Please sign in to comment.