mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Fail gracefully on Hamachi/Radmin/etc
This commit is contained in:
parent
1c6a286adf
commit
d66278dfeb
1 changed files with 53 additions and 15 deletions
|
|
@ -123,6 +123,11 @@ static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the
|
|||
// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled.
|
||||
static tic_t joindelay = 0;
|
||||
|
||||
// Set when the server requests a signature with an IP mismatch.
|
||||
// This is a common issue on Hamachi, Radmin, and other VPN software that does noncompliant IP remap horeseshit.
|
||||
// When ths is set, provide only blank signatures. If this is set while joining, the server will degrade us to a GUEST.
|
||||
static boolean forceGuest = false;
|
||||
|
||||
UINT16 pingmeasurecount = 1;
|
||||
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
|
||||
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
|
||||
|
|
@ -276,9 +281,26 @@ shouldsign_t ShouldSignChallenge(uint8_t *message)
|
|||
if ((max(now, then) - min(now, then)) > 60*15)
|
||||
return SIGN_BADTIME;
|
||||
|
||||
// ____ _____ ___ ____ _
|
||||
// / ___|_ _/ _ \| _ \| |
|
||||
// \___ \ | || | | | |_) | |
|
||||
// ___) || || |_| | __/|_|
|
||||
// |____/ |_| \___/|_| (_)
|
||||
// =========================
|
||||
// SIGN_BADIP MUST BE CHECKED LAST, AND RETURN ONLY IF ALL OTHER CHECKS HAVE ALREADY SUCCEEDED.
|
||||
// We allow IP failures through for compatibility with shitty VPNs and fucked-beyond-belief home networks.
|
||||
// If this is checked before other sign-safety conditons, bad actors can INTENTIONALLY SKIP CHECKS.
|
||||
if (realIP != claimedIP && I_IsExternalAddress(&realIP))
|
||||
return SIGN_BADIP;
|
||||
|
||||
#ifdef DEVELOP
|
||||
if (cv_badip.value)
|
||||
{
|
||||
CV_AddValue(&cv_badip, -1);
|
||||
CONS_Alert(CONS_WARNING, "cv_badip enabled, intentionally failing checks\n");
|
||||
return SIGN_BADIP;
|
||||
}
|
||||
#endif
|
||||
// Do NOT return SIGN_BADIP before doing all other available checks.
|
||||
return SIGN_OK;
|
||||
}
|
||||
|
||||
|
|
@ -951,17 +973,19 @@ static boolean CL_SendJoin(void)
|
|||
// Don't leak old signatures from prior sessions.
|
||||
memset(&netbuffer->u.clientcfg.challengeResponse, 0, sizeof(((clientconfig_pak *)0)->challengeResponse));
|
||||
|
||||
forceGuest = false;
|
||||
|
||||
if (client && netgame)
|
||||
{
|
||||
shouldsign_t safe = ShouldSignChallenge(awaitingChallenge);
|
||||
|
||||
if (safe != SIGN_OK)
|
||||
if (safe == SIGN_BADIP)
|
||||
{
|
||||
if (safe == SIGN_BADIP)
|
||||
{
|
||||
I_Error("External server IP didn't match the message it sent.");
|
||||
}
|
||||
else if (safe == SIGN_BADTIME)
|
||||
forceGuest = true;
|
||||
}
|
||||
else if (safe != SIGN_OK)
|
||||
{
|
||||
if (safe == SIGN_BADTIME)
|
||||
{
|
||||
I_Error("External server sent a message with an unusual timestamp.\nMake sure your system time is set correctly.");
|
||||
}
|
||||
|
|
@ -978,7 +1002,7 @@ static boolean CL_SendJoin(void)
|
|||
uint8_t signature[SIGNATURELENGTH];
|
||||
profile_t *localProfile = PR_GetLocalPlayerProfile(i);
|
||||
|
||||
if (PR_IsLocalPlayerGuest(i)) // GUESTS don't have keys
|
||||
if (PR_IsLocalPlayerGuest(i) || forceGuest) // GUESTS don't have keys
|
||||
{
|
||||
memset(signature, 0, sizeof(signature));
|
||||
}
|
||||
|
|
@ -1450,6 +1474,9 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (forceGuest)
|
||||
HU_AddChatText("\x85* This server uses a strange network configuration (VPN?). You have joined as a GUEST.", true);
|
||||
}
|
||||
|
||||
static void CL_ReloadReceivedSavegame(void)
|
||||
|
|
@ -4436,8 +4463,19 @@ static void HandleConnect(SINT8 node)
|
|||
|
||||
if (netgame && sigcheck != 0)
|
||||
{
|
||||
SV_SendRefuse(node, M_GetText("Signature verification failed."));
|
||||
return;
|
||||
uint8_t allZero[SIGNATURELENGTH];
|
||||
memset(allZero, 0, SIGNATURELENGTH);
|
||||
if (memcmp(netbuffer->u.clientcfg.challengeResponse[i], allZero, SIGNATURELENGTH) == 0)
|
||||
{
|
||||
// The connecting client didn't even try to sign this, probably due to an IP mismatch.
|
||||
// Let them in as a guest.
|
||||
memset(lastReceivedKey[node][i], 0, PUBKEYLENGTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
SV_SendRefuse(node, M_GetText("Signature verification failed."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5864,11 +5902,11 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
memcpy(lastChallengeAll, netbuffer->u.challengeall.secret, sizeof(lastChallengeAll));
|
||||
|
||||
shouldsign_t safe = ShouldSignChallenge(lastChallengeAll);
|
||||
if (safe != SIGN_OK)
|
||||
if (safe == SIGN_BADIP)
|
||||
forceGuest = true;
|
||||
else if (safe != SIGN_OK)
|
||||
{
|
||||
if (safe == SIGN_BADIP)
|
||||
HandleSigfail("External server sent the wrong IP");
|
||||
else if (safe == SIGN_BADTIME)
|
||||
if (safe == SIGN_BADTIME)
|
||||
HandleSigfail("Bad timestamp - is your time set correctly?");
|
||||
else
|
||||
HandleSigfail("Unknown auth error - contact a developer");
|
||||
|
|
@ -5893,7 +5931,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
{
|
||||
uint8_t signature[SIGNATURELENGTH];
|
||||
profile_t *localProfile = PR_GetLocalPlayerProfile(challengeplayers);
|
||||
if (!PR_IsLocalPlayerGuest(challengeplayers)) // GUESTS don't have keys
|
||||
if (!PR_IsLocalPlayerGuest(challengeplayers) && !forceGuest) // GUESTS don't have keys
|
||||
{
|
||||
crypto_eddsa_sign(signature, localProfile->secret_key, lastChallengeAll, sizeof(lastChallengeAll));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue