예제 #1
0
        public async Task <LoginCheckerResponse> DoLogin(Login login, string ip)
        {
            await semaphore.WaitAsync();

            try
            {
                var userID       = login.UserID;
                var lobbyVersion = login.LobbyVersion;

                using (var db = new ZkDataContext())
                {
                    if (!VerifyIp(ip))
                    {
                        return(new LoginCheckerResponse(LoginResponse.Code.BannedTooManyConnectionAttempts));
                    }

                    SteamWebApi.PlayerInfo info = null;
                    if (!string.IsNullOrEmpty(login.SteamAuthToken))
                    {
                        info = await server.SteamWebApi.VerifyAndGetAccountInformation(login.SteamAuthToken);

                        if (info == null)
                        {
                            LogIpFailure(ip);
                            return(new LoginCheckerResponse(LoginResponse.Code.InvalidSteamToken));
                        }
                    }

                    Account accBySteamID = null;
                    Account accByLogin   = null;
                    if (info != null)
                    {
                        accBySteamID = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.SteamID == info.steamid);
                    }
                    if (!string.IsNullOrEmpty(login.Name))
                    {
                        var loginToUpper = login.Name.ToUpper();
                        accByLogin = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name == login.Name) ?? db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name.ToUpper() == loginToUpper);
                    }

                    if (accBySteamID == null)
                    {
                        if (accByLogin == null)
                        {
                            LogIpFailure(ip);
                            if (!string.IsNullOrEmpty(login.Name))
                            {
                                return(new LoginCheckerResponse(LoginResponse.Code.InvalidName));
                            }
                            else
                            {
                                return(new LoginCheckerResponse(LoginResponse.Code.SteamNotLinkedAndLoginMissing));
                            }
                        }

                        if (string.IsNullOrEmpty(login.PasswordHash) || !accByLogin.VerifyPassword(login.PasswordHash))
                        {
                            LogIpFailure(ip);
                            return(new LoginCheckerResponse(LoginResponse.Code.InvalidPassword));
                        }
                    }
                    var acc = accBySteamID ?? accByLogin;

                    var ret = new LoginCheckerResponse(LoginResponse.Code.Ok);
                    ret.LoginResponse.Name = acc.Name;
                    var user = ret.User;

                    acc.Country = ResolveCountry(ip);
                    if ((acc.Country == null) || string.IsNullOrEmpty(acc.Country))
                    {
                        acc.Country = "??";
                    }
                    acc.LobbyVersion = lobbyVersion;
                    acc.LastLogin    = DateTime.UtcNow;
                    if (info != null)
                    {
                        if (db.Accounts.Any(x => x.SteamID == info.steamid && x.Name != acc.Name))
                        {
                            LogIpFailure(ip);
                            return(new LoginCheckerResponse(LoginResponse.Code.SteamLinkedToDifferentAccount));
                        }
                        acc.SteamID   = info.steamid;
                        acc.SteamName = info.personaname;
                    }

                    user.LobbyVersion = login.LobbyVersion;
                    user.IpAddress    = ip;

                    UpdateUserFromAccount(user, acc);
                    LogIP(db, acc, ip);
                    LogUserID(db, acc, userID);

                    db.SaveChanges();

                    ret.LoginResponse.SessionToken = Guid.NewGuid().ToString(); // create session token

                    var banPenalty = Punishment.GetActivePunishment(acc.AccountID, ip, userID, x => x.BanLobby);

                    if (banPenalty != null)
                    {
                        return
                            (BlockLogin(
                                 $"Banned until {banPenalty.BanExpires} (match to {banPenalty.AccountByAccountID.Name}), reason: {banPenalty.Reason}",
                                 acc,
                                 ip,
                                 userID));
                    }

                    if (!acc.HasVpnException && GlobalConst.VpnCheckEnabled)
                    {
                        if (HasVpn(ip, acc, db))
                        {
                            return(BlockLogin("Connection using proxy or VPN is not allowed! (You can ask for exception)", acc, ip, userID));
                        }
                    }

                    return(ret);
                }
            }
            finally
            {
                semaphore.Release();
            }
        }
        public async Task<RegisterResponse> DoRegister(Register register, string ip)
        {
            if (!Account.IsValidLobbyName(register.Name)) return new RegisterResponse(RegisterResponse.Code.NameHasInvalidCharacters);

            if (server.ConnectedUsers.ContainsKey(register.Name)) return new RegisterResponse(RegisterResponse.Code.AlreadyConnected);

            if (string.IsNullOrEmpty(register.PasswordHash) && string.IsNullOrEmpty(register.SteamAuthToken)) return new RegisterResponse(RegisterResponse.Code.MissingBothPasswordAndToken);

            if (!VerifyIp(ip)) return new RegisterResponse(RegisterResponse.Code.BannedTooManyAttempts);

            var banPenalty = Punishment.GetActivePunishment(null, ip, register.UserID, register.InstallID, x => x.BanLobby);
            if (banPenalty != null) return new RegisterResponse(RegisterResponse.Code.Banned) {BanReason =  banPenalty.Reason};

            SteamWebApi.PlayerInfo info = null;
            if (!string.IsNullOrEmpty(register.SteamAuthToken))
            {
                info = await server.SteamWebApi.VerifyAndGetAccountInformation(register.SteamAuthToken);
                if (info == null) return new RegisterResponse(RegisterResponse.Code.InvalidSteamToken);
            }

            using (var db = new ZkDataContext())
            {
                var registerName = register.Name.ToUpper();
                var existingByName = db.Accounts.FirstOrDefault(x => x.Name.ToUpper() == registerName);
                if (existingByName != null)
                {
                    if (info != null && existingByName.SteamID == info.steamid) return new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisSteamToken);

                    if (info == null && !string.IsNullOrEmpty(register.PasswordHash) && existingByName.VerifyPassword(register.PasswordHash)) return new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisPassword);

                    return new RegisterResponse(RegisterResponse.Code.NameAlreadyTaken);
                }

                var acc = new Account() { Name = register.Name };
                acc.SetPasswordHashed(register.PasswordHash);
                acc.SetName(register.Name);
                acc.SetAvatar();
                acc.Email = register.Email;
                if (info != null)
                {
                    var existingBySteam = db.Accounts.FirstOrDefault(x => x.SteamID == info.steamid);
                    if (existingBySteam != null)
                        return new RegisterResponse(RegisterResponse.Code.SteamAlreadyRegistered);

                    acc.SteamID = info.steamid;
                    acc.SteamName = info.personaname;
                } else if (string.IsNullOrEmpty(register.PasswordHash))
                {
                    return new RegisterResponse(RegisterResponse.Code.InvalidPassword);
                }
                LogIP(db, acc, ip);
                LogUserID(db, acc, register.UserID, register.InstallID);
                db.Accounts.Add(acc);
                db.SaveChanges();
                var smurfs = acc.GetSmurfs().Where(a => a.PunishmentsByAccountID.Any(x => x.BanExpires > DateTime.UtcNow));
                if (smurfs.Any())
                {
                    await server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("Smurf Alert! {0} might be a smurf of {1}. Check https://zero-k.info/Users/AdminUserDetail/{2}", acc.Name, smurfs.OrderByDescending(x => x.Level).First().Name, acc.AccountID));
                }
            }
            return new RegisterResponse(RegisterResponse.Code.Ok);
        }
