public static void HandleSelectRealm(WorldSession session, ClientSelectRealm selectRealm) { ServerInfo server = ServerManager.Servers.SingleOrDefault(s => s.Model.Id == selectRealm.RealmId); if (server == null) { throw new InvalidPacketValueException(); } // clicking back or selecting the current realm also triggers this packet, client crashes if we don't ignore it if (server.Model.Id == WorldServer.RealmId) { return; } byte[] sessionKey = RandomProvider.GetBytes(16u); session.EnqueueEvent(new TaskEvent(AuthDatabase.UpdateAccountSessionKey(session.Account, sessionKey), () => { session.EnqueueMessageEncrypted(new ServerNewRealm { SessionKey = sessionKey, GatewayData = new ServerNewRealm.Gateway { Address = server.Address, Port = server.Model.Port }, RealmName = server.Model.Name, Type = (RealmType)server.Model.Type }); })); }
/// <summary> /// Create a new account with the supplied email and password, the password will have a verifier generated that is inserted into the database. /// </summary> public static void CreateAccount(string email, string password) { using (var context = new AuthContext()) { byte[] s = RandomProvider.GetBytes(16u); byte[] v = Srp6Provider.GenerateVerifier(s, email, password); context.Account.Add(new Account { Email = email, S = s.ToHexString(), V = v.ToHexString() }); context.SaveChanges(); } }
public void DefaultGetBytesTest() { for (var repeat = 0; repeat < 10000; repeat++) { var r = new byte[4]; RandomProvider.GetBytes(r); var q = 0; foreach (var b in r) { unchecked { q += b; } } Assert.AreNotSame(q, 0); } }
public static void HandleHelloAuth(AuthSession session, ClientHelloAuth helloAuth) { session.EnqueueEvent(new TaskGenericEvent <Account>(AuthDatabase.GetAccountAsync(helloAuth.Email, helloAuth.GameToken.Guid), account => { if (account == null) { // TODO: send error return; } session.EnqueueMessageEncrypted(new ServerAuthAccepted()); session.EnqueueMessageEncrypted(new ServerRealmMessages { MessageGroup = { new ServerRealmMessages.Message { Index = 0, Messages = { "Welcome to this NexusForever server!\nVisit: https://github.com/Rawaho/NexusForever" } } } }); byte[] sessionKey = RandomProvider.GetBytes(16u); session.EnqueueEvent(new TaskEvent(AuthDatabase.UpdateAccountSessionKey(account, sessionKey), () => { ServerManager.ServerInfo server = ServerManager.Servers.First(); session.EnqueueMessageEncrypted(new ServerRealmInfo { AccountId = account.Id, SessionKey = sessionKey, Realm = server.Model.Name, Host = server.Address, Port = server.Model.Port, Type = server.Model.Type }); })); })); }
public static void HandleSelectRealm(WorldSession session, ClientSelectRealm selectRealm) { ServerInfo server = ServerManager.Instance.Servers.SingleOrDefault(s => s.Model.Id == selectRealm.RealmId); if (server == null) { throw new InvalidPacketValueException(); } // clicking back or selecting the current realm also triggers this packet, client crashes if we don't ignore it if (server.Model.Id == WorldServer.RealmId) { return; } // TODO: Return proper error packet if server is not online if (!server.IsOnline) { session.EnqueueMessageEncrypted(new ServerForceKick()); return; } byte[] sessionKeyBytes = RandomProvider.GetBytes(16u); string sessionKeyString = BitConverter.ToString(sessionKeyBytes).Replace("-", ""); session.EnqueueEvent(new TaskEvent(DatabaseManager.Instance.AuthDatabase.UpdateAccountSessionKey(session.Account, sessionKeyString), () => { session.EnqueueMessageEncrypted(new ServerNewRealm { SessionKey = sessionKeyBytes, GatewayData = new ServerNewRealm.Gateway { Address = server.Address, Port = server.Model.Port }, RealmName = server.Model.Name, Type = (RealmType)server.Model.Type }); })); }
public static void HandleHelloAuth(AuthSession session, ClientHelloAuth helloAuth) { session.EnqueueEvent(new TaskGenericEvent<Account>(AuthDatabase.GetAccountAsync(helloAuth.Email, helloAuth.GameToken.Guid), account => { if (account == null) { // TODO: send error return; } session.EnqueueMessageEncrypted(new ServerAuthAccepted()); session.EnqueueMessageEncrypted(new ServerRealmMessages { Messages = ServerManager.ServerMessages .Select(m => new ServerRealmMessages.Message { Index = m.Index, Messages = m.Messages }) .ToList() }); byte[] sessionKey = RandomProvider.GetBytes(16u); session.EnqueueEvent(new TaskEvent(AuthDatabase.UpdateAccountSessionKey(account, sessionKey), () => { ServerInfo server = ServerManager.Servers.First(); session.EnqueueMessageEncrypted(new ServerRealmInfo { AccountId = account.Id, SessionKey = sessionKey, Realm = server.Model.Name, Host = server.Address, Port = server.Model.Port, Type = server.Model.Type }); })); })); }
public static void HandleHelloAuth(AuthSession session, ClientHelloAuth helloAuth) { void SendServerAuthDenied(NpLoginResult result) { session.EnqueueMessageEncrypted(new ServerAuthDenied { LoginResult = result }); } if (helloAuth.Build != 16042) { SendServerAuthDenied(NpLoginResult.ClientServerVersionMismatch); return; } session.EnqueueEvent(new TaskGenericEvent <Account>(AuthDatabase.GetAccountAsync(helloAuth.Email, helloAuth.GameToken.Guid), account => { if (account == null) { SendServerAuthDenied(NpLoginResult.ErrorInvalidToken); return; } // TODO: might want to make this smarter in the future, eg: select a server the user has characters on ServerInfo server = ServerManager.Instance.Servers.FirstOrDefault(); if (server == null) { SendServerAuthDenied(NpLoginResult.NoRealmsAvailableAtThisTime); return; } session.EnqueueMessageEncrypted(new ServerAuthAccepted()); session.EnqueueMessageEncrypted(new ServerRealmMessages { Messages = ServerManager.Instance.ServerMessages .Select(m => new NetworkMessage { Index = m.Index, Messages = m.Messages }) .ToList() }); byte[] sessionKey = RandomProvider.GetBytes(16u); session.EnqueueEvent(new TaskEvent(AuthDatabase.UpdateAccountSessionKey(account, sessionKey), () => { session.EnqueueMessageEncrypted(new ServerRealmInfo { AccountId = account.Id, SessionKey = sessionKey, Realm = server.Model.Name, Address = server.Address, Port = server.Model.Port, Type = server.Model.Type }); })); })); }
/// <summary> /// Returns a random salt and SRP6 password verifier for supplied email and plaintext password. /// </summary> public static (string salt, string verifier) GenerateSaltAndVerifier(string email, string password) { byte[] s = RandomProvider.GetBytes(16u); byte[] v = Srp6Provider.GenerateVerifier(s, email, password); return(s.ToHexString(), v.ToHexString()); }