diff options
author | Parménides GV <parmegv@sdf.org> | 2014-12-20 20:14:23 +0100 |
---|---|---|
committer | Parménides GV <parmegv@sdf.org> | 2014-12-23 19:58:02 +0100 |
commit | d6190becb1c48ee912b11a4206116d0fd4c90772 (patch) | |
tree | 1a8d7f85690ce56196855fa969e86b1e53d813f3 /app/openvpn/src/openvpn/mudp.c | |
parent | b1219330faf64b2cd4330d44390fdec137b659b7 (diff) |
Update ics-openvpn to 1006
Diffstat (limited to 'app/openvpn/src/openvpn/mudp.c')
-rw-r--r-- | app/openvpn/src/openvpn/mudp.c | 92 |
1 files changed, 20 insertions, 72 deletions
diff --git a/app/openvpn/src/openvpn/mudp.c b/app/openvpn/src/openvpn/mudp.c index 51227a90..3e3f7508 100644 --- a/app/openvpn/src/openvpn/mudp.c +++ b/app/openvpn/src/openvpn/mudp.c @@ -33,67 +33,19 @@ #if P2MP_SERVER #include "multi.h" +#include <inttypes.h> #include "forward-inline.h" #include "memdbg.h" /* - * Update instance with new peer address - */ -void -update_floated(struct multi_context *m, struct multi_instance *mi, - struct mroute_addr real, uint32_t hv) -{ - struct mroute_addr real_old; - - real_old = mi->real; - generate_prefix (mi); - - /* remove before modifying mi->real, since it also modifies key in hash */ - hash_remove(m->hash, &real_old); - hash_remove(m->iter, &real_old); - - /* update address */ - memcpy(&mi->real, &real, sizeof(real)); - - mi->context.c2.from = m->top.c2.from; - mi->context.c2.to_link_addr = &mi->context.c2.from; - - /* switch to new log prefix */ - generate_prefix (mi); - /* inherit buffers */ - mi->context.c2.buffers = m->top.c2.buffers; - - /* inherit parent link_socket and link_socket_info */ - mi->context.c2.link_socket = m->top.c2.link_socket; - mi->context.c2.link_socket_info->lsa->actual = m->top.c2.from; - - /* fix remote_addr in tls structure */ - tls_update_remote_addr (mi->context.c2.tls_multi, &mi->context.c2.from); - mi->did_open_context = true; - - hash_add(m->hash, &mi->real, mi, false); - hash_add(m->iter, &mi->real, mi, false); - - mi->did_real_hash = true; -#ifdef MANAGEMENT_DEF_AUTH - hash_remove (m->cid_hash, &mi->context.c2.mda_context.cid); - hash_add (m->cid_hash, &mi->context.c2.mda_context.cid, mi, false); -#endif - -#ifdef MANAGEMENT_DEF_AUTH - mi->did_cid_hash = true; -#endif -} - -/* * Get a client instance based on real address. If * the instance doesn't exist, create it while * maintaining real address hash table atomicity. */ struct multi_instance * -multi_get_create_instance_udp (struct multi_context *m) +multi_get_create_instance_udp (struct multi_context *m, bool *floated) { struct gc_arena gc = gc_new (); struct mroute_addr real; @@ -108,32 +60,25 @@ multi_get_create_instance_udp (struct multi_context *m) uint8_t* ptr = BPTR(&m->top.c2.buf); uint8_t op = ptr[0] >> P_OPCODE_SHIFT; uint32_t peer_id; - bool hmac_mismatch = false; + int i; - if (op == P_DATA_V2) + /* 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)) { - peer_id = ntohl((*(uint32_t*)ptr)) & 0xFFFFFF; + peer_id = ntohl(*(uint32_t*)ptr) & 0xFFFFFF; if ((peer_id < m->max_clients) && (m->instances[peer_id])) { mi = m->instances[peer_id]; - if (!link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from)) - { - msg(D_MULTI_MEDIUM, "float from %s to %s", - print_link_socket_actual (&mi->context.c2.from, &gc), print_link_socket_actual (&m->top.c2.from, &gc)); + *floated = !link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from); - /* peer-id is not trusted, so check hmac */ - hmac_mismatch = !(crypto_test_hmac(&m->top.c2.buf, &mi->context.c2.crypto_options)); - if (hmac_mismatch) - { - mi = NULL; - msg (D_MULTI_MEDIUM, "HMAC mismatch for peer-id %d", peer_id); - } - else - { - update_floated(m, mi, real, hv); - } - } + if (*floated) + { + /* reset prefix, since here we are not sure peer is the one it claims to be */ + ungenerate_prefix(mi); + msg (D_MULTI_ERRORS, "Untrusted peer %" PRIu32 " wants to float to %s", peer_id, + mroute_addr_print (&real, &gc)); + } } } else @@ -144,7 +89,7 @@ multi_get_create_instance_udp (struct multi_context *m) mi = (struct multi_instance *) he->value; } } - if (!mi && !hmac_mismatch) + if (!mi) { if (!m->top.c2.tls_auth_standalone || tls_pre_decrypt_lite (m->top.c2.tls_auth_standalone, &m->top.c2.from, &m->top.c2.buf)) @@ -157,8 +102,7 @@ multi_get_create_instance_udp (struct multi_context *m) hash_add_fast (hash, bucket, &mi->real, hv, mi); mi->did_real_hash = true; - int i; - for (i = 0; i < m->max_clients; ++ i) + for (i = 0; i < m->max_clients; ++i) { if (!m->instances[i]) { @@ -167,6 +111,10 @@ multi_get_create_instance_udp (struct multi_context *m) break; } } + + /* should not really end up here, since multi_create_instance returns null + * if amount of clients exceeds max_clients */ + ASSERT(i < m->max_clients); } } else |