From f9dbb56db06ea784f7a087cabfb11b88a433d87e Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Wed, 5 Feb 2025 21:55:38 +0100 Subject: [PATCH 1/2] Add support for ifup hook. --- doc/openfortivpn.1.in | 9 +++++++++ src/config.c | 8 ++++++++ src/config.h | 1 + src/main.c | 10 ++++++++++ src/tunnel.c | 10 ++++++++++ 5 files changed, 38 insertions(+) diff --git a/doc/openfortivpn.1.in b/doc/openfortivpn.1.in index 797270aa..cc922523 100644 --- a/doc/openfortivpn.1.in +++ b/doc/openfortivpn.1.in @@ -33,6 +33,7 @@ openfortivpn \- Client for PPP+TLS VPN tunnel services [\fB\-\-cipher\-list=\fI\fR] [\fB\-\-min\-tls=\fI\fR] [\fB\-\-seclevel\-1\fR] +[\fB\-\-ifup\-hook=\fI\fR] [\fB\-\-pppd\-use\-peerdns=\fI\fR] [\fB\-\-pppd\-no\-peerdns\fR] [\fB\-\-pppd\-log=\fI\fR] @@ -207,6 +208,10 @@ ciphers. This lowers limits on dh key. \fBApplies to TLS v1.2 or lower only.\fR .TP +\fB\-\-ifup\-hook=\fI\fR +Execute the supplied command once the tunnel has been established and +routes and DNS have been configured (if applicable). +.TP \fB\-\-pppd\-use\-peerdns=\fI\fR, \fB\-\-pppd\-no\-peerdns\fR Whether to ask peer ppp server for DNS server addresses and let pppd rewrite /etc/resolv.conf. There is no mechanism to tell the dns\-suffix @@ -400,6 +405,10 @@ cipher\-list = HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4 persistent = 0 .br seclevel-1 = 0 +.br +# Invoke command once the tunnel has been established. +.br +# ifup-hook = command .SH SEE ALSO diff --git a/src/config.c b/src/config.c index d1e33ad2..1cb49b00 100644 --- a/src/config.c +++ b/src/config.c @@ -84,6 +84,7 @@ const struct vpn_config invalid_cfg = { .cipher_list = NULL, .min_tls = -1, .seclevel_1 = -1, + .ifup_hook = NULL, .cert_whitelist = NULL, .use_engine = -1, .user_agent = NULL, @@ -476,6 +477,9 @@ int load_config(struct vpn_config *cfg, const char *filename) } else if (strcmp(key, "check-virtual-desktop") == 0) { free(cfg->check_virtual_desktop); cfg->check_virtual_desktop = strdup(val); + } else if (strcmp(key, "ifup-hook") == 0) { + free(cfg->ifup_hook); + cfg->ifup_hook = strdup(val); } else { log_warn("Bad key in configuration file: \"%s\".\n", key); goto err_free; @@ -630,6 +634,10 @@ void merge_config(struct vpn_config *dst, struct vpn_config *src) dst->min_tls = src->min_tls; if (src->seclevel_1 != invalid_cfg.seclevel_1) dst->seclevel_1 = src->seclevel_1; + if (src->ifup_hook) { + free(dst->ifup_hook); + dst->ifup_hook = src->ifup_hook; + } if (src->cert_whitelist) { while (dst->cert_whitelist != NULL) { struct x509_digest *tmp = dst->cert_whitelist->next; diff --git a/src/config.h b/src/config.h index 50781e3f..52f07489 100644 --- a/src/config.h +++ b/src/config.h @@ -138,6 +138,7 @@ struct vpn_config { char *user_agent; char *hostcheck; char *check_virtual_desktop; + char *ifup_hook; }; int add_trusted_cert(struct vpn_config *cfg, const char *digest); diff --git a/src/main.c b/src/main.c index 4acf60fe..e10f807f 100644 --- a/src/main.c +++ b/src/main.c @@ -168,6 +168,9 @@ PPPD_USAGE \ " --seclevel-1 If --cipher-list is not specified, add @SECLEVEL=1 to\n" \ " (compiled in) list of ciphers. This lowers limits on\n" \ " dh key." help_seclevel_1 "\n" \ +" --ifup-hook= Execute the supplied command once the tunnel has been\n" \ +" established and routes and DNS have been configured (if\n" \ +" applicable).\n" \ " --persistent= Run the vpn persistently in a loop and try to re-\n" \ " connect every seconds when dropping out.\n" \ " -v Increase verbosity. Can be used multiple times\n" \ @@ -313,6 +316,7 @@ int main(int argc, char *argv[]) {"cipher-list", required_argument, NULL, 0}, {"min-tls", required_argument, NULL, 0}, {"seclevel-1", no_argument, &cli_cfg.seclevel_1, 1}, + {"ifup-hook", required_argument, NULL, 0}, #if HAVE_USR_SBIN_PPPD {"pppd-use-peerdns", required_argument, NULL, 0}, {"pppd-no-peerdns", no_argument, &cli_cfg.pppd_use_peerdns, 0}, @@ -513,6 +517,12 @@ int main(int argc, char *argv[]) } break; } + if (strcmp(long_options[option_index].name, + "ifup-hook") == 0) { + free(cli_cfg.ifup_hook); + cli_cfg.ifup_hook = strdup(optarg); + break; + } if (strcmp(long_options[option_index].name, "otp-prompt") == 0) { free(cli_cfg.otp_prompt); diff --git a/src/tunnel.c b/src/tunnel.c index 667410e6..c0d19396 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -65,6 +65,7 @@ #include #include #include +#include struct ofv_varr { @@ -125,6 +126,15 @@ static int on_ppp_if_up(struct tunnel *tunnel) ipv4_add_nameservers_to_resolv_conf(tunnel); } + if (tunnel->config->ifup_hook) { + log_info("Executing ifup hook...\n"); + + int code = system(tunnel->config->ifup_hook); + if (code != 0) { + log_warn("ifup hook failed with exit code %i\n", code); + } + } + log_info("Tunnel is up and running.\n"); #if HAVE_SYSTEMD From cd832dd6c23468f03e651b25bc4a8719decbe44e Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Wed, 5 Feb 2025 22:11:20 +0100 Subject: [PATCH 2/2] Code style. --- src/main.c | 2 +- src/tunnel.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index e10f807f..8aec1046 100644 --- a/src/main.c +++ b/src/main.c @@ -518,7 +518,7 @@ int main(int argc, char *argv[]) break; } if (strcmp(long_options[option_index].name, - "ifup-hook") == 0) { + "ifup-hook") == 0) { free(cli_cfg.ifup_hook); cli_cfg.ifup_hook = strdup(optarg); break; diff --git a/src/tunnel.c b/src/tunnel.c index c0d19396..ad09e044 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -128,11 +128,11 @@ static int on_ppp_if_up(struct tunnel *tunnel) if (tunnel->config->ifup_hook) { log_info("Executing ifup hook...\n"); - + int code = system(tunnel->config->ifup_hook); - if (code != 0) { + + if (code != 0) log_warn("ifup hook failed with exit code %i\n", code); - } } log_info("Tunnel is up and running.\n");