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: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file
72 */
73
74static bool
75cmp_prefix(const char *str, const bool n, const char *pre)
76{
77 size_t i = 0;
78
79 if (!str)
80 {
81 return false;
82 }
83
84 while (true)
85 {
86 const int c1 = pre[i];
87 int c2 = str[i];
88 ++i;
89 if (c1 == '\0')
90 {
91 if (n)
92 {
93 if (isdigit(c2))
94 {
95 c2 = str[i];
96 }
97 else
98 {
99 return false;
100 }
101 }
102 return c2 == '\0' || c2 == '.';
103 }
104 else if (c2 == '\0')
105 {
106 return false;
107 }
108 if (c1 != tolower(c2))
109 {
110 return false;
111 }
112 }
113}
114
115bool
116win_safe_filename(const char *fn)
117{
118 if (cmp_prefix(fn, false, "con"))
119 {
120 return false;
121 }
122 if (cmp_prefix(fn, false, "prn"))
123 {
124 return false;
125 }
126 if (cmp_prefix(fn, false, "aux"))
127 {
128 return false;
129 }
130 if (cmp_prefix(fn, false, "nul"))
131 {
132 return false;
133 }
134 if (cmp_prefix(fn, true, "com"))
135 {
136 return false;
137 }
138 if (cmp_prefix(fn, true, "lpt"))
139 {
140 return false;
141 }
142 if (cmp_prefix(fn, false, "clock$"))
143 {
144 return false;
145 }
146 return true;
147}
148
149const char *
151{
152 static char tmpdir[MAX_PATH];
153 WCHAR wtmpdir[MAX_PATH];
154
155 if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
156 {
157 return NULL;
158 }
159
160 if (WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) > sizeof(tmpdir))
161 {
162 msg(M_WARN, "Could not get temporary directory. Path is too long."
163 " Consider using --tmp-dir");
164 return NULL;
165 }
166
167 WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof(tmpdir), NULL, NULL);
168 return tmpdir;
169}
170#endif /* _WIN32 */
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
#define msg(flags,...)
Definition error.h:152
#define M_WARN
Definition error.h:92
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
struct gc_arena gc
Definition test_ssl.c:131
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:75
bool win_safe_filename(const char *fn)
Definition win32-util.c:116
const char * win_get_tempdir(void)
Definition win32-util.c:150
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
Definition win32-util.c:40