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