2022-02-27 07:53:44 -05:00
# include <STDInclude.hpp>
2023-01-03 07:16:44 -05:00
# include <Utils/InfoString.hpp>
# include <proto/auth.pb.h>
2022-12-26 07:07:24 -05:00
# include "Bans.hpp"
2023-04-16 05:27:19 -04:00
# include "Bots.hpp"
2017-01-19 16:23:59 -05:00
namespace Components
{
Auth : : TokenIncrementing Auth : : TokenContainer ;
Utils : : Cryptography : : Token Auth : : GuidToken ;
Utils : : Cryptography : : Token Auth : : ComputeToken ;
Utils : : Cryptography : : ECC : : Key Auth : : GuidKey ;
2022-02-26 17:50:53 -05:00
std : : vector < std : : uint64_t > Auth : : BannedUids =
{
2020-08-08 06:19:55 -04:00
0xf4d2c30b712ac6e3 ,
0xf7e33c4081337fa3 ,
0x6f5597f103cc50e9
2019-10-03 03:10:00 -04:00
} ;
2023-04-06 13:57:40 -04:00
bool Auth : : HasAccessToReservedSlot ;
2019-10-03 03:10:00 -04:00
2017-01-19 16:23:59 -05:00
void Auth : : Frame ( )
{
2023-04-06 13:57:40 -04:00
if ( TokenContainer . generating )
2017-01-19 16:23:59 -05:00
{
static double mseconds = 0 ;
static Utils : : Time : : Interval interval ;
if ( interval . elapsed ( 500 ms ) )
{
interval . update ( ) ;
2023-04-06 13:57:40 -04:00
int diff = Game : : Sys_Milliseconds ( ) - TokenContainer . startTime ;
double hashPMS = ( TokenContainer . hashes * 1.0 ) / diff ;
double requiredHashes = std : : pow ( 2 , TokenContainer . targetLevel + 1 ) - TokenContainer . hashes ;
2017-01-19 16:23:59 -05:00
mseconds = requiredHashes / hashPMS ;
if ( mseconds < 0 ) mseconds = 0 ;
}
2023-04-06 13:57:40 -04:00
Localization : : Set ( " MPUI_SECURITY_INCREASE_MESSAGE " , Utils : : String : : VA ( " Increasing security level from %d to %d (est. %s) " , GetSecurityLevel ( ) , TokenContainer . targetLevel , Utils : : String : : FormatTimeSpan ( static_cast < int > ( mseconds ) ) . data ( ) ) ) ;
2017-01-19 16:23:59 -05:00
}
2023-04-06 13:57:40 -04:00
else if ( TokenContainer . thread . joinable ( ) )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
TokenContainer . thread . join ( ) ;
TokenContainer . generating = false ;
2017-01-19 16:23:59 -05:00
2023-04-06 13:57:40 -04:00
StoreKey ( ) ;
Logger : : Debug ( " Security level is {} " , GetSecurityLevel ( ) ) ;
2017-01-19 16:23:59 -05:00
Command : : Execute ( " closemenu security_increase_popmenu " , false ) ;
2023-04-06 13:57:40 -04:00
if ( ! TokenContainer . cancel )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
if ( TokenContainer . command . empty ( ) )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
Game : : ShowMessageBox ( Utils : : String : : VA ( " Your new security level is %d " , GetSecurityLevel ( ) ) , " Success " ) ;
2017-01-19 16:23:59 -05:00
}
else
{
2023-04-06 13:57:40 -04:00
Toast : : Show ( " cardicon_locked " , " Success " , Utils : : String : : VA ( " Your new security level is %d " , GetSecurityLevel ( ) ) , 5000 ) ;
Command : : Execute ( TokenContainer . command , false ) ;
2017-01-19 16:23:59 -05:00
}
}
2023-04-06 13:57:40 -04:00
TokenContainer . cancel = false ;
2017-01-19 16:23:59 -05:00
}
}
2019-10-03 03:10:00 -04:00
2023-04-06 11:28:57 -04:00
void Auth : : SendConnectDataStub ( Game : : netsrc_t sock , Game : : netadr_t adr , const char * format , int len )
2017-01-19 16:23:59 -05:00
{
// Ensure our certificate is loaded
Steam : : SteamUser ( ) - > GetSteamID ( ) ;
2023-04-06 13:57:40 -04:00
if ( ! GuidKey . isValid ( ) )
2017-01-19 16:23:59 -05:00
{
2022-06-12 17:07:53 -04:00
Logger : : Error ( Game : : ERR_SERVERDISCONNECT , " Connecting failed: Guid key is invalid! " ) ;
2017-01-19 16:23:59 -05:00
return ;
}
2023-04-06 13:57:40 -04:00
if ( std : : find ( BannedUids . begin ( ) , BannedUids . end ( ) , Steam : : SteamUser ( ) - > GetSteamID ( ) . bits ) ! = BannedUids . end ( ) )
2019-10-03 03:10:00 -04:00
{
2023-04-06 13:57:40 -04:00
GenerateKey ( ) ;
2022-06-12 17:07:53 -04:00
Logger : : Error ( Game : : ERR_SERVERDISCONNECT , " Your online profile is invalid. A new key has been generated. " ) ;
2019-10-03 03:10:00 -04:00
return ;
}
2017-01-19 16:23:59 -05:00
std : : string connectString ( format , len ) ;
Game : : SV_Cmd_TokenizeString ( connectString . data ( ) ) ;
Command : : ServerParams params ;
2022-03-17 14:50:20 -04:00
if ( params . size ( ) < 3 )
2017-01-19 16:23:59 -05:00
{
Game : : SV_Cmd_EndTokenizedString ( ) ;
2022-06-12 17:07:53 -04:00
Logger : : Error ( Game : : ERR_SERVERDISCONNECT , " Connecting failed: Command parsing error! " ) ;
2017-01-19 16:23:59 -05:00
return ;
}
Utils : : InfoString infostr ( params [ 2 ] ) ;
std : : string challenge = infostr . get ( " challenge " ) ;
if ( challenge . empty ( ) )
{
Game : : SV_Cmd_EndTokenizedString ( ) ;
2022-06-12 17:07:53 -04:00
Logger : : Error ( Game : : ERR_SERVERDISCONNECT , " Connecting failed: Challenge parsing error! " ) ;
2017-01-19 16:23:59 -05:00
return ;
}
2019-01-10 15:18:18 -05:00
if ( Steam : : Enabled ( ) & & ! Friends : : IsInvisible ( ) & & ! Dvar : : Var ( " cl_anonymous " ) . get < bool > ( ) & & Steam : : Proxy : : SteamUser_ )
2017-02-17 06:26:07 -05:00
{
2017-02-18 03:42:55 -05:00
infostr . set ( " realsteamId " , Utils : : String : : VA ( " %llX " , Steam : : Proxy : : SteamUser_ - > GetSteamID ( ) . bits ) ) ;
2017-02-17 06:26:07 -05:00
}
// Build new connect string
connectString . clear ( ) ;
connectString . append ( params [ 0 ] ) ;
connectString . append ( " " ) ;
connectString . append ( params [ 1 ] ) ;
connectString . append ( " " ) ;
connectString . append ( " \" " + infostr . build ( ) + " \" " ) ;
2017-01-19 16:23:59 -05:00
Game : : SV_Cmd_EndTokenizedString ( ) ;
Proto : : Auth : : Connect connectData ;
2023-04-06 13:57:40 -04:00
connectData . set_token ( GuidToken . toString ( ) ) ;
connectData . set_publickey ( GuidKey . getPublicKey ( ) ) ;
connectData . set_signature ( Utils : : Cryptography : : ECC : : SignMessage ( GuidKey , challenge ) ) ;
2017-01-19 16:23:59 -05:00
connectData . set_infostring ( connectString ) ;
Network : : SendCommand ( sock , adr , " connect " , connectData . SerializeAsString ( ) ) ;
}
2017-02-01 07:44:25 -05:00
void Auth : : ParseConnectData ( Game : : msg_t * msg , Game : : netadr_t * addr )
2017-01-19 16:23:59 -05:00
{
Network : : Address address ( addr ) ;
// Parse proto data
Proto : : Auth : : Connect connectData ;
2022-08-13 11:19:45 -04:00
if ( msg - > cursize < = 12 | | ! connectData . ParseFromString ( std : : string ( reinterpret_cast < char * > ( & msg - > data [ 12 ] ) , msg - > cursize - 12 ) ) )
2017-01-19 16:23:59 -05:00
{
Network : : Send ( address , " error \n Invalid connect packet! " ) ;
return ;
}
2017-01-20 08:36:52 -05:00
// Simply connect, if we're in debug mode, we ignore all security checks
# ifndef DEBUG
if ( address . isLoopback ( ) )
2017-01-19 16:23:59 -05:00
# endif
{
if ( ! connectData . infostring ( ) . empty ( ) )
{
Game : : SV_Cmd_EndTokenizedString ( ) ;
Game : : SV_Cmd_TokenizeString ( connectData . infostring ( ) . data ( ) ) ;
Game : : SV_DirectConnect ( * address . get ( ) ) ;
}
else
{
Network : : Send ( address , " error \n Invalid infostring data! " ) ;
}
}
2017-01-20 08:36:52 -05:00
# ifndef DEBUG
2017-01-19 16:23:59 -05:00
else
{
// Validate proto data
if ( connectData . signature ( ) . empty ( ) | | connectData . publickey ( ) . empty ( ) | | connectData . token ( ) . empty ( ) | | connectData . infostring ( ) . empty ( ) )
{
Network : : Send ( address , " error \n Invalid connect data! " ) ;
return ;
}
// Setup new cmd params
Game : : SV_Cmd_EndTokenizedString ( ) ;
Game : : SV_Cmd_TokenizeString ( connectData . infostring ( ) . data ( ) ) ;
// Access the params
Command : : ServerParams params ;
// Ensure there are enough params
2022-03-17 14:50:20 -04:00
if ( params . size ( ) < 3 )
2017-01-19 16:23:59 -05:00
{
Network : : Send ( address , " error \n Invalid connect string! " ) ;
return ;
}
// Parse the infostring
2023-04-06 13:57:40 -04:00
Utils : : InfoString infostr ( params . get ( 2 ) ) ;
2017-01-19 16:23:59 -05:00
// Read the required data
2023-04-06 11:28:57 -04:00
const auto steamId = infostr . get ( " xuid " ) ;
const auto challenge = infostr . get ( " challenge " ) ;
2017-01-19 16:23:59 -05:00
if ( steamId . empty ( ) | | challenge . empty ( ) )
{
Network : : Send ( address , " error \n Invalid connect data! " ) ;
return ;
}
// Parse the id
2022-02-26 18:02:04 -05:00
const auto xuid = std : : strtoull ( steamId . data ( ) , nullptr , 16 ) ;
2017-01-19 16:23:59 -05:00
SteamID guid ;
2017-02-18 03:42:55 -05:00
guid . bits = xuid ;
2017-01-19 16:23:59 -05:00
2022-02-26 17:50:53 -05:00
if ( Bans : : IsBanned ( { guid , address . getIP ( ) } ) )
2017-01-19 16:23:59 -05:00
{
Network : : Send ( address , " error \n EXE_ERR_BANNED_PERM " ) ;
return ;
}
2023-04-06 13:57:40 -04:00
if ( std : : find ( BannedUids . begin ( ) , BannedUids . end ( ) , xuid ) ! = BannedUids . end ( ) )
2019-10-03 03:10:00 -04:00
{
Network : : Send ( address , " error \n Your online profile is invalid. Delete your players folder and restart ^2IW4x^7. " ) ;
return ;
}
2023-04-06 13:57:40 -04:00
if ( xuid ! = GetKeyHash ( connectData . publickey ( ) ) )
2017-01-19 16:23:59 -05:00
{
Network : : Send ( address , " error \n XUID doesn't match the certificate! " ) ;
return ;
}
// Verify the signature
Utils : : Cryptography : : ECC : : Key key ;
key . set ( connectData . publickey ( ) ) ;
if ( ! key . isValid ( ) | | ! Utils : : Cryptography : : ECC : : VerifyMessage ( key , challenge , connectData . signature ( ) ) )
{
Network : : Send ( address , " error \n Challenge signature was invalid! " ) ;
return ;
}
// Verify the security level
2022-02-26 17:50:53 -05:00
auto ourLevel = Dvar : : Var ( " sv_securityLevel " ) . get < unsigned int > ( ) ;
2023-04-06 13:57:40 -04:00
auto userLevel = GetZeroBits ( connectData . token ( ) , connectData . publickey ( ) ) ;
2017-01-19 16:23:59 -05:00
if ( userLevel < ourLevel )
{
Network : : Send ( address , Utils : : String : : VA ( " error \n Your security level (%d) is lower than the server's security level (%d) " , userLevel , ourLevel ) ) ;
return ;
}
2022-08-19 19:10:35 -04:00
Logger : : Debug ( " Verified XUID {:#X} ({}) from {} " , xuid , userLevel , address . getString ( ) ) ;
2017-01-19 16:23:59 -05:00
Game : : SV_DirectConnect ( * address . get ( ) ) ;
}
2017-01-20 08:36:52 -05:00
# endif
2017-01-19 16:23:59 -05:00
}
__declspec ( naked ) void Auth : : DirectConnectStub ( )
{
__asm
{
2017-02-01 07:44:25 -05:00
pushad
lea eax , [ esp + 20 h ]
push eax
2017-01-19 16:23:59 -05:00
push esi
2023-04-06 13:57:40 -04:00
call ParseConnectData
2017-01-19 16:23:59 -05:00
pop esi
2017-02-01 07:44:25 -05:00
pop eax
popad
2017-01-19 16:23:59 -05:00
2017-02-01 07:44:25 -05:00
push 6265F Eh
retn
2017-01-19 16:23:59 -05:00
}
}
2023-04-06 13:57:40 -04:00
char * Auth : : Info_ValueForKeyStub ( const char * s , const char * key )
{
auto * value = Game : : Info_ValueForKey ( s , key ) ;
HasAccessToReservedSlot = std : : strcmp ( ( * Game : : sv_privatePassword ) - > current . string , value ) = = 0 ;
2023-04-16 05:27:19 -04:00
// This stubs runs right before the 'server is full check' so we can call this here
Bots : : SV_DirectConnect_Full_Check ( ) ;
2023-04-06 13:57:40 -04:00
return value ;
}
2023-04-16 05:05:51 -04:00
__declspec ( naked ) void Auth : : DirectConnectPrivateClientStub ( )
2023-04-06 13:57:40 -04:00
{
2023-04-16 05:05:51 -04:00
__asm
2023-04-06 13:57:40 -04:00
{
2023-04-16 05:05:51 -04:00
push eax
mov al , HasAccessToReservedSlot
test al , al
pop eax
2023-04-16 04:47:02 -04:00
2023-04-16 05:05:51 -04:00
je noAccess
// Set the number of private clients to 0 if the client has the right password
xor eax , eax
jmp safeContinue
noAccess :
mov eax , dword ptr [ edx + 0x10 ]
safeContinue :
// Game code skipped by hook
add esp , 0xC
push 0x460FB3
ret
}
2023-04-06 13:57:40 -04:00
}
2018-12-17 08:29:18 -05:00
unsigned __int64 Auth : : GetKeyHash ( const std : : string & key )
2017-01-19 16:23:59 -05:00
{
std : : string hash = Utils : : Cryptography : : SHA1 : : Compute ( key ) ;
if ( hash . size ( ) > = 8 )
{
return * reinterpret_cast < unsigned __int64 * > ( const_cast < char * > ( hash . data ( ) ) ) ;
}
return 0 ;
}
unsigned __int64 Auth : : GetKeyHash ( )
{
2023-04-06 13:57:40 -04:00
LoadKey ( ) ;
return GetKeyHash ( GuidKey . getPublicKey ( ) ) ;
2017-01-19 16:23:59 -05:00
}
void Auth : : StoreKey ( )
{
2023-04-06 13:57:40 -04:00
if ( ! Dedicated : : IsEnabled ( ) & & ! ZoneBuilder : : IsEnabled ( ) & & GuidKey . isValid ( ) )
2017-01-19 16:23:59 -05:00
{
Proto : : Auth : : Certificate cert ;
2023-04-06 13:57:40 -04:00
cert . set_token ( GuidToken . toString ( ) ) ;
cert . set_ctoken ( ComputeToken . toString ( ) ) ;
cert . set_privatekey ( GuidKey . serialize ( PK_PRIVATE ) ) ;
2017-01-19 16:23:59 -05:00
Utils : : IO : : WriteFile ( " players/guid.dat " , cert . SerializeAsString ( ) ) ;
}
}
2019-10-03 03:16:26 -04:00
void Auth : : GenerateKey ( )
{
2023-04-06 13:57:40 -04:00
GuidToken . clear ( ) ;
ComputeToken . clear ( ) ;
GuidKey = Utils : : Cryptography : : ECC : : GenerateKey ( 512 ) ;
StoreKey ( ) ;
2019-10-03 03:16:26 -04:00
}
2017-01-19 16:23:59 -05:00
void Auth : : LoadKey ( bool force )
{
if ( Dedicated : : IsEnabled ( ) | | ZoneBuilder : : IsEnabled ( ) ) return ;
2023-04-06 13:57:40 -04:00
if ( ! force & & GuidKey . isValid ( ) ) return ;
2017-01-19 16:23:59 -05:00
Proto : : Auth : : Certificate cert ;
if ( cert . ParseFromString ( : : Utils : : IO : : ReadFile ( " players/guid.dat " ) ) )
{
2023-04-06 13:57:40 -04:00
GuidKey . deserialize ( cert . privatekey ( ) ) ;
GuidToken = cert . token ( ) ;
ComputeToken = cert . ctoken ( ) ;
2017-01-19 16:23:59 -05:00
}
else
{
2023-04-06 13:57:40 -04:00
GuidKey . free ( ) ;
2017-01-19 16:23:59 -05:00
}
2023-04-06 13:57:40 -04:00
if ( ! GuidKey . isValid ( ) )
2017-01-19 16:23:59 -05:00
{
2019-10-03 03:16:26 -04:00
Auth : : GenerateKey ( ) ;
2017-01-19 16:23:59 -05:00
}
}
uint32_t Auth : : GetSecurityLevel ( )
{
2023-04-06 13:57:40 -04:00
return GetZeroBits ( GuidToken , GuidKey . getPublicKey ( ) ) ;
2017-01-19 16:23:59 -05:00
}
2018-12-17 08:29:18 -05:00
void Auth : : IncreaseSecurityLevel ( uint32_t level , const std : : string & command )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
if ( GetSecurityLevel ( ) > = level ) return ;
2017-01-19 16:23:59 -05:00
2023-04-06 13:57:40 -04:00
if ( ! TokenContainer . generating )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
TokenContainer . cancel = false ;
TokenContainer . targetLevel = level ;
TokenContainer . command = command ;
2017-01-19 16:23:59 -05:00
// Open menu
Command : : Execute ( " openmenu security_increase_popmenu " , true ) ;
// Start thread
2023-04-06 13:57:40 -04:00
TokenContainer . thread = std : : thread ( [ & level ] ( )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
TokenContainer . generating = true ;
TokenContainer . hashes = 0 ;
TokenContainer . startTime = Game : : Sys_Milliseconds ( ) ;
IncrementToken ( GuidToken , ComputeToken , GuidKey . getPublicKey ( ) , TokenContainer . targetLevel , & TokenContainer . cancel , & TokenContainer . hashes ) ;
TokenContainer . generating = false ;
2017-01-19 16:23:59 -05:00
2023-04-06 13:57:40 -04:00
if ( TokenContainer . cancel )
2017-01-19 16:23:59 -05:00
{
Logger : : Print ( " Token incrementation thread terminated \n " ) ;
}
} ) ;
}
}
2018-12-17 08:29:18 -05:00
uint32_t Auth : : GetZeroBits ( Utils : : Cryptography : : Token token , const std : : string & publicKey )
2017-01-19 16:23:59 -05:00
{
std : : string message = publicKey + token . toString ( ) ;
std : : string hash = Utils : : Cryptography : : SHA512 : : Compute ( message , false ) ;
uint32_t bits = 0 ;
for ( unsigned int i = 0 ; i < hash . size ( ) ; + + i )
{
if ( hash [ i ] = = ' \0 ' )
{
bits + = 8 ;
continue ;
}
uint8_t value = static_cast < uint8_t > ( hash [ i ] ) ;
for ( int j = 7 ; j > = 0 ; - - j )
{
if ( ( value > > j ) & 1 )
{
return bits ;
}
+ + bits ;
}
}
return bits ;
}
2018-12-17 08:29:18 -05:00
void Auth : : IncrementToken ( Utils : : Cryptography : : Token & token , Utils : : Cryptography : : Token & computeToken , const std : : string & publicKey , uint32_t zeroBits , bool * cancel , uint64_t * count )
2017-01-19 16:23:59 -05:00
{
if ( zeroBits > 512 ) return ; // Not possible, due to SHA512
if ( computeToken < token )
{
computeToken = token ;
}
// Check if we already have the desired security level
2023-04-06 13:57:40 -04:00
uint32_t lastLevel = GetZeroBits ( token , publicKey ) ;
2017-01-19 16:23:59 -05:00
uint32_t level = lastLevel ;
if ( level > = zeroBits ) return ;
do
{
+ + computeToken ;
if ( count ) + + ( * count ) ;
2023-04-06 13:57:40 -04:00
level = GetZeroBits ( computeToken , publicKey ) ;
2017-01-19 16:23:59 -05:00
// Store level if higher than the last one
if ( level > = lastLevel )
{
token = computeToken ;
lastLevel = level ;
}
// Allow canceling that shit
if ( cancel & & * cancel ) return ;
2017-04-28 18:18:51 -04:00
} while ( level < zeroBits ) ;
2017-01-19 16:23:59 -05:00
token = computeToken ;
}
Auth : : Auth ( )
{
2023-04-06 13:57:40 -04:00
TokenContainer . cancel = false ;
TokenContainer . generating = false ;
HasAccessToReservedSlot = false ;
2017-01-19 16:23:59 -05:00
Localization : : Set ( " MPUI_SECURITY_INCREASE_MESSAGE " , " " ) ;
// Load the key
2023-04-06 13:57:40 -04:00
LoadKey ( true ) ;
2017-01-19 16:23:59 -05:00
Steam : : SteamUser ( ) - > GetSteamID ( ) ;
2023-04-06 13:57:40 -04:00
Scheduler : : Loop ( Frame , Scheduler : : Pipeline : : MAIN ) ;
2017-01-19 16:23:59 -05:00
// Register dvar
2022-07-02 13:52:57 -04:00
Dvar : : Register < int > ( " sv_securityLevel " , 23 , 0 , 512 , Game : : DVAR_SERVERINFO , " Security level for GUID certificates (POW) " ) ;
2017-01-19 16:23:59 -05:00
// Install registration hook
2023-04-06 13:57:40 -04:00
Utils : : Hook ( 0x6265F9 , DirectConnectStub , HOOK_JUMP ) . install ( ) - > quick ( ) ;
Utils : : Hook ( 0x460EF5 , Info_ValueForKeyStub , HOOK_CALL ) . install ( ) - > quick ( ) ;
2023-04-16 05:05:51 -04:00
Utils : : Hook ( 0x460FAD , DirectConnectPrivateClientStub , HOOK_JUMP ) . install ( ) - > quick ( ) ;
Utils : : Hook : : Nop ( 0x460FAD + 5 , 1 ) ;
2023-04-06 13:57:40 -04:00
Utils : : Hook ( 0x41D3E3 , SendConnectDataStub , HOOK_CALL ) . install ( ) - > quick ( ) ;
2017-01-19 16:23:59 -05:00
// SteamIDs can only contain 31 bits of actual 'id' data.
// The other 33 bits are steam internal data like universe and so on.
// Using only 31 bits for fingerprints is pretty insecure.
// The function below verifies the integrity steam's part of the SteamID.
// Patching that check allows us to use 64 bit for fingerprints.
2023-04-06 13:57:40 -04:00
Utils : : Hook : : Set < std : : uint32_t > ( 0x4D0D60 , 0xC301B0 ) ;
2017-01-19 16:23:59 -05:00
// Guid command
2023-03-23 10:08:21 -04:00
Command : : Add ( " guid " , [ ]
2017-01-19 16:23:59 -05:00
{
2022-06-12 17:07:53 -04:00
Logger : : Print ( " Your guid: {:#X} \n " , Steam : : SteamUser ( ) - > GetSteamID ( ) . bits ) ;
2017-01-19 16:23:59 -05:00
} ) ;
if ( ! Dedicated : : IsEnabled ( ) & & ! ZoneBuilder : : IsEnabled ( ) )
{
2017-04-28 18:18:51 -04:00
Command : : Add ( " securityLevel " , [ ] ( Command : : Params * params )
2017-01-19 16:23:59 -05:00
{
2022-03-17 14:50:20 -04:00
if ( params - > size ( ) < 2 )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
const auto level = GetZeroBits ( GuidToken , GuidKey . getPublicKey ( ) ) ;
2022-06-12 17:07:53 -04:00
Logger : : Print ( " Your current security level is {} \n " , level ) ;
2023-04-06 13:57:40 -04:00
Logger : : Print ( " Your security token is: {} \n " , Utils : : String : : DumpHex ( GuidToken . toString ( ) , " " ) ) ;
Logger : : Print ( " Your computation token is: {} \n " , Utils : : String : : DumpHex ( ComputeToken . toString ( ) , " " ) ) ;
2017-01-19 16:23:59 -05:00
Toast : : Show ( " cardicon_locked " , " ^5Security Level " , Utils : : String : : VA ( " Your security level is %d " , level ) , 3000 ) ;
}
else
{
2023-03-09 13:39:10 -05:00
const auto level = std : : strtoul ( params - > get ( 1 ) , nullptr , 10 ) ;
2023-04-06 13:57:40 -04:00
IncreaseSecurityLevel ( level ) ;
2017-01-19 16:23:59 -05:00
}
} ) ;
}
2022-08-24 10:38:14 -04:00
UIScript : : Add ( " security_increase_cancel " , [ ] ( [[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game : : uiInfo_s * info )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
TokenContainer . cancel = true ;
2017-01-19 16:23:59 -05:00
Logger : : Print ( " Token incrementation process canceled! \n " ) ;
} ) ;
}
Auth : : ~ Auth ( )
2017-01-23 16:06:50 -05:00
{
2023-04-06 13:57:40 -04:00
StoreKey ( ) ;
2017-01-23 16:06:50 -05:00
}
void Auth : : preDestroy ( )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
TokenContainer . cancel = true ;
TokenContainer . generating = false ;
2017-01-19 16:23:59 -05:00
// Terminate thread
2023-04-06 13:57:40 -04:00
if ( TokenContainer . thread . joinable ( ) )
2017-01-19 16:23:59 -05:00
{
2023-04-06 13:57:40 -04:00
TokenContainer . thread . join ( ) ;
2017-01-19 16:23:59 -05:00
}
}
bool Auth : : unitTest ( )
{
bool success = true ;
printf ( " Testing logical token operators: \n " ) ;
Utils : : Cryptography : : Token token1 ;
Utils : : Cryptography : : Token token2 ;
+ + token1 , token2 + + ; // Test incrementation operator
printf ( " Operator == : " ) ;
if ( token1 = = token2 & & ! ( + + token1 = = token2 ) ) printf ( " Success \n " ) ;
else
{
printf ( " Error \n " ) ;
success = false ;
}
printf ( " Operator != : " ) ;
if ( token1 ! = token2 & & ! ( + + token2 ! = token1 ) ) printf ( " Success \n " ) ;
else
{
printf ( " Error \n " ) ;
success = false ;
}
printf ( " Operator >= : " ) ;
if ( token1 > = token2 & & + + token1 > = token2 ) printf ( " Success \n " ) ;
else
{
printf ( " Error \n " ) ;
success = false ;
}
printf ( " Operator > : " ) ;
if ( token1 > token2 ) printf ( " Success \n " ) ;
else
{
printf ( " Error \n " ) ;
success = false ;
}
printf ( " Operator <= : " ) ;
if ( token1 < = + + token2 & & token1 < = + + token2 ) printf ( " Success \n " ) ;
else
{
printf ( " Error \n " ) ;
success = false ;
}
printf ( " Operator < : " ) ;
if ( token1 < token2 ) printf ( " Success \n " ) ;
else
{
printf ( " Error \n " ) ;
success = false ;
}
return success ;
}
}