summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-09-08 03:52:52 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-09-08 03:52:52 +0000
commit1c4af9eaf53a16b30b25a052bebded816191bf76 (patch)
treeed1fb38ad1614fb7489ff4ee8c25ee8779e6e30c
parentb4b5c311d376cd499dfeea146f0b448910700562 (diff)
downloadopenvpn-1c4af9eaf53a16b30b25a052bebded816191bf76.tar.gz
openvpn-1c4af9eaf53a16b30b25a052bebded816191bf76.tar.xz
openvpn-1c4af9eaf53a16b30b25a052bebded816191bf76.zip
Fixed bug in intra-session TLS key rollover that was introduced with
deferred authentication features in 2.1_rc8. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3316 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r--debug/valgrind-suppress28
-rw-r--r--errlevel.h1
-rw-r--r--ssl.c57
3 files changed, 68 insertions, 18 deletions
diff --git a/debug/valgrind-suppress b/debug/valgrind-suppress
index c62e569..bf30959 100644
--- a/debug/valgrind-suppress
+++ b/debug/valgrind-suppress
@@ -36,6 +36,34 @@
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
+ obj:/lib/libc-2.5.so
+ obj:/lib/ld-2.5.so
+ fun:__libc_dlopen_mode
+ fun:__nss_lookup_function
+ obj:/lib/libc-2.5.so
+ fun:getgrnam_r
+ fun:getgrnam
+ fun:get_group
+ fun:do_init_first_time
+ fun:init_instance
+ fun:init_instance_handle_signals
+ fun:tunnel_server_udp
+ fun:main
+}
+
+{
+ <insert a suppression name here>
+ Memcheck:Addr8
+ obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
+ obj:/lib/ld-2.5.so
obj:/lib/libc-2.5.so
obj:/lib/ld-2.5.so
fun:__libc_dlopen_mode
diff --git a/errlevel.h b/errlevel.h
index 95c8a30..08ba00f 100644
--- a/errlevel.h
+++ b/errlevel.h
@@ -138,6 +138,7 @@
#define D_PING LOGLEV(7, 70, M_DEBUG) /* PING send/receive messages */
#define D_PS_PROXY_DEBUG LOGLEV(7, 70, M_DEBUG) /* port share proxy debug */
#define D_AUTO_USERID LOGLEV(7, 70, M_DEBUG) /* AUTO_USERID debugging */
+#define D_TLS_KEYSELECT LOGLEV(7, 70, M_DEBUG) /* show information on key selection for data channel */
#define D_PF_DROPPED_BCAST LOGLEV(7, 71, M_DEBUG) /* packet filter dropped a broadcast packet */
#define D_PF_DEBUG LOGLEV(7, 72, M_DEBUG) /* packet filter debugging, must also define PF_DEBUG in pf.h */
diff --git a/ssl.c b/ssl.c
index f627999..7874611 100644
--- a/ssl.c
+++ b/ssl.c
@@ -3439,6 +3439,14 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
return false;
}
+static int
+auth_deferred_expire_window (const struct tls_options *o)
+{
+ const int hw = o->handshake_window;
+ const int r2 = o->renegotiate_seconds / 2;
+ return min_int (hw, r2);
+}
+
/*
* This is the primary routine for processing TLS stuff inside the
* the main event loop. When this routine exits
@@ -3519,7 +3527,8 @@ tls_process (struct tls_multi *multi,
buf = reliable_get_buf_output_sequenced (ks->send_reliable);
if (buf)
{
- ks->auth_deferred_expire = ks->must_negotiate = now + session->opt->handshake_window;
+ ks->must_negotiate = now + session->opt->handshake_window;
+ ks->auth_deferred_expire = now + auth_deferred_expire_window (session->opt);
/* null buffer */
reliable_mark_active_outgoing (ks->send_reliable, buf, ks->initial_opcode);
@@ -4084,8 +4093,8 @@ tls_pre_decrypt (struct tls_multi *multi,
ASSERT (buf_advance (buf, 1));
++ks->n_packets;
ks->n_bytes += buf->len;
- dmsg (D_TLS_DEBUG,
- "TLS: data channel, key_id=%d, IP=%s",
+ dmsg (D_TLS_KEYSELECT,
+ "TLS: tls_pre_decrypt, key_id=%d, IP=%s",
key_id, print_link_socket_actual (from, &gc));
gc_free (&gc);
return ret;
@@ -4592,6 +4601,7 @@ tls_pre_encrypt (struct tls_multi *multi,
if (buf->len > 0)
{
int i;
+ struct key_state *ks_select = NULL;
for (i = 0; i < KEY_SCAN_SIZE; ++i)
{
struct key_state *ks = multi->key_scan[i];
@@ -4600,25 +4610,36 @@ tls_pre_encrypt (struct tls_multi *multi,
#ifdef ENABLE_DEF_AUTH
&& !ks->auth_deferred
#endif
- && (!ks->key_id || now >= ks->auth_deferred_expire))
+ )
{
- opt->key_ctx_bi = &ks->key;
- opt->packet_id = multi->opt.replay ? &ks->packet_id : NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
- opt->flags |= multi->opt.crypto_flags_or;
- multi->save_ks = ks;
- dmsg (D_TLS_DEBUG, "TLS: tls_pre_encrypt: key_id=%d", ks->key_id);
- return;
+ if (!ks_select)
+ ks_select = ks;
+ if (now >= ks->auth_deferred_expire)
+ {
+ ks_select = ks;
+ break;
+ }
}
}
- {
- struct gc_arena gc = gc_new ();
- dmsg (D_TLS_NO_SEND_KEY, "TLS Warning: no data channel send key available: %s",
- print_key_id (multi, &gc));
- gc_free (&gc);
- }
+ if (ks_select)
+ {
+ opt->key_ctx_bi = &ks_select->key;
+ opt->packet_id = multi->opt.replay ? &ks_select->packet_id : NULL;
+ opt->pid_persist = NULL;
+ opt->flags &= multi->opt.crypto_flags_and;
+ opt->flags |= multi->opt.crypto_flags_or;
+ multi->save_ks = ks_select;
+ dmsg (D_TLS_KEYSELECT, "TLS: tls_pre_encrypt: key_id=%d", ks_select->key_id);
+ return;
+ }
+ else
+ {
+ struct gc_arena gc = gc_new ();
+ dmsg (D_TLS_KEYSELECT, "TLS Warning: no data channel send key available: %s",
+ print_key_id (multi, &gc));
+ gc_free (&gc);
+ }
}
buf->len = 0;