]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Add support to ignore specific options.
authorArne Schwabe <arne@rfc2549.org>
Fri, 16 Aug 2013 08:11:04 +0000 (10:11 +0200)
committerGert Doering <gert@greenie.muc.de>
Fri, 16 Aug 2013 15:49:52 +0000 (17:49 +0200)
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1376640664-26379-1-git-send-email-arne@rfc2549.org>
URL: http://article.gmane.org/gmane.network.openvpn.devel/7799

Signed-off-by: Gert Doering <gert@greenie.muc.de>
doc/openvpn.8
src/openvpn/options.c
src/openvpn/options.h

index 741f5541272b990629884f5150ca7eb30bd777d2..af72d2b514688be9153ebd1f1b03e46130453416 100644 (file)
@@ -1896,6 +1896,9 @@ It is also possible to tag a single directive so as not to trigger
 a fatal error if the directive isn't recognized.  To do this,
 prepend the following before the directive:
 .B setenv opt
+
+See also
+.B \-\-ignore-unknown-option
 .\"*********************************************************
 .TP
 .B \-\-setenv-safe name value
@@ -1909,6 +1912,25 @@ is a safety precaution to prevent a LD_PRELOAD style attack
 from a malicious or compromised server.
 .\"*********************************************************
 .TP
+.B \-\-ignore-unknown-option opt1 opt2 opt3 ... optN
+When one of options
+.B opt1 ... optN
+is encountered in the configuration file the configuration
+file parsing does not fail if this OpenVPN version does not
+support the option. Multiple
+.B \-\-ignore-unknown-option
+options can be given to support a larger number of options to ignore.
+
+This option should be used with caution, as there are good security
+reasons for having OpenVPN fail if it detects problems in a
+config file. Having said that, there are valid reasons for wanting
+new software features to gracefully degrade when encountered by
+older software versions.
+
+.B \-\-ignore-unknown-option
+is available since OpenVPN 2.3.3.
+.\"*********************************************************
+.TP
 .B \-\-script-security level
 This directive offers policy-level control over OpenVPN's usage of external programs
 and scripts.  Lower
index d84e908909d011f546387b862e87c18e9882d7d0..4d0271f1dec98a779bf73bcf8cfcaa325b88497c 100644 (file)
@@ -250,6 +250,8 @@ static const char usage_message[] =
   "--setenv name value : Set a custom environmental variable to pass to script.\n"
   "--setenv FORWARD_COMPATIBLE 1 : Relax config file syntax checking to allow\n"
   "                  directives for future OpenVPN versions to be ignored.\n"
+  "--ignore-unkown-option opt1 opt2 ...: Relax config file syntax. Allow\n"
+  "                  these options to be ignored when unknown\n"
   "--script-security level: Where level can be:\n"
   "                  0 -- strictly no calling of external programs\n"
   "                  1 -- (default) only call built-ins such as ifconfig\n"
@@ -4414,6 +4416,43 @@ add_option (struct options *options,
          uninit_options (&sub);
        }
     }
+  else if (streq (p[0], "ignore-unknown-option") && p[1])
+    {
+      int i;
+      int j;
+      int numignored=0;
+      const char **ignore;
+
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      /* Find out how many options to be ignored */
+      for (i=1;p[i];i++)
+        numignored++;
+
+      /* add number of options already ignored */
+      for (i=0;options->ignore_unknown_option &&
+             options->ignore_unknown_option[i]; i++)
+        numignored++;
+
+      /* Allocate array */
+      ALLOC_ARRAY_GC (ignore, const char*, numignored+1, &options->gc);
+      for (i=0;options->ignore_unknown_option &&
+             options->ignore_unknown_option[i]; i++)
+        ignore[i]=options->ignore_unknown_option[i];
+
+      options->ignore_unknown_option=ignore;
+
+      for (j=1;p[j];j++)
+        {
+          /* Allow the user to specify ignore-unknown-option --opt too */
+          if (p[j][0]=='-' && p[j][1]=='-')
+            options->ignore_unknown_option[i] = (p[j]+2);
+          else
+            options->ignore_unknown_option[i] = p[j];
+          i++;
+        }
+
+      options->ignore_unknown_option[i] = NULL;
+    }
   else if (streq (p[0], "remote-ip-hint") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -6913,10 +6952,22 @@ add_option (struct options *options,
 #endif
   else
     {
+      int i;
+      int msglevel= msglevel_fc;
+      /* Check if an option is in --ignore-unknown-option and
+         set warning level to non fatal */
+      for(i=0; options->ignore_unknown_option && options->ignore_unknown_option[i]; i++)
+        {
+          if (streq(p[0], options->ignore_unknown_option[i]))
+            {
+              msglevel = M_WARN;
+              break;
+            }
+        }
       if (file)
-       msg (msglevel_fc, "Unrecognized option or missing parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
+       msg (msglevel, "Unrecognized option or missing parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
       else
-       msg (msglevel_fc, "Unrecognized option or missing parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
+       msg (msglevel, "Unrecognized option or missing parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
     }
  err:
   gc_free (&gc);
index 6a132a6cd5da949644267f45844b76aff50daaa9..8e0e367d45501a8ad3d6af47b5af156e9652c937 100644 (file)
@@ -186,6 +186,8 @@ struct options
 
   /* enable forward compatibility for post-2.1 features */
   bool forward_compatible;
+  /* list of options that should be ignored even if unkown */
+  const char **  ignore_unknown_option;
 
   /* persist parms */
   bool persist_config;