Some more authentication stuff.
This commit is contained in:
parent
99af8fbae7
commit
00b7e3f920
@ -103,7 +103,7 @@ workspace "iw4x"
|
||||
-- Pre-compiled header
|
||||
pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives
|
||||
pchsource "src/STDInclude.cpp" -- real path
|
||||
buildoptions { "/Zm100 -Zm100" }
|
||||
buildoptions { "/Zm96 -Zm96" }
|
||||
filter "files:**.pb.*"
|
||||
flags {
|
||||
"NoPCH",
|
||||
|
@ -24,13 +24,13 @@ namespace Components
|
||||
// Not sending a response might allow the player to connect for a few seconds (<= 5) until the timeout is reached.
|
||||
if (client->state >= 5)
|
||||
{
|
||||
if (info->state == Auth::STATE_NEGOTIATING && (Game::Com_Milliseconds() - info->time) > 1000 * 3)
|
||||
if (info->state == Auth::STATE_NEGOTIATING && (Game::Com_Milliseconds() - info->time) > 1000 * 5)
|
||||
{
|
||||
info->state = Auth::STATE_INVALID;
|
||||
info->time = Game::Com_Milliseconds();
|
||||
Game::SV_KickClientError(client, "XUID verification timed out!");
|
||||
}
|
||||
else if (info->state == Auth::STATE_UNKNOWN && info->time && (Game::Com_Milliseconds() - info->time) > 1000 * 2) // Wait 2 seconds (error delay)
|
||||
else if (info->state == Auth::STATE_UNKNOWN && info->time && (Game::Com_Milliseconds() - info->time) > 1000 * 5) // Wait 5 seconds (error delay)
|
||||
{
|
||||
Logger::Print("Sending XUID authentication request to %s\n", Network::Address(client->adr).GetString());
|
||||
|
||||
@ -90,6 +90,9 @@ namespace Components
|
||||
|
||||
// Only accept requests from the server we're connected to
|
||||
if (address != *Game::connectedHost) return;
|
||||
|
||||
// Ensure our certificate is loaded
|
||||
Steam::SteamUser()->GetSteamID();
|
||||
if (!Steam::User::GuidKey.IsValid()) return;
|
||||
|
||||
Proto::Auth::Response response;
|
||||
@ -104,12 +107,6 @@ namespace Components
|
||||
{
|
||||
Logger::Print("Received XUID authentication response from %s\n", address.GetString());
|
||||
|
||||
Proto::Auth::Response response;
|
||||
response.ParseFromString(data);
|
||||
|
||||
if (response.signature().empty()) return;
|
||||
if (response.publickey().empty()) return;
|
||||
|
||||
for (int i = 0; i < *Game::svs_numclients; i++)
|
||||
{
|
||||
Game::client_t* client = &Game::svs_clients[i];
|
||||
@ -117,14 +114,24 @@ namespace Components
|
||||
|
||||
if (client->state >= 3 && address == client->adr && info->state == Auth::STATE_NEGOTIATING)
|
||||
{
|
||||
Proto::Auth::Response response;
|
||||
unsigned int id = static_cast<unsigned int>(~0x110000100000000 & client->steamid);
|
||||
|
||||
// Check if response is valid
|
||||
if (!response.ParseFromString(data) || response.signature().empty() || response.publickey().empty())
|
||||
{
|
||||
info->state = Auth::STATE_INVALID;
|
||||
Game::SV_KickClientError(client, "XUID authentication response was invalid!");
|
||||
}
|
||||
|
||||
// Check if guid matches the certificate
|
||||
if (id != (Utils::OneAtATime(response.publickey().data(), response.publickey().size()) & ~0x80000000))
|
||||
else if (id != (Utils::OneAtATime(response.publickey().data(), response.publickey().size()) & ~0x80000000))
|
||||
{
|
||||
info->state = Auth::STATE_INVALID;
|
||||
Game::SV_KickClientError(client, "XUID doesn't match the certificate!");
|
||||
}
|
||||
|
||||
// Verify GUID using the signature and certificate
|
||||
else
|
||||
{
|
||||
info->publicKey.Set(response.publickey());
|
||||
@ -140,6 +147,8 @@ namespace Components
|
||||
Game::SV_KickClientError(client, "Challenge signature was invalid!");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -7,3 +7,9 @@ message Response
|
||||
bytes signature = 1;
|
||||
bytes publickey = 2;
|
||||
}
|
||||
|
||||
message Certificate
|
||||
{
|
||||
bytes privatekey = 1;
|
||||
bytes token = 2;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
::Utils::Cryptography::Token User::GuidToken;
|
||||
::Utils::Cryptography::ECDSA::Key User::GuidKey;
|
||||
|
||||
int User::GetHSteamUser()
|
||||
@ -30,12 +31,23 @@ namespace Steam
|
||||
{
|
||||
if (!User::GuidKey.IsValid())
|
||||
{
|
||||
User::GuidKey.Import(::Utils::ReadFile("players/guid.dat"), PK_PRIVATE);
|
||||
Proto::Auth::Certificate cert;
|
||||
|
||||
if (cert.ParseFromString(::Utils::ReadFile("players/guid.dat")))
|
||||
{
|
||||
User::GuidKey.Import(cert.privatekey(), PK_PRIVATE);
|
||||
User::GuidToken = cert.token();
|
||||
}
|
||||
|
||||
if (!User::GuidKey.IsValid())
|
||||
{
|
||||
User::GuidToken.Clear();
|
||||
User::GuidKey = ::Utils::Cryptography::ECDSA::GenerateKey(512);
|
||||
::Utils::WriteFile("players/guid.dat", User::GuidKey.Export(PK_PRIVATE));
|
||||
|
||||
cert.set_token(User::GuidToken.ToString());
|
||||
cert.set_privatekey(User::GuidKey.Export(PK_PRIVATE));
|
||||
|
||||
::Utils::WriteFile("players/guid.dat", cert.SerializeAsString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ namespace Steam
|
||||
virtual void CancelAuthTicket(unsigned int hAuthTicket);
|
||||
virtual unsigned int UserHasLicenseForApp(SteamID steamID, unsigned int appID);
|
||||
|
||||
static ::Utils::Cryptography::Token GuidToken;
|
||||
static ::Utils::Cryptography::ECDSA::Key GuidKey;
|
||||
};
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ namespace Utils
|
||||
|
||||
void Rand::Initialize()
|
||||
{
|
||||
ltc_mp = ltm_desc;
|
||||
register_prng(&fortuna_desc);
|
||||
rng_make_prng(128, find_prng("fortuna"), &Rand::State, NULL);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ namespace Utils
|
||||
{
|
||||
public:
|
||||
Token() { this->TokenString.clear(); };
|
||||
Token(const Token& obj) : TokenString(obj.TokenString) { };
|
||||
Token(std::string token) : TokenString(token.begin(), token.end()) { };
|
||||
Token(std::basic_string<uint8_t> token) : TokenString(token.begin(), token.end()) { };
|
||||
|
||||
@ -50,8 +51,7 @@ namespace Utils
|
||||
|
||||
std::string ToString()
|
||||
{
|
||||
auto str = this->ToUnsignedString();
|
||||
return std::string(str.begin(), str.end());
|
||||
return std::string(this->TokenString.begin(), this->TokenString.end());
|
||||
}
|
||||
|
||||
std::basic_string<uint8_t> ToUnsignedString()
|
||||
@ -59,6 +59,11 @@ namespace Utils
|
||||
return this->TokenString;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
this->TokenString.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
std::basic_string<uint8_t> TokenString;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user