Skip to content

Commit

Permalink
Add --pppd-call option. (#270)
Browse files Browse the repository at this point in the history
Add --pppd-call option.

On systems where pppd supports the "call" option --- eg. Debian derived
distros --- privileged options to pppd can be moved to a config file
owned by root, and any unprivileged user in group "dip" can invoke
openfortivpn.

Static routes and DNS settings are managed by /etc/ppp/ip-up.local and
/etc/ppp/ip-down.local scripts, provided the following lines are added
to /etc/openfortivpn/config:

    set-routes = 0
    set-dns = 0
    pppd-ipparam = openfortivpn
    pppd-call = openfortivpn
  • Loading branch information
gbon121 authored and DimitriPapadopoulos committed Apr 3, 2018
1 parent 25b2585 commit a2dfcb6
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 0 deletions.
8 changes: 8 additions & 0 deletions doc/openfortivpn.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ openfortivpn \- Client for PPP+SSL VPN tunnel services
[\fB\-\-pppd-plugin=\fI<file>\fR]
[\fB\-\-pppd-ipparam=\fI<string>\fR]
[\fB\-\-pppd-ifname=\fI<string>\fR]
[\fB\-\-pppd-call=\fI<name>\fR]
[\fB\-\-persistent\fR]
[\fB\-c\fR \fI<file>\fR]
[\fB\-v|\-q\fR]
Expand Down Expand Up @@ -129,6 +130,13 @@ for further details
\fB\-\-pppd-ifname=\fI<string>\fR
Set the ppp interface name. Only if supported by pppd. Patched versions of pppd
implement this option but may not be available on your platform.
.TP
\fB\-\-pppd-call=\fI<name>\fR
Drop usual arguments from pppd command line and add `call <name>' instead.
This can be useful on Debian and Ubuntu, where unprivileged users in
group `dip' can invoke `pppd call <name>' to make pppd read and apply
options from /etc/ppp/peers/<name> (including privileged ones).
.TP
\fB\-\-persistent\=\fI<interval>fR
Runs the vpn persistently in an endless loop and tries to reconnect forever.
The reconnect interval may be specified in seconds, where 0 means
Expand Down
11 changes: 11 additions & 0 deletions etc/ppp/ip-down.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

case "$PPP_IPPARAM" in
openfortivpn*)
rconf=/etc/resolv.conf
[[ -f $rconf.openfortivpn ]] && cp -pv $rconf.openfortivpn $rconf
exit 0
;;
esac 2>&1 | logger -p daemon.debug -i -t "$0"

true
22 changes: 22 additions & 0 deletions etc/ppp/ip-up.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

case "$PPP_IPPARAM" in
openfortivpn*)
rconf=/etc/resolv.conf
routes=$(echo $PPP_IPPARAM | tr , ' ')
for r in $routes; do
[[ $r = "openfortivpn" ]] && continue
com="ip route add ${r%/*} via ${r##*/}"
echo $com
$com
done
cp -pv $rconf $rconf.openfortivpn
if [[ "$DNS1" ]]; then
echo nameserver $DNS1 > $rconf
[[ "$DNS2" ]] && [[ "$DNS1" != "$DNS2" ]] && echo nameserver $DNS2 >> $rconf
fi
exit 0
;;
esac 2>&1 | logger -p daemon.debug -i -t "$0"

