diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs index 1db8f5c7..5dcc3f86 100644 --- a/DepotDownloader/ContentDownloader.cs +++ b/DepotDownloader/ContentDownloader.cs @@ -238,25 +238,62 @@ namespace DepotDownloader if (branch != "Public" && node == KeyValue.Invalid) { var node_encrypted = manifests_encrypted[branch]; - if (node_encrypted != KeyValue.Invalid) - { - string password = Config.BetaPassword; - if (password == null) - { - Console.Write("Please enter the password for branch {0}: ", branch); - Config.BetaPassword = password = Console.ReadLine(); - } - - byte[] input = Util.DecodeHexString(node_encrypted["encrypted_gid"].Value); - byte[] manifest_bytes = CryptoHelper.VerifyAndDecryptPassword(input, password); - - if (manifest_bytes == null) - { - Console.WriteLine("Password was invalid for branch {0}", branch); - return INVALID_MANIFEST_ID; - } - - return BitConverter.ToUInt64(manifest_bytes, 0); + if (node_encrypted != KeyValue.Invalid) + { + string password = Config.BetaPassword; + if (password == null) + { + Console.Write("Please enter the password for branch {0}: ", branch); + Config.BetaPassword = password = Console.ReadLine(); + } + + var encrypted_v1 = node_encrypted["encrypted_gid"]; + var encrypted_v2 = node_encrypted["encrypted_gid_2"]; + + if (encrypted_v1 != KeyValue.Invalid) + { + byte[] input = Util.DecodeHexString(encrypted_v1.Value); + byte[] manifest_bytes = CryptoHelper.VerifyAndDecryptPassword(input, password); + + if (manifest_bytes == null) + { + Console.WriteLine("Password was invalid for branch {0}", branch); + return INVALID_MANIFEST_ID; + } + + return BitConverter.ToUInt64(manifest_bytes, 0); + } + else if (encrypted_v2 != KeyValue.Invalid) + { + // Submit the password to Steam now to get encryption keys + steam3.CheckAppBetaPassword(appId, Config.BetaPassword); + + if (!steam3.AppBetaPasswords.ContainsKey(branch)) + { + Console.WriteLine("Password was invalid for branch {0}", branch); + return INVALID_MANIFEST_ID; + } + + byte[] input = Util.DecodeHexString(encrypted_v2.Value); + byte[] manifest_bytes; + try + { + manifest_bytes = CryptoHelper.SymmetricDecryptECB(input, steam3.AppBetaPasswords[branch]); + } + catch (Exception e) + { + Console.WriteLine("Failed to decrypt branch {0}", branch); + return INVALID_MANIFEST_ID; + } + + return BitConverter.ToUInt64(manifest_bytes, 0); + } + else + { + Console.WriteLine("Unhandled depot encryption for depotId {0}", depotId); + return INVALID_MANIFEST_ID; + } + } return INVALID_MANIFEST_ID; @@ -431,14 +468,14 @@ namespace DepotDownloader steam3.RequestAppTicket((uint)depotId); ulong manifestID = GetSteam3DepotManifest(depotId, appId, branch); - if (manifestID == INVALID_MANIFEST_ID && branch != "public") - { - Console.WriteLine("Warning: Depot {0} does not have branch named \"{1}\". Trying public branch.", depotId, branch); - branch = "public"; + if (manifestID == INVALID_MANIFEST_ID && branch != "public") + { + Console.WriteLine("Warning: Depot {0} does not have branch named \"{1}\". Trying public branch.", depotId, branch); + branch = "public"; manifestID = GetSteam3DepotManifest(depotId, appId, branch); } - if (manifestID == INVALID_MANIFEST_ID) + if (manifestID == INVALID_MANIFEST_ID) { Console.WriteLine("Depot {0} ({1}) missing public subsection or manifest section.", depotId, contentName); return null; diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index 80bc16b3..832e959c 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -33,6 +33,7 @@ namespace DepotDownloader public Dictionary, SteamApps.CDNAuthTokenCallback> CDNAuthTokens { get; private set; } public Dictionary AppInfo { get; private set; } public Dictionary PackageInfo { get; private set; } + public Dictionary AppBetaPasswords { get; private set; } public SteamClient steamClient; public SteamUser steamUser; @@ -73,6 +74,7 @@ namespace DepotDownloader this.CDNAuthTokens = new Dictionary, SteamApps.CDNAuthTokenCallback>(); this.AppInfo = new Dictionary(); this.PackageInfo = new Dictionary(); + this.AppBetaPasswords = new Dictionary(); this.steamClient = new SteamClient(); @@ -309,6 +311,27 @@ namespace DepotDownloader }, () => { return completed; }); } + public void CheckAppBetaPassword(uint appid, string password) + { + bool completed = false; + Action cbMethod = (appPassword) => + { + completed = true; + + Console.WriteLine("Retrieved {0} beta keys with result: {1}", appPassword.BetaPasswords.Count, appPassword.Result); + + foreach (var entry in appPassword.BetaPasswords) + { + AppBetaPasswords.Add(entry.Key, entry.Value); + } + }; + + WaitUntilCallback(() => + { + callbacks.Subscribe(steamApps.CheckAppBetaPassword(appid, password), cbMethod); + }, () => { return completed; }); + } + void Connect() { bAborted = false;