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-2024 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 #endif
27 
28 #include "syshead.h"
29 
30 #include "init.h"
31 #include "forward.h"
32 #include "multi.h"
33 #include "win32.h"
34 #include "platform.h"
35 
36 #include "memdbg.h"
37 
38 #define P2P_CHECK_SIG() EVENT_LOOP_CHECK_SIGNAL(c, process_signal_p2p, c);
39 
40 static bool
42 {
43  remap_signal(c);
44  return process_signal(c);
45 }
46 
47 
48 /**************************************************************************/
56 static void
58 {
59  context_clear_2(c);
60 
61  /* set point-to-point mode */
62  c->mode = CM_P2P;
63 
64  /* initialize tunnel instance */
66  if (IS_SIG(c))
67  {
68  return;
69  }
70 
71  /* main event loop */
72  while (true)
73  {
75 
76  /* process timers, TLS, etc. */
77  pre_select(c);
78  P2P_CHECK_SIG();
79 
80  /* set up and do the I/O wait */
81  io_wait(c, p2p_iow_flags(c));
82  P2P_CHECK_SIG();
83 
84  /* timeout? */
85  if (c->c2.event_set_status == ES_TIMEOUT)
86  {
87  perf_pop();
88  continue;
89  }
90 
91  /* process the I/O which triggered select */
92  process_io(c);
93  P2P_CHECK_SIG();
94 
95  perf_pop();
96  }
97 
99 
101 
102  /* tear down tunnel instance (unless --persist-tun) */
103  close_instance(c);
104 }
105 
106 #undef PROCESS_SIGNAL_P2P
107 
108 void
109 init_early(struct context *c)
110 {
111  net_ctx_init(c, &c->net_ctx);
112 
113  /* init verbosity and mute levels */
115 
116  /* Initialise OpenSSL provider, this needs to be initialised this
117  * early since option post-processing and also openssl info
118  * printing depends on it */
119  for (int j = 1; j < MAX_PARMS && c->options.providers.names[j]; j++)
120  {
121  c->options.providers.providers[j] =
123  }
124 }
125 
126 static void
128 {
129  for (int j = 1; j < MAX_PARMS && c->options.providers.providers[j]; j++)
130  {
132  c->options.providers.providers[j]);
133  }
134  net_ctx_free(&c->net_ctx);
135 }
136 
137 
138 /**************************************************************************/
158 static
159 int
160 openvpn_main(int argc, char *argv[])
161 {
162  struct context c;
163 
164 #if PEDANTIC
165  fprintf(stderr, "Sorry, I was built with --enable-pedantic and I am incapable of doing any real work!\n");
166  return 1;
167 #endif
168 
169 #ifdef _WIN32
170  SetConsoleOutputCP(CP_UTF8);
171 #endif
172 
173  CLEAR(c);
174 
175  /* signify first time for components which can
176  * only be initialized once per program instantiation. */
177  c.first_time = true;
178 
179  /* initialize program-wide statics */
180  if (init_static())
181  {
182  /*
183  * This loop is initially executed on startup and then
184  * once per SIGHUP.
185  */
186  do
187  {
188  /* enter pre-initialization mode with regard to signal handling */
190 
191  /* zero context struct but leave first_time member alone */
193 
194  /* static signal info object */
195  c.sig = &siginfo_static;
196 
197  /* initialize garbage collector scoped to context object */
198  gc_init(&c.gc);
199 
200  /* initialize environmental variable store */
201  c.es = env_set_create(NULL);
202 #ifdef _WIN32
204 #endif
205 
206 #ifdef ENABLE_MANAGEMENT
207  /* initialize management subsystem */
208  init_management();
209 #endif
210 
211  /* initialize options to default state */
212  init_options(&c.options, true);
213 
214  /* parse command line options, and read configuration file */
215  parse_argv(&c.options, argc, argv, M_USAGE, OPT_P_DEFAULT, NULL, c.es);
216 
217 #ifdef ENABLE_PLUGIN
218  /* plugins may contribute options configuration */
220  init_plugins(&c);
222 #endif
223 
224  /* Early initialisation that need to happen before option
225  * post processing and other early startup but after parsing */
226  init_early(&c);
227 
228  /* set dev options */
230 
231  /* openssl print info? */
232  if (print_openssl_info(&c.options))
233  {
234  break;
235  }
236 
237  /* --genkey mode? */
238  if (do_genkey(&c.options))
239  {
240  break;
241  }
242 
243  /* tun/tap persist command? */
244  if (do_persist_tuntap(&c.options, &c.net_ctx))
245  {
246  break;
247  }
248 
249  /* sanity check on options */
251 
252  /* show all option settings */
254 
255  /* print version number */
256  msg(M_INFO, "%s", title_string);
257 #ifdef _WIN32
259 #endif
261 
263 
264  /* misc stuff */
265  pre_setup(&c.options);
266 
267  /* test crypto? */
268  if (do_test_crypto(&c.options))
269  {
270  break;
271  }
272 
273  /* Query passwords before becoming a daemon if we don't use the
274  * management interface to get them. */
275 #ifdef ENABLE_MANAGEMENT
277 #endif
279 
280  /* become a daemon if --daemon */
281  if (c.first_time)
282  {
285  }
286 
287 #ifdef ENABLE_MANAGEMENT
288  /* open management subsystem */
289  if (!open_management(&c))
290  {
291  break;
292  }
293  /* query for passwords through management interface, if needed */
295  {
297  }
298 #endif
299 
300  /* set certain options as environmental variables */
301  setenv_settings(c.es, &c.options);
302 
303  /* finish context init */
304  context_init_1(&c);
305 
306  do
307  {
308  /* run tunnel depending on mode */
309  switch (c.options.mode)
310  {
311  case MODE_POINT_TO_POINT:
313  break;
314 
315  case MODE_SERVER:
316  tunnel_server(&c);
317  break;
318 
319  default:
320  ASSERT(0);
321  }
322 
323  /* indicates first iteration -- has program-wide scope */
324  c.first_time = false;
325 
326  /* any signals received? */
327  if (IS_SIG(&c))
328  {
329  print_signal(c.sig, NULL, M_INFO);
330  }
331 
332  /* pass restart status to management subsystem */
334  }
335  while (signal_reset(c.sig, SIGUSR1) == SIGUSR1);
336 
337  env_set_destroy(c.es);
339  gc_reset(&c.gc);
340  uninit_early(&c);
341  }
342  while (signal_reset(c.sig, SIGHUP) == SIGHUP);
343  }
344 
345  context_gc_free(&c);
346 
347 #ifdef ENABLE_MANAGEMENT
348  /* close management interface */
350 #endif
351 
352  /* uninitialize program-wide statics */
353  uninit_static();
354 
355  openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
356  return 0; /* NOTREACHED */
357 }
358 
359 #ifdef _WIN32
360 int
361 wmain(int argc, wchar_t *wargv[])
362 {
363  char **argv;
364  int ret;
365  int i;
366 
367  if ((argv = calloc(argc+1, sizeof(char *))) == NULL)
368  {
369  return 1;
370  }
371 
372  for (i = 0; i < argc; i++)
373  {
374  int n = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL);
375  argv[i] = malloc(n);
376  WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], n, NULL, NULL);
377  }
378 
379  ret = openvpn_main(argc, argv);
380 
381  for (i = 0; i < argc; i++)
382  {
383  free(argv[i]);
384  }
385  free(argv);
386 
387  return ret;
388 }
389 #else /* ifdef _WIN32 */
390 int
391 main(int argc, char *argv[])
392 {
393  return openvpn_main(argc, argv);
394 }
395 #endif /* ifdef _WIN32 */
signal_restart_status
void signal_restart_status(const struct signal_info *si)
Definition: sig.c:348
uninit_early
static void uninit_early(struct context *c)
Definition: openvpn.c:127
do_test_crypto
bool do_test_crypto(const struct options *o)
Definition: init.c:5013
context_2::event_set_status
unsigned int event_set_status
Definition: openvpn.h:238
OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE
#define OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE
Definition: openvpn-plugin.h:766
M_INFO
#define M_INFO
Definition: errlevel.h:55
openvpn_main
static int openvpn_main(int argc, char *argv[])
OpenVPN's main init-run-cleanup loop.
Definition: openvpn.c:160
init_early
void init_early(struct context *c)
Definition: openvpn.c:109
print_signal
void print_signal(const struct signal_info *si, const char *title, int msglevel)
Definition: sig.c:294
forward.h
open_management
bool open_management(struct context *c)
Definition: init.c:4295
OPT_P_DEFAULT
#define OPT_P_DEFAULT
Definition: options.h:744
init_query_passwords
void init_query_passwords(const struct context *c)
Query for private key and auth-user-pass username/passwords.
Definition: init.c:641
win32.h
env_set_destroy
void env_set_destroy(struct env_set *es)
Definition: env_set.c:166
argv
Definition: argv.h:35
context
Contains all state information for one tunnel.
Definition: openvpn.h:476
OPENVPN_EXIT_STATUS_GOOD
#define OPENVPN_EXIT_STATUS_GOOD
Definition: error.h:53
print_openssl_info
bool print_openssl_info(const struct options *options)
Definition: init.c:973
options::mode
int mode
Definition: options.h:247
MAX_PARMS
#define MAX_PARMS
Definition: options.h:52
pre_select
void pre_select(struct context *c)
Definition: forward.c:1997
provider_list::providers
provider_t * providers[MAX_PARMS]
Definition: options.h:202
context_gc_free
void context_gc_free(struct context *c)
Definition: init.c:777
gc_reset
static void gc_reset(struct gc_arena *a)
Definition: buffer.h:1051
context::mode
int mode
Role of this context within the OpenVPN process.
Definition: openvpn.h:490
MODE_SERVER
#define MODE_SERVER
Definition: options.h:246
provider_list::names
const char * names[MAX_PARMS]
Definition: options.h:200
net_ctx_init
static int net_ctx_init(struct context *c, openvpn_net_ctx_t *ctx)
Definition: networking.h:48
CLEAR
#define CLEAR(x)
Definition: basic.h:33
wmain
int wmain(int argc, wchar_t *wargv[])
Definition: openvpn.c:361
context::c2
struct context_2 c2
Level 2 context.
Definition: openvpn.h:517
process_signal_p2p
static bool process_signal_p2p(struct context *c)
Definition: openvpn.c:41
options::writepid
const char * writepid
Definition: options.h:366
ASSERT
#define ASSERT(x)
Definition: error.h:195
tunnel_point_to_point
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:57
context::gc
struct gc_arena gc
Garbage collection arena for allocations done in the scope of this context structure.
Definition: openvpn.h:495
open_plugins
void open_plugins(struct context *c, const bool import_options, int init_point)
Definition: init.c:4138
io_wait
static void io_wait(struct context *c, const unsigned int flags)
Definition: forward.h:365
tunnel_server
void tunnel_server(struct context *top)
Main event loop for OpenVPN in server mode.
Definition: multi.c:4169
MF_QUERY_PASSWORDS
#define MF_QUERY_PASSWORDS
Definition: manage.h:29
init.h
context::first_time
bool first_time
True on the first iteration of OpenVPN's main loop.
Definition: openvpn.h:481
close_instance
void close_instance(struct context *c)
Definition: init.c:4711
perf_pop
static void perf_pop(void)
Definition: perf.h:82
init_verb_mute
void init_verb_mute(struct context *c, unsigned int flags)
Definition: init.c:940
context::options
struct options options
Options loaded from command line or configuration file.
Definition: openvpn.h:478
options::providers
struct provider_list providers
Definition: options.h:562
multi.h
set_win_sys_path_via_env
void set_win_sys_path_via_env(struct env_set *es)
Definition: win32.c:1128
write_pid_file
void write_pid_file(const char *filename, const char *chroot_dir)
Definition: init.c:4946
IVM_LEVEL_1
#define IVM_LEVEL_1
Definition: init.h:49
options_postprocess
void options_postprocess(struct options *options, struct env_set *es)
Definition: options.c:4179
git-version.main
def main()
Definition: git-version.py:56
context::did_we_daemonize
bool did_we_daemonize
Whether demonization has already taken place.
Definition: openvpn.h:510
crypto_unload_provider
void crypto_unload_provider(const char *provname, provider_t *provider)
Unloads the given (OpenSSL) provider.
Definition: crypto_openssl.c:177
pre_setup
void pre_setup(const struct options *options)
Definition: init.c:1295
openvpn_exit
void openvpn_exit(const int status)
Definition: error.c:735
show_windows_version
void show_windows_version(const unsigned int flags)
Definition: options.c:4857
init_management
void init_management(void)
Definition: init.c:4286
pre_init_signal_catch
void pre_init_signal_catch(void)
Definition: sig.c:398
init_static
bool init_static(void)
Definition: init.c:816
process_signal
bool process_signal(struct context *c)
Definition: sig.c:637
env_set_create
struct env_set * env_set_create(struct gc_arena *gc)
Definition: env_set.c:156
signal_reset
int signal_reset(struct signal_info *si, int signum)
Clear the signal if its current value equals signum.
Definition: sig.c:266
net_ctx_free
static void net_ctx_free(openvpn_net_ctx_t *ctx)
Definition: networking.h:63
syshead.h
options::management_flags
unsigned int management_flags
Definition: options.h:443
process_io
void process_io(struct context *c)
Definition: forward.c:2285
platform.h
uninit_static
void uninit_static(void)
Definition: init.c:922
context::sig
struct signal_info * sig
Internal error signaling object.
Definition: openvpn.h:503
context_clear_2
void context_clear_2(struct context *c)
Definition: init.c:88
MODE_POINT_TO_POINT
#define MODE_POINT_TO_POINT
Definition: options.h:245
do_genkey
bool do_genkey(const struct options *options)
Definition: init.c:1012
possibly_become_daemon
bool possibly_become_daemon(const struct options *options)
Definition: init.c:1158
show_library_versions
void show_library_versions(const unsigned int flags)
Definition: options.c:4876
uninit_management_callback
void uninit_management_callback(void)
Definition: init.c:4358
uninit_options
void uninit_options(struct options *o)
Definition: options.c:911
context::es
struct env_set * es
Set of environment variables.
Definition: openvpn.h:499
show_dco_version
void show_dco_version(const unsigned int flags)
Definition: options.c:4866
CC_HARD_USR1_TO_HUP
#define CC_HARD_USR1_TO_HUP
Definition: init.h:105
IS_SIG
#define IS_SIG(c)
Definition: sig.h:48
init_instance_handle_signals
void init_instance_handle_signals(struct context *c, const struct env_set *env, const unsigned int flags)
Definition: init.c:4384
ES_TIMEOUT
#define ES_TIMEOUT
Definition: event.h:69
init_options
void init_options(struct options *o, const bool init_gc)
Definition: options.c:789
init_options_dev
void init_options_dev(struct options *options)
Definition: init.c:963
show_settings
void show_settings(const struct options *o)
Definition: options.c:1798
P2P_CHECK_SIG
#define P2P_CHECK_SIG()
Definition: openvpn.c:38
options::chroot_dir
const char * chroot_dir
Definition: options.h:361
crypto_load_provider
provider_t * crypto_load_provider(const char *provider)
Load the given (OpenSSL) providers.
Definition: crypto_openssl.c:160
do_persist_tuntap
bool do_persist_tuntap(struct options *options, openvpn_net_ctx_t *ctx)
Definition: init.c:1095
config.h
setenv_settings
void setenv_settings(struct env_set *es, const struct options *o)
Definition: options.c:1007
init_plugins
void init_plugins(struct context *c)
Definition: init.c:4128
p2p_iow_flags
static unsigned int p2p_iow_flags(const struct context *c)
Definition: forward.h:340
gc_init
static void gc_init(struct gc_arena *a)
Definition: buffer.h:1017
PERF_EVENT_LOOP
#define PERF_EVENT_LOOP
Definition: perf.h:44
parse_argv
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:5390
remap_signal
void remap_signal(struct context *c)
Definition: sig.c:588
memdbg.h
context_clear_all_except_first_time
void context_clear_all_except_first_time(struct context *c)
Definition: init.c:94
title_string
const char title_string[]
Definition: options.c:67
M_USAGE
#define M_USAGE
Definition: error.h:106
msg
#define msg(flags,...)
Definition: error.h:144
context_init_1
void context_init_1(struct context *c)
Definition: init.c:730
siginfo_static
struct signal_info siginfo_static
Definition: sig.c:45
persist_client_stats
void persist_client_stats(struct context *c)
Definition: init.c:4369
perf_push
static void perf_push(int type)
Definition: perf.h:78
CM_P2P
#define CM_P2P
Definition: openvpn.h:485
close_management
void close_management(void)
Definition: init.c:4345
context::net_ctx
openvpn_net_ctx_t net_ctx
Networking API opaque context.
Definition: openvpn.h:501