git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@855 e7ae566f-a301-0410-adde-c780ea21d3b5
james authored on 2005/12/14 10:09:11... | ... |
@@ -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 |
*/ |