Browse code

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

james authored on 2008/09/08 12:52:52
Showing 3 changed files
... ...
@@ -36,6 +36,34 @@
36 36
    obj:/lib/ld-2.5.so
37 37
    obj:/lib/ld-2.5.so
38 38
    obj:/lib/ld-2.5.so
39
+   obj:/lib/ld-2.5.so
40
+   obj:/lib/ld-2.5.so
41
+   obj:/lib/ld-2.5.so
42
+   obj:/lib/libc-2.5.so
43
+   obj:/lib/ld-2.5.so
44
+   fun:__libc_dlopen_mode
45
+   fun:__nss_lookup_function
46
+   obj:/lib/libc-2.5.so
47
+   fun:getgrnam_r
48
+   fun:getgrnam
49
+   fun:get_group
50
+   fun:do_init_first_time
51
+   fun:init_instance
52
+   fun:init_instance_handle_signals
53
+   fun:tunnel_server_udp
54
+   fun:main
55
+}
56
+
57
+{
58
+   <insert a suppression name here>
59
+   Memcheck:Addr8
60
+   obj:/lib/ld-2.5.so
61
+   obj:/lib/ld-2.5.so
62
+   obj:/lib/ld-2.5.so
63
+   obj:/lib/ld-2.5.so
64
+   obj:/lib/ld-2.5.so
65
+   obj:/lib/ld-2.5.so
66
+   obj:/lib/ld-2.5.so
39 67
    obj:/lib/libc-2.5.so
40 68
    obj:/lib/ld-2.5.so
41 69
    fun:__libc_dlopen_mode
... ...
@@ -138,6 +138,7 @@
138 138
 #define D_PING               LOGLEV(7, 70, M_DEBUG)  /* PING send/receive messages */
139 139
 #define D_PS_PROXY_DEBUG     LOGLEV(7, 70, M_DEBUG)  /* port share proxy debug */
140 140
 #define D_AUTO_USERID        LOGLEV(7, 70, M_DEBUG)  /* AUTO_USERID debugging */
141
+#define D_TLS_KEYSELECT      LOGLEV(7, 70, M_DEBUG)  /* show information on key selection for data channel */
141 142
 #define D_PF_DROPPED_BCAST   LOGLEV(7, 71, M_DEBUG)  /* packet filter dropped a broadcast packet */
142 143
 #define D_PF_DEBUG           LOGLEV(7, 72, M_DEBUG)  /* packet filter debugging, must also define PF_DEBUG in pf.h */
143 144
 
... ...
@@ -3439,6 +3439,14 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
3439 3439
   return false;
3440 3440
 }
3441 3441
 
3442
+static int
3443
+auth_deferred_expire_window (const struct tls_options *o)
3444
+{
3445
+  const int hw = o->handshake_window;
3446
+  const int r2 = o->renegotiate_seconds / 2;
3447
+  return min_int (hw, r2);
3448
+}
3449
+
3442 3450
 /*
3443 3451
  * This is the primary routine for processing TLS stuff inside the
3444 3452
  * the main event loop.  When this routine exits
... ...
@@ -3519,7 +3527,8 @@ tls_process (struct tls_multi *multi,
3519 3519
 	      buf = reliable_get_buf_output_sequenced (ks->send_reliable);
3520 3520
 	      if (buf)
3521 3521
 		{
3522
-		  ks->auth_deferred_expire = ks->must_negotiate = now + session->opt->handshake_window;
3522
+		  ks->must_negotiate = now + session->opt->handshake_window;
3523
+		  ks->auth_deferred_expire = now + auth_deferred_expire_window (session->opt);
3523 3524
 
3524 3525
 		  /* null buffer */
3525 3526
 		  reliable_mark_active_outgoing (ks->send_reliable, buf, ks->initial_opcode);
... ...
@@ -4084,8 +4093,8 @@ tls_pre_decrypt (struct tls_multi *multi,
4084 4084
 		  ASSERT (buf_advance (buf, 1));
4085 4085
 		  ++ks->n_packets;
4086 4086
 		  ks->n_bytes += buf->len;
4087
-		  dmsg (D_TLS_DEBUG,
4088
-		       "TLS: data channel, key_id=%d, IP=%s",
4087
+		  dmsg (D_TLS_KEYSELECT,
4088
+		       "TLS: tls_pre_decrypt, key_id=%d, IP=%s",
4089 4089
 		       key_id, print_link_socket_actual (from, &gc));
4090 4090
 		  gc_free (&gc);
4091 4091
 		  return ret;
... ...
@@ -4592,6 +4601,7 @@ tls_pre_encrypt (struct tls_multi *multi,
4592 4592
   if (buf->len > 0)
4593 4593
     {
4594 4594
       int i;
4595
+      struct key_state *ks_select = NULL;
4595 4596
       for (i = 0; i < KEY_SCAN_SIZE; ++i)
4596 4597
 	{
4597 4598
 	  struct key_state *ks = multi->key_scan[i];
... ...
@@ -4600,25 +4610,36 @@ tls_pre_encrypt (struct tls_multi *multi,
4600 4600
 #ifdef ENABLE_DEF_AUTH
4601 4601
 	      && !ks->auth_deferred
4602 4602
 #endif
4603
-	      && (!ks->key_id || now >= ks->auth_deferred_expire))
4603
+	      )
4604 4604
 	    {
4605
-	      opt->key_ctx_bi = &ks->key;
4606
-	      opt->packet_id = multi->opt.replay ? &ks->packet_id : NULL;
4607
-	      opt->pid_persist = NULL;
4608
-	      opt->flags &= multi->opt.crypto_flags_and;
4609
-	      opt->flags |= multi->opt.crypto_flags_or;
4610
-	      multi->save_ks = ks;
4611
-	      dmsg (D_TLS_DEBUG, "TLS: tls_pre_encrypt: key_id=%d", ks->key_id);
4612
-	      return;
4605
+	      if (!ks_select)
4606
+		ks_select = ks;
4607
+	      if (now >= ks->auth_deferred_expire)
4608
+		{
4609
+		  ks_select = ks;
4610
+		  break;
4611
+		}
4613 4612
 	    }
4614 4613
 	}
4615 4614
 
4616
-      {
4617
-	struct gc_arena gc = gc_new ();
4618
-	dmsg (D_TLS_NO_SEND_KEY, "TLS Warning: no data channel send key available: %s",
4619
-	     print_key_id (multi, &gc));
4620
-	gc_free (&gc);
4621
-      }
4615
+      if (ks_select)
4616
+	{
4617
+	  opt->key_ctx_bi = &ks_select->key;
4618
+	  opt->packet_id = multi->opt.replay ? &ks_select->packet_id : NULL;
4619
+	  opt->pid_persist = NULL;
4620
+	  opt->flags &= multi->opt.crypto_flags_and;
4621
+	  opt->flags |= multi->opt.crypto_flags_or;
4622
+	  multi->save_ks = ks_select;
4623
+	  dmsg (D_TLS_KEYSELECT, "TLS: tls_pre_encrypt: key_id=%d", ks_select->key_id);
4624
+	  return;
4625
+	}
4626
+      else
4627
+	{
4628
+	  struct gc_arena gc = gc_new ();
4629
+	  dmsg (D_TLS_KEYSELECT, "TLS Warning: no data channel send key available: %s",
4630
+		print_key_id (multi, &gc));
4631
+	  gc_free (&gc);
4632
+	}
4622 4633
     }
4623 4634
 
4624 4635
   buf->len = 0;