示例#1
0
SECURITY_TOKEN CNetServer::GetToken(const NETADDR &Addr)
{
	md5_state_t md5;
	md5_byte_t digest[16];
	SECURITY_TOKEN SecurityToken;
	md5_init(&md5);

	md5_append(&md5, (unsigned char*)m_SecurityTokenSeed, sizeof(m_SecurityTokenSeed));
	md5_append(&md5, (unsigned char*)&Addr, sizeof(Addr));

	md5_finish(&md5, digest);
	SecurityToken = ToSecurityToken(digest);

	if (SecurityToken == NET_SECURITY_TOKEN_UNKNOWN ||
		SecurityToken == NET_SECURITY_TOKEN_UNSUPPORTED)
			SecurityToken = 1;

	return SecurityToken;
}
示例#2
0
int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr, SECURITY_TOKEN SecurityToken)
{
    if (State() != NET_CONNSTATE_OFFLINE && m_SecurityToken != NET_SECURITY_TOKEN_UNKNOWN && m_SecurityToken != NET_SECURITY_TOKEN_UNSUPPORTED)
    {
        // supposed to have a valid token in this packet, check it
        if (pPacket->m_DataSize < (int)sizeof(m_SecurityToken))
            return 0;
        pPacket->m_DataSize -= sizeof(m_SecurityToken);
        if (m_SecurityToken != ToSecurityToken(&pPacket->m_aChunkData[pPacket->m_DataSize]))
        {
            if(g_Config.m_Debug)
                dbg_msg("security", "token mismatch, expected %d got %d", m_SecurityToken, ToSecurityToken(&pPacket->m_aChunkData[pPacket->m_DataSize]));
            return 0;
        }
    }

    int64 Now = time_get();

    // check if resend is requested
    if(pPacket->m_Flags&NET_PACKETFLAG_RESEND)
        Resend();

    //
    if(pPacket->m_Flags&NET_PACKETFLAG_CONTROL)
    {
        int CtrlMsg = pPacket->m_aChunkData[0];

        if(CtrlMsg == NET_CTRLMSG_CLOSE)
        {
            if(net_addr_comp(&m_PeerAddr, pAddr) == 0)
            {
                m_State = NET_CONNSTATE_ERROR;
                m_RemoteClosed = 1;

                char Str[128] = {0};
                if(pPacket->m_DataSize > 1)
                {
                    // make sure to sanitize the error string form the other party
                    if(pPacket->m_DataSize < 128)
                        str_copy(Str, (char *)&pPacket->m_aChunkData[1], pPacket->m_DataSize);
                    else
                        str_copy(Str, (char *)&pPacket->m_aChunkData[1], sizeof(Str));
                    str_sanitize_strong(Str);
                }

                if(!m_BlockCloseMsg)
                {
                    // set the error string
                    SetError(Str);
                }

                if(g_Config.m_Debug)
                    dbg_msg("conn", "closed reason='%s'", Str);
            }
            return 0;
        }
        else
        {
            if(State() == NET_CONNSTATE_OFFLINE)
            {
                if(CtrlMsg == NET_CTRLMSG_CONNECT)
                {
                    NETADDR nAddr;
                    mem_copy(&nAddr, pAddr, sizeof(nAddr));
                    nAddr.port = 0;
                    m_PeerAddr.port = 0;
#ifndef FUZZING
                    if(net_addr_comp(&m_PeerAddr, &nAddr) == 0 && time_get() - m_LastUpdateTime < time_freq() * 3)
                        return 0;
#endif

                    // send response and init connection
                    Reset();
                    m_State = NET_CONNSTATE_PENDING;
                    m_PeerAddr = *pAddr;
                    mem_zero(m_ErrorString, sizeof(m_ErrorString));
                    m_LastSendTime = Now;
                    m_LastRecvTime = Now;
                    m_LastUpdateTime = Now;
                    if (m_SecurityToken == NET_SECURITY_TOKEN_UNKNOWN
                            && pPacket->m_DataSize >= (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(m_SecurityToken))
                            && !mem_comp(&pPacket->m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)))
                    {
                        m_SecurityToken = SecurityToken;
                        if(g_Config.m_Debug)
                            dbg_msg("security", "generated token %d", m_SecurityToken);
                    }
                    else
                    {
                        if(g_Config.m_Debug)
                            dbg_msg("security", "token not supported by client (packet size %d)", pPacket->m_DataSize);
                        m_SecurityToken = NET_SECURITY_TOKEN_UNSUPPORTED;
                    }
                    SendControl(NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC));
                    if(g_Config.m_Debug)
                        dbg_msg("connection", "got connection, sending connect+accept");
                }
            }
            else if(State() == NET_CONNSTATE_CONNECT)
            {
                // connection made
                if(CtrlMsg == NET_CTRLMSG_CONNECTACCEPT)
                {
                    if (m_SecurityToken == NET_SECURITY_TOKEN_UNKNOWN
                            && pPacket->m_DataSize >= (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(m_SecurityToken))
                            && !mem_comp(&pPacket->m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)))
                    {
                        m_SecurityToken = ToSecurityToken(&pPacket->m_aChunkData[1 + sizeof(SECURITY_TOKEN_MAGIC)]);
                        if(g_Config.m_Debug)
                            dbg_msg("security", "got token %d", m_SecurityToken);
                    }
                    else
                    {
                        m_SecurityToken = NET_SECURITY_TOKEN_UNSUPPORTED;
                        if(g_Config.m_Debug)
                            dbg_msg("security", "token not supported by server");
                    }
                    m_LastRecvTime = Now;
                    SendControl(NET_CTRLMSG_ACCEPT, 0, 0);
                    m_State = NET_CONNSTATE_ONLINE;
                    if(g_Config.m_Debug)
                        dbg_msg("connection", "got connect+accept, sending accept. connection online");
                }
            }
        }
    }
    else
    {
        if(State() == NET_CONNSTATE_PENDING)
        {
            m_LastRecvTime = Now;
            m_State = NET_CONNSTATE_ONLINE;
            if(g_Config.m_Debug)
                dbg_msg("connection", "connecting online");
        }
    }

    if(State() == NET_CONNSTATE_ONLINE)
    {
        m_LastRecvTime = Now;
        AckChunks(pPacket->m_Ack);
    }

    return 1;
}