diff --git a/BasePatches/BestHTTP.cs b/BasePatches/BestHTTP.cs index 0718d4b..a4e58f6 100644 --- a/BasePatches/BestHTTP.cs +++ b/BasePatches/BestHTTP.cs @@ -77,6 +77,10 @@ namespace undead_universal_patch_il2cpp.Patches { if (newUri.PathAndQuery.Contains(header)) { + // refresh the token if it expired + // this is somewhat inefficient, but we don't hook into many requests (see below) so it should be fine + GalvanicWebAuth.TokenExpiry(); + Type httpRequestType = request.GetType(); MethodInfo addHeaderMethod = httpRequestType.GetMethod("AddHeader"); addHeaderMethod.Invoke(request, ["GalvanicAuth", GalvanicWebAuth.Token]); diff --git a/BasePatches/GenuinePatch.cs b/BasePatches/GenuinePatch.cs deleted file mode 100644 index c4ec2c3..0000000 --- a/BasePatches/GenuinePatch.cs +++ /dev/null @@ -1,21 +0,0 @@ -using HarmonyLib; -using System.Reflection; - -namespace undead_universal_patch_il2cpp.Patches -{ - [HarmonyPatch] - class GenuinePatch - { - static readonly MethodInfo methodType = AccessTools.Method(AccessTools.TypeByName("Application"), "get_productName"); - static bool Prepare() - { - if (methodType == null) return false; - else return true; - } - static MethodBase TargetMethod() => methodType; - static void Prefix(ref string __result) - { - __result = string.Format("{0} (Custom Server)", __result); - } - } -} diff --git a/BasePatches/PhotonPatchEvents.cs b/BasePatches/PhotonPatchEvents.cs index 0cf6ef6..234e471 100644 --- a/BasePatches/PhotonPatchEvents.cs +++ b/BasePatches/PhotonPatchEvents.cs @@ -1,6 +1,5 @@ using HarmonyLib; using System; -using System.ComponentModel; using System.Reflection; namespace undead_universal_patch_il2cpp.Patches diff --git a/Config.cs b/Config.cs index df329b9..27fc2bd 100644 --- a/Config.cs +++ b/Config.cs @@ -46,11 +46,15 @@ namespace undead_universal_patch_il2cpp { public static ConfigEntry Enabled; public static ConfigEntry RegenerateKeypair; + public static ConfigEntry Export; + public static ConfigEntry Import; } public static class GalvanicConfigDefaults { public static bool Enabled = false; public static bool RegenerateKeypair = false; + public static string Export = "IDoNotWantToExportMyKeys"; + public static bool Import = false; } } diff --git a/Galvanic.cs b/Galvanic.cs index 6e476e6..deb9be5 100644 --- a/Galvanic.cs +++ b/Galvanic.cs @@ -4,6 +4,7 @@ using System.Security.Cryptography; using System.Text; using UnityEngine; using System.Text.Json; +using System.IO; // this entire file could be better @@ -70,6 +71,28 @@ namespace undead_universal_patch_il2cpp return Convert.ToBase64String(signature); } } + public static void Export() + { + File.WriteAllText("./galvanic_keys_export.txt", $"{GetPubKey()}\n{Convert.ToBase64String(GetPrivKey().ExportPkcs8PrivateKey())}"); + Plugin.Log.LogWarning("Galvanic Authentication keys were exported."); + } + public static void Import() + { + try + { + string imported = File.ReadAllText("./galvanic_keys_export.txt").ToString(); + string privkey = imported.Split("\n")[1]; + string pubkey = imported.Split("\n")[0]; + if (privkey == null || pubkey == null) throw new Exception("Either imported key was null"); + + PlayerPrefs.SetString("GalvanicPrivateKey", privkey); + PlayerPrefs.SetString("GalvanicPublicKey", pubkey); + PlayerPrefs.Save(); + } catch (Exception err) + { + Plugin.Log.LogError($"Could not import Galvanic Authentication keys: {err}"); + } + } public static ServerInfoRes GetServerInfo() { UriBuilder nameserver = new(NameserverConfig.NewUrl.Value); @@ -103,6 +126,22 @@ namespace undead_universal_patch_il2cpp public static class GalvanicWebAuth { public static string Token { get; private set; } = null; + public static void TokenExpiry() + { + string url = NameserverConfig.NewUrl.Value; + UriBuilder uri = new(url); + uri.Path = "/user/checkExpired"; + uri.Query = ""; + + HttpClient client = new(); + client.DefaultRequestHeaders.Add("GalvanicAuth", Token); + HttpResponseMessage res = client.GetAsync(uri.ToString()).Result; + if (res.IsSuccessStatusCode) + { + bool expired = JsonSerializer.Deserialize(res.Content.ReadAsStringAsync().Result.ToString()); + if (expired) GetToken(); + } + } public static void GetToken() { @@ -113,6 +152,7 @@ namespace undead_universal_patch_il2cpp var info = GalvanicAuth.GetServerInfo(); Plugin.Log.LogInfo($"Sending authentication request to server ID '{info.id}'"); + if (uri.Scheme == "http") Plugin.Log.LogWarning("The server is not secure! Please use HTTPS."); UserAuthPayload payload = new UserAuthPayload { diff --git a/Plugin.cs b/Plugin.cs index 7e4e867..74e6ff8 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,9 +1,7 @@ -using System; -using BepInEx; +using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; -using Il2CppSystem.Reflection; namespace undead_universal_patch_il2cpp; @@ -50,6 +48,15 @@ public class Plugin : BasePlugin "\nDo not enable if you either don't know what this does."); GalvanicConfig.RegenerateKeypair = Config.Bind("GalvanicCorrosion", "RegenerateKeypair", GalvanicConfigDefaults.RegenerateKeypair, "Regenerate the keypair upon startup. DO NOT ENABLE IF YOU WANT TO KEEP YOUR ACCOUNT."); + GalvanicConfig.Export = Config.Bind("GalvanicCorrosion", "Export", GalvanicConfigDefaults.Export, + "Export the keypair to a plaintext file in the game directory. Set to 'IWantToExportMyKeys' to enable." + + "\n**DO NOT ENABLE IF YOU DO NOT KNOW WHAT THIS DOES.**" + + "\n**DO NOT ENABLE THIS IF SOMEONE UNTRUSTWORTHY TOLD YOU TO.**" + + "\n**THESE KEYS CONTAIN THE CREDENTIALS THAT GRANT ACCESS TO YOUR ACCOUNTS.**"); + GalvanicConfig.Import = Config.Bind("GalvanicCorrosion", "Import", GalvanicConfigDefaults.Import, + "Import the Galvanic Authentication keys from a file." + + "\nBe sure to not enable this at the same time as `Export`, as that will cause the keys to" + + "\nbe unnecessarily written and read to and from the disk."); _hi.PatchAll(); if (GalvanicConfig.RegenerateKeypair.Value) @@ -57,6 +64,8 @@ public class Plugin : BasePlugin Log.LogInfo("Regenerating keypair"); GalvanicAuth.PrepareKeys(); } + if (GalvanicConfig.Export.Value == "IWantToExportMyKeys") GalvanicAuth.Export(); + if (GalvanicConfig.Import.Value) GalvanicAuth.Import(); if (GalvanicConfig.Enabled.Value) GalvanicWebAuth.GetToken(); } } \ No newline at end of file diff --git a/undead-universal-patch-il2cpp.csproj b/undead-universal-patch-il2cpp.csproj index 1d73825..4df5367 100644 --- a/undead-universal-patch-il2cpp.csproj +++ b/undead-universal-patch-il2cpp.csproj @@ -4,7 +4,7 @@ net6.0 undead_universal_patch_il2cpp Non-EAC, IL2CPP build patcher for Rec Room (Late 2018*-*April-2020) - 1.0.0 + 1.1.0 true latest