]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
gen_path now rejects filenames that match Windows
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Thu, 17 Jul 2008 22:41:15 +0000 (22:41 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Thu, 17 Jul 2008 22:41:15 +0000 (22:41 +0000)
device names such as CON, NUL, LPT1, etc.

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3072 e7ae566f-a301-0410-adde-c780ea21d3b5

misc.c
win32.c
win32.h

diff --git a/misc.c b/misc.c
index 985879cbaa3a0ba3d54618785579d3d7596df735..8f80ee1dbf60f4c00285dac881cda0db17375fb7 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -35,6 +35,7 @@
 #include "manage.h"
 #include "crypto.h"
 #include "route.h"
+#include "win32.h"
 
 #include "memdbg.h"
 
@@ -1114,7 +1115,11 @@ gen_path (const char *directory, const char *filename, struct gc_arena *gc)
 
   if (safe_filename
       && strcmp (safe_filename, ".")
-      && strcmp (safe_filename, ".."))
+      && strcmp (safe_filename, "..")
+#ifdef WIN32
+      && win_safe_filename (safe_filename)
+#endif
+      )
     {
       struct buffer out = alloc_buf_gc (256, gc);
       char dirsep[2];
diff --git a/win32.c b/win32.c
index 6945ba1a411173864471d0326ffc59a13919935b..516bf8e966035bb2c4d7374b37f82d853ee5b9d7 100644 (file)
--- a/win32.c
+++ b/win32.c
@@ -753,4 +753,67 @@ getpass (const char *prompt)
     return NULL;
 }
 
+/*
+ * Return true if filename is safe to be used on Windows,
+ * by avoiding the following reserved names:
+ *
+ * CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9,
+ * LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, and CLOCK$
+ *
+ * See: http://msdn.microsoft.com/en-us/library/aa365247.aspx
+ *  and http://msdn.microsoft.com/en-us/library/86k9f82k(VS.80).aspx
+ */
+
+static bool
+cmp_prefix (const char *str, const bool n, const char *pre)
+{
+  const size_t len = strlen (pre);
+  size_t i = 0;
+
+  if (!str)
+    return false;
+
+  while (true)
+    {
+      const int c1 = pre[i];
+      int c2 = str[i];
+      ++i;
+      if (c1 == '\0')
+       {
+         if (n)
+           {
+             if (isdigit (c2))
+               c2 = str[i];
+             else
+               return false;
+           }
+         return c2 == '\0' || c2 == '.';
+       }
+      else if (c2 == '\0')
+       return false;
+      if (c1 != tolower(c2))
+       return false;
+    }
+}
+
+bool
+win_safe_filename (const char *fn)
+{
+  if (cmp_prefix (fn, false, "con"))
+    return false;
+  if (cmp_prefix (fn, false, "prn"))
+    return false;
+  if (cmp_prefix (fn, false, "aux"))
+    return false;
+  if (cmp_prefix (fn, false, "nul"))
+    return false;
+  if (cmp_prefix (fn, true, "com"))
+    return false;
+  if (cmp_prefix (fn, true, "lpt"))
+    return false;
+  if (cmp_prefix (fn, false, "clock$"))
+    return false;
+  return true;
+}
+
 #endif
diff --git a/win32.h b/win32.h
index 2697ae245dce7ce03b848d9171658247a98eeba6..8cf8af2842f58435a9275674ae9e673088ee030e 100644 (file)
--- a/win32.h
+++ b/win32.h
@@ -247,5 +247,8 @@ char *getpass (const char *prompt);
 /* Set Win32 security attributes structure to allow all access */
 bool init_security_attributes_allow_all (struct security_attributes *obj);
 
+/* return true if filename is safe to be used on Windows */
+bool win_safe_filename (const char *fn);
+
 #endif
 #endif