Пример #1
0
        // Forward this model to the user of this library.

        /// <summary>
        /// Copies the input structure into the current structure.
        /// </summary>
        /// <param name="whois">The input structure to copy.</param>
        public void Copy(Whois.NET.WhoisResponse whois)
        {
            AddressRange = whois.AddressRange;
            OrganizationName = whois.OrganizationName;
            RespondedServers = whois.RespondedServers;
            Raw = whois.Raw;
        }
Пример #2
0
        public override void ProcessRequest(HttpContext context)
        {
            ISession s = this.CurrentSession;

            using (ITransaction t = s.BeginTransaction())
            {
                Guid userID   = new Guid(context.Request["UserID"]);
                Guid clientID = new Guid(context.Request["ClientID"]);

                PersistentUser   user   = s.Get <PersistentUser>(userID);
                PersistentClient client = s.Get <PersistentClient>(clientID);

                if (user == null || !user.HasAPIAccess)
                {
                    throw new Exception("no api access");
                }

                if (client == null || !client.HasAPIAccess)
                {
                    throw new Exception("no api access");
                }
            }

            IToolOptions options = new WhoisToolOptions();

            (options as WhoisToolOptions).Host = context.Request["Host"];
            (options as WhoisToolOptions).Path = ConfigurationManager.AppSettings["whoisPath"];

            Whois whois = new Whois(options as IToolOptions);

            WhoisToolResults results = whois.Run() as WhoisToolResults;

            context.Response.Write(results.FullOutput);
        }
        public async Task RunQuery() {
            var whois = new Whois();
            var data = whois.QueryByIp("31.7.187.232");
            Assert.AreEqual("PRIVAX-LTD", data["netname"]);

            data = whois.QueryByIp("62.233.34.238");
            Assert.AreEqual("*****@*****.**", data["abuse-mailbox"]);
        }
Пример #4
0
        public async Task RunQuery()
        {
            var whois = new Whois();
            var data  = whois.QueryByIp("31.7.187.232");

            Assert.AreEqual("PRIVAX-LTD", data["netname"]);

            data = whois.QueryByIp("62.233.34.238");
            Assert.AreEqual("*****@*****.**", data["abuse-mailbox"]);
        }
Пример #5
0
        public void CreateInstance_of_IWhois_When_CorrectArgument_IsPassed()
        {
            // Arrange
            var socketMock = new Mock <ISocket>();
            var expected   = typeof(IWhois);

            // Act
            var actual = new Whois(socketMock.Object);

            // Assert
            Assert.IsInstanceOf(expected, actual);
        }
        public void Throw_Exception_When_DomainName_Is_Null()
        {
            // Arrange
            var socketMock  = new Mock <ISocket>();
            var whois       = new Whois(socketMock.Object);
            var port        = WhoisConstants.Port;
            var whoisServer = WhoisConstants.WhoisServer;
            var whoisServerLookupQueryPrefix = WhoisConstants.WhoisServerLookupQueryPrefix;
            var responseBufferSizeInBytes    = WhoisConstants.RecommendedBufferSizeInBytes;

            // Act & Assert
            Assert.Throws(typeof(ArgumentNullException),
                          () => whois.LookupDotComDomain(null, port, whoisServer, whoisServerLookupQueryPrefix, responseBufferSizeInBytes));
        }
        public void Throw_Exception_When_ResponseBufferSizeInBytes_isOutOfRange(int bufferSize)
        {
            // Arrange
            var socketMock  = new Mock <ISocket>();
            var whois       = new Whois(socketMock.Object);
            var domainName  = "test.com";
            var port        = WhoisConstants.Port;
            var whoisServer = WhoisConstants.WhoisServer;
            var whoisServerLookupQueryPrefix = WhoisConstants.WhoisServerLookupQueryPrefix;
            var responseBufferSizeInBytes    = bufferSize;

            // Act & Assert
            Assert.Throws(typeof(ArgumentOutOfRangeException),
                          () => whois.LookupDotComDomain(domainName, port, whoisServer, whoisServerLookupQueryPrefix, responseBufferSizeInBytes));
        }
        public void Throw_Exception_When_DomainNameLength_isOutOfRange()
        {
            // Arrange
            var socketMock  = new Mock <ISocket>();
            var whois       = new Whois(socketMock.Object);
            var domainName  = new String('a', 255) + ".com";
            var port        = WhoisConstants.Port;
            var whoisServer = WhoisConstants.WhoisServer;
            var whoisServerLookupQueryPrefix = WhoisConstants.WhoisServerLookupQueryPrefix;
            var responseBufferSizeInBytes    = WhoisConstants.RecommendedBufferSizeInBytes;

            // Act & Assert
            Assert.Throws(typeof(ArgumentOutOfRangeException),
                          () => whois.LookupDotComDomain(domainName, port, whoisServer, whoisServerLookupQueryPrefix, responseBufferSizeInBytes));
        }
        public void Throw_Exception_When_DomainName_Contains_Illegal_Characters_AndDoesNotMatchPattern(string domain)
        {
            // Arrange
            var socketMock  = new Mock <ISocket>();
            var whois       = new Whois(socketMock.Object);
            var domainName  = domain;
            var port        = WhoisConstants.Port;
            var whoisServer = WhoisConstants.WhoisServer;
            var whoisServerLookupQueryPrefix = WhoisConstants.WhoisServerLookupQueryPrefix;
            var responseBufferSizeInBytes    = WhoisConstants.RecommendedBufferSizeInBytes;

            // Act & Assert
            Assert.Throws(typeof(ArgumentException),
                          () => whois.LookupDotComDomain(domainName, port, whoisServer, whoisServerLookupQueryPrefix, responseBufferSizeInBytes));
        }
        public void Call_ISocket_ConnectMethod_WithExpectedParams()
        {
            // Arrange
            var socketStub  = new Mock <ISocket>();
            var whois       = new Whois(socketStub.Object);
            var domainName  = "test.com";
            var port        = WhoisConstants.Port;
            var whoisServer = WhoisConstants.WhoisServer;
            var whoisServerLookupQueryPrefix = WhoisConstants.WhoisServerLookupQueryPrefix;
            var responseBufferSizeInBytes    = WhoisConstants.RecommendedBufferSizeInBytes;

            // Act
            whois.LookupDotComDomain(domainName, port, whoisServer, whoisServerLookupQueryPrefix, responseBufferSizeInBytes);

            // Assert
            socketStub.Verify(s => s.Connect(WhoisConstants.WhoisServer, port));
        }
