Skip to content

Commit 33683e0

Browse files
committed
Improve connection challenge further
1 parent d8d4af9 commit 33683e0

File tree

2 files changed

+42
-11
lines changed

2 files changed

+42
-11
lines changed

source/netfilter/baseserver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ enum server_state_t
2727
};
2828

2929
// time a challenge nonce is valid for, in seconds
30-
#define CHALLENGE_NONCE_LIFETIME 6.0f
30+
#define CHALLENGE_NONCE_LIFETIME 6
3131

3232
class CBaseServer : public IServer
3333
{

source/netfilter/core.cpp

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <cstring>
2727
#include <queue>
2828
#include <string>
29+
#include <array>
2930

3031
#if defined SYSTEM_WINDOWS
3132

@@ -217,6 +218,8 @@ namespace netfilter
217218
static constexpr int32_t PROTOCOL_STEAM = 0x03; // Steam certificates
218219
static constexpr int32_t PROTOCOL_LASTVALID = 0x03; // Last valid protocol
219220

221+
static constexpr int32_t MAX_RANDOM_RANGE = 0x7FFFFFFFUL;
222+
220223
inline const char *IPToString( const in_addr &addr )
221224
{
222225
static char buffer[16] = { };
@@ -914,8 +917,6 @@ namespace netfilter
914917
public:
915918
virtual bool CheckChallengeNr( netadr_t &adr, int nChallengeValue )
916919
{
917-
TargetClass *self = This( );
918-
919920
// See if the challenge is valid
920921
// Don't care if it is a local address.
921922
if( adr.IsLoopback( ) )
@@ -925,20 +926,23 @@ namespace netfilter
925926
if( IsX360( ) )
926927
return true;
927928

928-
uint64 challenge = ( static_cast<uint64>( adr.GetIPNetworkByteOrder( ) ) << 32 ) + self->m_CurrentRandomNonce;
929+
UpdateChallengeIfNeeded( );
930+
931+
m_challenge[4] = adr.GetIPNetworkByteOrder( );
932+
929933
CSHA1 hasher;
930-
hasher.Update( reinterpret_cast<uint8_t *>( &challenge ), sizeof( challenge ) );
934+
hasher.Update( reinterpret_cast<uint8_t *>( &m_challenge[0] ), sizeof( uint32_t ) * m_challenge.size( ) );
931935
hasher.Final( );
932936
SHADigest_t hash = { 0 };
933937
hasher.GetHash( hash );
934938
if( reinterpret_cast<int *>( hash )[0] == nChallengeValue )
935939
return true;
936940

937941
// try with the old random nonce
938-
challenge &= 0xffffffff00000000ull;
939-
challenge += self->m_LastRandomNonce;
942+
m_previous_challenge[4] = adr.GetIPNetworkByteOrder( );
943+
940944
hasher.Reset( );
941-
hasher.Update( reinterpret_cast<uint8_t *>( &challenge ), sizeof( challenge ) );
945+
hasher.Update( reinterpret_cast<uint8_t *>( &m_previous_challenge[0] ), sizeof( uint32_t ) * m_previous_challenge.size( ) );
942946
hasher.Final( );
943947
hasher.GetHash( hash );
944948
if( reinterpret_cast<int *>( hash )[0] == nChallengeValue )
@@ -949,19 +953,46 @@ namespace netfilter
949953

950954
virtual int GetChallengeNr( netadr_t &adr )
951955
{
952-
TargetClass *self = This( );
953-
uint64 challenge = ( static_cast<uint64>( adr.GetIPNetworkByteOrder( ) ) << 32 ) + self->m_CurrentRandomNonce;
956+
UpdateChallengeIfNeeded( );
957+
958+
m_challenge[4] = adr.GetIPNetworkByteOrder( );
959+
954960
CSHA1 hasher;
955-
hasher.Update( reinterpret_cast<uint8_t *>( &challenge ), sizeof( challenge ) );
961+
hasher.Update( reinterpret_cast<uint8_t *>( &m_challenge[0] ), sizeof( uint32_t ) * m_challenge.size( ) );
956962
hasher.Final( );
957963
SHADigest_t hash = { 0 };
958964
hasher.GetHash( hash );
959965
return reinterpret_cast<int *>( hash )[0];
960966
}
961967

968+
void UpdateChallengeIfNeeded( )
969+
{
970+
const double current_time = Plat_FloatTime( );
971+
if( m_challenge_gen_time >= 0 && current_time < m_challenge_gen_time + CHALLENGE_NONCE_LIFETIME )
972+
return;
973+
974+
m_challenge_gen_time = current_time;
975+
m_previous_challenge.swap( m_challenge );
976+
977+
// RandomInt maps a uniform distribution on the interval [0,INT_MAX].
978+
// RandomInt will always return the minimum value if the difference in min and max is greater than or equal to INT_MAX.
979+
m_challenge[0] = static_cast<uint32>( RandomInt( 0, MAX_RANDOM_RANGE ) );
980+
m_challenge[1] = static_cast<uint32>( RandomInt( 0, MAX_RANDOM_RANGE ) );
981+
m_challenge[2] = static_cast<uint32>( RandomInt( 0, MAX_RANDOM_RANGE ) );
982+
m_challenge[3] = static_cast<uint32>( RandomInt( 0, MAX_RANDOM_RANGE ) );
983+
}
984+
985+
static double m_challenge_gen_time;
986+
static std::array<uint32_t, 5> m_previous_challenge;
987+
static std::array<uint32_t, 5> m_challenge;
988+
962989
static CBaseServerProxy Singleton;
963990
};
964991

992+
double CBaseServerProxy::m_challenge_gen_time = -1;
993+
std::array<uint32_t, 5> CBaseServerProxy::m_previous_challenge;
994+
std::array<uint32_t, 5> CBaseServerProxy::m_challenge;
995+
965996
CBaseServerProxy CBaseServerProxy::Singleton;
966997

967998
void Initialize( GarrysMod::Lua::ILuaBase *LUA )

0 commit comments

Comments
 (0)