git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@855 e7ae566f-a301-0410-adde-c780ea21d3b5
| ... | ... |
@@ -19,6 +19,19 @@ $Id$ |
| 19 | 19 |
* Patch to support --topology subnet on Mac OS X (Mathias Sundman). |
| 20 | 20 |
* Added --auto-proxy directive to auto-detect HTTP or SOCKS |
| 21 | 21 |
proxy settings (currently Windows only). |
| 22 |
+* Removed redundant base64 code. |
|
| 23 |
+* Better sanity checking of --server and --server-bridge |
|
| 24 |
+ IP pool ranges, so as not to hit the assertion at |
|
| 25 |
+ pool.c:119 (2.0.5). |
|
| 26 |
+* Fixed bug where --daemon and --management-query-passwords |
|
| 27 |
+ used together would cause OpenVPN to block prior to |
|
| 28 |
+ daemonization. |
|
| 29 |
+* Fixed client/server race condition which could occur |
|
| 30 |
+ when --auth-retry interact is set and the initially |
|
| 31 |
+ provided auth-user-pass credentials are incorrect, |
|
| 32 |
+ forcing a username/password re-query. |
|
| 33 |
+* Fixed bug where if --daemon and --management-hold are |
|
| 34 |
+ used together, --user or --group options would be ignored. |
|
| 22 | 35 |
|
| 23 | 36 |
2005.11.12 -- Version 2.1-beta7 |
| 24 | 37 |
|
| ... | ... |
@@ -30,9 +43,7 @@ $Id$ |
| 30 | 30 |
claimed that it would support subnets of /30 or less |
| 31 | 31 |
but actually would only accept /29 or less. |
| 32 | 32 |
* Extend byte counters to 64 bits (M. van Cuijk). |
| 33 |
-* PKCS#11 fixes (Alon Bar-Lev). |
|
| 34 |
-* Removed redundant base64 code. |
|
| 35 |
- |
|
| 33 |
+ |
|
| 36 | 34 |
2005.11.02 -- Version 2.0.5 |
| 37 | 35 |
|
| 38 | 36 |
* Fixed bug in Linux get_default_gateway function |
| ... | ... |
@@ -302,6 +302,7 @@ check_inactivity_timeout_dowork (struct context *c) |
| 302 | 302 |
void |
| 303 | 303 |
schedule_exit (struct context *c, const int n_seconds) |
| 304 | 304 |
{
|
| 305 |
+ tls_set_single_session (c->c2.tls_multi); |
|
| 305 | 306 |
update_time (); |
| 306 | 307 |
reset_coarse_timers (c); |
| 307 | 308 |
event_timeout_init (&c->c2.scheduled_exit, n_seconds, now); |
| ... | ... |
@@ -223,6 +223,7 @@ helper_client_server (struct options *o) |
| 223 | 223 |
o->ifconfig_pool_defined = true; |
| 224 | 224 |
o->ifconfig_pool_start = o->server_network + 4; |
| 225 | 225 |
o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - pool_end_reserve; |
| 226 |
+ ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); |
|
| 226 | 227 |
} |
| 227 | 228 |
|
| 228 | 229 |
helper_add_route (o->server_network, o->server_netmask, o); |
| ... | ... |
@@ -241,6 +242,7 @@ helper_client_server (struct options *o) |
| 241 | 241 |
o->ifconfig_pool_defined = true; |
| 242 | 242 |
o->ifconfig_pool_start = o->server_network + 2; |
| 243 | 243 |
o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 2; |
| 244 |
+ ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); |
|
| 244 | 245 |
o->ifconfig_pool_netmask = o->server_netmask; |
| 245 | 246 |
} |
| 246 | 247 |
|
| ... | ... |
@@ -267,6 +269,7 @@ helper_client_server (struct options *o) |
| 267 | 267 |
o->ifconfig_pool_defined = true; |
| 268 | 268 |
o->ifconfig_pool_start = o->server_network + 2; |
| 269 | 269 |
o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1; |
| 270 |
+ ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); |
|
| 270 | 271 |
o->ifconfig_pool_netmask = o->server_netmask; |
| 271 | 272 |
} |
| 272 | 273 |
|
| ... | ... |
@@ -325,6 +328,7 @@ helper_client_server (struct options *o) |
| 325 | 325 |
o->ifconfig_pool_defined = true; |
| 326 | 326 |
o->ifconfig_pool_start = o->server_bridge_pool_start; |
| 327 | 327 |
o->ifconfig_pool_end = o->server_bridge_pool_end; |
| 328 |
+ ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end); |
|
| 328 | 329 |
o->ifconfig_pool_netmask = o->server_bridge_netmask; |
| 329 | 330 |
push_option (o, print_opt_route_gateway (o->server_bridge_ip, &o->gc), M_USAGE); |
| 330 | 331 |
|
| ... | ... |
@@ -99,6 +99,25 @@ init_remote_list (struct context *c) |
| 99 | 99 |
} |
| 100 | 100 |
} |
| 101 | 101 |
|
| 102 |
+/* |
|
| 103 |
+ * Query for private key and auth-user-pass username/passwords |
|
| 104 |
+ */ |
|
| 105 |
+static void |
|
| 106 |
+init_query_passwords (struct context *c) |
|
| 107 |
+{
|
|
| 108 |
+#if defined(USE_CRYPTO) && defined(USE_SSL) |
|
| 109 |
+ /* Certificate password input */ |
|
| 110 |
+ if (c->options.key_pass_file) |
|
| 111 |
+ pem_password_setup (c->options.key_pass_file); |
|
| 112 |
+#endif |
|
| 113 |
+ |
|
| 114 |
+#if P2MP |
|
| 115 |
+ /* Auth user/pass input */ |
|
| 116 |
+ if (c->options.auth_user_pass_file) |
|
| 117 |
+ auth_user_pass_setup (c->options.auth_user_pass_file); |
|
| 118 |
+#endif |
|
| 119 |
+} |
|
| 120 |
+ |
|
| 102 | 121 |
void |
| 103 | 122 |
context_init_1 (struct context *c) |
| 104 | 123 |
{
|
| ... | ... |
@@ -113,11 +132,7 @@ context_init_1 (struct context *c) |
| 113 | 113 |
packet_id_persist_init (&c->c1.pid_persist); |
| 114 | 114 |
init_remote_list (c); |
| 115 | 115 |
|
| 116 |
-#if defined(USE_CRYPTO) && defined(USE_SSL) |
|
| 117 |
- /* Certificate password input */ |
|
| 118 |
- if (c->options.key_pass_file) |
|
| 119 |
- pem_password_setup (c->options.key_pass_file); |
|
| 120 |
-#endif |
|
| 116 |
+ init_query_passwords (c); |
|
| 121 | 117 |
|
| 122 | 118 |
#if defined(ENABLE_PKCS11) |
| 123 | 119 |
if (c->first_time) {
|
| ... | ... |
@@ -142,14 +157,6 @@ context_init_1 (struct context *c) |
| 142 | 142 |
} |
| 143 | 143 |
#endif |
| 144 | 144 |
|
| 145 |
-#if P2MP |
|
| 146 |
- /* Auth user/pass input */ |
|
| 147 |
- if (c->options.auth_user_pass_file) |
|
| 148 |
- {
|
|
| 149 |
- auth_user_pass_setup (c->options.auth_user_pass_file); |
|
| 150 |
- } |
|
| 151 |
-#endif |
|
| 152 |
- |
|
| 153 | 145 |
#ifdef ENABLE_HTTP_PROXY |
| 154 | 146 |
if (c->options.http_proxy_options || c->options.auto_proxy_info) |
| 155 | 147 |
{
|
| ... | ... |
@@ -417,8 +424,9 @@ static void |
| 417 | 417 |
do_uid_gid_chroot (struct context *c, bool no_delay) |
| 418 | 418 |
{
|
| 419 | 419 |
static const char why_not[] = "will be delayed because of --client, --pull, or --up-delay"; |
| 420 |
+ struct context_0 *c0 = c->c0; |
|
| 420 | 421 |
|
| 421 |
- if (c->first_time && !c->c2.uid_gid_set) |
|
| 422 |
+ if (c->first_time && c0 && !c0->uid_gid_set) |
|
| 422 | 423 |
{
|
| 423 | 424 |
/* chroot if requested */ |
| 424 | 425 |
if (c->options.chroot_dir) |
| ... | ... |
@@ -432,11 +440,11 @@ do_uid_gid_chroot (struct context *c, bool no_delay) |
| 432 | 432 |
/* set user and/or group that we want to setuid/setgid to */ |
| 433 | 433 |
if (no_delay) |
| 434 | 434 |
{
|
| 435 |
- set_group (&c->c2.group_state); |
|
| 436 |
- set_user (&c->c2.user_state); |
|
| 437 |
- c->c2.uid_gid_set = true; |
|
| 435 |
+ set_group (&c0->group_state); |
|
| 436 |
+ set_user (&c0->user_state); |
|
| 437 |
+ c0->uid_gid_set = true; |
|
| 438 | 438 |
} |
| 439 |
- else if (c->c2.uid_gid_specified) |
|
| 439 |
+ else if (c0->uid_gid_specified) |
|
| 440 | 440 |
{
|
| 441 | 441 |
msg (M_INFO, "NOTE: UID/GID downgrade %s", why_not); |
| 442 | 442 |
} |
| ... | ... |
@@ -1104,7 +1112,7 @@ do_hold (struct context *c) |
| 1104 | 1104 |
if (management) |
| 1105 | 1105 |
{
|
| 1106 | 1106 |
/* if c is defined, daemonize before hold */ |
| 1107 |
- if (c && c->options.daemon && management_would_hold (management)) |
|
| 1107 |
+ if (c && c->options.daemon && management_should_daemonize (management)) |
|
| 1108 | 1108 |
do_init_first_time (c); |
| 1109 | 1109 |
|
| 1110 | 1110 |
/* block until management hold is released */ |
| ... | ... |
@@ -1937,15 +1945,20 @@ do_compute_occ_strings (struct context *c) |
| 1937 | 1937 |
static void |
| 1938 | 1938 |
do_init_first_time (struct context *c) |
| 1939 | 1939 |
{
|
| 1940 |
- if (c->first_time && !c->did_we_daemonize) |
|
| 1940 |
+ if (c->first_time && !c->did_we_daemonize && !c->c0) |
|
| 1941 | 1941 |
{
|
| 1942 |
+ struct context_0 *c0; |
|
| 1943 |
+ |
|
| 1944 |
+ ALLOC_OBJ_CLEAR_GC (c->c0, struct context_0, &c->gc); |
|
| 1945 |
+ c0 = c->c0; |
|
| 1946 |
+ |
|
| 1942 | 1947 |
/* get user and/or group that we want to setuid/setgid to */ |
| 1943 |
- c->c2.uid_gid_specified = |
|
| 1944 |
- get_group (c->options.groupname, &c->c2.group_state) | |
|
| 1945 |
- get_user (c->options.username, &c->c2.user_state); |
|
| 1948 |
+ c0->uid_gid_specified = |
|
| 1949 |
+ get_group (c->options.groupname, &c0->group_state) | |
|
| 1950 |
+ get_user (c->options.username, &c0->user_state); |
|
| 1946 | 1951 |
|
| 1947 | 1952 |
/* get --writepid file descriptor */ |
| 1948 |
- get_pid_file (c->options.writepid, &c->c2.pid_state); |
|
| 1953 |
+ get_pid_file (c->options.writepid, &c0->pid_state); |
|
| 1949 | 1954 |
|
| 1950 | 1955 |
/* become a daemon if --daemon */ |
| 1951 | 1956 |
c->did_we_daemonize = possibly_become_daemon (&c->options, c->first_time); |
| ... | ... |
@@ -1955,7 +1968,7 @@ do_init_first_time (struct context *c) |
| 1955 | 1955 |
do_mlockall (true); /* call again in case we daemonized */ |
| 1956 | 1956 |
|
| 1957 | 1957 |
/* save process ID in a file */ |
| 1958 |
- write_pid (&c->c2.pid_state); |
|
| 1958 |
+ write_pid (&c0->pid_state); |
|
| 1959 | 1959 |
|
| 1960 | 1960 |
/* should we change scheduling priority? */ |
| 1961 | 1961 |
set_nice (c->options.nice); |
| ... | ... |
@@ -2475,6 +2488,12 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int |
| 2475 | 2475 |
goto sig; |
| 2476 | 2476 |
} |
| 2477 | 2477 |
|
| 2478 |
+#if P2MP |
|
| 2479 |
+ /* get passwords if undefined */ |
|
| 2480 |
+ if (auth_retry_get () == AR_INTERACT) |
|
| 2481 |
+ init_query_passwords (c); |
|
| 2482 |
+#endif |
|
| 2483 |
+ |
|
| 2478 | 2484 |
/* initialize context level 2 --verb/--mute parms */ |
| 2479 | 2485 |
init_verb_mute (c, IVM_LEVEL_2); |
| 2480 | 2486 |
|
| ... | ... |
@@ -2714,8 +2733,6 @@ inherit_context_child (struct context *dest, |
| 2714 | 2714 |
ASSERT (0); |
| 2715 | 2715 |
} |
| 2716 | 2716 |
|
| 2717 |
- dest->first_time = false; |
|
| 2718 |
- |
|
| 2719 | 2717 |
dest->gc = gc_new (); |
| 2720 | 2718 |
|
| 2721 | 2719 |
ALLOC_OBJ_CLEAR_GC (dest->sig, struct signal_info, &dest->gc); |
| ... | ... |
@@ -2793,6 +2810,7 @@ inherit_context_top (struct context *dest, |
| 2793 | 2793 |
dest->mode = CM_TOP_CLONE; |
| 2794 | 2794 |
|
| 2795 | 2795 |
dest->first_time = false; |
| 2796 |
+ dest->c0 = NULL; |
|
| 2796 | 2797 |
|
| 2797 | 2798 |
options_detach (&dest->options); |
| 2798 | 2799 |
gc_detach (&dest->gc); |
| ... | ... |
@@ -1863,6 +1863,16 @@ management_would_hold (struct management *man) |
| 1863 | 1863 |
} |
| 1864 | 1864 |
|
| 1865 | 1865 |
/* |
| 1866 |
+ * Return true if (from the management interface's perspective) OpenVPN should |
|
| 1867 |
+ * daemonize. |
|
| 1868 |
+ */ |
|
| 1869 |
+bool |
|
| 1870 |
+management_should_daemonize (struct management *man) |
|
| 1871 |
+{
|
|
| 1872 |
+ return management_would_hold (man) || man->settings.up_query_passwords; |
|
| 1873 |
+} |
|
| 1874 |
+ |
|
| 1875 |
+/* |
|
| 1866 | 1876 |
* If the hold flag is enabled, hibernate until a management client releases the hold. |
| 1867 | 1877 |
* Return true if the caller should not sleep for an additional time interval. |
| 1868 | 1878 |
*/ |
| ... | ... |
@@ -288,6 +288,7 @@ void management_clear_callback (struct management *man); |
| 288 | 288 |
|
| 289 | 289 |
bool management_query_user_pass (struct management *man, struct user_pass *up, const char *type, const unsigned int flags); |
| 290 | 290 |
|
| 291 |
+bool management_should_daemonize (struct management *man); |
|
| 291 | 292 |
bool management_would_hold (struct management *man); |
| 292 | 293 |
bool management_hold (struct management *man); |
| 293 | 294 |
|
| ... | ... |
@@ -117,6 +117,23 @@ struct context_buffers |
| 117 | 117 |
struct buffer read_tun_buf; |
| 118 | 118 |
}; |
| 119 | 119 |
|
| 120 |
+/* |
|
| 121 |
+ * level 0 context contains data related to |
|
| 122 |
+ * once-per OpenVPN instantiation events |
|
| 123 |
+ * such as daemonization. |
|
| 124 |
+ */ |
|
| 125 |
+struct context_0 |
|
| 126 |
+{
|
|
| 127 |
+ /* workspace for get_pid_file/write_pid */ |
|
| 128 |
+ struct pid_state pid_state; |
|
| 129 |
+ |
|
| 130 |
+ /* workspace for --user/--group */ |
|
| 131 |
+ bool uid_gid_specified; |
|
| 132 |
+ bool uid_gid_set; |
|
| 133 |
+ struct user_state user_state; |
|
| 134 |
+ struct group_state group_state; |
|
| 135 |
+}; |
|
| 136 |
+ |
|
| 120 | 137 |
/* |
| 121 | 138 |
* Contains the persist-across-restart OpenVPN tunnel instance state. |
| 122 | 139 |
* Reset only for SIGHUP restarts. |
| ... | ... |
@@ -337,15 +354,6 @@ struct context_2 |
| 337 | 337 |
*/ |
| 338 | 338 |
bool ipv4_tun; |
| 339 | 339 |
|
| 340 |
- /* workspace for get_pid_file/write_pid */ |
|
| 341 |
- struct pid_state pid_state; |
|
| 342 |
- |
|
| 343 |
- /* workspace for --user/--group */ |
|
| 344 |
- bool uid_gid_specified; |
|
| 345 |
- bool uid_gid_set; |
|
| 346 |
- struct user_state user_state; |
|
| 347 |
- struct group_state group_state; |
|
| 348 |
- |
|
| 349 | 340 |
/* should we print R|W|r|w to console on packet transfers? */ |
| 350 | 341 |
bool log_rw; |
| 351 | 342 |
|
| ... | ... |
@@ -453,6 +461,11 @@ struct context |
| 453 | 453 |
/* set to true after we daemonize */ |
| 454 | 454 |
bool did_we_daemonize; |
| 455 | 455 |
|
| 456 |
+ /* level 0 context contains data related to |
|
| 457 |
+ once-per OpenVPN instantiation events |
|
| 458 |
+ such as daemonization */ |
|
| 459 |
+ struct context_0 *c0; |
|
| 460 |
+ |
|
| 456 | 461 |
/* level 1 context is preserved for |
| 457 | 462 |
SIGUSR1 restarts, but initialized |
| 458 | 463 |
for SIGHUP restarts */ |
| ... | ... |
@@ -4058,17 +4058,8 @@ add_option (struct options *options, |
| 4058 | 4058 |
msg (msglevel, "error parsing --ifconfig-pool parameters"); |
| 4059 | 4059 |
goto err; |
| 4060 | 4060 |
} |
| 4061 |
- if (start > end) |
|
| 4062 |
- {
|
|
| 4063 |
- msg (msglevel, "--ifconfig-pool start IP is greater than end IP"); |
|
| 4064 |
- goto err; |
|
| 4065 |
- } |
|
| 4066 |
- if (end - start >= IFCONFIG_POOL_MAX) |
|
| 4067 |
- {
|
|
| 4068 |
- msg (msglevel, "--ifconfig-pool address range is too large. Current maximum is %d addresses.", |
|
| 4069 |
- IFCONFIG_POOL_MAX); |
|
| 4070 |
- goto err; |
|
| 4071 |
- } |
|
| 4061 |
+ if (!ifconfig_pool_verify_range (msglevel, start, end)) |
|
| 4062 |
+ goto err; |
|
| 4072 | 4063 |
|
| 4073 | 4064 |
options->ifconfig_pool_defined = true; |
| 4074 | 4065 |
options->ifconfig_pool_start = start; |
| ... | ... |
@@ -109,6 +109,33 @@ ifconfig_pool_find (struct ifconfig_pool *pool, const char *common_name) |
| 109 | 109 |
return -1; |
| 110 | 110 |
} |
| 111 | 111 |
|
| 112 |
+/* |
|
| 113 |
+ * Verify start/end range |
|
| 114 |
+ */ |
|
| 115 |
+bool |
|
| 116 |
+ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_addr_t end) |
|
| 117 |
+{
|
|
| 118 |
+ struct gc_arena gc = gc_new (); |
|
| 119 |
+ bool ret = true; |
|
| 120 |
+ |
|
| 121 |
+ if (start > end) |
|
| 122 |
+ {
|
|
| 123 |
+ msg (msglevel, "--ifconfig-pool start IP [%s] is greater than end IP [%s]", |
|
| 124 |
+ print_in_addr_t (start, 0, &gc), |
|
| 125 |
+ print_in_addr_t (end, 0, &gc)); |
|
| 126 |
+ ret = false; |
|
| 127 |
+ } |
|
| 128 |
+ if (end - start >= IFCONFIG_POOL_MAX) |
|
| 129 |
+ {
|
|
| 130 |
+ msg (msglevel, "--ifconfig-pool address range is too large [%s -> %s]. Current maximum is %d addresses, as defined by IFCONFIG_POOL_MAX variable.", |
|
| 131 |
+ print_in_addr_t (start, 0, &gc), |
|
| 132 |
+ print_in_addr_t (end, 0, &gc), |
|
| 133 |
+ IFCONFIG_POOL_MAX); |
|
| 134 |
+ ret = false; |
|
| 135 |
+ } |
|
| 136 |
+ gc_free (&gc); |
|
| 137 |
+ return ret; |
|
| 138 |
+} |
|
| 112 | 139 |
|
| 113 | 140 |
struct ifconfig_pool * |
| 114 | 141 |
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 |
| 68 | 68 |
|
| 69 | 69 |
void ifconfig_pool_free (struct ifconfig_pool *pool); |
| 70 | 70 |
|
| 71 |
+bool ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_addr_t end); |
|
| 72 |
+ |
|
| 71 | 73 |
ifconfig_pool_handle ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, const char *common_name); |
| 72 | 74 |
|
| 73 | 75 |
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, |
| 3886 | 3886 |
if (multi->opt.single_session && multi->n_sessions) |
| 3887 | 3887 |
{
|
| 3888 | 3888 |
msg (D_TLS_ERRORS, |
| 3889 |
- "TLS Error: Cannot accept new session request from %s due to --single-session [1]", |
|
| 3889 |
+ "TLS Error: Cannot accept new session request from %s due to session context expire or --single-session [1]", |
|
| 3890 | 3890 |
print_link_socket_actual (from, &gc)); |
| 3891 | 3891 |
goto error; |
| 3892 | 3892 |
} |
| ... | ... |
@@ -3929,7 +3929,7 @@ tls_pre_decrypt (struct tls_multi *multi, |
| 3929 | 3929 |
if (multi->opt.single_session) |
| 3930 | 3930 |
{
|
| 3931 | 3931 |
msg (D_TLS_ERRORS, |
| 3932 |
- "TLS Error: Cannot accept new session request from %s due to --single-session [2]", |
|
| 3932 |
+ "TLS Error: Cannot accept new session request from %s due to session context expire or --single-session [2]", |
|
| 3933 | 3933 |
print_link_socket_actual (from, &gc)); |
| 3934 | 3934 |
goto error; |
| 3935 | 3935 |
} |
| ... | ... |
@@ -663,6 +663,13 @@ tls_test_payload_len (const struct tls_multi *multi) |
| 663 | 663 |
return 0; |
| 664 | 664 |
} |
| 665 | 665 |
|
| 666 |
+static inline void |
|
| 667 |
+tls_set_single_session (struct tls_multi *multi) |
|
| 668 |
+{
|
|
| 669 |
+ if (multi) |
|
| 670 |
+ multi->opt.single_session = true; |
|
| 671 |
+} |
|
| 672 |
+ |
|
| 666 | 673 |
/* |
| 667 | 674 |
* protocol_dump() flags |
| 668 | 675 |
*/ |