Hi,

On Fri, Oct 23, 2015 at 10:12:36AM +0200, David Sommerseth wrote:
> > Am 21.10.15 um 00:50 schrieb David Sommerseth:
> >>> >  --push-filter ifconfig-ipv6 tun-ipv6 route-ipv6
> >>> > 
> >>> > which would do exactly what the current patch did, but is much more 
> >>> > flexible
> >>> > depending on what exactly needs to be worked around with *this* 
> >>> > client...
[..]
> That's better.  Another suggestion could be --push-remove.  But I have
> no strong opinion either way.

So, you asked for it, you or Arne get to review this :-) - it's currently
missing a man page entry, but the commit message explains how it works -
just put

  push-remove tun-ipv6
  push-remove route-ipv6

into your ccd/ file, and all options strings starting with one of these
strings are removed.  Caveat: "push-remove route" will remove IPv4 and
IPv6 routes, so to remove only IPv4 routes, use

  push-remove 'route '

(our config parser is just magic :) )

Missing in this patch is "openvpn.8" and you can't remove "ifconfig-ipv6"
(or "ifconfig", for that matter) from the push list as these are not normal
options but special cased - but that is actually not very hard to add if
you agree with the general direction.

gert

PS: merry christmas everyone :-)

-- 
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             g...@greenie.muc.de
fax: +49-89-35655025                        g...@net.informatik.tu-muenchen.de
From 06a634bb966c6adbc8f5bd66a0cf796e25727c6d Mon Sep 17 00:00:00 2001
From: Gert Doering <g...@greenie.muc.de>
List-Post: openvpn-devel@lists.sourceforge.net
Date: Sat, 26 Dec 2015 23:08:14 +0100
Subject: [PATCH] Implement push-remove option to selectively remove pushed
 options.

With this option, the server can remove individual options from the
set pushed to a client (call from --client-config-dir file, or from
--client-connect script or plugin).  Options are removed at parse
time, so it is possible to do stuff like:

  push-remove route-ipv6
  push "route-ipv6 fd00::/8"

to first remove all IPv6 route options set so far, then add something
specific (what "push-reset" does to all the options).

Arguments to push-remove are strncmp()'ed to option string, so partial
matches like

  push-remove route-ipv6 2001:

are possible ("remove all IPv6 routes starting with 2001:").

Implementation of remove_iroutes_from_push_route_list() had to be changed
slightly to stop it from re-enabling all disabled options again.

Signed-off-by: Gert Doering <g...@greenie.muc.de>
---
 src/openvpn/options.c |  9 +++++++++
 src/openvpn/push.c    | 38 ++++++++++++++++++++++++++++++++------
 src/openvpn/push.h    |  1 +
 3 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 46aa824..952e171 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -5578,6 +5578,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_INSTANCE);
       push_reset (options);
     }
+  else if (streq (p[0], "push-remove"))
+    {
+      int j;
+      VERIFY_PERMISSION (OPT_P_INSTANCE);
+      for (j = 1; j < MAX_PARMS && p[j]; ++j)
+        {
+	  push_remove_option (options,p[j]);
+	}
+    }
   else if (streq (p[0], "ifconfig-pool") && p[1] && p[2] && !p[4])
     {
       const int lev = M_WARN;
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index d4f3cb6..59fb4cf 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -414,6 +414,31 @@ push_reset (struct options *o)
 {
   CLEAR (o->push_list);
 }
+
+void
+push_remove_option (struct options *o, const char *p)
+{
+  msg( D_PUSH, "PUSH_REMOVE '%s'", p );
+
+  if (o && o->push_list.head )
+    {
+      struct gc_arena gc = gc_new ();
+      struct push_entry *e = o->push_list.head;
+
+      /* cycle through the push list */
+      while (e)
+	{
+	  if ( e->enable &&
+               strncmp( e->option, p, strlen(p) ) == 0 )
+	    {
+	      msg (D_PUSH, "PUSH_REMOVE removing: '%s'", e->option);
+	      e->enable = false;
+	    }
+
+	  e = e->next;
+	}
+    }
+}
 #endif
 
 #if P2MP_SERVER
@@ -543,7 +568,8 @@ remove_iroutes_from_push_route_list (struct options *o)
 
 	  /* parse the push item */
 	  CLEAR (p);
-	  if (parse_line (e->option, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
+	  if ( e->enable &&
+               parse_line (e->option, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
 	    {
 	      /* is the push item a route directive? */
 	      if (p[0] && !strcmp (p[0], "route") && !p[3])
@@ -569,12 +595,12 @@ remove_iroutes_from_push_route_list (struct options *o)
 			}
 		    }
 		}
-	    }
 
-	  /* should we copy the push item? */
-	  e->enable = enable;
-	  if (!enable)
-	    msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option);
+	      /* should we copy the push item? */
+	      e->enable = enable;
+	      if (!enable)
+		msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option);
+	    }
 
 	  e = e->next;
 	}
diff --git a/src/openvpn/push.h b/src/openvpn/push.h
index fa06e08..e756582 100644
--- a/src/openvpn/push.h
+++ b/src/openvpn/push.h
@@ -61,6 +61,7 @@ void push_option (struct options *o, const char *opt, int msglevel);
 void push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc);
 
 void push_reset (struct options *o);
+void push_remove_option (struct options *o, const char *p);
 
 bool send_push_reply (struct context *c);
 
-- 
2.4.10

Attachment: signature.asc
Description: PGP signature

Reply via email to