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-2010 OpenVPN Technologies, 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
20 *  along with this program (see the file COPYING included with this
21 *  distribution); if not, write to the Free Software Foundation, Inc.,
22 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25#ifdef WIN32
26#ifndef OPENVPN_WIN32_H
27#define OPENVPN_WIN32_H
28
29#include "mtu.h"
30
31/* location of executables */
32#define SYS_PATH_ENV_VAR_NAME "SystemRoot"  /* environmental variable name that normally contains the system path */
33#define NETSH_PATH_SUFFIX     "\\system32\\netsh.exe"
34#define WIN_ROUTE_PATH_SUFFIX "\\system32\\route.exe"
35#define WIN_IPCONFIG_PATH_SUFFIX "\\system32\\ipconfig.exe"
36#define WIN_NET_PATH_SUFFIX "\\system32\\net.exe"
37
38/*
39 * Win32-specific OpenVPN code, targetted at the mingw
40 * development environment.
41 */
42
43/* MSVC headers do not define this macro, so do it here */
44#ifndef IN6_ARE_ADDR_EQUAL
45#define IN6_ARE_ADDR_EQUAL(a,b) \
46  (memcmp ((const void*)(a), (const void*)(b), sizeof (struct in6_addr)) == 0)
47#endif
48
49void init_win32 (void);
50void uninit_win32 (void);
51
52void set_pause_exit_win32 (void);
53
54struct security_attributes
55{
56  SECURITY_ATTRIBUTES sa;
57  SECURITY_DESCRIPTOR sd;
58};
59
60#define HANDLE_DEFINED(h) ((h) != NULL && (h) != INVALID_HANDLE_VALUE)
61
62/*
63 * Save old window title.
64 */
65struct window_title
66{
67  bool saved;
68  char old_window_title [256];
69};
70
71struct rw_handle {
72  HANDLE read;
73  HANDLE write;
74};
75
76/*
77 * Event-based notification of incoming TCP connections
78 */
79
80#define NE32_PERSIST_EVENT (1<<0)
81#define NE32_WRITE_EVENT   (1<<1)
82
83static inline bool
84defined_net_event_win32 (const struct rw_handle *event)
85{
86  return event->read != NULL;
87}
88
89void init_net_event_win32 (struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags);
90long reset_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd);
91void close_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd, unsigned int flags);
92
93/*
94 * A stateful variant of the net_event_win32 functions above
95 */
96
97struct net_event_win32
98{
99  struct rw_handle handle;
100  socket_descriptor_t sd;
101  long event_mask;
102};
103
104void net_event_win32_init (struct net_event_win32 *ne);
105void net_event_win32_start (struct net_event_win32 *ne, long network_events, socket_descriptor_t sd);
106void net_event_win32_reset (struct net_event_win32 *ne);
107void net_event_win32_reset_write (struct net_event_win32 *ne);
108void net_event_win32_stop (struct net_event_win32 *ne);
109void net_event_win32_close (struct net_event_win32 *ne);
110
111static inline bool
112net_event_win32_defined (const struct net_event_win32 *ne)
113{
114  return defined_net_event_win32 (&ne->handle);
115}
116
117static inline struct rw_handle *
118net_event_win32_get_event (struct net_event_win32 *ne)
119{
120  return &ne->handle;
121}
122
123static inline long
124net_event_win32_get_event_mask (const struct net_event_win32 *ne)
125{
126  return ne->event_mask;
127}
128
129static inline void
130net_event_win32_clear_selected_events (struct net_event_win32 *ne, long selected_events)
131{
132  ne->event_mask &= ~selected_events;
133}
134
135/*
136 * Signal handling
137 */
138struct win32_signal {
139# define WSO_MODE_UNDEF   0
140# define WSO_MODE_SERVICE 1
141# define WSO_MODE_CONSOLE 2
142  int mode;
143  struct rw_handle in;
144  DWORD console_mode_save;
145  bool console_mode_save_defined;
146};
147
148extern struct win32_signal win32_signal; /* static/global */
149extern struct window_title window_title; /* static/global */
150
151void win32_signal_clear (struct win32_signal *ws);
152
153/* win32_signal_open startup type */
154#define WSO_NOFORCE       0
155#define WSO_FORCE_SERVICE 1
156#define WSO_FORCE_CONSOLE 2
157
158void win32_signal_open (struct win32_signal *ws,
159			int force, /* set to WSO force parm */
160			const char *exit_event_name,
161			bool exit_event_initial_state);
162
163void win32_signal_close (struct win32_signal *ws);
164
165int win32_signal_get (struct win32_signal *ws);
166
167void win32_pause (struct win32_signal *ws);
168
169bool win32_service_interrupt (struct win32_signal *ws);
170
171/*
172 * Set the text on the window title bar
173 */
174
175void window_title_clear (struct window_title *wt);
176void window_title_save (struct window_title *wt);
177void window_title_restore (const struct window_title *wt);
178void window_title_generate (const char *title);
179
180/*
181 * We try to do all Win32 I/O using overlapped
182 * (i.e. asynchronous) I/O for a performance win.
183 */
184struct overlapped_io {
185# define IOSTATE_INITIAL          0
186# define IOSTATE_QUEUED           1 /* overlapped I/O has been queued */
187# define IOSTATE_IMMEDIATE_RETURN 2 /* I/O function returned immediately without queueing */
188  int iostate;
189  OVERLAPPED overlapped;
190  DWORD size;
191  DWORD flags;
192  int status;
193  bool addr_defined;
194  union {
195    struct sockaddr_in addr;
196    struct sockaddr_in6 addr6;
197  };
198  int addrlen;
199  struct buffer buf_init;
200  struct buffer buf;
201};
202
203void overlapped_io_init (struct overlapped_io *o,
204			 const struct frame *frame,
205			 BOOL event_state,
206			 bool tuntap_buffer);
207
208void overlapped_io_close (struct overlapped_io *o);
209
210static inline bool
211overlapped_io_active (struct overlapped_io *o)
212{
213  return o->iostate == IOSTATE_QUEUED || o->iostate == IOSTATE_IMMEDIATE_RETURN;
214}
215
216char *overlapped_io_state_ascii (const struct overlapped_io *o);
217
218/*
219 * Use to control access to resources that only one
220 * OpenVPN process on a given machine can access at
221 * a given time.
222 */
223
224struct semaphore
225{
226  const char *name;
227  bool locked;
228  HANDLE hand;
229};
230
231void semaphore_clear (struct semaphore *s);
232void semaphore_open (struct semaphore *s, const char *name);
233bool semaphore_lock (struct semaphore *s, int timeout_milliseconds);
234void semaphore_release (struct semaphore *s);
235void semaphore_close (struct semaphore *s);
236
237/*
238 * Special global semaphore used to protect network
239 * shell commands from simultaneous instantiation.
240 *
241 * It seems you can't run more than one instance
242 * of netsh on the same machine at the same time.
243 */
244
245extern struct semaphore netcmd_semaphore;
246void netcmd_semaphore_init (void);
247void netcmd_semaphore_close (void);
248void netcmd_semaphore_lock (void);
249void netcmd_semaphore_release (void);
250
251/* Set Win32 security attributes structure to allow all access */
252bool init_security_attributes_allow_all (struct security_attributes *obj);
253
254/* return true if filename is safe to be used on Windows */
255bool win_safe_filename (const char *fn);
256
257/* add constant environmental variables needed by Windows */
258struct env_set;
259
260/* get and set the current windows system path */
261void set_win_sys_path (const char *newpath, struct env_set *es);
262void set_win_sys_path_via_env (struct env_set *es);
263char *get_win_sys_path (void);
264
265/* call self in a subprocess */
266void fork_to_self (const char *cmdline);
267
268/* Find temporary directory */
269const char *win_get_tempdir();
270
271/* Convert a string from UTF-8 to UCS-2 */
272WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
273
274#endif
275#endif
276