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(&c);
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  /* init verbosity and mute levels */
220 
221  /* set dev options */
223 
224  /* openssl print info? */
225  if (print_openssl_info(&c.options))
226  {
227  break;
228  }
229 
230  /* --genkey mode? */
231  if (do_genkey(&c.options))
232  {
233  break;
234  }
235 
236  /* tun/tap persist command? */
237  if (do_persist_tuntap(&c.options))
238  {
239  break;
240  }
241 
242  /* sanity check on options */
244 
245  /* show all option settings */
247 
248  /* print version number */
249  msg(M_INFO, "%s", title_string);
250 #ifdef _WIN32
252 #endif
254 
255  /* misc stuff */
256  pre_setup(&c.options);
257 
258  /* test crypto? */
259  if (do_test_crypto(&c.options))
260  {
261  break;
262  }
263 
264  /* Query passwords before becoming a daemon if we don't use the
265  * management interface to get them. */
266 #ifdef ENABLE_MANAGEMENT
268 #endif
270 
271  /* become a daemon if --daemon */
272  if (c.first_time)
273  {
276  }
277 
278 #ifdef ENABLE_MANAGEMENT
279  /* open management subsystem */
280  if (!open_management(&c))
281  {
282  break;
283  }
284  /* query for passwords through management interface, if needed */
286  {
288  }
289 #endif
290 
291  /* set certain options as environmental variables */
292  setenv_settings(c.es, &c.options);
293 
294  /* finish context init */
295  context_init_1(&c);
296 
297  do
298  {
299  /* run tunnel depending on mode */
300  switch (c.options.mode)
301  {
302  case MODE_POINT_TO_POINT:
304  break;
305 
306 #if P2MP_SERVER
307  case MODE_SERVER:
308  tunnel_server(&c);
309  break;
310 
311 #endif
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  }
334  while (c.sig->signal_received == SIGHUP);
335  }
336 
337  context_gc_free(&c);
338 
339 #ifdef ENABLE_MANAGEMENT
340  /* close management interface */
342 #endif
343 
344  /* uninitialize program-wide statics */
345  uninit_static();
346 
347  openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
348  return 0; /* NOTREACHED */
349 }
350 
351 #ifdef _WIN32
352 int
353 wmain(int argc, wchar_t *wargv[])
354 {
355  char **argv;
356  int ret;
357  int i;
358 
359  if ((argv = calloc(argc+1, sizeof(char *))) == NULL)
360  {
361  return 1;
362  }
363 
364  for (i = 0; i < argc; i++)
365  {
366  int n = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL);
367  argv[i] = malloc(n);
368  WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], n, NULL, NULL);
369  }
370 
371  ret = openvpn_main(argc, argv);
372 
373  for (i = 0; i < argc; i++)
374  {
375  free(argv[i]);
376  }
377  free(argv);
378 
379  return ret;
380 }
381 #else /* ifdef _WIN32 */
382 int
383 main(int argc, char *argv[])
384 {
385  return openvpn_main(argc, argv);
386 }
387 #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:652
unsigned int management_flags
Definition: options.h:371
struct options options
Options loaded from command line or configuration file.
Definition: openvpn.h:500
void init_verb_mute(struct context *c, unsigned int flags)
Definition: init.c:981
#define OPENVPN_EXIT_STATUS_GOOD
Definition: error.h:55
#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:498
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:521
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:4288
#define ASSERT(x)
Definition: error.h:221
#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
#define CLEAR(x)
Definition: basic.h:33
struct signal_info * sig
Internal error signaling object.
Definition: openvpn.h:523
void open_plugins(struct context *c, const bool import_options, int init_point)
Definition: init.c:3717
void pre_select(struct context *c)
Definition: forward.c:1764
int wmain(int argc, wchar_t *wargv[])
Definition: openvpn.c:353
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
void init_management(struct context *c)
Definition: init.c:3862
void close_management(void)
Definition: init.c:3922
#define ES_TIMEOUT
Definition: openvpn.h:239
bool init_static(void)
Definition: init.c:725
#define MODE_SERVER
Definition: options.h:186
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:3950
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
bool open_management(struct context *c)
Definition: init.c:3871
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:1221
int mode
Definition: options.h:187
int main(void)
Definition: test.c:44
#define malloc
Definition: cmocka.c:1795
#define M_USAGE
Definition: error.h:111
bool do_persist_tuntap(const struct options *options)
Definition: init.c:1085
static void gc_init(struct gc_arena *a)
Definition: buffer.h:978
void uninit_static(void)
Definition: init.c:963
#define M_ERR
Definition: error.h:110
static bool process_signal_p2p(struct context *c)
Definition: openvpn.c:43
bool possibly_become_daemon(const struct options *options)
Definition: init.c:1125
#define OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE
static void io_wait(struct context *c, const unsigned int flags)
Definition: forward.h:353
void init_plugins(struct context *c)
Definition: init.c:3707
void process_io(struct context *c)
Definition: forward.c:2026
Interface functions to the internal and external multiplexers.
#define IS_SIG(c)
Definition: sig.h:50
struct context_2 c2
Level 2 context.
Definition: openvpn.h:537
const char * writepid
Definition: options.h:291
void env_set_destroy(struct env_set *es)
Definition: env_set.c:168
void show_library_versions(const unsigned int flags)
Definition: options.c:4103
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:4094
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:3385
#define MODE_POINT_TO_POINT
Definition: options.h:185
#define MF_QUERY_PASSWORDS
Definition: manage.h:333
void pre_setup(const struct options *options)
Definition: init.c:1254
volatile int signal_received
Definition: sig.h:45
void init_options(struct options *o, const bool init_gc)
Definition: options.c:779
void show_settings(const struct options *o)
Definition: options.c:1495
void uninit_options(struct options *o)
Definition: options.c:901
int mode
Role of this context within the OpenVPN process.
Definition: openvpn.h:512
#define msg
Definition: error.h:173
bool do_test_crypto(const struct options *o)
Definition: init.c:4551
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:503
#define IVM_LEVEL_1
Definition: init.h:49
#define free
Definition: cmocka.c:1850
static unsigned int p2p_iow_flags(const struct context *c)
Definition: forward.h:334
struct gc_arena gc
Garbage collection arena for allocations done in the scope of this context structure.
Definition: openvpn.h:517
void setenv_settings(struct env_set *es, const struct options *o)
Definition: options.c:983
static void gc_reset(struct gc_arena *a)
Definition: buffer.h:1012
Definition: argv.h:35
bool did_we_daemonize
Whether demonization has already taken place.
Definition: openvpn.h:530
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:4607
unsigned int event_set_status
Definition: openvpn.h:248
#define CM_P2P
Definition: openvpn.h:507
const char title_string[]
Definition: options.c:65
#define CC_HARD_USR1_TO_HUP
Definition: init.h:107
void uninit_management_callback(void)
Definition: init.c:3935
void options_postprocess(struct options *options)
Definition: options.c:3340