Hello all,

I am submitting a minor patch which includes an option to specify --script-dir.
i.e. any user defined script will be run ONLY IF it is present in "script-dir".

The reason I needed this is because I had a frontend to configuration file 
which allowed administrator to change configuration.

I also have script-security set to 2 because I wanted to run a script when 
client connects.

These two option make it insecure. As admin (with bad intention or if admin 
password is leaked) can simply call "rm -rf /" for certain commands.

So my idea was
1) Add a new option called script-dir
2) Frontend will not allow word "script-dir" in config file (so admin cant 
change it)
3) script-dir will be passed on command line

This way admin can not run anything other than what I have put in script-dir. 
This also helps prevent accidentally run script in some other path.

Patch also fixes minor bug in init.c where warning for SSEC_PW_ENV actually 
would never be shown.



So please have a look at it and if acceptable then merge in source tree.

Thanks

AMM.
--- openvpn-2.2.2/init.c	2011-12-13 22:28:56.000000000 +0530
+++ openvpn-2.2.2/init.c	2012-08-21 11:53:22.809410085 +0530
@@ -2291,9 +2291,13 @@
 #endif
 
   if (script_security >= SSEC_SCRIPTS)
-    msg (M_WARN, "NOTE: the current --script-security setting may allow this configuration to call user-defined scripts");
-  else if (script_security >= SSEC_PW_ENV)
-    msg (M_WARN, "WARNING: the current --script-security setting may allow passwords to be passed to scripts via environmental variables");
+    {
+      msg (M_WARN, "NOTE: the current --script-security setting may allow this configuration to call user-defined scripts");
+      if (script_security >= SSEC_PW_ENV)
+        msg (M_WARN, "WARNING: the current --script-security setting may allow passwords to be passed to scripts via environmental variables");
+      if (script_dir == NULL)
+        msg (M_WARN, "WARNING: setting --script-dir is recommended for higher security");
+    }
   else
     msg (M_WARN, "NOTE: " PACKAGE_NAME " 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables");
 
--- openvpn-2.2.2/misc.c	2011-12-13 22:28:56.000000000 +0530
+++ openvpn-2.2.2/misc.c	2012-08-21 12:27:24.332296778 +0530
@@ -45,6 +45,7 @@
 
 /* contains an SSEC_x value defined in misc.h */
 int script_security = SSEC_BUILT_IN; /* GLOBAL */
+const char *script_dir = NULL; /* GLOBAL */
 
 /* contains SM_x value defined in misc.h */
 int script_method = SM_EXECVE; /* GLOBAL */
@@ -484,10 +485,14 @@
 }
 
 bool
-openvpn_execve_allowed (const unsigned int flags)
+openvpn_execve_allowed (const char *cmd, const unsigned int flags)
 {
   if (flags & S_SCRIPT)
-    return script_security >= SSEC_SCRIPTS;
+    {
+      if (script_dir != NULL && strncmp(script_dir, cmd, strlen(script_dir)))
+	return false;
+      return script_security >= SSEC_SCRIPTS;
+    }
   else
     return script_security >= SSEC_BUILT_IN;
 }
@@ -509,11 +514,11 @@
   if (a && a->argv[0])
     {
 #if defined(ENABLE_EXECVE)
-      if (openvpn_execve_allowed (flags))
+      const char *cmd = a->argv[0];
+      if (openvpn_execve_allowed (cmd, flags))
 	{
 	  if (script_method == SM_EXECVE)
 	    {
-	      const char *cmd = a->argv[0];
 	      char *const *argv = a->argv;
 	      char *const *envp = (char *const *)make_env_array (es, true, &gc);
 	      pid_t pid;
--- openvpn-2.2.2/misc.h	2011-12-13 22:28:56.000000000 +0530
+++ openvpn-2.2.2/misc.h	2012-08-21 12:10:59.916050919 +0530
@@ -133,7 +133,7 @@
 /* wrapper around the execve() call */
 int openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned int flags);
 bool openvpn_execve_check (const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message);
-bool openvpn_execve_allowed (const unsigned int flags);
+bool openvpn_execve_allowed (const char *cmd, const unsigned int flags);
 int openvpn_system (const char *command, const struct env_set *es, unsigned int flags);
 
 static inline bool
@@ -353,6 +353,7 @@
 #define SSEC_SCRIPTS   2 /* allow calling of built-in programs and user-defined scripts */
 #define SSEC_PW_ENV    3 /* allow calling of built-in programs and user-defined scripts that may receive a password as an environmental variable */
 extern int script_security; /* GLOBAL */
+extern const char *script_dir; /* GLOBAL */
 
 #define SM_EXECVE 0      /* call external programs with execve() or CreateProcess() */
 #define SM_SYSTEM 1      /* call external programs with system() */
--- openvpn-2.2.2/options.c	2011-12-13 22:28:56.000000000 +0530
+++ openvpn-2.2.2/options.c	2012-08-21 11:33:15.955648666 +0530
@@ -218,6 +218,7 @@
   "                  1 -- (default) only call built-ins such as ifconfig\n"
   "                  2 -- allow calling of built-ins and scripts\n"
   "                  3 -- allow password to be passed to scripts via env\n"
+  "--script-dir dir: Only run user-defined scripts if it resides in this directory\n"
   "--shaper n      : Restrict output to peer to n bytes per second.\n"
   "--keepalive n m : Helper option for setting timeouts in server mode.  Send\n"
   "                  ping once every n seconds, restart if ping not received\n"
@@ -4748,6 +4749,11 @@
       else
 	script_method = SM_EXECVE;
     }
+  else if (streq (p[0], "script-dir") && p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      script_dir = p[1];
+    }
   else if (streq (p[0], "mssfix"))
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
--- openvpn-2.2.2/win32.c	2011-12-13 22:28:56.000000000 +0530
+++ openvpn-2.2.2/win32.c	2012-08-21 12:15:56.355627974 +0530
@@ -956,7 +956,8 @@
 
   if (a && a->argv[0])
     {
-      if (openvpn_execve_allowed (flags))
+      char *cmd = a->argv[0];
+      if (openvpn_execve_allowed (cmd, flags))
 	{
 	  if (script_method == SM_EXECVE)
 	    {
@@ -965,7 +966,6 @@
 
 	      char *env = env_block (es);
 	      char *cl = cmd_line (a);
-	      char *cmd = a->argv[0];
 
 	      CLEAR (start_info);
 	      CLEAR (proc_info);

Reply via email to