public async Task EULoginHandler(ProudSession session, LoginEUReqMessage message) { var ip = session.RemoteEndPoint.Address.ToString(); var account = new AccountDto(); using (var db = AuthDatabase.Open()) { if (message.Username != "" && message.Password != "") { Logger.Information($"Login from {ip}"); if (message.Username.Length > 5 && message.Password.Length > 5) { if (!Namecheck.IsNameValid(message.Username)) { await session.SendAsync(new LoginEUAckMessage(AuthLoginResult.WrongIdorPw)); Logger.Error("Wrong login for {ip}", ip); return; } var result = db.Find <AccountDto>(statement => statement .Where($"{nameof(AccountDto.Username):C} = @{nameof(message.Username)}") .Include <BanDto>(join => join.LeftOuterJoin()) .WithParameters(new { message.Username })); account = result.FirstOrDefault(); if (account == null && (Config.Instance.NoobMode || Config.Instance.AutoRegister)) { account = new AccountDto { Username = message.Username }; var newSalt = new byte[24]; using (var csprng = new RNGCryptoServiceProvider()) { csprng.GetBytes(newSalt); } var hash = new Rfc2898DeriveBytes(message.Password, newSalt, 24000).GetBytes(24); account.Password = Convert.ToBase64String(hash); account.Salt = Convert.ToBase64String(newSalt); await db.InsertAsync(account); } var salt = Convert.FromBase64String(account?.Salt ?? ""); var passwordGuess = new Rfc2898DeriveBytes(message.Password, salt, 24000).GetBytes(24); var actualPassword = Convert.FromBase64String(account?.Password ?? ""); var difference = (uint)passwordGuess.Length ^ (uint)actualPassword.Length; for (var i = 0; i < passwordGuess.Length && i < actualPassword.Length; i++) { difference |= (uint)(passwordGuess[i] ^ actualPassword[i]); } if ((difference != 0 || string.IsNullOrWhiteSpace(account?.Password ?? "")) && !Config.Instance.NoobMode) { await session.SendAsync(new LoginEUAckMessage(AuthLoginResult.WrongIdorPw)); Logger.Error("Wrong login for {ip}", ip); return; } if (account != null) { account.AuthToken = ""; account.newToken = ""; await db.UpdateAsync(account); } } else { await session.SendAsync(new LoginEUAckMessage(AuthLoginResult.WrongIdorPw)); Logger.Error("Wrong login for {ip}", ip); return; } } else if (message.token != "") { Logger.Information($"Login from {ip}"); var result = await db.FindAsync <AccountDto>(statement => statement .Where($"{nameof(AccountDto.LoginToken):C} = @{nameof(message.token)}") .Include <BanDto>(join => join.LeftOuterJoin()) .WithParameters(new { message.token })); account = result.FirstOrDefault(); if (account != null) { var lastlogin = DateTimeOffset.ParseExact(account.LastLogin, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None); if ((DateTimeOffset.Now - lastlogin).Minutes >= 5) { await session.SendAsync(new LoginEUAckMessage(AuthLoginResult.Failed2)); Logger.Error("Wrong login for {ip}", ip); return; } } else { await session.SendAsync(new LoginEUAckMessage(AuthLoginResult.Failed2)); Logger.Error("Wrong login for {ip}", ip); return; } } else if (message.AuthToken != "" && message.NewToken != "") { Logger.Information("Session login from {ip}", ip); var result = await db.FindAsync <AccountDto>(statement => statement .Where($"{nameof(AccountDto.AuthToken):C} = @{nameof(message.AuthToken)}") .Include <BanDto>(join => join.LeftOuterJoin()) .WithParameters(new { message.AuthToken })); account = result.FirstOrDefault(); if (account != null) { if (account.AuthToken != message.AuthToken && account.newToken != message.NewToken) { await session.SendAsync(new LoginEUAckMessage(AuthLoginResult.Failed2)); Logger.Error("Wrong session login for {ip} ({AuthToken}, {newToken})", ip, account.AuthToken, account.newToken); return; } } else { await session.SendAsync(new LoginEUAckMessage(AuthLoginResult.Failed2)); Logger.Error("Wrong session login for {ip}", ip); return; } } if (account == null) { return; } var now = DateTimeOffset.Now.ToUnixTimeSeconds(); var ban = account.Bans.FirstOrDefault(b => b.Date + (b.Duration ?? 0) > now); if (ban != null) { var unbanDate = DateTimeOffset.FromUnixTimeSeconds(ban.Date + (ban.Duration ?? 0)); Logger.Error("{user} is banned until {until}", account.Username, unbanDate); await session.SendAsync(new LoginEUAckMessage(unbanDate)); return; } Logger.Information("Login success for {user}", account.Username); var entry = new LoginHistoryDto { AccountId = account.Id, Date = DateTimeOffset.Now.ToUnixTimeSeconds(), IP = ip }; await db.InsertAsync(entry); } var datetime = $"{DateTimeOffset.UtcNow:yyyyMMddHHmmss}"; var sessionId = Hash.GetUInt32 <CRC32>($"<{account.Username}+{account.Password}>"); var authsessionId = Hash.GetString <CRC32>($"<{account.Username}+{sessionId}+{datetime}>"); var newsessionId = Hash.GetString <CRC32>($"<{authsessionId}+{sessionId}>"); using (var db = AuthDatabase.Open()) { account.LastLogin = $"{DateTimeOffset.UtcNow:yyyyMMddHHmmss}"; account.LoginToken = ""; account.AuthToken = authsessionId; account.newToken = newsessionId; await db.UpdateAsync(account); } await session.SendAsync(new LoginEUAckMessage(AuthLoginResult.OK, (ulong)account.Id, sessionId, authsessionId, newsessionId, datetime)); }
public async Task LoginHandler(ISession session, CAuthInEUReqMessage message) { var ip = ((IPEndPoint)((TcpTransport)session.Transport).Socket.RemoteEndPoint).Address.ToString(); Logger.Debug($"Login from {ip} with username {message.Username}"); AccountDto account; string password; using (var db = AuthDatabase.Open()) { var result = await db.FindAsync <AccountDto>(statement => statement .Where($"{nameof(AccountDto.Username):C} = @{nameof(message.Username)}") .Include <BanDto>(join => join.LeftOuterJoin()) .WithParameters(new { message.Username })) .ConfigureAwait(false); account = result.FirstOrDefault(); if (account == null) { if (Config.Instance.NoobMode) { // NoobMode: Create a new account if non exists account = new AccountDto { Username = message.Username }; var bytes = new byte[16]; using (var rng = new RNGCryptoServiceProvider()) rng.GetBytes(bytes); account.Salt = Hash.GetString <SHA1CryptoServiceProvider>(bytes); account.Password = Hash.GetString <SHA1CryptoServiceProvider>(message.Password + "+" + account.Salt); await db.InsertAsync(account) .ConfigureAwait(false); } else { Logger.Error($"Wrong login for {message.Username}"); await session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.WrongIdorPw)) .ConfigureAwait(false); return; } } password = Hash.GetString <SHA1CryptoServiceProvider>(message.Password + "+" + account.Salt); if (string.IsNullOrWhiteSpace(account.Password) || !account.Password.Equals(password, StringComparison.InvariantCultureIgnoreCase)) { if (Config.Instance.NoobMode) { // Noob Mode: Save new password var bytes = new byte[16]; using (var rng = new RNGCryptoServiceProvider()) rng.GetBytes(bytes); var salt = Hash.GetString <SHA1CryptoServiceProvider>(bytes); password = Hash.GetString <SHA1CryptoServiceProvider>(message.Password + "+" + salt); account.Password = password; account.Salt = salt; await db.UpdateAsync(account) .ConfigureAwait(false); } else { Logger.Error($"Wrong login for {message.Username}"); await session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.WrongIdorPw)) .ConfigureAwait(false); return; } } var now = DateTimeOffset.Now.ToUnixTimeSeconds(); var ban = account.Bans.FirstOrDefault(b => b.Date + (b.Duration ?? 0) > now); if (ban != null) { var unbanDate = DateTimeOffset.FromUnixTimeSeconds(ban.Date + (ban.Duration ?? 0)); Logger.Error($"{message.Username} is banned until {unbanDate}"); await session.SendAsync(new SAuthInEuAckMessage(unbanDate)) .ConfigureAwait(false); return; } Logger.Info($"Login success for {message.Username}"); var entry = new LoginHistoryDto { AccountId = account.Id, Date = DateTimeOffset.Now.ToUnixTimeSeconds(), IP = ip }; await db.InsertAsync(entry) .ConfigureAwait(false); } // ToDo proper session generation var sessionId = Hash.GetUInt32 <CRC32>($"<{account.Username}+{password}>"); await session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.OK, (ulong)account.Id, sessionId)) .ConfigureAwait(false); }
public async Task LoginHandler(ProudSession session, CAuthInEUReqMessage message) { var ip = session.RemoteEndPoint.Address.ToString(); Logger.Debug($"Login from {ip} with username {message.Username}"); AccountDto account; using (var db = AuthDatabase.Open()) { var result = await db.FindAsync <AccountDto>(statement => statement .Where($"{nameof(AccountDto.Username):C} = @{nameof(message.Username)}") .Include <BanDto>(join => join.LeftOuterJoin()) .WithParameters(new { message.Username })); account = result.FirstOrDefault(); if (account == null) { if (Config.Instance.NoobMode || Config.Instance.AutoRegister) { // NoobMode/AutoRegister: Create a new account if non exists account = new AccountDto { Username = message.Username }; var newSalt = new byte[24]; using (var csprng = new RNGCryptoServiceProvider()) csprng.GetBytes(newSalt); var hash = new byte[24]; using (var pbkdf2 = new Rfc2898DeriveBytes(message.Password, newSalt, 24000)) hash = pbkdf2.GetBytes(24); account.Password = Convert.ToBase64String(hash); account.Salt = Convert.ToBase64String(newSalt); await db.InsertAsync(account); } else { Logger.Error($"Wrong login for {message.Username}"); session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.WrongIdorPw)); return; } } var salt = Convert.FromBase64String(account.Salt); var passwordGuess = new byte[24]; using (var pbkdf2 = new Rfc2898DeriveBytes(message.Password, salt, 24000)) passwordGuess = pbkdf2.GetBytes(24); var actualPassword = Convert.FromBase64String(account.Password); uint difference = (uint)passwordGuess.Length ^ (uint)actualPassword.Length; for (var i = 0; i < passwordGuess.Length && i < actualPassword.Length; i++) { difference |= (uint)(passwordGuess[i] ^ actualPassword[i]); } if (difference != 0 || string.IsNullOrWhiteSpace(account.Password)) { if (Config.Instance.NoobMode) { // Noob Mode: Save new password var newSalt = new byte[24]; using (var csprng = new RNGCryptoServiceProvider()) csprng.GetBytes(newSalt); var hash = new byte[24]; using (var pbkdf2 = new Rfc2898DeriveBytes(message.Password, newSalt, 24000)) hash = pbkdf2.GetBytes(24); account.Password = Convert.ToBase64String(hash); account.Salt = Convert.ToBase64String(newSalt); await db.UpdateAsync(account); } else { Logger.Error($"Wrong login for {message.Username}"); session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.WrongIdorPw)); return; } } var now = DateTimeOffset.Now.ToUnixTimeSeconds(); var ban = account.Bans.FirstOrDefault(b => b.Date + (b.Duration ?? 0) > now); if (ban != null) { var unbanDate = DateTimeOffset.FromUnixTimeSeconds(ban.Date + (ban.Duration ?? 0)); Logger.Error($"{message.Username} is banned until {unbanDate}"); session.SendAsync(new SAuthInEuAckMessage(unbanDate)); return; } Logger.Information($"Login success for {message.Username}"); var entry = new LoginHistoryDto { AccountId = account.Id, Date = DateTimeOffset.Now.ToUnixTimeSeconds(), IP = ip }; await db.InsertAsync(entry); } // ToDo proper session generation var sessionId = Hash.GetUInt32 <CRC32>($"<{account.Username}+{account.Password}>"); session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.OK, (ulong)account.Id, sessionId)); }
public async Task KRLoginHandler(ProudSession session, LoginKRReqMessage message) { var ip = session.RemoteEndPoint.Address.ToString(); var account = new AccountDto(); using (var db = AuthDatabase.Open()) { if (message.AccountHashCode != "") { Logger.Information($"Login from {ip}"); var result = await db.FindAsync <AccountDto>(statement => statement .Where($"{nameof(AccountDto.LoginToken):C} = @{nameof(message.AccountHashCode)}") .Include <BanDto>(join => join.LeftOuterJoin()) .WithParameters(new { message.AccountHashCode })); account = result.FirstOrDefault(); if (account != null) { if ((DateTimeOffset.Now - DateTimeOffset.Parse(account.LastLogin)).Minutes >= 5) { await session.SendAsync(new LoginKRAckMessage(AuthLoginResult.Failed2)); Logger.Error("Wrong login for {ip}", ip); return; } } else { await session.SendAsync(new LoginKRAckMessage(AuthLoginResult.Failed2)); Logger.Error("Wrong login for {ip}", ip); return; } } else if (message.AuthToken != "" && message.NewToken != "") { Logger.Information("Session login from {ip}", ip); var result = await db.FindAsync <AccountDto>(statement => statement .Where($"{nameof(AccountDto.AuthToken):C} = @{nameof(message.AuthToken)}") .Include <BanDto>(join => join.LeftOuterJoin()) .WithParameters(new { message.AuthToken })); account = result.FirstOrDefault(); if (account != null) { if (account.AuthToken != message.AuthToken && account.newToken != message.NewToken) { await session.SendAsync(new LoginKRAckMessage(AuthLoginResult.Failed2)); Logger.Error("Wrong session login for {ip} ({AuthToken}, {newToken})", ip, account.AuthToken, account.newToken); return; } } else { await session.SendAsync(new LoginKRAckMessage(AuthLoginResult.Failed2)); Logger.Error("Wrong session login for {ip}", ip); return; } } var now = DateTimeOffset.Now.ToUnixTimeSeconds(); var ban = account.Bans.FirstOrDefault(b => b.Date + (b.Duration ?? 0) > now); if (ban != null) { var unbanDate = DateTimeOffset.FromUnixTimeSeconds(ban.Date + (ban.Duration ?? 0)); Logger.Error("{user} is banned until {until}", account.Username, unbanDate); await session.SendAsync(new LoginKRAckMessage(unbanDate)); return; } Logger.Information("Login success for {user}", account.Username); var entry = new LoginHistoryDto { AccountId = account.Id, Date = DateTimeOffset.Now.ToUnixTimeSeconds(), IP = ip }; await db.InsertAsync(entry); } var datetime = $"{DateTimeOffset.Now.DateTime}"; var sessionId = Hash.GetUInt32 <CRC32>($"<{account.Username}+{account.Password}>"); var authsessionId = Hash.GetString <CRC32>($"<{account.Username}+{sessionId}+{datetime}>"); var newsessionId = Hash.GetString <CRC32>($"<{authsessionId}+{sessionId}>"); using (var db = AuthDatabase.Open()) { account.LoginToken = ""; account.AuthToken = authsessionId; account.newToken = newsessionId; await db.UpdateAsync(account); } await session.SendAsync(new LoginKRAckMessage(AuthLoginResult.OK, (ulong)account.Id, sessionId, authsessionId, newsessionId, datetime)); }