📄 init.c
字号:
if (dev == DEV_TYPE_TUN) gw = options->ifconfig_remote_netmask; if (options->route_default_gateway) gw = options->route_default_gateway; if (!init_route_list (route_list, options->routes, gw, link_socket_current_remote (link_socket_info))) { if (fatal) openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */ } else { /* copy routes to environment */ setenv_routes (route_list); }}/* * Possibly add routes and/or call route-up script * based on options. */voiddo_route (const struct options *options, struct route_list *route_list){ if (!options->route_noexec) add_routes (route_list, false); if (options->route_script) { setenv_str ("script_type", "route-up"); system_check (options->route_script, "Route script failed", false); }}/* * initialize tun/tap device object */static voiddo_init_tun (struct context *c){ c->c1.tuntap = init_tun (c->options.dev, c->options.dev_type, c->options.ifconfig_local, c->options.ifconfig_remote_netmask, addr_host (&c->c1.link_socket_addr.local), addr_host (&c->c1.link_socket_addr.remote)); init_tun_post (c->c1.tuntap, &c->c2.frame, &c->options.tuntap_options); c->c1.tuntap_owned = true;}/* * Open tun/tap device, ifconfig, call up script, etc. */static booldo_open_tun (struct context *c){ struct gc_arena gc = gc_new (); bool ret = false; c->c2.ipv4_tun = (!c->options.tun_ipv6 && is_dev_type (c->options.dev, c->options.dev_type, "tun")); if (!c->c1.tuntap) { /* initialize (but do not open) tun/tap object */ do_init_tun (c); /* allocate route list structure */ do_alloc_route_list (c); /* parse and resolve the route option list */ if (c->c1.route_list && c->c2.link_socket) do_init_route_list (&c->options, c->c1.route_list, &c->c2.link_socket->info, true); /* do ifconfig */ if (!c->options.ifconfig_noexec && ifconfig_order () == IFCONFIG_BEFORE_TUN_OPEN) { /* guess actual tun/tap unit number that will be returned by open_tun */ const char *guess = guess_tuntap_dev (c->options.dev, c->options.dev_type, c->options.dev_node, &gc); do_ifconfig (c->c1.tuntap, guess, TUN_MTU_SIZE (&c->c2.frame)); } /* open the tun device */ open_tun (c->options.dev, c->options.dev_type, c->options.dev_node, c->options.tun_ipv6, c->c1.tuntap); /* do ifconfig */ if (!c->options.ifconfig_noexec && ifconfig_order () == IFCONFIG_AFTER_TUN_OPEN) { do_ifconfig (c->c1.tuntap, c->c1.tuntap->actual_name, TUN_MTU_SIZE (&c->c2.frame)); } /* run the up script */ run_script (c->options.up_script, c->c1.tuntap->actual_name, TUN_MTU_SIZE (&c->c2.frame), EXPANDED_SIZE (&c->c2.frame), print_in_addr_t (c->c1.tuntap->local, true, &gc), print_in_addr_t (c->c1.tuntap->remote_netmask, true, &gc), "init", NULL, "up"); /* possibly add routes */ if (!c->options.route_delay_defined && c->c1.route_list) do_route (&c->options, c->c1.route_list); /* * Did tun/tap driver give us an MTU? */ if (c->c1.tuntap->post_open_mtu) frame_set_mtu_dynamic (&c->c2.frame, c->c1.tuntap->post_open_mtu, SET_MTU_TUN | SET_MTU_UPPER_BOUND); ret = true; } else { msg (M_INFO, "Preserving previous TUN/TAP instance: %s", c->c1.tuntap->actual_name); /* run the up script if user specified --up-restart */ if (c->options.up_restart) run_script (c->options.up_script, c->c1.tuntap->actual_name, TUN_MTU_SIZE (&c->c2.frame), EXPANDED_SIZE (&c->c2.frame), print_in_addr_t (c->c1.tuntap->local, true, &gc), print_in_addr_t (c->c1.tuntap->remote_netmask, true, &gc), "restart", NULL, "up"); } gc_free (&gc); return ret;}/* * Handled delayed tun/tap interface bringup due to --up-delay or --pull */unsigned intpull_permission_mask (void){ return ( OPT_P_UP | OPT_P_ROUTE | OPT_P_IPWIN32 | OPT_P_SETENV | OPT_P_SHAPER | OPT_P_TIMER | OPT_P_PERSIST | OPT_P_MESSAGES);}voiddo_deferred_options (struct context *c, const unsigned int found){ if (found & OPT_P_MESSAGES) { init_verb_mute (c, IVM_LEVEL_1|IVM_LEVEL_2); msg (D_PUSH, "OPTIONS IMPORT: --verb and/or --mute level changed"); } if (found & OPT_P_TIMER) { do_init_timers (c, true); msg (D_PUSH, "OPTIONS IMPORT: timers and/or timeouts modified"); } if (found & OPT_P_SHAPER) { msg (D_PUSH, "OPTIONS IMPORT: traffic shaper enabled"); do_init_traffic_shaper (c); } if (found & OPT_P_PERSIST) msg (D_PUSH, "OPTIONS IMPORT: --persist options modified"); if (found & OPT_P_UP) msg (D_PUSH, "OPTIONS IMPORT: --ifconfig/up options modified"); if (found & OPT_P_ROUTE) msg (D_PUSH, "OPTIONS IMPORT: route options modified"); if (found & OPT_P_IPWIN32) msg (D_PUSH, "OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified"); if (found & OPT_P_SETENV) msg (D_PUSH, "OPTIONS IMPORT: environment modified");}voiddo_up (struct context *c, bool pulled_options, unsigned int option_types_found){ if (!c->c2.do_up_ran) { reset_coarse_timers (c); if (pulled_options && option_types_found) do_deferred_options (c, option_types_found); /* if --up-delay specified, open tun, do ifconfig, and run up script now */ if (c->options.up_delay || PULL_DEFINED (&c->options)) { c->c2.did_open_tun = do_open_tun (c); update_time (); } if (c->c2.did_open_tun) { /* if --route-delay was specified, start timer */ if (c->options.route_delay_defined) event_timeout_init (&c->c2.route_wakeup, c->options.route_delay, now); } else if (pulled_options && (option_types_found & (OPT_P_UP|OPT_P_ROUTE|OPT_P_IPWIN32))) { msg (D_PUSH_ERRORS, "WARNING: Options pulled from the server relating to tun/tap interface configuration and routes were not applied"); } c->c2.do_up_ran = true; }}/* * Depending on protocol, sleep before restart to prevent * TCP race. */static voidsocket_restart_pause (int proto, bool http_proxy, bool socks_proxy){ int sec = 0; switch (proto) { case PROTO_UDPv4: sec = socks_proxy ? 3 : 0; break; case PROTO_TCPv4_SERVER: sec = 1; break; case PROTO_TCPv4_CLIENT: sec = (http_proxy || socks_proxy) ? 10 : 3; break; } if (sec) { msg (D_RESTART, "Restart pause, %d second(s)", sec); sleep (sec); }}/* * Finalize MTU parameters based on command line or config file options. */static voidframe_finalize_options (struct frame *frame, const struct options *options){ frame_finalize (frame, options->link_mtu_defined, options->link_mtu, options->tun_mtu_defined, options->tun_mtu);}/* * Free a key schedule, including OpenSSL components. */static voidkey_schedule_free (struct key_schedule *ks, bool free_ssl_ctx){#ifdef USE_CRYPTO free_key_ctx_bi (&ks->static_key);#ifdef USE_SSL if (ks->ssl_ctx && free_ssl_ctx) { SSL_CTX_free (ks->ssl_ctx); free_key_ctx_bi (&ks->tls_auth_key); }#endif /* USE_SSL */#endif /* USE_CRYPTO */ CLEAR (*ks);}#ifdef USE_CRYPTOstatic voidinit_crypto_pre (struct context *c, const unsigned int flags){ if (c->options.engine) init_crypto_lib_engine (); if (flags & CF_LOAD_PERSISTED_PACKET_ID) { /* load a persisted packet-id for cross-session replay-protection */ if (c->options.packet_id_file) packet_id_persist_load (&c->c1.pid_persist, c->options.packet_id_file); } /* Initialize crypto options */ c->c2.crypto_options.use_iv = c->options.use_iv;}/* * Static Key Mode (using a pre-shared key) */static voiddo_init_crypto_static (struct context *c, const unsigned int flags){ const struct options *options = &c->options; ASSERT (options->shared_secret_file); init_crypto_pre (c, flags); /* Initialize packet ID tracking */ if (options->replay) { packet_id_init (&c->c2.packet_id, options->replay_window, options->replay_time); c->c2.crypto_options.packet_id = &c->c2.packet_id; c->c2.crypto_options.pid_persist = &c->c1.pid_persist; c->c2.crypto_options.packet_id_long_form = true; packet_id_persist_load_obj (&c->c1.pid_persist, c->c2.crypto_options.packet_id); } if (!key_ctx_bi_defined (&c->c1.ks.static_key)) { struct key2 key2; struct key_direction_state kds; /* Get cipher & hash algorithms */ init_key_type (&c->c1.ks.key_type, options->ciphername, options->ciphername_defined, options->authname, options->authname_defined, options->keysize, options->test_crypto, true); /* Read cipher and hmac keys from shared secret file */ read_key_file (&key2, options->shared_secret_file, true); /* Check for and fix highly unlikely key problems */ verify_fix_key2 (&key2, &c->c1.ks.key_type, options->shared_secret_file); /* Initialize OpenSSL key objects */ key_direction_state_init (&kds, options->key_direction); must_have_n_keys (options->shared_secret_file, "secret", &key2, kds.need_keys); init_key_ctx (&c->c1.ks.static_key.encrypt, &key2.keys[kds.out_key], &c->c1.ks.key_type, DO_ENCRYPT, "Static Encrypt"); init_key_ctx (&c->c1.ks.static_key.decrypt, &key2.keys[kds.in_key], &c->c1.ks.key_type, DO_DECRYPT, "Static Decrypt"); /* Erase the temporary copy of key */ CLEAR (key2); } else { msg (M_INFO, "Re-using pre-shared static key"); } /* Get key schedule */ c->c2.crypto_options.key_ctx_bi = &c->c1.ks.static_key; /* Compute MTU parameters */ crypto_adjust_frame_parameters (&c->c2.frame, &c->c1.ks.key_type, options->ciphername_defined, options->use_iv, options->replay, true); /* Sanity check on IV, sequence number, and cipher mode options */ check_replay_iv_consistency (&c->c1.ks.key_type, options->replay, options->use_iv);}#ifdef USE_SSL/* * Initialize the persistent component of OpenVPN's TLS mode, * which is preserved across SIGUSR1 resets. */static voiddo_init_crypto_tls_c1 (struct context *c){ const struct options *options = &c->options; if (!c->c1.ks.ssl_ctx) { /* * Initialize the OpenSSL library's global * SSL context. */ c->c1.ks.ssl_ctx = init_ssl (options->tls_server, options->ca_file, options->dh_file, options->cert_file, options->priv_key_file, options->cipher_list); /* Get cipher & hash algorithms */ init_key_type (&c->c1.ks.key_type, options->ciphername, options->ciphername_defined, options->authname, options->authname_defined, options->keysize, true, true); /* TLS handshake authentication (--tls-auth) */ if (options->tls_auth_file) get_tls_handshake_key (&c->c1.ks.key_type, &c->c1.ks.tls_auth_key, options->tls_auth_file, options->key_direction); } else { msg (M_INFO, "Re-using SSL/TLS context"); }}static voiddo_init_crypto_tls (struct context *c, const unsigned int flags){ const struct options *options = &c->options; struct tls_options to; bool packet_id_long_form; ASSERT (options->tls_server || options->tls_client); ASSERT (!options->test_crypto); init_crypto_pre (c, flags); /* Make sure we are either a TLS client or server but not both */ ASSERT (options->tls_server == !options->tls_client); /* initialize persistent component */ do_init_crypto_tls_c1 (c); /* Sanity check on IV, sequence number, and cipher mode options */ check_replay_iv_consistency (&c->c1.ks.key_type, options->replay, options->use_iv); /* In short form, unique datagram identifier is 32 bits, in long form 64 bits */ packet_id_long_form = cfb_ofb_mode (&c->c1.ks.key_type); /* Compute MTU parameters */ crypto_adjust_frame_parameters (&c->c2.frame, &c->c1.ks.key_type, options->ciphername_defined, options->use_iv, options->replay, packet_id_long_form); tls_adjust_frame_parameters (&c->c2.frame); /* Set all command-line TLS-related options */ CLEAR (to); to.ssl_ctx = c->c1.ks.ssl_ctx; to.key_type = c->c1.ks.key_type; to.server = options->tls_server; to.key_method = options->key_method; to.replay = options->replay; to.packet_id_long_form = packet_id_long_form; to.replay_window = options->replay_window; to.replay_time = options->replay_time; to.transition_window = options->transition_window; to.handshake_window = options->handshake_window; to.packet_timeout = options->tls_timeout; to.renegotiate_bytes = options->renegotiate_bytes; to.renegotiate_packets = options->renegotiate_packets; to.renegotiate_seconds = options->renegotiate_seconds; to.single_session = options->single_session; to.disable_occ = !options->occ; to.verify_command = options->tls_verify; to.verify_x509name = options->tls_remote; to.crl_file = options->crl_file; /* TLS handshake authentication (--tls-auth) */ if (options->tls_auth_file) { to.tls_auth_key = c->c1.ks.tls_auth_key; to.tls_auth.pid_persist = &c->c1.pid_persist; to.tls_auth.packet_id_long_form = true; crypto_adjust_frame_parameters (&to.frame, &c->c1.ks.key_type, false, false, true, true); } /* If we are running over TCP, allow for length prefix */ socket_adjust_frame_parameters (&to.frame, options->proto); /* * Initialize OpenVPN's master TLS-mode object. */ if (flags & CF_INIT_TLS_MULTI) c->c2.tls_multi = tls_multi_init (&to); if (flags & CF_INIT_TLS_AUTH_STANDALONE) c->c2.tls_auth_standalone = tls_auth_standalone_init (&to, &c->c2.gc);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -