]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Support for disabled peer-id
authorLev Stipakov <lev.stipakov@f-secure.com>
Sun, 18 Sep 2016 06:51:36 +0000 (09:51 +0300)
committerGert Doering <gert@greenie.muc.de>
Sun, 18 Sep 2016 07:09:56 +0000 (09:09 +0200)
v5:
* Few more nickpicks

v4:
* replace magic number with define
* show user a decimal value instead of hex

v3:
* move assert outside of loop
* add max-clients value check to options

v2:
* Add round brackets for clarity
* Rephrase comment

Support for disabled peer-id

When peer-id value is 0xFFFFFF, server should ignore it and treat packet
in a same way as P_DATA_V1.
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <1474181496-24846-1-git-send-email-lstipakov@gmail.com>
URL: http://www.mail-archive.com/search?l=mid&q=1474181496-24846-1-git-send-email-lstipakov@gmail.com

Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/mudp.c
src/openvpn/multi.c
src/openvpn/openvpn.h
src/openvpn/options.c

index 21a7e97f73bfd7883da95b291fc741c3ad079b14..fec5e8d9244e95385ffe940898150a3735c16a68 100644 (file)
@@ -64,12 +64,16 @@ multi_get_create_instance_udp (struct multi_context *m, bool *floated)
       struct hash_bucket *bucket = hash_bucket (hash, hv);
       uint8_t* ptr = BPTR(&m->top.c2.buf);
       uint8_t op = ptr[0] >> P_OPCODE_SHIFT;
+      bool v2 = (op == P_DATA_V2) && (m->top.c2.buf.len >= (1 + 3));
+      bool peer_id_disabled = false;
 
       /* make sure buffer has enough length to read opcode (1 byte) and peer-id (3 bytes) */
-      if (op == P_DATA_V2 && m->top.c2.buf.len >= (1 + 3))
+      if (v2)
        {
          uint32_t peer_id = ntohl(*(uint32_t*)ptr) & 0xFFFFFF;
-         if ((peer_id < m->max_clients) && (m->instances[peer_id]))
+         peer_id_disabled = (peer_id == MAX_PEER_ID);
+
+         if (!peer_id_disabled && (peer_id < m->max_clients) && (m->instances[peer_id]))
            {
              mi = m->instances[peer_id];
 
@@ -84,7 +88,7 @@ multi_get_create_instance_udp (struct multi_context *m, bool *floated)
              }
            }
        }
-      else
+      if (!v2 || peer_id_disabled)
        {
          he = hash_lookup_fast (hash, bucket, &real, hv);
          if (he)
@@ -107,6 +111,9 @@ multi_get_create_instance_udp (struct multi_context *m, bool *floated)
                      hash_add_fast (hash, bucket, &mi->real, hv, mi);
                      mi->did_real_hash = true;
 
+                     /* max_clients must be less then max peer-id value */
+                     ASSERT(m->max_clients < MAX_PEER_ID);
+
                      for (i = 0; i < m->max_clients; ++i)
                        {
                          if (!m->instances[i])
index ba7f2c0a40b3b0b9a7784e0b9d931308d82fa027..3bc6ee91da6174def5ee663ee6c88266a5f217c8 100644 (file)
@@ -605,7 +605,8 @@ multi_close_instance (struct multi_context *m,
        }
 #endif
 
-      m->instances[mi->context.c2.tls_multi->peer_id] = NULL;
+      if (mi->context.c2.tls_multi->peer_id != MAX_PEER_ID)
+       m->instances[mi->context.c2.tls_multi->peer_id] = NULL;
 
       schedule_remove_entry (m->schedule, (struct schedule_entry *) mi);
 
index 1a458f1c1c260810f8a376a2b251df0021852464..65a183a736db0c4046ffca0b9f29bede4546b6c0 100644 (file)
@@ -595,4 +595,7 @@ struct context
 #define CIPHER_ENABLED(c) (false)
 #endif
 
+/* this represents "disabled peer-id" */
+#define MAX_PEER_ID 0xFFFFFF
+
 #endif
index c9688c372638f013437f88aa359a36cd0569f22c..4b7203d9ba3bbed5a941f3fb817e7e0623146b9f 100644 (file)
@@ -5893,6 +5893,11 @@ add_option (struct options *options,
          msg (msglevel, "--max-clients must be at least 1");
          goto err;
        }
+      if (max_clients >= MAX_PEER_ID) /* max peer-id value */
+       {
+         msg (msglevel, "--max-clients must be less than %d", MAX_PEER_ID);
+         goto err;
+       }
       options->max_clients = max_clients;
     }
   else if (streq (p[0], "max-routes-per-client") && p[1] && !p[2])