From de41ab367fd0bf21c481175086d8f59bdb5d9ef6 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Fri, 21 Jun 2024 21:26:22 +0700 Subject: [PATCH] Fixed collisions of SteamIDs issued to non-unique serial numbers "0000_0000_0000_0000_0000_0100_0000_0000". For these non-steam clients, SteamIDs will now be generated based on IP. --- reunion/src/client_auth.cpp | 9 ++++++++- reunion/src/reunion_authorizers.cpp | 6 ++++-- reunion/src/reunion_utils.cpp | 13 +++++++++++++ reunion/src/reunion_utils.h | 1 + 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/reunion/src/client_auth.cpp b/reunion/src/client_auth.cpp index 20b88c4..3f4d56d 100644 --- a/reunion/src/client_auth.cpp +++ b/reunion/src/client_auth.cpp @@ -97,6 +97,7 @@ uint64_t SteamByIp(uint32_t ip) bool Reunion_FinishClientAuth(CReunionPlayer* reunionPlr, USERID_t* userid, client_auth_context_t* ctx) { client_auth_kind authkind; + client_id_kind idkind = CI_UNKNOWN; if (!ctx->authentificatedInSteam) { // native auth failed, try authorize by emulators @@ -125,6 +126,10 @@ bool Reunion_FinishClientAuth(CReunionPlayer* reunionPlr, USERID_t* userid, clie authkind = CA_STEAM_PENDING; } else { + // check for bad authkey + if (!IsValidHddsnNumber(authdata.authKey, authdata.authKeyLen)) + idkind = CI_VALVE_BY_IP; + // salt steamid if (g_ReunionConfig->getSteamIdSaltLen()) { SaltSteamId(&authdata); @@ -162,7 +167,9 @@ bool Reunion_FinishClientAuth(CReunionPlayer* reunionPlr, USERID_t* userid, clie } // add prefix - client_id_kind idkind = g_ReunionConfig->getIdGenOptions(authkind)->id_kind; + if (idkind == CI_UNKNOWN) + idkind = g_ReunionConfig->getIdGenOptions(authkind)->id_kind; + switch (idkind) { // check for deprecation case CI_DEPRECATED: diff --git a/reunion/src/reunion_authorizers.cpp b/reunion/src/reunion_authorizers.cpp index 6d861e7..0b05008 100644 --- a/reunion/src/reunion_authorizers.cpp +++ b/reunion/src/reunion_authorizers.cpp @@ -58,14 +58,16 @@ void RevEmuFinishAuthorization(authdata_t* authdata, const char* authStr, bool s if (IsHddsnNumber(authStr)) { authdata->authKeyKind = AK_HDDSN; - LCPrintf(false, "RevEmu raw auth string: '%s' (HDDSN)\n", authStr); - if (stripSpecialChars) { authdata->authKeyLen = strecpy(hddsn, authStr, authKeyMaxLen, " \\/-"); authStr = hddsn; } else authdata->authKeyLen = min(strlen(authStr), authKeyMaxLen); + + LCPrintf(false, "RevEmu raw auth string: '%s' (HDDSN)%s\n", authStr, + IsValidHddsnNumber(authStr, authdata->authKeyLen) ? "" : " (INVALID)" + ); } else { authdata->authKeyKind = AK_VOLUMEID; diff --git a/reunion/src/reunion_utils.cpp b/reunion/src/reunion_utils.cpp index bd259bb..19919bd 100644 --- a/reunion/src/reunion_utils.cpp +++ b/reunion/src/reunion_utils.cpp @@ -145,6 +145,19 @@ bool IsHddsnNumber(const char* authstring) return strtoull(authstring, nullptr, 10) >= UINT32_MAX; // SSD } +// This serial number is actually not a valid serial number +// it is a system bug that provides an incorrect serial number for NVMe solid-state drives (Netac NVMe SSD), +// retrieved from the Storage Descriptor instead of reading it from the driver. +// Therefore, obtaining the serial number from the Storage Descriptor means we should not generate a SteamID based on such serial numbers, +// as it increases the risk of SteamID collisions. +// Instead, it is better to generate a SteamID based on the client's IP. +const char *BadHddsnNumber = "0000_0000_0000_0000_0000_0100_0"; + +bool IsValidHddsnNumber(const void* data, size_t maxlen) +{ + return memcmp(data, BadHddsnNumber, min(strlen(BadHddsnNumber), maxlen)) != 0; +} + void util_console_print(const char* fmt, ...) { char buf[1024]; diff --git a/reunion/src/reunion_utils.h b/reunion/src/reunion_utils.h index 2f6bcd9..5f150de 100644 --- a/reunion/src/reunion_utils.h +++ b/reunion/src/reunion_utils.h @@ -16,6 +16,7 @@ extern bool IsUniqueIdKind(client_id_kind idkind); extern bool IsValidId(uint32 authId); extern bool IsValidSteamTicket(const uint8 *pvSteam2Key, size_t ucbSteam2Key); extern bool IsHddsnNumber(const char* authstring); +extern bool IsValidHddsnNumber(const void* data, size_t maxlen); extern void util_console_print(const char* fmt, ...); extern void util_syserror(const char* fmt, ...);