summaryrefslogtreecommitdiffhomepage
path: root/StarsEx/NetAuth.cpp
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2022-04-01 21:23:39 +0200
committerAki <please@ignore.pl>2022-04-01 21:23:39 +0200
commit3c487c5cd69c53d6fea948643c0a76df03516605 (patch)
tree72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /StarsEx/NetAuth.cpp
parent8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff)
downloadstarshatter-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.cpp204
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;
+}
+
+// +-------------------------------------------------------------------+
+