From patchwork Tue May 31 05:17:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maximilian Fillinger X-Patchwork-Id: 2502 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director15.mail.ord1d.rsapps.net ([172.30.191.6]) by backend41.mail.ord1d.rsapps.net with LMTP id cMCYHfcxlmIGaQAAqwncew (envelope-from ) for ; Tue, 31 May 2022 11:19:19 -0400 Received: from proxy14.mail.ord1d.rsapps.net ([172.30.191.6]) by director15.mail.ord1d.rsapps.net with LMTP id oP8GIvcxlmKUEQAAIcMcQg (envelope-from ) for ; Tue, 31 May 2022 11:19:19 -0400 Received: from smtp7.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy14.mail.ord1d.rsapps.net with LMTPS id KGnPIfcxlmIqXwAAtEH5vw (envelope-from ) for ; Tue, 31 May 2022 11:19:19 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp7.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (key not found in DNS) header.d=foxcrypto.com; dmarc=fail (p=none; dis=none) header.from=foxcrypto.com X-Suspicious-Flag: YES X-Classification-ID: 0a482e60-e0f5-11ec-bcd5-525400d0c497-1-1 Received: from [216.105.38.7] ([216.105.38.7:37502] helo=lists.sourceforge.net) by smtp7.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id A0/14-02493-6F136926; Tue, 31 May 2022 11:19:19 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1nw3dQ-0001nn-PH; Tue, 31 May 2022 15:18:17 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nw3dP-0001ng-Mp for openvpn-devel@lists.sourceforge.net; Tue, 31 May 2022 15:18:16 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Date:Subject:CC:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=CqX+DXV8/GhMbBqaQfWH9Gq1M4FUrzUqSDDsbV0alHE=; b=MIGyDlCubIx5IMaFZvXiFb/VR4 RTFAR+qdOIoEHxQlJ4KBzwvrygL12daNFWFgxUXNuaMWGwKa/yt6wLccCucgA92RPB/OuJqLotUR/ xONXepX8mDGRcYl3ua0x6+SoW4M06UNVmNQx1iW7qi4qqLc4uxLPow6bd7Y2xGozlEHE=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Date: Subject:CC:To:From:Sender:Reply-To:Content-ID:Content-Description:Resent-Date :Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=CqX+DXV8/GhMbBqaQfWH9Gq1M4FUrzUqSDDsbV0alHE=; b=R hiKwdDJeTO4Nlf8N8/RafVA4hrr4pXm4z/DGfpKuayrFLkBAaAvxEQ+Pn9K9sKxpFpn8KaQMxhfJY XA1+i38caklSUf2z98FnqpShg5Xkp+24n0FA2LGZcjom60gB9RRjaIXCde2lmbcFwFES2BchGfCnT hnN7se3lc5MOu49E=; Received: from nl-dft-mx-01.fox-it.com ([178.250.144.135]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.94.2) id 1nw3dG-0006mH-3f for openvpn-devel@lists.sourceforge.net; Tue, 31 May 2022 15:18:16 +0000 From: Max Fillinger To: Date: Tue, 31 May 2022 17:17:46 +0200 Message-ID: <20220531151746.101904-1-maximilian.fillinger@foxcrypto.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-ClientProxiedBy: FOXDFT1EX01.FOX.local (10.0.0.129) To FOXDFT1EX01.FOX.local (10.0.0.129) X-FE-Policy-ID: 13:3:2:SYSTEM DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; d=foxcrypto.com; s=NL-DFT-MX-01; c=relaxed/relaxed; h=from:to:cc:subject:date:message-id:mime-version:content-type; bh=CqX+DXV8/GhMbBqaQfWH9Gq1M4FUrzUqSDDsbV0alHE=; b=WmpjUnKovH3eCycdZOislpmeHgPnBIaJ6Uqnswn0LC2qoaE15ItZ0n0+7AJDxFG4wxby0wIWZ+cF uakawY3F6zB2Ugw0JyXgfFetMkp/N58EG0kAzILnTliJneawhr5p23hRNVNb5MydvVoHkv0jWngx MDfZW5U40HqZpveloeGS5h/kMpppNk59OvuI+Y4uKVEoM6AlbH3TjuS9Ng+jczEmoauZdi3tq7AK myf1gq1QYNmabO6qsq5keqfGAy3udnynJnm26ImW1wMrBKhqsUkn0nbqEEGUoZAYM5IDWFmGKkjd ogiVqF1A49eK8ThdhsDeYPBQnwndGr+T2qWxkQ== X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: When running with --ifconfig-noexec, OpenVPN does not execute ifconfig, but on exit, it still tries to "undo" the configuration it would have done. This patch fixes it by extracting an undo_ifconfig() [...] Content analysis details: (0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.0 T_SCC_BODY_TEXT_LINE No description available. 0.1 DKIM_INVALID DKIM or DK signature exists, but is not valid X-Headers-End: 1nw3dG-0006mH-3f Subject: [Openvpn-devel] [PATCH v4] Don't "undo" ifconfig on exit if it wasn't done X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox When running with --ifconfig-noexec, OpenVPN does not execute ifconfig, but on exit, it still tries to "undo" the configuration it would have done. This patch fixes it by extracting an undo_ifconfig() function from close_tun(). The undo function is called before close_tun(), but only if --ifconfig-noexec isn't set. This is symmetric to how open_tun() and do_ifconfig() are used. This change also allows us to drop the second argument from close_tun(). v2: Fix tabs-vs-spaces. v3: Fix another style mistake. v4: Move undo_ifconfig{4,6}() out of #ifdef TARGET_LINUX. Signed-off-by: Max Fillinger --- src/openvpn/init.c | 9 ++- src/openvpn/tun.c | 187 +++++++++++++++++++++++---------------------- src/openvpn/tun.h | 13 +++- 3 files changed, 113 insertions(+), 96 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index b0c62a85..949cdad0 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1072,8 +1072,7 @@ do_persist_tuntap(const struct options *options, openvpn_net_ctx_t *ctx) #ifdef ENABLE_FEATURE_TUN_PERSIST tuncfg(options->dev, options->dev_type, options->dev_node, options->persist_mode, - options->username, options->groupname, &options->tuntap_options, - ctx); + options->username, options->groupname, &options->tuntap_options); if (options->persist_mode && options->lladdr) { set_lladdr(ctx, options->dev, options->lladdr, NULL); @@ -1858,7 +1857,11 @@ do_close_tun_simple(struct context *c) msg(D_CLOSE, "Closing TUN/TAP interface"); if (c->c1.tuntap) { - close_tun(c->c1.tuntap, &c->net_ctx); + if (!c->options.ifconfig_noexec) + { + undo_ifconfig(c->c1.tuntap, &c->net_ctx); + } + close_tun(c->c1.tuntap); c->c1.tuntap = NULL; } c->c1.tuntap_owned = false; diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index e12f0369..b863e9c9 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -1605,6 +1605,89 @@ do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu, net_ctx_free(ctx); } +static void +undo_ifconfig_ipv4(struct tuntap *tt, openvpn_net_ctx_t *ctx) +{ +#if defined(TARGET_LINUX) + int netbits = netmask_to_netbits2(tt->remote_netmask); + + if (is_tun_p2p(tt)) + { + if (net_addr_ptp_v4_del(ctx, tt->actual_name, &tt->local, + &tt->remote_netmask) < 0) + { + msg(M_WARN, "Linux can't del IP from iface %s", + tt->actual_name); + } + } + else + { + if (net_addr_v4_del(ctx, tt->actual_name, &tt->local, netbits) < 0) + { + msg(M_WARN, "Linux can't del IP from iface %s", + tt->actual_name); + } + } +#elif !defined(_WIN32) /* if !defined(TARGET_LINUX) && !defined(_WIN32) */ + struct argv argv = argv_new(); + + argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name); + + argv_msg(M_INFO, &argv); + openvpn_execve_check(&argv, NULL, 0, "Generic ip addr del failed"); + + argv_free(&argv); +#endif /* ifdef TARGET_LINUX */ + /* Empty for _WIN32. */ +} + +static void +undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx) +{ +#if defined(TARGET_LINUX) + if (net_addr_v6_del(ctx, tt->actual_name, &tt->local_ipv6, + tt->netbits_ipv6) < 0) + { + msg(M_WARN, "Linux can't del IPv6 from iface %s", tt->actual_name); + } +#elif !defined(_WIN32) /* if !defined(TARGET_LINUX) && !defined(_WIN32) */ + struct gc_arena gc = gc_new(); + const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, gc); + struct argv argv = argv_new(); + + argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name, + ifconfig_ipv6_local, tt->netbits_ipv6); + + argv_msg(M_INFO, &argv); + openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed"); + + argv_free(&argv); + gc_free(&gc); +#endif /* ifdef TARGET_LINUX */ + /* Empty for _WIN32. */ +} + +void +undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx) +{ + if (tt->type != DEV_TYPE_NULL) + { + if (tt->did_ifconfig_setup) + { + undo_ifconfig_ipv4(tt, ctx); + } + + if (tt->did_ifconfig_ipv6_setup) + { + undo_ifconfig_ipv6(tt, ctx); + } + + /* release resources potentially allocated during undo */ + net_ctx_reset(ctx); + } + +} + static void clear_tuntap(struct tuntap *tuntap) { @@ -1910,7 +1993,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun } void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -2073,7 +2156,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun void tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, - const struct tuntap_options *options, openvpn_net_ctx_t *ctx) + const struct tuntap_options *options) { struct tuntap *tt; @@ -2112,93 +2195,17 @@ tuncfg(const char *dev, const char *dev_type, const char *dev_node, msg(M_ERR, "Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev); } } - close_tun(tt, ctx); + close_tun(tt); msg(M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF")); } #endif /* ENABLE_FEATURE_TUN_PERSIST */ -static void -undo_ifconfig_ipv4(struct tuntap *tt, openvpn_net_ctx_t *ctx) -{ -#if defined(TARGET_LINUX) - int netbits = netmask_to_netbits2(tt->remote_netmask); - - if (is_tun_p2p(tt)) - { - if (net_addr_ptp_v4_del(ctx, tt->actual_name, &tt->local, - &tt->remote_netmask) < 0) - { - msg(M_WARN, "Linux can't del IP from iface %s", - tt->actual_name); - } - } - else - { - if (net_addr_v4_del(ctx, tt->actual_name, &tt->local, netbits) < 0) - { - msg(M_WARN, "Linux can't del IP from iface %s", - tt->actual_name); - } - } -#else /* ifndef TARGET_LINUX */ - struct argv argv = argv_new(); - - argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name); - - argv_msg(M_INFO, &argv); - openvpn_execve_check(&argv, NULL, 0, "Generic ip addr del failed"); - - argv_free(&argv); -#endif /* ifdef TARGET_LINUX */ -} - -static void -undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx) -{ -#if defined(TARGET_LINUX) - if (net_addr_v6_del(ctx, tt->actual_name, &tt->local_ipv6, - tt->netbits_ipv6) < 0) - { - msg(M_WARN, "Linux can't del IPv6 from iface %s", tt->actual_name); - } -#else /* ifndef TARGET_LINUX */ - struct gc_arena gc = gc_new(); - const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, gc); - struct argv argv = argv_new(); - - argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name, - ifconfig_ipv6_local, tt->netbits_ipv6); - - argv_msg(M_INFO, &argv); - openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed"); - - argv_free(&argv); - gc_free(&gc); -#endif /* ifdef TARGET_LINUX */ -} - void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); - if (tt->type != DEV_TYPE_NULL) - { - if (tt->did_ifconfig_setup) - { - undo_ifconfig_ipv4(tt, ctx); - } - - if (tt->did_ifconfig_ipv6_setup) - { - undo_ifconfig_ipv6(tt, ctx); - } - - /* release resources potentially allocated during undo */ - net_ctx_reset(ctx); - } - close_tun_generic(tt); free(tt); } @@ -2513,7 +2520,7 @@ solaris_close_tun(struct tuntap *tt) * Close TUN device. */ void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -2546,7 +2553,7 @@ solaris_error_close(struct tuntap *tt, const struct env_set *es, argv_msg(M_INFO, &argv); openvpn_execve_check(&argv, es, 0, "Solaris ifconfig unplumb failed"); - close_tun(tt, NULL); + close_tun(tt); msg(M_FATAL, "Solaris ifconfig failed"); argv_free(&argv); } @@ -2609,7 +2616,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun */ void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -2695,7 +2702,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun * need to be explicitly destroyed */ void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -2836,7 +2843,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun * we need to call "ifconfig ... destroy" for cleanup */ void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -2952,7 +2959,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun } void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -3218,7 +3225,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun } void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -3366,7 +3373,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun /* tap devices need to be manually destroyed on AIX */ void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -6704,7 +6711,7 @@ netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc } void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); @@ -6887,7 +6894,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun } void -close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) +close_tun(struct tuntap *tt) { ASSERT(tt); diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index 4bc35916..4e41f6ff 100644 --- a/src/openvpn/tun.h +++ b/src/openvpn/tun.h @@ -247,7 +247,7 @@ tuntap_ring_empty(struct tuntap *tt) void open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt); -void close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx); +void close_tun(struct tuntap *tt); int write_tun(struct tuntap *tt, uint8_t *buf, int len); @@ -255,8 +255,7 @@ int read_tun(struct tuntap *tt, uint8_t *buf, int len); void tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, - const char *groupname, const struct tuntap_options *options, - openvpn_net_ctx_t *ctx); + const char *groupname, const struct tuntap_options *options); const char *guess_tuntap_dev(const char *dev, const char *dev_type, @@ -296,6 +295,14 @@ void do_ifconfig_setenv(const struct tuntap *tt, void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx); +/** + * undo_ifconfig - undo configuration of the tunnel interface + * + * @param tt the tuntap interface context + * @param ctx the networking API opaque context + */ +void undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx); + bool is_dev_type(const char *dev, const char *dev_type, const char *match_type); int dev_type_enum(const char *dev, const char *dev_type);