public static String Decrypt(Byte[] mapKey, Byte[] encrypted) { Sha1 sha1 = new Sha1(); Byte[] xorKey = new Byte[encrypted.Length + 19]; UInt32 xorKeyLength = 0; int counter = 0; while (xorKeyLength < encrypted.Length) { Byte[] counterStringBytes = Encoding.ASCII.GetBytes(counter.ToString()); sha1.Add(counterStringBytes, 0, counterStringBytes.Length); sha1.Add(mapKey, 0, mapKey.Length); sha1.Add(sharedServerSecret, 0, sharedServerSecret.Length); sha1.Add(counterStringBytes, 0, counterStringBytes.Length); UInt32[] hash = sha1.Finish(); xorKey.BigEndianSetUInt32(xorKeyLength + 0, hash[0]); xorKey.BigEndianSetUInt32(xorKeyLength + 4, hash[1]); xorKey.BigEndianSetUInt32(xorKeyLength + 8, hash[2]); xorKey.BigEndianSetUInt32(xorKeyLength + 12, hash[3]); xorKey.BigEndianSetUInt32(xorKeyLength + 16, hash[4]); xorKeyLength += 20; sha1.Reset(); counter++; } Char[] decrypted = new Char[encrypted.Length]; for (int i = 0; i < decrypted.Length; i++) { decrypted[i] = (Char)(xorKey[i] ^ encrypted[i]); } return(new String(decrypted)); }
public static async void AuthSessionHandler(AuthSession authSession, CharacterSession session) { var accountParts = authSession.Account.Split(new[] { '#' }); var authResult = AuthResult.Ok; if (accountParts.Length == 2) { var accountId = int.Parse(accountParts[0]); var gameIndex = byte.Parse(accountParts[1]); session.Account = DB.Auth.Single <Account>(a => a.Id == accountId); if (session.Account != null) { session.GameAccount = session.Account.GameAccounts.SingleOrDefault(ga => ga.Index == gameIndex); } if (session.GameAccount != null) { session.Crypt = new WoWCrypt(session.GameAccount.SessionKey.ToByteArray()); } else { authResult = AuthResult.Failed; } } session.Realm = DB.Auth.Single <Realm>(r => r.Id == authSession.RealmID); if (authSession.LoginServerType != (sbyte)LoginServerTypes.Battlenet || session.Realm == null) { authResult = AuthResult.Reject; } if (authResult == AuthResult.Ok) { var sha1 = new Sha1(); sha1.Process(authSession.Account); sha1.Process(0u); sha1.Process(authSession.LocalChallenge); sha1.Process(session.Challenge); sha1.Finish(session.GameAccount.SessionKey.ToByteArray(), 40); // Check the password digest. if (!sha1.Digest.Compare(authSession.Digest)) { authResult = AuthResult.Failed; } } var authResponse = new AuthResponse { Result = authResult, HasSuccessInfo = authResult == AuthResult.Ok, }; if (authResponse.HasSuccessInfo) { session.State = SessionState.Authenticated; var addonData = AddonHandler.GetAddonInfoData(session, authSession.AddonInfo, authSession.CompressedAddonInfoSize, authSession.UncompressedAddonInfoSize); if (addonData != null && addonData.Length != authSession.UncompressedAddonInfoSize) { Log.Error("Addon Info data size mismatch."); session.Dispose(); return; } authResponse.SuccessInfo.ActiveExpansionLevel = session.GameAccount.BoxLevel; authResponse.SuccessInfo.AccountExpansionLevel = session.GameAccount.BoxLevel; authResponse.SuccessInfo.AvailableRaces = Manager.GameAccount.GetAvailableRaces(session.GameAccount, session.Realm); authResponse.SuccessInfo.AvailableClasses = Manager.GameAccount.GetAvailableClasses(session.GameAccount, session.Realm); authResponse.SuccessInfo.Templates = Manager.GameAccount.GetAvailableCharacterTemplates(session.GameAccount, session.Realm); await session.Send(authResponse); AddonHandler.HandleAddonInfo(session, addonData); await session.Send(new TutorialFlags()); } else { await session.Send(authResponse); } }
public static void OnAuthSession(Packet packet, RealmSession session) { // Part of the header packet.Read <ushort>(); var loginServerId = packet.Read <int>(); var build = packet.Read <short>(); var regionId = packet.Read <uint>(); var siteId = packet.Read <uint>(); var realmId = packet.Read <uint>(); var loginServerType = packet.Read <LoginServerTypes>(); var buildType = packet.Read <sbyte>(); var localChallenge = packet.Read <uint>(); var dosResponse = packet.Read <ulong>(); var digest = packet.ReadBytes(20); var accountName = packet.ReadString(11); var useIPv6 = packet.GetBit(); // AddonInfo stuff var compressedAddonInfoSize = packet.Read <int>(); var uncompressedAddonInfoSize = packet.Read <int>(); var compressedAddonData = packet.ReadBytes(compressedAddonInfoSize - 4); var accountParts = accountName.Split(new[] { '#' }); var authResult = AuthResults.Ok; session.Realm = DB.Auth.Single <Realm>(r => r.Id == realmId); if (loginServerType != LoginServerTypes.Battlenet || session.Realm == null) { authResult = AuthResults.Reject; } if (authResult == AuthResults.Ok) { if (accountParts.Length == 2) { var accountId = int.Parse(accountParts[0]); var gameIndex = byte.Parse(accountParts[1]); var account = DB.Auth.Single <Account>(a => a.Id == accountId); if (account != null) { var gameAccount = account.GameAccounts.SingleOrDefault(ga => ga.Index == gameIndex); if (gameAccount != null) { var sha1 = new Sha1(); sha1.Process(accountName); sha1.Process(0u); sha1.Process(localChallenge); sha1.Process(session.Challenge); sha1.Finish(gameAccount.SessionKey.ToByteArray(), 40); // Check the password digest. if (sha1.Digest.Compare(digest)) { session.Crypt = new WoWCrypt(gameAccount.SessionKey.ToByteArray()); session.GameAccount = gameAccount; AddonHandler.LoadAddonInfoData(session, compressedAddonData, compressedAddonInfoSize, uncompressedAddonInfoSize); } else { authResult = AuthResults.Failed; } } else { authResult = AuthResults.UnknownAccount; } } else { authResult = AuthResults.UnknownAccount; } } else { authResult = AuthResults.UnknownAccount; } } HandleAuthResponse(authResult, session); //TODO [partially done] Implement security checks & field handling. //TODO [partially done] Implement AuthResponse. }