Пример #11
0
        public ActionResult CheckDomain(DomainViewModels model)
        {
            string whoisText = null;
            var    tldServer = Whois.GetWhoisServerName(model.DomainName);

            if (tldServer != null)
            {
                whoisText = Whois.GetWhoisInformation(tldServer, model.DomainName);
            }
            else
            {
                whoisText = Whois.GetWhoisInformation("whois.verisign-grs.com", model.DomainName + ".com");
            }

            whoisText           = whoisText.Replace("\r\n", "<br/>");
            model.DomainDetails = whoisText;
            return(View("Index", model));
        }
        public void Call_ISocket_ReceiveMethod_Once()
        {
            // Arrange
            var socketStub  = new Mock <ISocket>();
            var whois       = new Whois(socketStub.Object);
            var domainName  = "test.com";
            var port        = WhoisConstants.Port;
            var whoisServer = WhoisConstants.WhoisServer;
            var whoisServerLookupQueryPrefix = WhoisConstants.WhoisServerLookupQueryPrefix;
            var responseBufferSizeInBytes    = WhoisConstants.RecommendedBufferSizeInBytes;

            byte[] responseBytes = new byte[responseBufferSizeInBytes];
            // Act
            whois.LookupDotComDomain(domainName, port, whoisServer, whoisServerLookupQueryPrefix, responseBufferSizeInBytes);

            // Assert
            socketStub.Verify(s => s.Receive(responseBytes), Times.Once());
        }
