From 73b7e6988491781703859675b0c86051e79a7d9d Mon Sep 17 00:00:00 2001 From: james Date: Thu, 17 Jul 2008 22:41:15 +0000 Subject: gen_path now rejects filenames that match Windows 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 | 7 ++++++- win32.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ win32.h | 3 +++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/misc.c b/misc.c index 985879c..8f80ee1 100644 --- 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 6945ba1..516bf8e 100644 --- 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 2697ae2..8cf8af2 100644 --- 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 -- cgit