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.
This commit is contained in:
heinrich5991 2018-10-14 08:18:32 +02:00
parent 865678afef
commit c7750f3616

View file

@ -508,45 +508,38 @@ void CNetServer::OnConnCtrlMsg(NETADDR &Addr, int ClientID, int ControlMsg, cons
void CNetServer::OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet) void CNetServer::OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet)
{ {
if (ClientExists(Addr)) if(ClientExists(Addr))
return; // silently ignore return; // silently ignore
if (Addr.type == NETTYPE_WEBSOCKET_IPV4) if(Addr.type == NETTYPE_WEBSOCKET_IPV4)
{ {
// websocket client doesn't send token // websocket client doesn't send token
// direct accept // direct accept
SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), NET_SECURITY_TOKEN_UNSUPPORTED); SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), NET_SECURITY_TOKEN_UNSUPPORTED);
TryAcceptClient(Addr, 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 >= // response connection request with token
(int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(SECURITY_TOKEN)) && SECURITY_TOKEN Token = GetToken(Addr);
!mem_comp(&Packet.m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)); SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), Token);
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);
}
} }
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]); SECURITY_TOKEN Token = ToSecurityToken(&Packet.m_aChunkData[1]);
if (Token == GetToken(Addr)) if(Token == GetToken(Addr))
{ {
// correct token // correct token
// try to accept client // try to accept client
if (g_Config.m_Debug) if(g_Config.m_Debug)
dbg_msg("security", "new client (ddnet token)"); dbg_msg("security", "new client (ddnet token)");
TryAcceptClient(Addr, Token); TryAcceptClient(Addr, Token);
} }
else else
{ {
// invalid token // invalid token
if (g_Config.m_Debug) if(g_Config.m_Debug)
dbg_msg("security", "invalid token"); dbg_msg("security", "invalid token");
} }
} }
@ -570,6 +563,29 @@ int CNetServer::GetClientSlot(const NETADDR &Addr)
return Slot; 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 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 // not found, client that wants to connect
if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL && if(IsDDNetControlMsg(&m_RecvUnpacker.m_Data))
m_RecvUnpacker.m_Data.m_DataSize > 1) // got ddnet control msg
// got control msg with extra size (should support token)
OnTokenCtrlMsg(Addr, m_RecvUnpacker.m_Data.m_aChunkData[0], m_RecvUnpacker.m_Data); OnTokenCtrlMsg(Addr, m_RecvUnpacker.m_Data.m_aChunkData[0], m_RecvUnpacker.m_Data);
else else
// got connection-less ctrl or sys msg // got connection-less ctrl or sys msg