Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        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));
        }