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-2025 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, see <https://www.gnu.org/licenses/>.
21 */
22
23/*
24 * Win32-specific OpenVPN code, targeted at the mingw
25 * development environment.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "syshead.h"
33
34#ifdef _WIN32
35
36#include "buffer.h"
37#include "win32-util.h"
38
39WCHAR *
40wide_string(const char *utf8, struct gc_arena *gc)
41{
42 int n = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
43 WCHAR *ucs16 = gc_malloc(n * sizeof(WCHAR), false, gc);
44 MultiByteToWideChar(CP_UTF8, 0, utf8, -1, ucs16, n);
45 return ucs16;
46}
47
48char *
49utf16to8(const wchar_t *utf16, struct gc_arena *gc)
50{
51 char *utf8 = NULL;
52 int n = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL);
53 if (n > 0)
54 {
55 utf8 = gc_malloc(n, true, gc);
56 if (utf8)
57 {
58 WideCharToMultiByte(CP_UTF8, 0, utf16, -1, utf8, n, NULL, NULL);
59 }
60 }
61 return utf8;
62}
63
64/*
65 * Return true if filename is safe to be used on Windows,
66 * by avoiding the following reserved names:
67 *
68 * CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9,
69 * LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, and CLOCK$
70 *
71 * See: http://msdn.microsoft.com/en-us/library/aa365247.aspx
72 * and http://msdn.microsoft.com/en-us/library/86k9f82k(VS.80).aspx
73 */
74
75static bool
76cmp_prefix(const char *str, const bool n, const char *pre)
77{
78 size_t i = 0;
79
80 if (!str)
81 {
82 return false;
83 }
84
85 while (true)
86 {
87 const int c1 = pre[i];
88 int c2 = str[i];
89 ++i;
90 if (c1 == '\0')
91 {
92 if (n)
93 {
94 if (isdigit(c2))
95 {
96 c2 = str[i];
97 }
98 else
99 {
100 return false;
101 }
102 }
103 return c2 == '\0' || c2 == '.';
104 }
105 else if (c2 == '\0')
106 {
107 return false;
108 }
109 if (c1 != tolower(c2))
110 {
111 return false;
112 }
113 }
114}
115
116bool
117win_safe_filename(const char *fn)
118{
119 if (cmp_prefix(fn, false, "con"))
120 {
121 return false;
122 }
123 if (cmp_prefix(fn, false, "prn"))
124 {
125 return false;
126 }
127 if (cmp_prefix(fn, false, "aux"))
128 {
129 return false;
130 }
131 if (cmp_prefix(fn, false, "nul"))
132 {
133 return false;
134 }
135 if (cmp_prefix(fn, true, "com"))
136 {
137 return false;
138 }
139 if (cmp_prefix(fn, true, "lpt"))
140 {
141 return false;
142 }
143 if (cmp_prefix(fn, false, "clock$"))
144 {
145 return false;
146 }
147 return true;
148}
149
150const char *
152{
153 static char tmpdir[MAX_PATH];
154 WCHAR wtmpdir[MAX_PATH];
155
156 if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
157 {
158 return NULL;
159 }
160
161 if (WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) > sizeof(tmpdir))
162 {
163 msg(M_WARN, "Could not get temporary directory. Path is too long."
164 " Consider using --tmp-dir");
165 return NULL;
166 }
167
168 WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof(tmpdir), NULL, NULL);
169 return tmpdir;
170}
171#endif /* _WIN32 */
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
#define msg(flags,...)
Definition error.h:150
#define M_WARN
Definition error.h:90
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
struct gc_arena gc
Definition test_ssl.c:154
char * utf16to8(const wchar_t *utf16, struct gc_arena *gc)
Definition win32-util.c:49
static bool cmp_prefix(const char *str, const bool n, const char *pre)
Definition win32-util.c:76
bool win_safe_filename(const char *fn)
Definition win32-util.c:117
const char * win_get_tempdir(void)
Definition win32-util.c:151
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
Definition win32-util.c:40