true
12 changes: 12 additions & 0 deletions etc/ppp/peers/openfortivpn
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
38400
:1.1.1.1
noipdefault
noaccomp
noauth
default-asyncmap
nopcomp
receive-all
nodefaultroute
nodetach
lcp-max-configure 40
mru 1354
2 changes: 2 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ int load_config(struct vpn_config *cfg, const char *filename)
cfg->pppd_ipparam = strdup(val);
} else if (strcmp(key, "pppd-ifname") == 0) {
cfg->pppd_ifname = strdup(val);
} else if (strcmp(key, "pppd-call") == 0) {
cfg->pppd_call = strdup(val);
} else if (strcmp(key, "use-syslog") == 0) {
int use_syslog = strtob(val);
if (use_syslog < 0) {
Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct vpn_config {
char *pppd_plugin;
char *pppd_ipparam;
char *pppd_ifname;
char *pppd_call;

char *ca_file;
char *user_cert;
Expand Down
25 changes: 25 additions & 0 deletions src/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,37 @@ int ipv4_protect_tunnel_route(struct tunnel *tunnel)
return ret;
}

static void add_text_route(struct tunnel *tunnel, const char *dest,
const char *mask, const char *gw)
{
size_t l0, l1;
const char fmt[] = ",%s/%s/%s";
const char trigger[] = "openfortivpn";
char **target = &tunnel->config->pppd_ipparam;
char *ptr;

if (*target == NULL || strncmp(*target, trigger, strlen(trigger)))
return;
if (!dest || !mask || !gw)
return;
log_info("Registering route %s/%s via %s\n", dest, mask, gw);
l0 = strlen(*target);
l1 = strlen(fmt) + strlen(dest) + strlen(mask) + strlen(gw) + 1;
if ((ptr = realloc(*target, l0 + l1))) {
*target = ptr;
snprintf(*target + l0, l1, fmt, dest, mask, gw);
} else {
log_error("realloc: %s\n", strerror(errno));
}
}

int ipv4_add_split_vpn_route(struct tunnel *tunnel, char *dest, char *mask,
char *gateway)
{
struct rtentry *route;
char env_var[24];

add_text_route(tunnel, dest, mask, gateway);
if (tunnel->ipv4.split_routes == MAX_SPLIT_ROUTES)
return ERR_IPV4_NO_MEM;
if ((tunnel->ipv4.split_rt == NULL)
Expand Down
11 changes: 11 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
" [--half-internet-routes=<0|1>] [--set-dns=<0|1>]\n" \
" [--pppd-no-peerdns] [--pppd-log=<file>]\n" \
" [--pppd-ifname=<string>] [--pppd-ipparam=<string>]\n" \
" [--pppd-call=<name>]\n" \
" [--pppd-plugin=<file>] [--ca-file=<file>]\n" \
" [--user-cert=<file>] [--user-key=<file>]\n" \
" [--trusted-cert=<digest>] [--use-syslog]\n" \
Expand Down Expand Up @@ -94,6 +95,9 @@
" --pppd-ifname=<string> Set the pppd interface name, if supported by pppd.\n" \
" --pppd-ipparam=<string> Provides an extra parameter to the ip-up, ip-pre-up\n" \
" and ip-down scripts. See man (8) pppd\n" \
" --pppd-call=<name> Move most pppd options from pppd cmdline to\n" \
" /etc/ppp/peers/<name> and invoke pppd with\n" \
" 'call <name>'\n" \
" --persistent=<interval> Run the vpn persistently in a loop and try to re-\n" \
" connect every <interval> seconds when dropping out\n" \
" -v Increase verbosity. Can be used multiple times\n" \
Expand Down Expand Up @@ -160,6 +164,7 @@ int main(int argc, char **argv)
.pppd_log = NULL,
.pppd_plugin = NULL,
.pppd_ipparam = NULL,
.pppd_call = NULL,
.ca_file = NULL,
.user_cert = NULL,
.user_key = NULL,
Expand Down Expand Up @@ -195,6 +200,7 @@ int main(int argc, char **argv)
{"pppd-plugin", required_argument, 0, 0},
{"pppd-ipparam", required_argument, 0, 0},
{"pppd-ifname", required_argument, 0, 0},
{"pppd-call", required_argument, 0, 0},
{"plugin", required_argument, 0, 0}, // deprecated
{0, 0, 0, 0}
};
Expand Down Expand Up @@ -243,6 +249,11 @@ int main(int argc, char **argv)
cfg.pppd_ipparam = strdup(optarg);
break;
}
if (strcmp(long_options[option_index].name,
"pppd-call") == 0) {
cfg.pppd_call = strdup(optarg);
break;
}
// --plugin is deprecated, --pppd-plugin should be used
if (cfg.pppd_plugin == NULL &&
strcmp(long_options[option_index].name,
Expand Down
10 changes: 10 additions & 0 deletions src/tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ static int pppd_run(struct tunnel *tunnel)
NULL // terminal null pointer required by execvp()
};

if (tunnel->config->pppd_call) {
/* overwrite args[]: keep pppd_path, replace all
* options with "call <name>" */
int j = 1;
args[j++] = "call";
args[j++] = tunnel->config->pppd_call;
while (j < ARRAY_SIZE(args))
args[j++] = NULL;
}

// Dynamically get first NULL pointer so that changes of
// args above don't need code changes here
int i = ARRAY_SIZE(args) - 1;
Expand Down

0 comments on commit a2dfcb6

Please sign in to comment.