Пример #13
0
        static void Main(string[] args)
        {
            Console.WriteLine("Enter a domain name to get the whois information.");
            var domainName = Console.ReadLine();

            try
            {
                var whoisText = Whois.Lookup(domainName, RecordType.domain);
                Console.WriteLine(whoisText);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            Console.WriteLine("Press any key to exit..");
            Console.Read();
        }
        public void Call_ISocket_SendMethod_WithExpectedParams()
        {
            // Arrange
            var socketStub  = new Mock <ISocket>();
            var whois       = new Whois(socketStub.Object);
            var domainName  = "test.com";
            var port        = WhoisConstants.Port;
            var whoisServer = WhoisConstants.WhoisServer;
            var whoisServerLookupQueryPrefix = WhoisConstants.WhoisServerLookupQueryPrefix;
            var responseBufferSizeInBytes    = WhoisConstants.RecommendedBufferSizeInBytes;
            var responseBytes = new byte[responseBufferSizeInBytes];

            byte[] query = Encoding.ASCII.GetBytes(whoisServerLookupQueryPrefix + domainName + Environment.NewLine);
            // Act
            whois.LookupDotComDomain(domainName, port, whoisServer, whoisServerLookupQueryPrefix, responseBufferSizeInBytes);

            // Assert
            socketStub.Verify(s => s.Send(query));
        }
        public void Return_CorrectResults()
        {
            // Arrange
            string expectedMessage = "test.com whois message";

            var socketStub  = new FakeSocket(expectedMessage);
            var whois       = new Whois(socketStub);
            var domainName  = "test.com";
            var port        = WhoisConstants.Port;
            var whoisServer = WhoisConstants.WhoisServer;
            var whoisServerLookupQueryPrefix = WhoisConstants.WhoisServerLookupQueryPrefix;
            var responseBufferSizeInBytes    = WhoisConstants.RecommendedBufferSizeInBytes;

            // Act
            string actualMessage = whois.LookupDotComDomain(domainName, port, whoisServer, whoisServerLookupQueryPrefix, responseBufferSizeInBytes);

            // Assert
            StringAssert.Contains(expectedMessage, actualMessage);
        }
Пример #16
0
        async void GetUserData(string token)
        {
            ISharedPreferences       prefs  = PreferenceManager.GetDefaultSharedPreferences(this);
            ISharedPreferencesEditor editor = prefs.Edit();

            editor.PutString("token", token).Apply();

            var    httpClient = new HttpClient(new NativeMessageHandler());
            string url        = "https://enl.io/api/whoami?token=" + token;

            using (HttpClient client = new HttpClient(new NativeMessageHandler()))
                using (HttpResponseMessage response = await client.GetAsync(url))
                {
                    HttpContent content = response.Content;
                    string      result  = await content.ReadAsStringAsync();

                    Whois agent = JsonConvert.DeserializeObject <Whois> (result);
                    if (agent != null)
                    {
                        editor.PutString("agentId", agent.agent_id).Apply();

                        TextView helloText = FindViewById <TextView> (Resource.Id.helloText);
                        helloText.Text = "Hello " + agent.agent_name + ",";

                        updateView();
                        GetLatestPasscodes();

                        // Setup Update GCM settings
                        if (IsPlayServicesAvailable())
                        {
                            var intent = new Intent(this, typeof(RegistrationIntentService));
                            StartService(intent);
                        }
                    }
                }
        }
Пример #17
0
 protected void btnCheckDomain_Click(object sender, EventArgs e)
 {
     ltKQ.Text = Whois.GetWhoisInformation(txtDomain.Text);
 }
        private bool HasVpn(string ip, Account acc, ZkDataContext db)
        {
            // check user IP against http://dnsbl.tornevall.org
            // does not catch all smurfs
            // mostly false positives, do not use
            var reversedIP = string.Join(".", ip.Split('.').Reverse().ToArray());
            try
            {
                var 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)));
                    return true;
                }
            }
            catch (SocketException sockEx)
            {
                // not in database, do nothing
            }

            try
            {
                //for (int i = 0; i <= 1; i++) {
                for (var i = 1; i <= 1; i++)
                {
                    var whois = new Whois();
                    var 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";

                    var blockedCompanies = db.BlockedCompanies.Select(x => x.CompanyName.ToLower()).ToList();
                    var blockedHosts = db.BlockedHosts.Select(x => x.HostName).ToList();

                    //Trace.TraceInformation($"VPN check for USER {acc.Name}\nnetname: {data["netname"]}\norgname: {data["org-name"]}\ndescr: {data["descr"]}\nabuse-mailbox: {data["abuse-mailbox"]}", false);

                    if (blockedHosts.Any(x => data["abuse-mailbox"].Contains(x)) || blockedHosts.Any(x => data["notify"].Contains(x))) return true;

                    foreach (var 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)) return true;

                    // this can throw a SocketException, so make sure we block login already if we ought to
                    try
                    {
                        var hostname = Dns.GetHostEntry(ip)?.HostName;
                        if (blockedHosts.Any(hostname.Contains)) return true;
                    }
                    catch (SocketException) { }
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError("VPN check error for user {0}: {1}", acc.Name, ex);
            }
            return false;
        }
