OpenVPN
win32-util.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2023 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /*
25  * Win32-specific OpenVPN code, targeted at the mingw
26  * development environment.
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "syshead.h"
34 
35 #ifdef _WIN32
36 
37 #include "buffer.h"
38 #include "win32-util.h"
39 
40 WCHAR *
41 wide_string(const char *utf8, struct gc_arena *gc)
42 {
43  int n = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
44  WCHAR *ucs16 = gc_malloc(n * sizeof(WCHAR), false, gc);
45  MultiByteToWideChar(CP_UTF8, 0, utf8, -1, ucs16, n);
46  return ucs16;
47 }
48 
49 char *
50 utf16to8(const wchar_t *utf16, struct gc_arena *gc)
51 {
52  char *utf8 = NULL;
53  int n = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL);
54  if (n > 0)
55  {
56  utf8 = gc_malloc(n, true, gc);
57  if (utf8)
58  {
59  WideCharToMultiByte(CP_UTF8, 0, utf16, -1, utf8, n, NULL, NULL);
60  }
61  }
62  return utf8;
63 }
64 
65 /*
66  * Return true if filename is safe to be used on Windows,
67  * by avoiding the following reserved names:
68  *
69  * CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9,
70  * LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, and CLOCK$
71  *
72  * See: http://msdn.microsoft.com/en-us/library/aa365247.aspx
73  * and http://msdn.microsoft.com/en-us/library/86k9f82k(VS.80).aspx
74  */
75 
76 static bool
77 cmp_prefix(const char *str, const bool n, const char *pre)
78 {
79  size_t i = 0;
80 
81  if (!str)
82  {
83  return false;
84  }
85 
86  while (true)
87  {
88  const int c1 = pre[i];
89  int c2 = str[i];
90  ++i;
91  if (c1 == '\0')
92  {
93  if (n)
94  {
95  if (isdigit(c2))
96  {
97  c2 = str[i];
98  }
99  else
100  {
101  return false;
102  }
103  }
104  return c2 == '\0' || c2 == '.';
105  }
106  else if (c2 == '\0')
107  {
108  return false;
109  }
110  if (c1 != tolower(c2))
111  {
112  return false;
113  }
114  }
115 }
116 
117 bool
118 win_safe_filename(const char *fn)
119 {
120  if (cmp_prefix(fn, false, "con"))
121  {
122  return false;
123  }
124  if (cmp_prefix(fn, false, "prn"))
125  {
126  return false;
127  }
128  if (cmp_prefix(fn, false, "aux"))
129  {
130  return false;
131  }
132  if (cmp_prefix(fn, false, "nul"))
133  {
134  return false;
135  }
136  if (cmp_prefix(fn, true, "com"))
137  {
138  return false;
139  }
140  if (cmp_prefix(fn, true, "lpt"))
141  {
142  return false;
143  }
144  if (cmp_prefix(fn, false, "clock$"))
145  {
146  return false;
147  }
148  return true;
149 }
150 
151 const char *
153 {
154  static char tmpdir[MAX_PATH];
155  WCHAR wtmpdir[MAX_PATH];
156 
157  if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
158  {
159  return NULL;
160  }
161 
162  if (WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) > sizeof(tmpdir))
163  {
164  msg(M_WARN, "Could not get temporary directory. Path is too long."
165  " Consider using --tmp-dir");
166  return NULL;
167  }
168 
169  WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof(tmpdir), NULL, NULL);
170  return tmpdir;
171 }
172 #endif /* _WIN32 */
multi_instance::gc
struct gc_arena gc
Definition: multi.h:105
M_WARN
#define M_WARN
Definition: error.h:97
wide_string
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
Definition: win32-util.c:41
cmp_prefix
static bool cmp_prefix(const char *str, const bool n, const char *pre)
Definition: win32-util.c:77
buffer.h
syshead.h
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
gc_malloc
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:380
utf16to8
char * utf16to8(const wchar_t *utf16, struct gc_arena *gc)
Definition: win32-util.c:50
win_get_tempdir
const char * win_get_tempdir(void)
Definition: win32-util.c:152
config.h
win_safe_filename
bool win_safe_filename(const char *fn)
Definition: win32-util.c:118
msg
#define msg(flags,...)
Definition: error.h:150
win32-util.h