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  case MODE_SERVER:
309  tunnel_server(&c);
310  break;
311 
312  default:
313  ASSERT(0);
314  }
315 
316  /* indicates first iteration -- has program-wide scope */
317  c.first_time = false;
318 
319  /* any signals received? */
320  if (IS_SIG(&c))
321  {
322  print_signal(c.sig, NULL, M_INFO);
323  }
324 
325  /* pass restart status to management subsystem */
327  }
328  while (c.sig->signal_received == SIGUSR1);
329 
330  env_set_destroy(c.es);
332  gc_reset(&c.gc);
333  net_ctx_free(&c.net_ctx);
334  }
335  while (c.sig->signal_received == SIGHUP);
336  }
337 
338  context_gc_free(&c);
339 
340 #ifdef ENABLE_MANAGEMENT
341  /* close management interface */
343 #endif
344 
345  /* uninitialize program-wide statics */
346  uninit_static();
347 
348  openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
349  return 0; /* NOTREACHED */
350 }
351 
352 #ifdef _WIN32
353 int
354 wmain(int argc, wchar_t *wargv[])
355 {
356  char **argv;
357  int ret;
358  int i;
359 
360  if ((argv = calloc(argc+1, sizeof(char *))) == NULL)
361  {
362  return 1;
363  }
364 
365  for (i = 0; i < argc; i++)
366  {
367  int n = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL);
368  argv[i] = malloc(n);
369  WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], n, NULL, NULL);
370  }
371 
372  ret = openvpn_main(argc, argv);
373 
374  for (i = 0; i < argc; i++)
375  {
376  free(argv[i]);
377  }
378  free(argv);
379 
380  return ret;
381 }
382 #else /* ifdef _WIN32 */
383 int
384 main(int argc, char *argv[])
385 {
386  return openvpn_main(argc, argv);
387 }
388 #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:693
unsigned int management_flags
Definition: options.h:395
struct options options
Options loaded from command line or configuration file.
Definition: openvpn.h:499
void init_verb_mute(struct context *c, unsigned int flags)
Definition: init.c:978
#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:497
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:520
#define M_USAGE
Definition: error.h:111
void remap_signal(struct context *c)
Definition: sig.c:377
void openvpn_exit(const int status)
Definition: error.c:737
void close_instance(struct context *c)
Definition: init.c:4413
#define SIGUSR1
Definition: config-msvc.h:153
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:524
void open_plugins(struct context *c, const bool import_options, int init_point)
Definition: init.c:3842
void pre_select(struct context *c)
Definition: forward.c:1940
int wmain(int argc, wchar_t *wargv[])
Definition: openvpn.c:354
void init_query_passwords(const struct context *c)
Query for private key and auth-user-pass username/passwords.
Definition: init.c:537
#define SIGHUP
Definition: config-msvc.h:151
#define ASSERT(x)
Definition: error.h:221
void close_management(void)
Definition: init.c:4047
#define ES_TIMEOUT
Definition: openvpn.h:239
bool init_static(void)
Definition: init.c:731
#define MODE_SERVER
Definition: options.h:205
bool print_openssl_info(const struct options *options)
Definition: init.c:1011
void init_instance_handle_signals(struct context *c, const struct env_set *env, const unsigned int flags)
Definition: init.c:4075
void pre_init_signal_catch(void)
Definition: sig.c:239
void init_options_dev(struct options *options)
Definition: init.c:1001
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:522
bool open_management(struct context *c)
Definition: init.c:3996
#define CLEAR(x)
Definition: basic.h:33
void context_gc_free(struct context *c)
Definition: init.c:692
bool do_genkey(const struct options *options)
Definition: init.c:1050
void set_win_sys_path_via_env(struct env_set *es)
Definition: win32.c:1224
int mode
Definition: options.h:206
int main(void)
Definition: test.c:49
#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:960
static bool process_signal_p2p(struct context *c)
Definition: openvpn.c:43
bool possibly_become_daemon(const struct options *options)
Definition: init.c:1174
#define OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE
static void io_wait(struct context *c, const unsigned int flags)
Definition: forward.h:392
void init_plugins(struct context *c)
Definition: init.c:3832
void process_io(struct context *c)
Definition: forward.c:2213
#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:1133
struct context_2 c2
Level 2 context.
Definition: openvpn.h:538
const char * writepid
Definition: options.h:313
void env_set_destroy(struct env_set *es)
Definition: env_set.c:168
void show_library_versions(const unsigned int flags)
Definition: options.c:4294
void context_clear_all_except_first_time(struct context *c)
Definition: init.c:90
void show_windows_version(const unsigned int flags)
Definition: options.c:4285
void context_init_1(struct context *c)
Definition: init.c:643
bool process_signal(struct context *c)
Definition: sig.c:442
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:3434
#define MODE_POINT_TO_POINT
Definition: options.h:204
#define MF_QUERY_PASSWORDS
Definition: manage.h:333
void pre_setup(const struct options *options)
Definition: init.c:1303
volatile int signal_received
Definition: sig.h:45
void init_options(struct options *o, const bool init_gc)
Definition: options.c:802
#define M_ERR
Definition: error.h:110
void show_settings(const struct options *o)
Definition: options.c:1532
void uninit_options(struct options *o)
Definition: options.c:923
int mode
Role of this context within the OpenVPN process.
Definition: openvpn.h:511
bool do_test_crypto(const struct options *o)
Definition: init.c:4678
static void net_ctx_free(openvpn_net_ctx_t *ctx)
Definition: networking.h:50
void context_clear_2(struct context *c)
Definition: init.c:84
#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:502
#define IVM_LEVEL_1
Definition: init.h:49
#define free
Definition: cmocka.c:1850
void init_management(void)
Definition: init.c:3987
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:516
void setenv_settings(struct env_set *es, const struct options *o)
Definition: options.c:1005
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:531
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:4808
unsigned int event_set_status
Definition: openvpn.h:248
#define CM_P2P
Definition: openvpn.h:506
#define OPENVPN_EXIT_STATUS_GOOD
Definition: error.h:55
const char title_string[]
Definition: options.c:67
#define CC_HARD_USR1_TO_HUP
Definition: init.h:108
void uninit_management_callback(void)
Definition: init.c:4060
void options_postprocess(struct options *options)
Definition: options.c:3502