예제 #3
0
        public async Task <RegisterResponse> DoRegister(Register register, string ip)
        {
            if (!Account.IsValidLobbyName(register.Name))
            {
                return(new RegisterResponse(RegisterResponse.Code.NameHasInvalidCharacters));
            }

            if (server.ConnectedUsers.ContainsKey(register.Name))
            {
                return(new RegisterResponse(RegisterResponse.Code.AlreadyConnected));
            }

            if (string.IsNullOrEmpty(register.PasswordHash) && string.IsNullOrEmpty(register.SteamAuthToken))
            {
                return(new RegisterResponse(RegisterResponse.Code.MissingBothPasswordAndToken));
            }

            if (!VerifyIp(ip))
            {
                return(new RegisterResponse(RegisterResponse.Code.BannedTooManyAttempts));
            }

            var banPenalty = Punishment.GetActivePunishment(null, ip, register.UserID, x => x.BanLobby);

            if (banPenalty != null)
            {
                return new RegisterResponse(RegisterResponse.Code.Banned)
                       {
                           BanReason = banPenalty.Reason
                       }
            }
            ;

            SteamWebApi.PlayerInfo info = null;
            if (!string.IsNullOrEmpty(register.SteamAuthToken))
            {
                info = await server.SteamWebApi.VerifyAndGetAccountInformation(register.SteamAuthToken);

                if (info == null)
                {
                    return(new RegisterResponse(RegisterResponse.Code.InvalidSteamToken));
                }
            }

            using (var db = new ZkDataContext())
            {
                var registerName   = register.Name.ToUpper();
                var existingByName = db.Accounts.FirstOrDefault(x => x.Name.ToUpper() == registerName);
                if (existingByName != null)
                {
                    if (info != null && existingByName.SteamID == info.steamid)
                    {
                        return(new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisSteamToken));
                    }

                    if (info == null && !string.IsNullOrEmpty(register.PasswordHash) && existingByName.VerifyPassword(register.PasswordHash))
                    {
                        return(new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisPassword));
                    }

                    return(new RegisterResponse(RegisterResponse.Code.NameAlreadyTaken));
                }

                var acc = new Account()
                {
                    Name = register.Name
                };
                acc.SetPasswordHashed(register.PasswordHash);
                acc.SetName(register.Name);
                acc.SetAvatar();
                acc.Email = register.Email;
                if (info != null)
                {
                    var existingBySteam = db.Accounts.FirstOrDefault(x => x.SteamID == info.steamid);
                    if (existingBySteam != null)
                    {
                        return(new RegisterResponse(RegisterResponse.Code.SteamAlreadyRegistered));
                    }

                    acc.SteamID   = info.steamid;
                    acc.SteamName = info.personaname;
                }
                else if (string.IsNullOrEmpty(register.PasswordHash))
                {
                    return(new RegisterResponse(RegisterResponse.Code.InvalidPassword));
                }
                LogIP(db, acc, ip);
                LogUserID(db, acc, register.UserID);
                db.Accounts.Add(acc);
                db.SaveChanges();
            }
            return(new RegisterResponse(RegisterResponse.Code.Ok));
        }
