From c7750f3616586d5b68aae0f328741c68f1e44042 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Sun, 14 Oct 2018 08:18:32 +0200 Subject: [PATCH] Don't ignore CONNECT packets with data that we don't know This specifically affects 0.6.5. Just treat them the same way as those without any data. --- src/engine/shared/network_server.cpp | 55 ++++++++++++++++++---------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index d4e0abe65..705a19ad1 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -508,45 +508,38 @@ void CNetServer::OnConnCtrlMsg(NETADDR &Addr, int ClientID, int ControlMsg, cons void CNetServer::OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet) { - if (ClientExists(Addr)) + if(ClientExists(Addr)) return; // silently ignore - if (Addr.type == NETTYPE_WEBSOCKET_IPV4) + if(Addr.type == NETTYPE_WEBSOCKET_IPV4) { // websocket client doesn't send token // direct accept SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), NET_SECURITY_TOKEN_UNSUPPORTED); TryAcceptClient(Addr, NET_SECURITY_TOKEN_UNSUPPORTED); } - else if (ControlMsg == NET_CTRLMSG_CONNECT) + else if(ControlMsg == NET_CTRLMSG_CONNECT) { - bool SupportsToken = Packet.m_DataSize >= - (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(SECURITY_TOKEN)) && - !mem_comp(&Packet.m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)); - - if (SupportsToken) - { - // response connection request with token - SECURITY_TOKEN Token = GetToken(Addr); - SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), Token); - } + // response connection request with token + SECURITY_TOKEN Token = GetToken(Addr); + SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), Token); } - else if (ControlMsg == NET_CTRLMSG_ACCEPT && Packet.m_DataSize == 1 + sizeof(SECURITY_TOKEN)) + else if(ControlMsg == NET_CTRLMSG_ACCEPT) { SECURITY_TOKEN Token = ToSecurityToken(&Packet.m_aChunkData[1]); - if (Token == GetToken(Addr)) + if(Token == GetToken(Addr)) { // correct token // try to accept client - if (g_Config.m_Debug) + if(g_Config.m_Debug) dbg_msg("security", "new client (ddnet token)"); TryAcceptClient(Addr, Token); } else { // invalid token - if (g_Config.m_Debug) + if(g_Config.m_Debug) dbg_msg("security", "invalid token"); } } @@ -570,6 +563,29 @@ int CNetServer::GetClientSlot(const NETADDR &Addr) return Slot; } +static bool IsDDNetControlMsg(const CNetPacketConstruct *pPacket) +{ + if(!(pPacket->m_Flags&NET_PACKETFLAG_CONTROL) + || pPacket->m_DataSize < 1) + { + return false; + } + if(pPacket->m_aChunkData[0] == NET_CTRLMSG_CONNECT + && pPacket->m_DataSize >= (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(SECURITY_TOKEN)) + && mem_comp(&pPacket->m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)) == 0) + { + // DDNet CONNECT + return true; + } + if(pPacket->m_aChunkData[0] == NET_CTRLMSG_ACCEPT + && pPacket->m_DataSize >= 1 + (int)sizeof(SECURITY_TOKEN)) + { + // DDNet ACCEPT + return true; + } + return false; +} + /* TODO: chopp up this function into smaller working parts */ @@ -643,9 +659,8 @@ int CNetServer::Recv(CNetChunk *pChunk) { // not found, client that wants to connect - if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL && - m_RecvUnpacker.m_Data.m_DataSize > 1) - // got control msg with extra size (should support token) + if(IsDDNetControlMsg(&m_RecvUnpacker.m_Data)) + // got ddnet control msg OnTokenCtrlMsg(Addr, m_RecvUnpacker.m_Data.m_aChunkData[0], m_RecvUnpacker.m_Data); else // got connection-less ctrl or sys msg