public LoginResponse Login(User user, Login login, Client client) { string ip = client.RemoteEndpointIP; long userID = login.UserID; string lobbyVersion = login.LobbyVersion; using (var db = new ZkDataContext()) { Account acc = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name == login.Name); if (acc == null) { return new LoginResponse { ResultCode = LoginResponse.Code.InvalidName } } ; if (!acc.VerifyPassword(login.PasswordHash)) { return new LoginResponse { ResultCode = LoginResponse.Code.InvalidPassword } } ; if (state.Clients.ContainsKey(login.Name)) { return new LoginResponse { ResultCode = LoginResponse.Code.AlreadyConnected } } ; acc.Country = ResolveCountry(ip); acc.LobbyVersion = lobbyVersion; acc.LastLogin = DateTime.UtcNow; user.ClientType = login.ClientType; user.LobbyVersion = login.LobbyVersion; UpdateUserFromAccount(user, acc); LogIP(db, acc, ip); LogUserID(db, acc, userID); db.SaveChanges(); var banMute = Punishment.GetActivePunishment(acc.AccountID, ip, userID, x => x.BanMute, db); if (banMute != null) { user.BanMute = true; } Punishment banPenalty = Punishment.GetActivePunishment(acc.AccountID, ip, userID, x => x.BanLobby, db); if (banPenalty != null) { return (BlockLogin( string.Format("Banned until {0} (match to {1}), reason: {2}", banPenalty.BanExpires, banPenalty.AccountByAccountID.Name, banPenalty.Reason), acc, ip, userID)); } Account accAnteep = db.Accounts.FirstOrDefault(x => x.AccountID == 4490); if (accAnteep != null) { if (accAnteep.AccountUserIDs.Any(y => y.UserID == userID)) { Talk(String.Format("Suspected Anteep smurf: {0} (ID match {1}) {2}", acc.Name, userID, string.Format("{1}/Users/Detail/{0}", acc.AccountID, GlobalConst.BaseSiteUrl))); } if (userID > 0 && userID < 1000) { Talk(String.Format("Suspected Anteep smurf: {0} (too short userID {1}) {2}", acc.Name, userID, string.Format("{1}/Users/Detail/{0}", acc.AccountID, GlobalConst.BaseSiteUrl))); } if (accAnteep.AccountIPs.Any(y => y.IP == ip)) { Talk(String.Format("Suspected Anteep smurf: {0} (IP match {1}) {2}", acc.Name, ip, string.Format("{1}/Users/Detail/{0}", acc.AccountID, GlobalConst.BaseSiteUrl))); } } if (!acc.HasVpnException && GlobalConst.VpnCheckEnabled) { // check user IP against http://dnsbl.tornevall.org // does not catch all smurfs // mostly false positives, do not use string reversedIP = string.Join(".", ip.Split('.').Reverse().ToArray()); try { IPAddress[] resolved = Dns.GetHostEntry(string.Format("{0}.dnsbl.tornevall.org", reversedIP)).AddressList; if (resolved.Length > 0) { Talk(String.Format("User {0} {3} has IP {1} on dnsbl.tornevall.org ({2} result/s)", acc.Name, ip, resolved.Length, string.Format("{1}/Users/Detail/{0}", acc.AccountID, GlobalConst.BaseSiteUrl))); } } catch (SocketException sockEx) { // not in database, do nothing } } try { if (!acc.HasVpnException) { for (int i = 0; i <= 1; i++) { var whois = new Whois(); Dictionary <string, string> data = whois.QueryByIp(ip, i == 1); if (!data.ContainsKey("netname")) { data["netname"] = "UNKNOWN NETNAME"; } if (!data.ContainsKey("org-name")) { data["org-name"] = "UNKNOWN ORG"; } if (!data.ContainsKey("abuse-mailbox")) { data["abuse-mailbox"] = "no mailbox"; } if (!data.ContainsKey("notify")) { data["notify"] = "no notify address"; } if (!data.ContainsKey("role")) { data["role"] = "UNKNOWN ROLE"; } if (!data.ContainsKey("descr")) { data["descr"] = "no description"; } if (!data.ContainsKey("remarks")) { data["remarks"] = "no remarks"; } List <string> blockedCompanies = db.BlockedCompanies.Select(x => x.CompanyName.ToLower()).ToList(); List <string> blockedHosts = db.BlockedHosts.Select(x => x.HostName).ToList(); /*if (acc.Country == "MY") * { * client.Say(SayPlace.User, "KingRaptor", String.Format("USER {0}\nnetname: {1}\norgname: {2}\ndescr: {3}\nabuse-mailbox: {4}", * acc.Name, data["netname"], data["org-name"], data["descr"], data["abuse-mailbox"]), false); * }*/ bool blockedHost = blockedHosts.Any(x => data["abuse-mailbox"].Contains(x)) || (blockedHosts.Any(x => data["notify"].Contains(x))); foreach (string company in blockedCompanies) { if (data["netname"].ToLower().Contains(company) || data["org-name"].ToLower().Contains(company) || data["descr"].ToLower().Contains(company) || data["role"].ToLower().Contains(company) || data["remarks"].ToLower().Contains(company)) { blockedHost = true; break; } } string hostname = Dns.GetHostEntry(ip).HostName; if (blockedHosts.Any(hostname.Contains)) { blockedHost = true; } if (blockedHost) { return(BlockLogin("Connection using proxy or VPN is not allowed! (You can ask for exception)", acc, ip, userID)); } } } } catch (SocketException sockEx) {} catch (Exception ex) { Trace.TraceError("VPN check error: {0}", ex); } if (state.Clients.TryAdd(login.Name, client)) { return new LoginResponse { ResultCode = LoginResponse.Code.Ok } } ; else { return new LoginResponse() { ResultCode = LoginResponse.Code.AlreadyConnected } }; } } string ResolveCountry(string ip) { if (IsLanIP(ip)) { return("CZ"); } else { try { return(geoIP.Country(ip).Country.IsoCode); } catch (Exception ex) { Trace.TraceWarning("{0} Unable to resolve country", this); return("??"); } } } LoginResponse BlockLogin(string reason, Account acc, string ip, long user_id) { Talk(string.Format("Login denied for {0} IP:{1} ID:{2} reason: {3}", acc.Name, ip, user_id, reason)); return(new LoginResponse { Reason = reason, ResultCode = LoginResponse.Code.Banned }); }