aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--forward.c1
-rw-r--r--helper.c4
-rw-r--r--init.c72
-rw-r--r--manage.c10
-rw-r--r--manage.h1
-rw-r--r--openvpn.h31
-rw-r--r--options.c13
-rw-r--r--pool.c27
-rw-r--r--pool.h2
-rw-r--r--ssl.c4
-rw-r--r--ssl.h7
12 files changed, 137 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index a186b6f..9aa1378 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/forward.c b/forward.c
index 338d862..5c35562 100644
--- a/forward.c
+++ b/forward.c
@@ -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);
diff --git a/helper.c b/helper.c
index 7a69816..d2b3d6f 100644
--- a/helper.c
+++ b/helper.c
@@ -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);
diff --git a/init.c b/init.c
index 24f1a7f..8e730f1 100644
--- a/init.c
+++ b/init.c
@@ -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);
diff --git a/manage.c b/manage.c
index dca5500..127e933 100644
--- a/manage.c
+++ b/manage.c
@@ -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.
*/
diff --git a/manage.h b/manage.h
index dce08e8..c492866 100644
--- a/manage.h
+++ b/manage.h
@@ -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);
diff --git a/openvpn.h b/openvpn.h
index e635dba..437a02f 100644
--- a/openvpn.h
+++ b/openvpn.h
@@ -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 */
diff --git a/options.c b/options.c
index d02530e..1ef201c 100644
--- a/options.c
+++ b/options.c
@@ -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;
diff --git a/pool.c b/pool.c
index 95682f7..cb666b8 100644
--- a/pool.c
+++ b/pool.c
@@ -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)
diff --git a/pool.h b/pool.h
index 6ab19c5..20edd70 100644
--- a/pool.h
+++ b/pool.h
@@ -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);
diff --git a/ssl.c b/ssl.c
index d76cda6..7be2394 100644
--- a/ssl.c
+++ b/ssl.c
@@ -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;
}
diff --git a/ssl.h b/ssl.h
index 4acb259..afebb8e 100644
--- a/ssl.h
+++ b/ssl.h
@@ -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
*/