diff options
author | Aki <please@ignore.pl> | 2022-04-01 21:23:39 +0200 |
---|---|---|
committer | Aki <please@ignore.pl> | 2022-04-01 21:23:39 +0200 |
commit | 3c487c5cd69c53d6fea948643c0a76df03516605 (patch) | |
tree | 72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /StarsEx/NetAuth.cpp | |
parent | 8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff) | |
download | starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.zip starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.gz starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.bz2 |
Moved Stars45 to StarsEx
Diffstat (limited to 'StarsEx/NetAuth.cpp')
-rw-r--r-- | StarsEx/NetAuth.cpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/StarsEx/NetAuth.cpp b/StarsEx/NetAuth.cpp new file mode 100644 index 0000000..f9e4d02 --- /dev/null +++ b/StarsEx/NetAuth.cpp @@ -0,0 +1,204 @@ +/* Starshatter: The Open Source Project + Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors + Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors + Copyright (c) 1997-2006, Destroyer Studios LLC. + + AUTHOR: John DiCamillo + + + OVERVIEW + ======== + This class represents a user connecting to the multiplayer lobby +*/ + + +#include "NetAuth.h" +#include "NetLobby.h" +#include "NetUser.h" +#include "ModConfig.h" +#include "ModInfo.h" +#include "Random.h" +#include "Sha1.h" + +static int auth_level = NetAuth::NET_AUTH_MINIMAL; + +// +-------------------------------------------------------------------+ + +int +NetAuth::AuthLevel() +{ + return auth_level; +} + + +void +NetAuth::SetAuthLevel(int n) +{ + if (n >= NET_AUTH_MINIMAL && n <= NET_AUTH_SECURE) + auth_level = n; +} + +// +-------------------------------------------------------------------+ + +Text +NetAuth::CreateAuthRequest(NetUser* u) +{ + Text request; + + if (u) { + u->SetAuthLevel(auth_level); + + if (auth_level == NET_AUTH_MINIMAL) { + u->SetAuthState(NET_AUTH_OK); + u->SetSalt("Very Low Sodium"); + } + + else if (auth_level == NET_AUTH_STANDARD) { + u->SetAuthState(NET_AUTH_INITIAL); + u->SetSalt("Very Low Sodium"); + + request = "level 1"; + } + + else { + char salt[33]; + + for (int i = 0; i < 32; i++) + salt[i] = (char) ('0' + (int) Random(0, 9.4)); + + salt[32] = 0; + u->SetSalt(salt); + u->SetAuthState(NET_AUTH_INITIAL); + + request = "level 2 salt "; + request += salt; + } + } + + return request; +} + +// +-------------------------------------------------------------------+ + +static Text Digest(const char* salt, const char* file) +{ + int length = 0; + int offset = 0; + char block[4096]; + char digest[64]; + + ZeroMemory(digest, sizeof(digest)); + + if (file) { + FILE* f; + fopen_s(&f, file, "rb"); + + if (f) { + SHA1 sha1; + + if (salt) { + sha1.Input(salt, strlen(salt)); + } + + fseek(f, 0, SEEK_END); + length = ftell(f); + fseek(f, 0, SEEK_SET); + + while (offset < length) { + int n = fread(block, sizeof(char), 4096, f); + sha1.Input(block, n); + offset += n; + } + + fclose(f); + + unsigned result[5]; + if (sha1.Result(result)) { + sprintf_s(digest, "SHA1_%08X_%08X_%08X_%08X_%08X", + result[0], result[1], result[2], result[3], result[4]); + } + } + } + + return digest; +} + +// +-------------------------------------------------------------------+ + +Text +NetAuth::CreateAuthResponse(int level, const char* salt) +{ + Text response; + ModConfig* config = ModConfig::GetInstance(); + + if (level == NET_AUTH_SECURE) { + response += "exe "; + response += Digest(salt, "stars.exe"); // XXX should look up name of this exe + response += " "; + + response += "dat "; + response += Digest(salt, "shatter.dat"); + response += " "; + + response += "etc "; + response += Digest(salt, "start.dat"); + response += " "; + } + + if (level >= NET_AUTH_STANDARD) { + List<ModInfo>& mods = config->GetModInfoList(); + ListIter<ModInfo> mod_iter = mods; + + char buffer[32]; + sprintf_s(buffer, "num %d ", mods.size()); + response += buffer; + + while (++mod_iter) { + ModInfo* info = mod_iter.value(); + + response += "mod \""; + response += info->Name(); + response += "\" ver \""; + response += info->Version(); + response += "\" "; + + if (level == NET_AUTH_SECURE) { + response += "sha "; + response += Digest(salt, info->Filename()); + response += " "; + } + } + } + + return response; +} + +// +-------------------------------------------------------------------+ + +bool +NetAuth::AuthUser(NetUser* u, Text response) +{ + bool authentic = false; + + if (auth_level == NET_AUTH_MINIMAL) { // (this case should not occur) + if (u) { + u->SetAuthLevel(auth_level); + u->SetAuthState(NET_AUTH_OK); + } + + authentic = (u != 0); + } + + else if (u) { + Text expected_response = CreateAuthResponse(auth_level, u->Salt()); + if (expected_response == response) + authentic = true; + + u->SetAuthState(authentic ? NET_AUTH_OK : NET_AUTH_FAILED); + } + + return authentic; +} + +// +-------------------------------------------------------------------+ + |