Пример #19
0
        private bool HasVpn(string ip, Account acc, ZkDataContext db)
        {
            // check user IP against http://dnsbl.tornevall.org
            // does not catch all smurfs
            // mostly false positives, do not use
            var reversedIP = string.Join(".", ip.Split('.').Reverse().ToArray());

            try
            {
                var 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)));
                    return(true);
                }
            }
            catch (SocketException sockEx)
            {
                // not in database, do nothing
            }

            try
            {
                //for (int i = 0; i <= 1; i++) {
                for (var i = 1; i <= 1; i++)
                {
                    var whois = new Whois();
                    var 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";
                    }

                    var blockedCompanies = db.BlockedCompanies.Select(x => x.CompanyName.ToLower()).ToList();
                    var blockedHosts     = db.BlockedHosts.Select(x => x.HostName).ToList();

                    //Trace.TraceInformation($"VPN check for USER {acc.Name}\nnetname: {data["netname"]}\norgname: {data["org-name"]}\ndescr: {data["descr"]}\nabuse-mailbox: {data["abuse-mailbox"]}", false);

                    if (blockedHosts.Any(x => data["abuse-mailbox"].Contains(x)) || blockedHosts.Any(x => data["notify"].Contains(x)))
                    {
                        return(true);
                    }

                    foreach (var 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))
                        {
                            return(true);
                        }
                    }

                    // this can throw a SocketException, so make sure we block login already if we ought to
                    try
                    {
                        var hostname = Dns.GetHostEntry(ip)?.HostName;
                        if (blockedHosts.Any(hostname.Contains))
                        {
                            return(true);
                        }
                    }
                    catch (SocketException) { }
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError("VPN check error for user {0}: {1}", acc.Name, ex);
            }
            return(false);
        }
Пример #20
0
        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
            });
        }
