Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --pppd-call option. #270

Merged
merged 7 commits into from
Apr 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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