/* * Return a file to print messages to before syslog is opened. */ FILE * msg_fp() { FILE *fp = msgfp; if (!fp) fp = OPENVPN_MSG_FP; if (!fp) openvpn_exit (OPENVPN_EXIT_STATUS_CANNOT_OPEN_DEBUG_FILE); /* exit point */ return fp; }
/* * Return a file to print messages to before syslog is opened. */ FILE * msg_fp(const unsigned int flags) { FILE *fp = msgfp; if (!fp) fp = (flags & (M_FATAL|M_USAGE_SMALL)) ? default_err : default_out; if (!fp) openvpn_exit (OPENVPN_EXIT_STATUS_CANNOT_OPEN_DEBUG_FILE); /* exit point */ return fp; }
void error_reset () { use_syslog = std_redir = false; suppress_timestamps = false; x_debug_level = 1; mute_cutoff = 0; mute_count = 0; mute_category = 0; #ifdef OPENVPN_DEBUG_COMMAND_LINE msgfp = fopen (OPENVPN_DEBUG_FILE, "w"); if (!msgfp) openvpn_exit (OPENVPN_EXIT_STATUS_CANNOT_OPEN_DEBUG_FILE); /* exit point */ #else msgfp = NULL; #endif }
/** * OpenVPN's main init-run-cleanup loop. * @ingroup eventloop * * This function contains the two outer OpenVPN loops. Its structure is * as follows: * - Once-per-process initialization. * - Outer loop, run at startup and then once per \c SIGHUP: * - Level 1 initialization * - Inner loop, run at startup and then once per \c SIGUSR1: * - Call event loop function depending on client or server mode: * - \c tunnel_point_to_point() * - \c tunnel_server() * - Level 1 cleanup * - Once-per-process cleanup. * * @param argc - Commandline argument count. * @param argv - Commandline argument values. */ int main (int argc, char *argv[]) { struct context c; #if PEDANTIC fprintf (stderr, "Sorry, I was built with --enable-pedantic and I am incapable of doing any real work!\n"); return 1; #endif CLEAR (c); /* signify first time for components which can only be initialized once per program instantiation. */ c.first_time = true; /* initialize program-wide statics */ if (init_static ()) { /* * This loop is initially executed on startup and then * once per SIGHUP. */ do { /* enter pre-initialization mode with regard to signal handling */ pre_init_signal_catch (); /* zero context struct but leave first_time member alone */ context_clear_all_except_first_time (&c); /* static signal info object */ CLEAR (siginfo_static); c.sig = &siginfo_static; /* initialize garbage collector scoped to context object */ gc_init (&c.gc); /* initialize environmental variable store */ c.es = env_set_create (NULL); #ifdef WIN32 env_set_add_win32 (c.es); #endif #ifdef ENABLE_MANAGEMENT /* initialize management subsystem */ init_management (&c); #endif /* initialize options to default state */ init_options (&c.options, true); /* parse command line options, and read configuration file */ parse_argv (&c.options, argc, argv, M_USAGE, OPT_P_DEFAULT, NULL, c.es); #ifdef ENABLE_PLUGIN /* plugins may contribute options configuration */ init_verb_mute (&c, IVM_LEVEL_1); init_plugins (&c); open_plugins (&c, true, OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE); #endif /* init verbosity and mute levels */ init_verb_mute (&c, IVM_LEVEL_1); /* set dev options */ init_options_dev (&c.options); /* openssl print info? */ if (print_openssl_info (&c.options)) break; /* --genkey mode? */ if (do_genkey (&c.options)) break; /* tun/tap persist command? */ if (do_persist_tuntap (&c.options)) break; /* sanity check on options */ options_postprocess (&c.options); /* show all option settings */ show_settings (&c.options); /* print version number */ msg (M_INFO, "%s", title_string); /* misc stuff */ pre_setup (&c.options); /* test crypto? */ if (do_test_crypto (&c.options)) break; #ifdef ENABLE_MANAGEMENT /* open management subsystem */ if (!open_management (&c)) break; #endif /* set certain options as environmental variables */ setenv_settings (c.es, &c.options); /* finish context init */ context_init_1 (&c); do { /* run tunnel depending on mode */ switch (c.options.mode) { case MODE_POINT_TO_POINT: tunnel_point_to_point (&c); break; #if P2MP_SERVER case MODE_SERVER: tunnel_server (&c); break; #endif default: ASSERT (0); } /* indicates first iteration -- has program-wide scope */ c.first_time = false; /* any signals received? */ if (IS_SIG (&c)) print_signal (c.sig, NULL, M_INFO); /* pass restart status to management subsystem */ signal_restart_status (c.sig); } while (c.sig->signal_received == SIGUSR1); uninit_options (&c.options); gc_reset (&c.gc); } while (c.sig->signal_received == SIGHUP); } context_gc_free (&c); env_set_destroy (c.es); #ifdef ENABLE_MANAGEMENT /* close management interface */ close_management (); #endif /* uninitialize program-wide statics */ uninit_static (); openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ return 0; /* NOTREACHED */ }
void x_msg_va (const unsigned int flags, const char *format, va_list arglist) { struct gc_arena gc; #if SYSLOG_CAPABILITY int level; #endif char *m1; char *m2; char *tmp; int e; const char *prefix; const char *prefix_sep; void usage_small (void); #ifndef HAVE_VARARG_MACROS /* the macro has checked this otherwise */ if (!MSG_TEST (flags)) return; #endif e = openvpn_errno (); /* * Apply muting filter. */ #ifndef HAVE_VARARG_MACROS /* the macro has checked this otherwise */ if (!dont_mute (flags)) return; #endif gc_init (&gc); m1 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc); m2 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc); vsnprintf (m1, ERR_BUF_SIZE, format, arglist); m1[ERR_BUF_SIZE - 1] = 0; /* windows vsnprintf needs this */ if ((flags & M_ERRNO) && e) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s (errno=%d)", m1, strerror_ts (e, &gc), e); SWAP; } #ifdef ENABLE_CRYPTO #ifdef ENABLE_CRYPTO_OPENSSL if (flags & M_SSL) { int nerrs = 0; int err; while ((err = ERR_get_error ())) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s", m1, ERR_error_string (err, NULL)); SWAP; ++nerrs; } if (!nerrs) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s (OpenSSL)", m1); SWAP; } } #endif #endif if (flags & M_OPTERR) { openvpn_snprintf (m2, ERR_BUF_SIZE, "Options error: %s", m1); SWAP; } #if SYSLOG_CAPABILITY if (flags & (M_FATAL|M_NONFATAL|M_USAGE_SMALL)) level = LOG_ERR; else if (flags & M_WARN) level = LOG_WARNING; else level = LOG_NOTICE; #endif /* set up client prefix */ if (flags & M_NOIPREFIX) prefix = NULL; else prefix = msg_get_prefix (); prefix_sep = " "; if (!prefix) prefix_sep = prefix = ""; /* virtual output capability used to copy output to management subsystem */ if (!forked) { const struct virtual_output *vo = msg_get_virtual_output (); if (vo) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s%s%s", prefix, prefix_sep, m1); virtual_output_print (vo, flags, m2); } } if (!(flags & M_MSG_VIRT_OUT)) { if (use_syslog && !std_redir && !forked) { #if SYSLOG_CAPABILITY syslog (level, "%s%s%s", prefix, prefix_sep, m1); #endif } else { FILE *fp = msg_fp(flags); const bool show_usec = check_debug_level (DEBUG_LEVEL_USEC_TIME); if ((flags & M_NOPREFIX) || suppress_timestamps) { fprintf (fp, "%s%s%s%s", prefix, prefix_sep, m1, (flags&M_NOLF) ? "" : "\n"); } else { fprintf (fp, "%s %s%s%s%s", time_string (0, 0, show_usec, &gc), prefix, prefix_sep, m1, (flags&M_NOLF) ? "" : "\n"); } fflush(fp); ++x_msg_line_num; } } if (flags & M_FATAL) msg (M_INFO, "Exiting due to fatal error"); if (flags & M_FATAL) openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */ if (flags & M_USAGE_SMALL) usage_small (); gc_free (&gc); }