git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3072 e7ae566f-a301-0410-adde-c780ea21d3b5
james authored on 2008/07/18 07:41:15... | ... |
@@ -35,6 +35,7 @@ |
35 | 35 |
#include "manage.h" |
36 | 36 |
#include "crypto.h" |
37 | 37 |
#include "route.h" |
38 |
+#include "win32.h" |
|
38 | 39 |
|
39 | 40 |
#include "memdbg.h" |
40 | 41 |
|
... | ... |
@@ -1114,7 +1115,11 @@ gen_path (const char *directory, const char *filename, struct gc_arena *gc) |
1114 | 1114 |
|
1115 | 1115 |
if (safe_filename |
1116 | 1116 |
&& strcmp (safe_filename, ".") |
1117 |
- && strcmp (safe_filename, "..")) |
|
1117 |
+ && strcmp (safe_filename, "..") |
|
1118 |
+#ifdef WIN32 |
|
1119 |
+ && win_safe_filename (safe_filename) |
|
1120 |
+#endif |
|
1121 |
+ ) |
|
1118 | 1122 |
{ |
1119 | 1123 |
struct buffer out = alloc_buf_gc (256, gc); |
1120 | 1124 |
char dirsep[2]; |
... | ... |
@@ -753,4 +753,67 @@ getpass (const char *prompt) |
753 | 753 |
return NULL; |
754 | 754 |
} |
755 | 755 |
|
756 |
+/* |
|
757 |
+ * Return true if filename is safe to be used on Windows, |
|
758 |
+ * by avoiding the following reserved names: |
|
759 |
+ * |
|
760 |
+ * CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, |
|
761 |
+ * LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, and CLOCK$ |
|
762 |
+ * |
|
763 |
+ * See: http://msdn.microsoft.com/en-us/library/aa365247.aspx |
|
764 |
+ * and http://msdn.microsoft.com/en-us/library/86k9f82k(VS.80).aspx |
|
765 |
+ */ |
|
766 |
+ |
|
767 |
+static bool |
|
768 |
+cmp_prefix (const char *str, const bool n, const char *pre) |
|
769 |
+{ |
|
770 |
+ const size_t len = strlen (pre); |
|
771 |
+ size_t i = 0; |
|
772 |
+ |
|
773 |
+ if (!str) |
|
774 |
+ return false; |
|
775 |
+ |
|
776 |
+ while (true) |
|
777 |
+ { |
|
778 |
+ const int c1 = pre[i]; |
|
779 |
+ int c2 = str[i]; |
|
780 |
+ ++i; |
|
781 |
+ if (c1 == '\0') |
|
782 |
+ { |
|
783 |
+ if (n) |
|
784 |
+ { |
|
785 |
+ if (isdigit (c2)) |
|
786 |
+ c2 = str[i]; |
|
787 |
+ else |
|
788 |
+ return false; |
|
789 |
+ } |
|
790 |
+ return c2 == '\0' || c2 == '.'; |
|
791 |
+ } |
|
792 |
+ else if (c2 == '\0') |
|
793 |
+ return false; |
|
794 |
+ if (c1 != tolower(c2)) |
|
795 |
+ return false; |
|
796 |
+ } |
|
797 |
+} |
|
798 |
+ |
|
799 |
+bool |
|
800 |
+win_safe_filename (const char *fn) |
|
801 |
+{ |
|
802 |
+ if (cmp_prefix (fn, false, "con")) |
|
803 |
+ return false; |
|
804 |
+ if (cmp_prefix (fn, false, "prn")) |
|
805 |
+ return false; |
|
806 |
+ if (cmp_prefix (fn, false, "aux")) |
|
807 |
+ return false; |
|
808 |
+ if (cmp_prefix (fn, false, "nul")) |
|
809 |
+ return false; |
|
810 |
+ if (cmp_prefix (fn, true, "com")) |
|
811 |
+ return false; |
|
812 |
+ if (cmp_prefix (fn, true, "lpt")) |
|
813 |
+ return false; |
|
814 |
+ if (cmp_prefix (fn, false, "clock$")) |
|
815 |
+ return false; |
|
816 |
+ return true; |
|
817 |
+} |
|
818 |
+ |
|
756 | 819 |
#endif |
... | ... |
@@ -247,5 +247,8 @@ char *getpass (const char *prompt); |
247 | 247 |
/* Set Win32 security attributes structure to allow all access */ |
248 | 248 |
bool init_security_attributes_allow_all (struct security_attributes *obj); |
249 | 249 |
|
250 |
+/* return true if filename is safe to be used on Windows */ |
|
251 |
+bool win_safe_filename (const char *fn); |
|
252 |
+ |
|
250 | 253 |
#endif |
251 | 254 |
#endif |