Browse code

Add support to ignore specific options.

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>

Arne Schwabe authored on 2013/08/16 17:11:04
Showing 3 changed files
... ...
@@ -1896,6 +1896,9 @@ It is also possible to tag a single directive so as not to trigger
1896 1896
 a fatal error if the directive isn't recognized.  To do this,
1897 1897
 prepend the following before the directive:
1898 1898
 .B setenv opt
1899
+
1900
+See also
1901
+.B \-\-ignore-unknown-option
1899 1902
 .\"*********************************************************
1900 1903
 .TP
1901 1904
 .B \-\-setenv-safe name value
... ...
@@ -1909,6 +1912,25 @@ is a safety precaution to prevent a LD_PRELOAD style attack
1909 1909
 from a malicious or compromised server.
1910 1910
 .\"*********************************************************
1911 1911
 .TP
1912
+.B \-\-ignore-unknown-option opt1 opt2 opt3 ... optN
1913
+When one of options
1914
+.B opt1 ... optN
1915
+is encountered in the configuration file the configuration
1916
+file parsing does not fail if this OpenVPN version does not
1917
+support the option. Multiple
1918
+.B \-\-ignore-unknown-option
1919
+options can be given to support a larger number of options to ignore.
1920
+
1921
+This option should be used with caution, as there are good security
1922
+reasons for having OpenVPN fail if it detects problems in a
1923
+config file. Having said that, there are valid reasons for wanting
1924
+new software features to gracefully degrade when encountered by
1925
+older software versions.
1926
+
1927
+.B \-\-ignore-unknown-option
1928
+is available since OpenVPN 2.3.3.
1929
+.\"*********************************************************
1930
+.TP
1912 1931
 .B \-\-script-security level
1913 1932
 This directive offers policy-level control over OpenVPN's usage of external programs
1914 1933
 and scripts.  Lower
... ...
@@ -250,6 +250,8 @@ static const char usage_message[] =
250 250
   "--setenv name value : Set a custom environmental variable to pass to script.\n"
251 251
   "--setenv FORWARD_COMPATIBLE 1 : Relax config file syntax checking to allow\n"
252 252
   "                  directives for future OpenVPN versions to be ignored.\n"
253
+  "--ignore-unkown-option opt1 opt2 ...: Relax config file syntax. Allow\n"
254
+  "                  these options to be ignored when unknown\n"
253 255
   "--script-security level: Where level can be:\n"
254 256
   "                  0 -- strictly no calling of external programs\n"
255 257
   "                  1 -- (default) only call built-ins such as ifconfig\n"
... ...
@@ -4414,6 +4416,43 @@ add_option (struct options *options,
4414 4414
 	  uninit_options (&sub);
4415 4415
 	}
4416 4416
     }
4417
+  else if (streq (p[0], "ignore-unknown-option") && p[1])
4418
+    {
4419
+      int i;
4420
+      int j;
4421
+      int numignored=0;
4422
+      const char **ignore;
4423
+
4424
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4425
+      /* Find out how many options to be ignored */
4426
+      for (i=1;p[i];i++)
4427
+        numignored++;
4428
+
4429
+      /* add number of options already ignored */
4430
+      for (i=0;options->ignore_unknown_option &&
4431
+             options->ignore_unknown_option[i]; i++)
4432
+        numignored++;
4433
+
4434
+      /* Allocate array */
4435
+      ALLOC_ARRAY_GC (ignore, const char*, numignored+1, &options->gc);
4436
+      for (i=0;options->ignore_unknown_option &&
4437
+             options->ignore_unknown_option[i]; i++)
4438
+        ignore[i]=options->ignore_unknown_option[i];
4439
+
4440
+      options->ignore_unknown_option=ignore;
4441
+
4442
+      for (j=1;p[j];j++)
4443
+        {
4444
+          /* Allow the user to specify ignore-unknown-option --opt too */
4445
+          if (p[j][0]=='-' && p[j][1]=='-')
4446
+            options->ignore_unknown_option[i] = (p[j]+2);
4447
+          else
4448
+            options->ignore_unknown_option[i] = p[j];
4449
+          i++;
4450
+        }
4451
+
4452
+      options->ignore_unknown_option[i] = NULL;
4453
+    }
4417 4454
   else if (streq (p[0], "remote-ip-hint") && p[1])
4418 4455
     {
4419 4456
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -6913,10 +6952,22 @@ add_option (struct options *options,
6913 6913
 #endif
6914 6914
   else
6915 6915
     {
6916
+      int i;
6917
+      int msglevel= msglevel_fc;
6918
+      /* Check if an option is in --ignore-unknown-option and
6919
+         set warning level to non fatal */
6920
+      for(i=0; options->ignore_unknown_option && options->ignore_unknown_option[i]; i++)
6921
+        {
6922
+          if (streq(p[0], options->ignore_unknown_option[i]))
6923
+            {
6924
+              msglevel = M_WARN;
6925
+              break;
6926
+            }
6927
+        }
6916 6928
       if (file)
6917
-	msg (msglevel_fc, "Unrecognized option or missing parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
6929
+	msg (msglevel, "Unrecognized option or missing parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
6918 6930
       else
6919
-	msg (msglevel_fc, "Unrecognized option or missing parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
6931
+	msg (msglevel, "Unrecognized option or missing parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
6920 6932
     }
6921 6933
  err:
6922 6934
   gc_free (&gc);
... ...
@@ -186,6 +186,8 @@ struct options
186 186
 
187 187
   /* enable forward compatibility for post-2.1 features */
188 188
   bool forward_compatible;
189
+  /* list of options that should be ignored even if unkown */
190
+  const char **  ignore_unknown_option;
189 191
 
190 192
   /* persist parms */
191 193
   bool persist_config;