Browse code

Extend push-remove to also handle 'ifconfig'.

Push-remove (introduced in commit 970312f1850) did not handle "ifconfig"
yet, as both "ifconfig" and "ifconfig-ipv6" are handled differently from
all other pushed options. Since there was no valid use-case to not-push
"ifconfig" (no support on the client side for running IPv6-only) this
was not an issue so far - but with the recent commits to enable ipv6-only
operation it can be a desirable feature.

The implementation is similar to "push-remove ifconfig-ipv6" - namely,
flagging via a new context option (c->options.push_ifconfig_ipv4_blocked)
and then not creating the push statement in "send_push_reply()".

While not truly elegant, it's much less invasive than the alternatives
(storing the list of "push-remove" statements somewhere and then checking
in push_option_ex())

Trac: #1072

Signed-off-by: Gert Doering <gert@greenie.muc.de>

Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <20180701195938.2541-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17169.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Gert Doering authored on 2018/07/02 04:59:38
Showing 3 changed files
... ...
@@ -3045,6 +3045,11 @@ an option,
3045 3045
 can be used to first remove the old value, and then add a new
3046 3046
 .B \-\-push
3047 3047
 option with the new value.
3048
+
3049
+NOTE2: due to implementation details, 'ifconfig' and 'ifconfig-ipv6'
3050
+can only be removed with an exact match on the option ("push-remove ifconfig"),
3051
+no substring matching and no matching on the IPv4/IPv6 address argument
3052
+is possible.
3048 3053
 .\"*********************************************************
3049 3054
 .TP
3050 3055
 .B \-\-push\-peer\-info
... ...
@@ -425,6 +425,7 @@ struct options
425 425
     bool push_ifconfig_constraint_defined;
426 426
     in_addr_t push_ifconfig_constraint_network;
427 427
     in_addr_t push_ifconfig_constraint_netmask;
428
+    bool push_ifconfig_ipv4_blocked;                    /* IPv4 */
428 429
     bool push_ifconfig_ipv6_defined;                    /* IPv6 */
429 430
     struct in6_addr push_ifconfig_ipv6_local;           /* IPv6 */
430 431
     int push_ifconfig_ipv6_netbits;                     /* IPv6 */
... ...
@@ -342,7 +342,8 @@ prepare_push_reply(struct context *c, struct gc_arena *gc,
342 342
 
343 343
     /* ipv4 */
344 344
     if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local
345
-        && c->c2.push_ifconfig_remote_netmask)
345
+        && c->c2.push_ifconfig_remote_netmask
346
+        && !o->push_ifconfig_ipv4_blocked)
346 347
     {
347 348
         in_addr_t ifconfig_local = c->c2.push_ifconfig_local;
348 349
         if (c->c2.push_ifconfig_local_alias)
... ...
@@ -602,6 +603,13 @@ push_remove_option(struct options *o, const char *p)
602 602
 {
603 603
     msg(D_PUSH_DEBUG, "PUSH_REMOVE searching for: '%s'", p);
604 604
 
605
+    /* ifconfig is special, as not part of the push list */
606
+    if (streq(p, "ifconfig"))
607
+    {
608
+        o->push_ifconfig_ipv4_blocked = true;
609
+        return;
610
+    }
611
+
605 612
     /* ifconfig-ipv6 is special, as not part of the push list */
606 613
     if (streq( p, "ifconfig-ipv6" ))
607 614
     {