OpenVPN
openvpn.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/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-2018 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 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #elif defined(_MSC_VER)
27 #include "config-msvc.h"
28 #endif
29 
30 #include "syshead.h"
31 
32 #include "init.h"
33 #include "forward.h"
34 #include "multi.h"
35 #include "win32.h"
36 #include "platform.h"
37 
38 #include "memdbg.h"
39 
40 #define P2P_CHECK_SIG() EVENT_LOOP_CHECK_SIGNAL(c, process_signal_p2p, c);
41 
42 static bool
44 {
45  remap_signal(c);
46  return process_signal(c);
47 }
48 
49 /* Write our PID to a file */
50 static void
51 write_pid(const char *filename)
52 {
53  if (filename)
54  {
55  unsigned int pid = 0;
56  FILE *fp = platform_fopen(filename, "w");
57  if (!fp)
58  {
59  msg(M_ERR, "Open error on pid file %s", filename);
60  }
61 
62  pid = platform_getpid();
63  fprintf(fp, "%u\n", pid);
64  if (fclose(fp))
65  {
66  msg(M_ERR, "Close error on pid file %s", filename);
67  }
68  }
69 }
70 
71 
72 /**************************************************************************/
80 static void
82 {
83  context_clear_2(c);
84 
85  /* set point-to-point mode */
86  c->mode = CM_P2P;
87 
88  /* initialize tunnel instance */
90  if (IS_SIG(c))
91  {
92  return;
93  }
94 
95  /* main event loop */
96  while (true)
97  {
99 
100  /* process timers, TLS, etc. */
101  pre_select(c);
102  P2P_CHECK_SIG();
103 
104  /* set up and do the I/O wait */
105  io_wait(c, p2p_iow_flags(c));
106  P2P_CHECK_SIG();
107 
108  /* timeout? */
109  if (c->c2.event_set_status == ES_TIMEOUT)
110  {
111  perf_pop();
112  continue;
113  }
114 
115  /* process the I/O which triggered select */
116  process_io(c);
117  P2P_CHECK_SIG();
118 
119  perf_pop();
120  }
121 
123 
124  /* tear down tunnel instance (unless --persist-tun) */
125  close_instance(c);
126 }
127 
128 #undef PROCESS_SIGNAL_P2P
129 
130 
131 /**************************************************************************/
151 static
152 int
153 openvpn_main(int argc, char *argv[])
154 {
155  struct context c;
156 
157 #if PEDANTIC
158  fprintf(stderr, "Sorry, I was built with --enable-pedantic and I am incapable of doing any real work!\n");
159  return 1;
160 #endif
161 
162 #ifdef _WIN32
163  SetConsoleOutputCP(CP_UTF8);
164 #endif
165 
166  CLEAR(c);
167 
168  /* signify first time for components which can
169  * only be initialized once per program instantiation. */
170  c.first_time = true;
171 
172  /* initialize program-wide statics */
173  if (init_static())
174  {
175  /*
176  * This loop is initially executed on startup and then
177  * once per SIGHUP.
178  */
179  do
180  {
181  /* enter pre-initialization mode with regard to signal handling */
183 
184  /* zero context struct but leave first_time member alone */
186 
187  /* static signal info object */
189  c.sig = &siginfo_static;
190 
191  /* initialize garbage collector scoped to context object */
192  gc_init(&c.gc);
193 
194  /* initialize environmental variable store */
195  c.es = env_set_create(NULL);
196 #ifdef _WIN32
198 #endif
199 
200 #ifdef ENABLE_MANAGEMENT
201  /* initialize management subsystem */
202  init_management();
203 #endif
204 
205  /* initialize options to default state */
206  init_options(&c.options, true);
207 
208  /* parse command line options, and read configuration file */
209  parse_argv(&c.options, argc, argv, M_USAGE, OPT_P_DEFAULT, NULL, c.es);
210 
211 #ifdef ENABLE_PLUGIN
212  /* plugins may contribute options configuration */
214  init_plugins(&c);
216 #endif
217 
218  net_ctx_init(&c, &c.net_ctx);
219 
220  /* init verbosity and mute levels */
222 
223  /* set dev options */
225 
226  /* openssl print info? */
227  if (print_openssl_info(&c.options))
228  {
229  break;
230  }
231 
232  /* --genkey mode? */
233  if (do_genkey(&c.options))
234  {
235  break;
236  }
237 
238  /* tun/tap persist command? */
239  if (do_persist_tuntap(&c.options, &c.net_ctx))
240  {
241  break;
242  }
243 
244  /* sanity check on options */
246 
247  /* show all option settings */
249 
250  /* print version number */
251  msg(M_INFO, "%s", title_string);
252 #ifdef _WIN32
254 #endif
256 
257  /* misc stuff */
258  pre_setup(&c.options);
259 
260  /* test crypto? */
261  if (do_test_crypto(&c.options))
262  {
263  break;
264  }
265 
266  /* Query passwords before becoming a daemon if we don't use the
267  * management interface to get them. */
268 #ifdef ENABLE_MANAGEMENT
270 #endif
272 
273  /* become a daemon if --daemon */
274  if (c.first_time)
275  {
278  }
279 
280 #ifdef ENABLE_MANAGEMENT
281  /* open management subsystem */
282  if (!open_management(&c))
283  {
284  break;
285  }
286  /* query for passwords through management interface, if needed */
288  {
290  }
291 #endif
292 
293  /* set certain options as environmental variables */
294  setenv_settings(c.es, &c.options);
295 
296  /* finish context init */
297  context_init_1(&c);
298 
299  do
300  {
301  /* run tunnel depending on mode */
302  switch (c.options.mode)
303  {
304  case MODE_POINT_TO_POINT:
306  break;
307 
308 #if P2MP_SERVER
309  case MODE_SERVER:
310  tunnel_server(&c);
311  break;
312 
313 #endif
314  default:
315  ASSERT(0);
316  }
317 
318  /* indicates first iteration -- has program-wide scope */
319  c.first_time = false;
320 
321  /* any signals received? */
322  if (IS_SIG(&c))
323  {
324  print_signal(c.sig, NULL, M_INFO);
325  }
326 
327  /* pass restart status to management subsystem */
329  }
330  while (c.sig->signal_received == SIGUSR1);
331 
332  env_set_destroy(c.es);
334  gc_reset(&c.gc);
335  }
336  while (c.sig->signal_received == SIGHUP);
337  }
338 
339  context_gc_free(&c);
340 
341 #ifdef ENABLE_MANAGEMENT
342  /* close management interface */
344 #endif
345 
346  /* uninitialize program-wide statics */
347  uninit_static();
348 
349  openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
350  return 0; /* NOTREACHED */
351 }
352 
353 #ifdef _WIN32
354 int
355 wmain(int argc, wchar_t *wargv[])
356 {
357  char **argv;
358  int ret;
359  int i;
360 
361  if ((argv = calloc(argc+1, sizeof(char *))) == NULL)
362  {
363  return 1;
364  }
365 
366  for (i = 0; i < argc; i++)
367  {
368  int n = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL);
369  argv[i] = malloc(n);
370  WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], n, NULL, NULL);
371  }
372 
373  ret = openvpn_main(argc, argv);
374 
375  for (i = 0; i < argc; i++)
376  {
377  free(argv[i]);
378  }
379  free(argv);
380 
381  return ret;
382 }
383 #else /* ifdef _WIN32 */
384 int
385 main(int argc, char *argv[])
386 {
387  return openvpn_main(argc, argv);
388 }
389 #endif /* ifdef _WIN32 */
struct signal_info siginfo_static
Definition: sig.c:46
static int openvpn_main(int argc, char *argv[])
OpenVPN&#39;s main init-run-cleanup loop.
Definition: openvpn.c:153
void print_signal(const struct signal_info *si, const char *title, int msglevel)
Definition: sig.c:130
unsigned int platform_getpid(void)
Definition: platform.c:178
struct env_set * env_set_create(struct gc_arena *gc)
Definition: env_set.c:158
#define OPT_P_DEFAULT
Definition: options.h:670
unsigned int management_flags
Definition: options.h:378
struct options options
Options loaded from command line or configuration file.
Definition: openvpn.h:502
void init_verb_mute(struct context *c, unsigned int flags)
Definition: init.c:981
#define PERF_EVENT_LOOP
Definition: perf.h:44
#define M_INFO
Definition: errlevel.h:55
Contains all state information for one tunnel.
Definition: openvpn.h:500
static void tunnel_point_to_point(struct context *c)
Main event loop for OpenVPN in client mode, where only one VPN tunnel is active.
Definition: openvpn.c:81
struct env_set * es
Set of environment variables.
Definition: openvpn.h:523
#define M_USAGE
Definition: error.h:111
void remap_signal(struct context *c)
Definition: sig.c:374
void openvpn_exit(const int status)
Definition: error.c:734
void close_instance(struct context *c)
Definition: init.c:4360
#define SIGUSR1
Definition: config-msvc.h:116
static void write_pid(const char *filename)
Definition: openvpn.c:51
static void perf_pop(void)
Definition: perf.h:82
static void perf_push(int type)
Definition: perf.h:78
struct signal_info * sig
Internal error signaling object.
Definition: openvpn.h:527
void open_plugins(struct context *c, const bool import_options, int init_point)
Definition: init.c:3789
void pre_select(struct context *c)
Definition: forward.c:1924
int wmain(int argc, wchar_t *wargv[])
Definition: openvpn.c:355
void init_query_passwords(const struct context *c)
Query for private key and auth-user-pass username/passwords.
Definition: init.c:531
#define SIGHUP
Definition: config-msvc.h:114
#define ASSERT(x)
Definition: error.h:221
void close_management(void)
Definition: init.c:3994
#define ES_TIMEOUT
Definition: openvpn.h:241
bool init_static(void)
Definition: init.c:725
#define MODE_SERVER
Definition: options.h:191
bool print_openssl_info(const struct options *options)
Definition: init.c:1014
void init_instance_handle_signals(struct context *c, const struct env_set *env, const unsigned int flags)
Definition: init.c:4022
void pre_init_signal_catch(void)
Definition: sig.c:239
void init_options_dev(struct options *options)
Definition: init.c:1004
FILE * platform_fopen(const char *path, const char *mode)
Definition: platform.c:302
openvpn_net_ctx_t net_ctx
Networking API opaque context.
Definition: openvpn.h:525
bool open_management(struct context *c)
Definition: init.c:3943
#define CLEAR(x)
Definition: basic.h:33
void context_gc_free(struct context *c)
Definition: init.c:686
bool do_genkey(const struct options *options)
Definition: init.c:1053
void set_win_sys_path_via_env(struct env_set *es)
Definition: win32.c:1224
int mode
Definition: options.h:192
int main(void)
Definition: test.c:44
#define malloc
Definition: cmocka.c:1795
static void gc_init(struct gc_arena *a)
Definition: buffer.h:1002
static int net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx)
Definition: networking.h:38
void uninit_static(void)
Definition: init.c:963
static bool process_signal_p2p(struct context *c)
Definition: openvpn.c:43
bool possibly_become_daemon(const struct options *options)
Definition: init.c:1149
#define OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE
static void io_wait(struct context *c, const unsigned int flags)
Definition: forward.h:386
void init_plugins(struct context *c)
Definition: init.c:3779
void process_io(struct context *c)
Definition: forward.c:2186
#define msg
Definition: error.h:173
Interface functions to the internal and external multiplexers.
#define IS_SIG(c)
Definition: sig.h:50
bool do_persist_tuntap(const struct options *options, openvpn_net_ctx_t *ctx)
Definition: init.c:1108
struct context_2 c2
Level 2 context.
Definition: openvpn.h:541
const char * writepid
Definition: options.h:296
void env_set_destroy(struct env_set *es)
Definition: env_set.c:168
void show_library_versions(const unsigned int flags)
Definition: options.c:4144
void context_clear_all_except_first_time(struct context *c)
Definition: init.c:88
void show_windows_version(const unsigned int flags)
Definition: options.c:4135
void context_init_1(struct context *c)
Definition: init.c:637
bool process_signal(struct context *c)
Definition: sig.c:439
void signal_restart_status(const struct signal_info *si)
Definition: sig.c:184
void tunnel_server(struct context *top)
Main event loop for OpenVPN in server mode.
Definition: multi.c:3377
#define MODE_POINT_TO_POINT
Definition: options.h:190
#define MF_QUERY_PASSWORDS
Definition: manage.h:333
void pre_setup(const struct options *options)
Definition: init.c:1278
volatile int signal_received
Definition: sig.h:45
void init_options(struct options *o, const bool init_gc)
Definition: options.c:794
#define M_ERR
Definition: error.h:110
void show_settings(const struct options *o)
Definition: options.c:1511
void uninit_options(struct options *o)
Definition: options.c:916
int mode
Role of this context within the OpenVPN process.
Definition: openvpn.h:514
bool do_test_crypto(const struct options *o)
Definition: init.c:4624
void context_clear_2(struct context *c)
Definition: init.c:82
#define P2P_CHECK_SIG()
Definition: openvpn.c:40
bool first_time
True on the first iteration of OpenVPN&#39;s main loop.
Definition: openvpn.h:505
#define IVM_LEVEL_1
Definition: init.h:49
#define free
Definition: cmocka.c:1850
void init_management(void)
Definition: init.c:3934
static unsigned int p2p_iow_flags(const struct context *c)
Definition: forward.h:367
struct gc_arena gc
Garbage collection arena for allocations done in the scope of this context structure.
Definition: openvpn.h:519
void setenv_settings(struct env_set *es, const struct options *o)
Definition: options.c:998
static void gc_reset(struct gc_arena *a)
Definition: buffer.h:1036
Definition: argv.h:35
bool did_we_daemonize
Whether demonization has already taken place.
Definition: openvpn.h:534
void parse_argv(struct options *options, const int argc, char *argv[], const int msglevel, const unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es)
Definition: options.c:4648
unsigned int event_set_status
Definition: openvpn.h:250
#define CM_P2P
Definition: openvpn.h:509
#define OPENVPN_EXIT_STATUS_GOOD
Definition: error.h:55
const char title_string[]
Definition: options.c:65
#define CC_HARD_USR1_TO_HUP
Definition: init.h:108
void uninit_management_callback(void)
Definition: init.c:4007
void options_postprocess(struct options *options)
Definition: options.c:3379