diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | forward.c | 1 | ||||
-rw-r--r-- | helper.c | 4 | ||||
-rw-r--r-- | init.c | 72 | ||||
-rw-r--r-- | manage.c | 10 | ||||
-rw-r--r-- | manage.h | 1 | ||||
-rw-r--r-- | openvpn.h | 31 | ||||
-rw-r--r-- | options.c | 13 | ||||
-rw-r--r-- | pool.c | 27 | ||||
-rw-r--r-- | pool.h | 2 | ||||
-rw-r--r-- | ssl.c | 4 | ||||
-rw-r--r-- | ssl.h | 7 |
12 files changed, 137 insertions, 52 deletions
@@ -19,6 +19,19 @@ $Id$ * Patch to support --topology subnet on Mac OS X (Mathias Sundman). * Added --auto-proxy directive to auto-detect HTTP or SOCKS proxy settings (currently Windows only). +* Removed redundant base64 code. +* Better sanity checking of --server and --server-bridge + IP pool ranges, so as not to hit the assertion at + pool.c:119 (2.0.5). +* Fixed bug where --daemon and --management-query-passwords + used together would cause OpenVPN to block prior to + daemonization. +* Fixed client/server race condition which could occur + when --auth-retry interact is set and the initially + provided auth-user-pass credentials are incorrect, + forcing a username/password re-query. +* Fixed bug where if --daemon and --management-hold are + used together, --user or --group options would be ignored. 2005.11.12 -- Version 2.1-beta7 @@ -30,9 +43,7 @@ $Id$ claimed that it would support subnets of /30 or less but actually would only accept /29 or less. * Extend byte counters to 64 bits (M. van Cuijk). -* PKCS#11 fixes (Alon Bar-Lev). -* Removed redundant base64 code. - + 2005.11.02 -- Version 2.0.5 * Fixed bug in Linux get_default_gateway function @@ -302,6 +302,7 @@ check_inactivity_timeout_dowork (struct context *c) void schedule_exit (struct context *c, const int n_seconds) { + tls_set_single_session (c->c2.tls_multi); update_time (); reset_coarse_timers (c); event_timeout_init (&c->c2.scheduled_exit, n_seconds, now); @@ -223,6 +223,7 @@ helper_client_server (struct options *o) o->ifconfig_pool_defined = true; o->ifconfig_pool_start = o->server_network + 4; o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - pool_end_reserve; + ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); } helper_add_route (o->server_network, o->server_netmask, o); @@ -241,6 +242,7 @@ helper_client_server (struct options *o) o->ifconfig_pool_defined = true; o->ifconfig_pool_start = o->server_network + 2; o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 2; + ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); o->ifconfig_pool_netmask = o->server_netmask; } @@ -267,6 +269,7 @@ helper_client_server (struct options *o) o->ifconfig_pool_defined = true; o->ifconfig_pool_start = o->server_network + 2; o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1; + ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); o->ifconfig_pool_netmask = o->server_netmask; } @@ -325,6 +328,7 @@ helper_client_server (struct options *o) o->ifconfig_pool_defined = true; o->ifconfig_pool_start = o->server_bridge_pool_start; o->ifconfig_pool_end = o->server_bridge_pool_end; + ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); o->ifconfig_pool_netmask = o->server_bridge_netmask; push_option (o, print_opt_route_gateway (o->server_bridge_ip, &o->gc), M_USAGE); @@ -99,6 +99,25 @@ init_remote_list (struct context *c) } } +/* + * Query for private key and auth-user-pass username/passwords + */ +static void +init_query_passwords (struct context *c) +{ +#if defined(USE_CRYPTO) && defined(USE_SSL) + /* Certificate password input */ + if (c->options.key_pass_file) + pem_password_setup (c->options.key_pass_file); +#endif + +#if P2MP + /* Auth user/pass input */ + if (c->options.auth_user_pass_file) + auth_user_pass_setup (c->options.auth_user_pass_file); +#endif +} + void context_init_1 (struct context *c) { @@ -113,11 +132,7 @@ context_init_1 (struct context *c) packet_id_persist_init (&c->c1.pid_persist); init_remote_list (c); -#if defined(USE_CRYPTO) && defined(USE_SSL) - /* Certificate password input */ - if (c->options.key_pass_file) - pem_password_setup (c->options.key_pass_file); -#endif + init_query_passwords (c); #if defined(ENABLE_PKCS11) if (c->first_time) { @@ -142,14 +157,6 @@ context_init_1 (struct context *c) } #endif -#if P2MP - /* Auth user/pass input */ - if (c->options.auth_user_pass_file) - { - auth_user_pass_setup (c->options.auth_user_pass_file); - } -#endif - #ifdef ENABLE_HTTP_PROXY if (c->options.http_proxy_options || c->options.auto_proxy_info) { @@ -417,8 +424,9 @@ static void do_uid_gid_chroot (struct context *c, bool no_delay) { static const char why_not[] = "will be delayed because of --client, --pull, or --up-delay"; + struct context_0 *c0 = c->c0; - if (c->first_time && !c->c2.uid_gid_set) + if (c->first_time && c0 && !c0->uid_gid_set) { /* chroot if requested */ if (c->options.chroot_dir) @@ -432,11 +440,11 @@ do_uid_gid_chroot (struct context *c, bool no_delay) /* set user and/or group that we want to setuid/setgid to */ if (no_delay) { - set_group (&c->c2.group_state); - set_user (&c->c2.user_state); - c->c2.uid_gid_set = true; + set_group (&c0->group_state); + set_user (&c0->user_state); + c0->uid_gid_set = true; } - else if (c->c2.uid_gid_specified) + else if (c0->uid_gid_specified) { msg (M_INFO, "NOTE: UID/GID downgrade %s", why_not); } @@ -1104,7 +1112,7 @@ do_hold (struct context *c) if (management) { /* if c is defined, daemonize before hold */ - if (c && c->options.daemon && management_would_hold (management)) + if (c && c->options.daemon && management_should_daemonize (management)) do_init_first_time (c); /* block until management hold is released */ @@ -1937,15 +1945,20 @@ do_compute_occ_strings (struct context *c) static void do_init_first_time (struct context *c) { - if (c->first_time && !c->did_we_daemonize) + if (c->first_time && !c->did_we_daemonize && !c->c0) { + struct context_0 *c0; + + ALLOC_OBJ_CLEAR_GC (c->c0, struct context_0, &c->gc); + c0 = c->c0; + /* get user and/or group that we want to setuid/setgid to */ - c->c2.uid_gid_specified = - get_group (c->options.groupname, &c->c2.group_state) | - get_user (c->options.username, &c->c2.user_state); + c0->uid_gid_specified = + get_group (c->options.groupname, &c0->group_state) | + get_user (c->options.username, &c0->user_state); /* get --writepid file descriptor */ - get_pid_file (c->options.writepid, &c->c2.pid_state); + get_pid_file (c->options.writepid, &c0->pid_state); /* become a daemon if --daemon */ c->did_we_daemonize = possibly_become_daemon (&c->options, c->first_time); @@ -1955,7 +1968,7 @@ do_init_first_time (struct context *c) do_mlockall (true); /* call again in case we daemonized */ /* save process ID in a file */ - write_pid (&c->c2.pid_state); + write_pid (&c0->pid_state); /* should we change scheduling priority? */ set_nice (c->options.nice); @@ -2475,6 +2488,12 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int goto sig; } +#if P2MP + /* get passwords if undefined */ + if (auth_retry_get () == AR_INTERACT) + init_query_passwords (c); +#endif + /* initialize context level 2 --verb/--mute parms */ init_verb_mute (c, IVM_LEVEL_2); @@ -2714,8 +2733,6 @@ inherit_context_child (struct context *dest, ASSERT (0); } - dest->first_time = false; - dest->gc = gc_new (); ALLOC_OBJ_CLEAR_GC (dest->sig, struct signal_info, &dest->gc); @@ -2793,6 +2810,7 @@ inherit_context_top (struct context *dest, dest->mode = CM_TOP_CLONE; dest->first_time = false; + dest->c0 = NULL; options_detach (&dest->options); gc_detach (&dest->gc); @@ -1863,6 +1863,16 @@ management_would_hold (struct management *man) } /* + * Return true if (from the management interface's perspective) OpenVPN should + * daemonize. + */ +bool +management_should_daemonize (struct management *man) +{ + return management_would_hold (man) || man->settings.up_query_passwords; +} + +/* * If the hold flag is enabled, hibernate until a management client releases the hold. * Return true if the caller should not sleep for an additional time interval. */ @@ -288,6 +288,7 @@ void management_clear_callback (struct management *man); bool management_query_user_pass (struct management *man, struct user_pass *up, const char *type, const unsigned int flags); +bool management_should_daemonize (struct management *man); bool management_would_hold (struct management *man); bool management_hold (struct management *man); @@ -117,6 +117,23 @@ struct context_buffers struct buffer read_tun_buf; }; +/* + * level 0 context contains data related to + * once-per OpenVPN instantiation events + * such as daemonization. + */ +struct context_0 +{ + /* workspace for get_pid_file/write_pid */ + struct pid_state pid_state; + + /* workspace for --user/--group */ + bool uid_gid_specified; + bool uid_gid_set; + struct user_state user_state; + struct group_state group_state; +}; + /* * Contains the persist-across-restart OpenVPN tunnel instance state. * Reset only for SIGHUP restarts. @@ -337,15 +354,6 @@ struct context_2 */ bool ipv4_tun; - /* workspace for get_pid_file/write_pid */ - struct pid_state pid_state; - - /* workspace for --user/--group */ - bool uid_gid_specified; - bool uid_gid_set; - struct user_state user_state; - struct group_state group_state; - /* should we print R|W|r|w to console on packet transfers? */ bool log_rw; @@ -453,6 +461,11 @@ struct context /* set to true after we daemonize */ bool did_we_daemonize; + /* level 0 context contains data related to + once-per OpenVPN instantiation events + such as daemonization */ + struct context_0 *c0; + /* level 1 context is preserved for SIGUSR1 restarts, but initialized for SIGHUP restarts */ @@ -4058,17 +4058,8 @@ add_option (struct options *options, msg (msglevel, "error parsing --ifconfig-pool parameters"); goto err; } - if (start > end) - { - msg (msglevel, "--ifconfig-pool start IP is greater than end IP"); - goto err; - } - if (end - start >= IFCONFIG_POOL_MAX) - { - msg (msglevel, "--ifconfig-pool address range is too large. Current maximum is %d addresses.", - IFCONFIG_POOL_MAX); - goto err; - } + if (!ifconfig_pool_verify_range (msglevel, start, end)) + goto err; options->ifconfig_pool_defined = true; options->ifconfig_pool_start = start; @@ -109,6 +109,33 @@ ifconfig_pool_find (struct ifconfig_pool *pool, const char *common_name) return -1; } +/* + * Verify start/end range + */ +bool +ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_addr_t end) +{ + struct gc_arena gc = gc_new (); + bool ret = true; + + if (start > end) + { + msg (msglevel, "--ifconfig-pool start IP [%s] is greater than end IP [%s]", + print_in_addr_t (start, 0, &gc), + print_in_addr_t (end, 0, &gc)); + ret = false; + } + if (end - start >= IFCONFIG_POOL_MAX) + { + msg (msglevel, "--ifconfig-pool address range is too large [%s -> %s]. Current maximum is %d addresses, as defined by IFCONFIG_POOL_MAX variable.", + print_in_addr_t (start, 0, &gc), + print_in_addr_t (end, 0, &gc), + IFCONFIG_POOL_MAX); + ret = false; + } + gc_free (&gc); + return ret; +} struct ifconfig_pool * ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn) @@ -68,6 +68,8 @@ struct ifconfig_pool *ifconfig_pool_init (int type, in_addr_t start, in_addr_t e void ifconfig_pool_free (struct ifconfig_pool *pool); +bool ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_addr_t end); + ifconfig_pool_handle ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, const char *common_name); bool ifconfig_pool_release (struct ifconfig_pool* pool, ifconfig_pool_handle hand, const bool hard); @@ -3886,7 +3886,7 @@ tls_pre_decrypt (struct tls_multi *multi, if (multi->opt.single_session && multi->n_sessions) { msg (D_TLS_ERRORS, - "TLS Error: Cannot accept new session request from %s due to --single-session [1]", + "TLS Error: Cannot accept new session request from %s due to session context expire or --single-session [1]", print_link_socket_actual (from, &gc)); goto error; } @@ -3929,7 +3929,7 @@ tls_pre_decrypt (struct tls_multi *multi, if (multi->opt.single_session) { msg (D_TLS_ERRORS, - "TLS Error: Cannot accept new session request from %s due to --single-session [2]", + "TLS Error: Cannot accept new session request from %s due to session context expire or --single-session [2]", print_link_socket_actual (from, &gc)); goto error; } @@ -663,6 +663,13 @@ tls_test_payload_len (const struct tls_multi *multi) return 0; } +static inline void +tls_set_single_session (struct tls_multi *multi) +{ + if (multi) + multi->opt.single_session = true; +} + /* * protocol_dump() flags */ |