Check known peer keys after authenticated transport handshake before UP

This commit is contained in:
evgeny committed 2026-10-30 22:39:09 +01:00
1 parent 90f70f2b72
commit 0850a52180
1 file changed
+28
+28
View File
@@ -30,6 +30,22 @@
#include "../lib/u_async.h"
#include "../lib/debug_config.h"
#include "etcp_loadbalancer.h"
/* Вызывать только после аутентификации ciphertext/STCP, под active_users/callbacks_running.
* Новый handshake перепроверяет членство; обычные DATA используют положительный кэш этого линка. */
static int admit_peer(struct ETCP_LINK* link, int handshake) {
struct ETCP_CONN* c = link->etcp;
if (!c->require_known_node && !link->require_known_node) return 1;
if (!handshake && link->peer_admitted) return 1;
if (c->peer_node_id != sc_derive_node_id_from_pubkey(c->crypto_ctx.peer_public_key)
|| !topo_groups_peer_key_known(c->instance, c->crypto_ctx.peer_public_key)) {
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] authenticated handshake denied: unknown peer key path=%u", c->log_name, link->local_link_id);
etcp_link_close(link); return 0;
}
link->peer_admitted = 1;
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] authenticated known peer admitted path=%u", c->log_name, link->local_link_id);
return 1;
}
#include "etcp_keepalive.h"
#ifdef UTUN_HAVE_STANDBY
#include "standby.h"
@@ -1408,6 +1424,8 @@ void etcp_link_enter_ready_tcp(struct ETCP_LINK *link) {
etcp->callbacks_running++;
link->active_users++;
if (!admit_peer(link, 1)) goto done;
/* reinit только при смене reset_id пира — синхронизация через etcp_conn_apply_peer_reset_id */
if (link->tcp_link) {
uint64_t peer_rid = stcp_link_get_peer_reset_id(link->tcp_link);
@@ -2411,6 +2429,8 @@ static void bound_receive(struct ETCP_LINK* link, struct ll_entry* entry) {
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] packet channel authentication/format failed: result=%d bytes=%zu",
conn->log_name, result, length); goto done;
}
if (!admit_peer(link, !link->initialized || pkt->data[0] == ETCP_INIT_REQUEST
|| pkt->data[0] == ETCP_INIT_REQUEST_NOINIT)) goto done;
pkt->data_len = length - 3; pkt->noencrypt_len = 0; pkt->link = link;
DEBUG_TRACE(DEBUG_CATEGORY_DEBUG, "[%s] packet channel RX path=%u wire=%u plain=%zu code=%02x up=%u",
conn->log_name, link->local_link_id, entry->len, length, pkt->data[0], pkt->flag_up);
@@ -2698,6 +2718,11 @@ static void etcp_process_packet_direct(struct ETCP_SOCKET* e_sock, uint8_t* data
}// коллизия - peer id совпал а ключи разные.
}
if (conn->require_known_node && !topo_groups_peer_key_known(conn->instance, sc.peer_public_key)) {
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] authenticated UDP INIT denied: unknown peer key", conn->log_name);
errorcode = 8; goto ec_fr;
}
if (conn->fin_wait) {
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] received INIT during fin_wait, clearing", conn->log_name);
conn->fin_wait = 0;
@@ -2911,6 +2936,9 @@ int etcp_packet_decrypted(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt,
pkt->link=link;
if (!pkt->data_len) { DEBUG_WARN(DEBUG_CATEGORY_ETCP,"empty decrypted ETCP packet"); result = 46; goto done; }
if (conn->close_requested) { memory_pool_free(conn->instance->pkt_pool, pkt); goto done; }
if (!admit_peer(link, pkt->data[0] == ETCP_INIT_RESPONSE || pkt->data[0] == ETCP_INIT_RESPONSE_NOINIT)) {
result = 8; goto done;
}
if (etcp_session_receive(link->etcp,pkt->data,pkt->data_len)) {
memory_pool_free(conn->instance->pkt_pool,pkt); goto done;
}