예제 #4
0
        public async Task <LoginCheckerResponse> DoLogin(Login login, string ip, List <ulong> dlc)
        {
            var limit = MiscVar.ZklsMaxUsers;

            if (limit > 0 && server.ConnectedUsers.Count >= limit)
            {
                return(new LoginCheckerResponse(LoginResponse.Code.ServerFull));
            }
            await semaphore.WaitAsync();

            try
            {
                var userID       = login.UserID;
                var installID    = login.InstallID;
                var lobbyVersion = login.LobbyVersion;

                using (var db = new ZkDataContext())
                {
                    if (!VerifyIp(ip))
                    {
                        return(new LoginCheckerResponse(LoginResponse.Code.BannedTooManyConnectionAttempts));
                    }

                    SteamWebApi.PlayerInfo info = null;
                    if (!string.IsNullOrEmpty(login.SteamAuthToken))
                    {
                        info = await server.SteamWebApi.VerifyAndGetAccountInformation(login.SteamAuthToken);

                        if (info == null)
                        {
                            LogIpFailure(ip);
                            return(new LoginCheckerResponse(LoginResponse.Code.InvalidSteamToken));
                        }
                    }

                    Account accBySteamID = null;
                    Account accByLogin   = null;
                    if (info != null)
                    {
                        accBySteamID = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.SteamID == info.steamid);
                    }
                    if (!string.IsNullOrEmpty(login.Name))
                    {
                        accByLogin = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name == login.Name) ?? db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name.Equals(login.Name, StringComparison.CurrentCultureIgnoreCase));
                    }

                    if (accBySteamID == null)
                    {
                        if (accByLogin == null)
                        {
                            LogIpFailure(ip);
                            if (!string.IsNullOrEmpty(login.Name))
                            {
                                return(new LoginCheckerResponse(LoginResponse.Code.InvalidName));
                            }
                            else
                            {
                                return(new LoginCheckerResponse(LoginResponse.Code.SteamNotLinkedAndLoginMissing));
                            }
                        }

                        if (string.IsNullOrEmpty(login.PasswordHash) || !accByLogin.VerifyPassword(login.PasswordHash))
                        {
                            LogIpFailure(ip);
                            return(new LoginCheckerResponse(LoginResponse.Code.InvalidPassword));
                        }
                    }
                    var acc = accBySteamID ?? accByLogin;

                    var ret = new LoginCheckerResponse(LoginResponse.Code.Ok);
                    ret.LoginResponse.Name = acc.Name;
                    var user = ret.User;

                    acc.Country = ResolveCountry(ip);
                    if ((acc.Country == null) || string.IsNullOrEmpty(acc.Country))
                    {
                        acc.Country = "??";
                    }
                    acc.LobbyVersion = lobbyVersion;
                    acc.LastLogin    = DateTime.UtcNow;
                    if (info != null)
                    {
                        if (db.Accounts.Any(x => x.SteamID == info.steamid && x.Name != acc.Name))
                        {
                            LogIpFailure(ip);
                            return(new LoginCheckerResponse(LoginResponse.Code.SteamLinkedToDifferentAccount));
                        }
                        acc.SteamID   = info.steamid;
                        acc.SteamName = info.personaname;
                    }

                    user.LobbyVersion = login.LobbyVersion;
                    user.IpAddress    = ip;

                    acc.VerifyAndAddDlc(dlc);

                    UpdateUserFromAccount(user, acc);
                    LogIP(db, acc, ip);
                    LogUserID(db, acc, userID, installID);

                    if (String.IsNullOrEmpty(installID) && !acc.HasVpnException)
                    {
                        await server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("{0} just logged in with an unsupported lobby https://zero-k.info/Users/AdminUserDetail/{1}", acc.Name, acc.AccountID));
                    }

                    db.SaveChanges();

                    ret.LoginResponse.SessionToken = Guid.NewGuid().ToString(); // create session token

                    var banPenalty = Punishment.GetActivePunishment(acc.AccountID, ip, userID, installID, x => x.BanLobby);

                    if (banPenalty != null)
                    {
                        return
                            (BlockLogin(
                                 $"Banned until {banPenalty.BanExpires} (match to {banPenalty.AccountByAccountID.Name}), reason: {banPenalty.Reason}",
                                 acc,
                                 ip,
                                 userID,
                                 installID));
                    }

                    if (!acc.HasVpnException && GlobalConst.VpnCheckEnabled)
                    {
                        if (HasVpn(ip, acc, db))
                        {
                            return(BlockLogin("Connection using proxy or VPN is not allowed! (You can ask for exception)", acc, ip, userID, installID));
                        }
                    }

                    return(ret);
                }
            }
            finally
            {
                semaphore.Release();
            }
        }