Пример #21
0
        public AuthService(TasClient client)
        {
            this.client = client;

            /*
             * this.client.Input += (s, e) =>
             * {
             * Console.WriteLine(e.Command +" "+ Utils.Glue(e.Args));
             * };
             * this.client.Output += (s, e) =>
             * {
             * Console.WriteLine(e.Data.Key + " " +Utils.Glue(e.Data.Value.Select(x=>x.ToString()).ToArray()));
             * };*/

            this.client.LoginAccepted += (s, e) =>
            {
                requests.Clear();
                client.JoinChannel(ModeratorChannel);
                client.JoinChannel(Top20Channel);
                using (var db = new ZkDataContext()) foreach (var fac in db.Factions.Where(x => !x.IsDeleted))
                    {
                        client.JoinChannel(fac.Shortcut);
                    }
            };

            this.client.TestLoginAccepted += (s, e) =>
            {
                RequestInfo entry;
                if (requests.TryGetValue(client.MessageID, out entry))
                {
                    entry.CorrectName = e.ServerParams[0];
                    entry.LobbyID     = Convert.ToInt32(e.ServerParams[1]);
                    if (client.ExistingUsers.ContainsKey(entry.CorrectName))
                    {
                        entry.User = client.ExistingUsers[entry.CorrectName];
                    }
                    entry.WaitHandle.Set();
                }

                requests.TryRemove(client.MessageID, out entry);
            };

            this.client.UserAdded += (s, e) =>
            {
                using (var db = new ZkDataContext())
                {
                    var acc = Account.AccountByLobbyID(db, e.Data.LobbyID);
                    if (acc != null)
                    {
                        this.client.Extensions.PublishAccountData(acc);
                        if (acc.SpringieLevel > 2 || acc.IsZeroKAdmin)
                        {
                            client.ForceJoinChannel(e.Data.Name, ModeratorChannel);
                        }
                        if (topPlayers.IsTop20(e.Data.LobbyID))
                        {
                            client.ForceJoinChannel(e.Data.Name, Top20Channel);
                        }
                        if (acc.Clan != null)
                        {
                            client.ForceJoinChannel(e.Data.Name, acc.Clan.GetClanChannel(), acc.Clan.Password);
                        }
                        if (acc.Faction != null && acc.Level >= GlobalConst.FactionChannelMinLevel && acc.CanPlayerPlanetWars())
                        {
                            client.ForceJoinChannel(e.Data.Name, acc.Faction.Shortcut);
                        }
                    }
                    client.RequestUserIP(e.Data.Name);
                    client.RequestUserID(e.Data.Name);
                }
            };

            this.client.UserIDRecieved += (sender, args) =>
            {
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        using (var db = new ZkDataContext())
                        {
                            var acc     = Account.AccountByName(db, args.Name);
                            var penalty = Punishment.GetActivePunishment(acc != null ? acc.AccountID : 0, null, args.ID, x => x.BanLobby, db);

                            if (penalty != null)
                            {
                                client.AdminKickFromLobby(args.Name,
                                                          string.Format("Banned until {0} (ID match to {1}), reason: {2}", penalty.BanExpires, penalty.AccountByAccountID.Name, penalty.Reason));
                            }
                            ;

                            if (acc != null && args.ID != 0)
                            {
                                var entry = acc.AccountUserIDS.FirstOrDefault(x => x.UserID == args.ID);
                                if (entry == null)
                                {
                                    entry = new AccountUserID {
                                        AccountID = acc.AccountID, UserID = args.ID, FirstLogin = DateTime.UtcNow
                                    };
                                    db.AccountUserIDS.InsertOnSubmit(entry);
                                }
                                entry.LoginCount++;
                                entry.LastLogin = DateTime.UtcNow;
                            }

                            Account accAnteep  = db.Accounts.FirstOrDefault(x => x.AccountID == 4490);
                            bool isAnteepSmurf = accAnteep.AccountUserIDS.Any(x => x.UserID == args.ID);
                            if (isAnteepSmurf)
                            {
                                client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (ID match {1}) {2}", args.Name, args.ID,
                                                                                                       acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false);
                            }

                            if (args.ID != 0 && args.ID < 1000)
                            {
                                client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (too short userID {1}) {2}", args.Name, args.ID,
                                                                                                       acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false);
                            }

                            db.SubmitChanges();
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Error getting user ID: {0}", ex);
                    }
                });
            };

            this.client.UserIPRecieved += (sender, args) =>
            {
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        Account acc = null;
                        using (var db = new ZkDataContext())
                        {
                            acc = Account.AccountByName(db, args.Name);

                            var penalty = Punishment.GetActivePunishment(acc != null ? acc.AccountID : 0, args.IP, null, x => x.BanLobby, db);
                            if (penalty != null)
                            {
                                client.AdminKickFromLobby(args.Name,
                                                          string.Format("Banned until {0} (IP match to {1}), reason: {2}", penalty.BanExpires, penalty.AccountByAccountID.Name, penalty.Reason));
                            }
                            if (acc != null)
                            {
                                var entry = acc.AccountIPS.FirstOrDefault(x => x.IP == args.IP);
                                if (entry == null)
                                {
                                    entry = new AccountIP {
                                        AccountID = acc.AccountID, IP = args.IP, FirstLogin = DateTime.UtcNow
                                    };
                                    db.AccountIPS.InsertOnSubmit(entry);
                                }
                                entry.LoginCount++;
                                entry.LastLogin = DateTime.UtcNow;
                            }
                            db.SubmitChanges();
                        }

                        try
                        {
                            if (acc == null || !acc.HasVpnException)
                            {
                                if (GlobalConst.VpnCheckEnabled)
                                {
                                    // check user IP against http://dnsbl.tornevall.org
                                    // does not catch all smurfs
                                    // mostly false positives, do not use
                                    var reversedIP = string.Join(".", args.IP.Split('.').Reverse().ToArray());
                                    try
                                    {
                                        var resolved = Dns.GetHostEntry(string.Format("{0}.dnsbl.tornevall.org", reversedIP)).AddressList;
                                        if (resolved.Length > 0)
                                        {
                                            client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("User {0} {3} has IP {1} on dnsbl.tornevall.org ({2} result/s)",
                                                                                                                   args.Name, args.IP, resolved.Length, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false);
                                            //client.AdminKickFromLobby(args.Name,
                                            //                      "Connection using proxy or VPN is not allowed! (You can ask for exception). See http://dnsbl.tornevall.org/removal.php to get your IP removed from the blacklist.");
                                        }
                                    }
                                    catch (System.Net.Sockets.SocketException sockEx)
                                    {
                                        // not in database, do nothing
                                    }
                                }
                                using (var db = new ZkDataContext())
                                {
                                    Account accAnteep  = db.Accounts.FirstOrDefault(x => x.AccountID == 4490);
                                    bool isAnteepSmurf = accAnteep.AccountIPS.Any(x => x.IP == args.IP);
                                    if (isAnteepSmurf)
                                    {
                                        client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (IP match {1}) {2}", args.Name, args.IP,
                                                                                                               acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false);
                                    }
                                }

                                using (ZkDataContext db = new ZkDataContext())
                                {
                                    for (int i = 0; i <= 1; i++)
                                    {
                                        var whois = new Whois();
                                        var data  = whois.QueryByIp(args.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";
                                        }

                                        var blockedCompanies = db.BlockedCompanies.Select(x => x.CompanyName.ToLower()).ToList();
                                        var blockedHosts     = db.BlockedHosts.Select(x => x.HostName).ToList();

                                        /*if (acc.Country == "MY")
                                         * {
                                         *  client.Say(TasClient.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);
                                         * }*/
                                        if (blockedHosts.Any(x => data["abuse-mailbox"].Contains(x)) || (blockedHosts.Any(x => data["notify"].Contains(x))))
                                        {
                                            client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)");
                                        }
                                        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))
                                            {
                                                client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)");
                                                break;
                                            }
                                        }

                                        var hostname = Dns.GetHostEntry(args.IP).HostName;
                                        if (blockedHosts.Any(hostname.Contains))
                                        {
                                            client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)");
                                        }
                                    }
                                }
                            }
                        }
                        catch (System.Net.Sockets.SocketException sockEx)
                        {
                            // do nothing
                        }
                        catch (Exception ex)
                        {
                            Trace.TraceError("VPN check error: {0}", ex);
                            client.Say(TasClient.SayPlace.Channel, ModeratorChannel, ex.ToString(), false);
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Error getting user IP: {0}", ex);
                        //client.Say(TasClient.SayPlace.User, "KingRaptor", ex.ToString(), false);
                    }
                });
            };

            this.client.UserStatusChanged += (s, e) =>
            {
                var user = client.ExistingUsers[e.ServerParams[0]];
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        using (var db = new ZkDataContext()) UpdateUser(user.LobbyID, user.Name, user, null, db);
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError(ex.ToString());
                    }
                },
                                      TaskCreationOptions.LongRunning);
            };

            this.client.BattleUserJoined += (s, e) =>
            {
                var battle  = client.ExistingBattles[e.BattleID];
                var founder = battle.Founder;
                if (founder.IsSpringieManaged)
                {
                    try
                    {
                        var user = client.ExistingUsers[e.UserName];

                        /*  obsolete; all major lobbies have multiengine support
                         * if (!user.IsZkLobbyUser && !user.IsNotaLobby && battle.EngineVersion != client.ServerSpringVersion &&
                         *  battle.EngineVersion != client.ServerSpringVersion + ".0") {
                         *  client.Say(TasClient.SayPlace.User,
                         *             user.Name,
                         *             string.Format(
                         *                 "ALERT! YOU WILL DESYNC!! You NEED SPRING ENGINE {0} to play here. Simply join the game with Zero-K lobby ( http://zero-k.info/Wiki/Download ) OR get the engine from http://springrts.com/dl/buildbot/default/ OR build it on your Linux: http://springrts.com/wiki/Building_Spring_on_Linux ",
                         *                 battle.EngineVersion),
                         *             false);
                         * }
                         */
                        using (var db = new ZkDataContext())
                        {
                            var acc   = Account.AccountByLobbyID(db, user.LobbyID);
                            var name  = founder.Name.TrimNumbers();
                            var aconf = db.AutohostConfigs.FirstOrDefault(x => x.Login == name);
                            if (acc != null && user != null && aconf != null &&
                                (acc.LastLobbyVersionCheck == null || DateTime.UtcNow.Subtract(acc.LastLobbyVersionCheck.Value).TotalDays > 3) &&
                                aconf.AutohostMode != 0)
                            {
                                client.RequestLobbyVersion(user.Name);
                            }

                            /*
                             * if (acc != null)
                             * {
                             *  int numIDs = acc.AccountUserIDS != null ? acc.AccountUserIDS.Count : 0;
                             *  if (numIDs == 0) client.Say(TasClient.SayPlace.User, "KingRaptor", string.Format("USER {0} joined battle {1}; has {2} userIDs; lobby version {3}", acc.Name, founder.Name, numIDs, acc.LobbyVersion), false);
                             * }
                             * else
                             *  client.Say(TasClient.SayPlace.User, "KingRaptor", string.Format("USER {0} joined battle {1}", e.UserName + " (NO ACCOUNT)", founder.Name), false);
                             *
                             * if (acc != null)
                             * {
                             *  if (!acc.AccountUserIDS.Any())
                             *  {
                             *      string reason = string.Format("Sorry you are using unsupported lobby ({0}), please upgrade or use Zero-K Lobby, Weblobby or SpringLobby", acc.LobbyVersion);
                             *      client.Say(TasClient.SayPlace.User, user.Name, reason, false);
                             *      client.Say(TasClient.SayPlace.User, founder.Name, string.Format("!kick {0} {1}", acc.LobbyVersion, reason), false);
                             *  }
                             * }*/
                        }
                    }
                    catch (Exception ex)
                    {
                        //client.Say(TasClient.SayPlace.User, "KingRaptor", ex.ToString(), false);
                        Trace.TraceError("Error procesisng battle user joined: {0}", ex);
                    }
                }
            };

            this.client.TestLoginDenied += (s, e) =>
            {
                RequestInfo entry;
                if (requests.TryGetValue(client.MessageID, out entry))
                {
                    entry.WaitHandle.Set();
                }
                requests.TryRemove(client.MessageID, out entry);
            };

            this.client.UserLobbyVersionRecieved += (s, e) =>
            {
                using (var db = new ZkDataContext())
                {
                    var acc = Account.AccountByName(db, e.Name);
                    if (acc != null)
                    {
                        acc.LobbyVersion          = e.LobbyVersion;
                        acc.LastLobbyVersionCheck = DateTime.UtcNow;
                        db.SubmitAndMergeChanges();
                        if (!acc.LobbyVersion.StartsWith("ZK"))
                        {
                            // FIXME abma broke this (LobbyVersion is now some huge-ass integer instead)
                            //client.Say(TasClient.SayPlace.User,
                            //           e.Name,
                            //           string.Format(
                            //               "WARNING: You are connected using {0} which is not fully compatible with this host. Please use Zero-K lobby. Download it from http://zero-k.info   NOTE: to play all Spring games with Zero-K lobby, untick \"Official games\" on its multiplayer tab. Thank you!",
                            //               e.LobbyVersion),
                            //           false);
                        }
                    }
                }
            };

            this.client.BattleFound +=
                (s, e) => { if (e.Data.Founder.IsZkLobbyUser && !e.Data.Founder.IsBot)
                            {
                                client.SetBotMode(e.Data.Founder.Name, true);
                            }
            };

            this.client.ChannelUserAdded += (sender, args) =>
            {
                try
                {
                    var channel = args.ServerParams[0];
                    var user    = args.ServerParams[1];
                    if (channel == ModeratorChannel)
                    {
                        var u = client.ExistingUsers[user];
                        if (u.SpringieLevel <= 2 && !u.IsZeroKAdmin)
                        {
                            client.ForceLeaveChannel(user, ModeratorChannel);
                        }
                    }
                    else if (channel == Top20Channel)
                    {
                        var u = client.ExistingUsers[user];
                        if (!topPlayers.IsTop20(u.LobbyID) && u.Name != client.UserName)
                        {
                            client.ForceLeaveChannel(user, Top20Channel);
                        }
                    }
                    else
                    {
                        using (var db = new ZkDataContext())
                        {
                            var fac = db.Factions.FirstOrDefault(x => x.Shortcut == channel);
                            if (fac != null)
                            {
                                // faction channel
                                var u   = client.ExistingUsers[user];
                                var acc = Account.AccountByLobbyID(db, u.LobbyID);
                                if (acc == null || acc.FactionID != fac.FactionID || acc.Level < GlobalConst.FactionChannelMinLevel)
                                {
                                    client.ForceLeaveChannel(user, channel);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Error procesisng channel user added: {0}", ex);
                }
            };
            this.client.ChannelUserRemoved += (sender, args) =>
            {
                try
                {
                    var channel = args.ServerParams[0];
                    var user    = args.ServerParams[1];
                    if (channel == ModeratorChannel)
                    {
                        var u = client.ExistingUsers[user];
                        if (u.SpringieLevel > 2 || u.IsZeroKAdmin)
                        {
                            client.ForceJoinChannel(user, ModeratorChannel);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Error procesisng channel user added: {0}", ex);
                }
            };
        }
        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);
                if (acc.Country == null || String.IsNullOrEmpty(acc.Country)) acc.Country = "unknown";
                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};
            }
        }