Beispiel #1
0
        private void HandleConnection(System.Net.Sockets.Socket s)
        {
            User currentuser = null;

            try
            {
                s.ReceiveTimeout = 0;
                s.SendTimeout    = 0;
                s.NoDelay        = true;
                string ipr = s.RemoteEndPoint.ToString().Split(':')[0];

                NetworkStream stream = new NetworkStream(s);
                SslStream     ssl    = new SslStream(stream, false);

                ssl.AuthenticateAsServer(Certificate, false, SslProtocols.Tls12 | SslProtocols.Tls13, true);
                while (s.Connected)
                {
                    if (!ssl.CanRead && !stream.DataAvailable)
                    {
                        Thread.Sleep(100);
                        continue;
                    }

                    byte[] leng = new byte[4];
                    int    k2   = 0;
                    try
                    {
                        k2 = ssl.Read(leng, 0, leng.Length);
                    }
                    catch (Exception ex)
                    {
                        if (ex.ToString()
                            .Contains("An established connection was aborted by the software in your host machine"))
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        if (ex.ToString().Contains("System.NullReferenceException"))
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        Logger.Log("[Communication Error] General error. " + ipr + " " + ex);
                    }

                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(leng);
                    }

                    int upcominglength = (BitConverter.ToInt32(leng, 0));
                    if (upcominglength > 15000000 || upcominglength <= 0)
                    {
                        ssl.Flush();
                        s.Close();
                        return;
                    }

                    byte[] b = ByteReader(upcominglength, ssl, s);
                    if (b == null || k2 == 0)
                    {
                        ssl.Flush();
                        s.Close();
                        return;
                    }

                    b = LZ4Compresser.Decompress(b);

                    string message = Encoding.UTF8.GetString(b, 0, b.Length);
                    if (string.IsNullOrEmpty(message) || !message.Contains(Constants.MainSeparator))
                    {
                        ssl.Flush();
                        s.Close();
                        return;
                    }

                    string[] split = message.Split(Constants.MainSeparator);
                    if (split.Length != 2 || string.IsNullOrEmpty(split[1]) || string.IsNullOrEmpty(split[0]))
                    {
                        s.Close();
                        return;
                    }

                    Codes code = Codes.Unknown;
                    int   intp = -1;
                    bool  bbbb = int.TryParse(split[0], out intp);
                    if (!bbbb || intp == -1)
                    {
                        s.Close();
                        return;
                    }

                    if (!Enum.IsDefined(typeof(Codes), intp))
                    {
                        s.Close();
                        return;
                    }

                    code = (Codes)intp;

                    string[] otherdata = split[1].Split(Constants.AssistantSeparator);
                    string   bmsg      = "";
                    switch (code)
                    {
                    case Codes.Login:
                    {
                        try
                        {
                            if (otherdata.Length != 3)
                            {
                                if (s.Connected)
                                {
                                    s.Close();
                                }

                                return;
                            }

                            string name     = otherdata[0].Substring(0, Math.Min(otherdata[0].Length, 50));
                            string password = otherdata[1].Substring(0, Math.Min(otherdata[1].Length, 50));
                            string version  = otherdata[2].Substring(0, Math.Min(otherdata[2].Length, 10));

                            if (string.IsNullOrEmpty(name) ||
                                string.IsNullOrEmpty(password) ||
                                string.IsNullOrEmpty(version))
                            {
                                if (s.Connected)
                                {
                                    s.Close();
                                }

                                return;
                            }

                            bmsg = MessageConnector.FormMessage(Codes.Login, "InvalidNameOrPassword");

                            currentuser = PermissionLoader.GetUser(name);
                            if (currentuser != null && !currentuser.IsLoggedIn &&
                                currentuser.PasswordCheck(password) && version == Program.Version)
                            {
                                currentuser.Token      = TokenHandler.AddNewToken(currentuser.UserName);
                                currentuser.IsLoggedIn = true;
                                // TODO: Only send authorized servers.
                                bmsg = (int)Codes.Login + Constants.MainSeparator + "Success" + Constants.AssistantSeparator + currentuser.Token + Constants.AssistantSeparator +
                                       string.Join(Constants.AssistantSeparator, SquadServerLoader.AllServers.Keys);
                                Logger.Log("[TCPServer] Authentication from " + ipr + " Name: " + name);
                            }
                            else
                            {
                                Logger.Log("[TCPServer] Authentication failure from " + ipr + " Name: " + name);
                            }

                            if (s.Connected)
                            {
                                byte[] messagebyte = asen.GetBytes(bmsg);
                                byte[] intBytes    = BitConverter.GetBytes(messagebyte.Length);
                                if (BitConverter.IsLittleEndian)
                                {
                                    Array.Reverse(intBytes);
                                }
                                ssl.Write(intBytes);
                                ssl.Write(messagebyte);
                                if (bmsg.Contains("InvalidNameOrPassword"))
                                {
                                    s.Close();
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.LogError("[Authentication] Error: " + ex);
                        }

                        break;
                    }

                    case Codes.RequestPlayers:
                    {
                        if (otherdata.Length != 2)
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        string token      = otherdata[0].Substring(0, Math.Min(otherdata[0].Length, 50));
                        string servername = otherdata[1].Substring(0, Math.Min(otherdata[1].Length, 50));

                        if (string.IsNullOrEmpty(token) ||
                            string.IsNullOrEmpty(servername))
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        if (currentuser != null)
                        {
                            // If token is no longer valid, or doesn't equal with the current one something is wrong.
                            if (currentuser.Token != token || !TokenHandler.HasValidToken(currentuser.UserName) || !currentuser.IsLoggedIn)
                            {
                                if (s.Connected)
                                {
                                    s.Close();
                                }
                                return;
                            }

                            bmsg = MessageConnector.FormMessage(Codes.RequestPlayers, "Unknown");
                            if (ValidServers.ContainsKey(servername))
                            {
                                string response = ValidServers[servername].GetPlayerList();
                                try
                                {
                                    PlayerListProcesser x      = new PlayerListProcesser(response);
                                    string players             = JsonParser.Serialize(x.Players);
                                    string disconnectedplayers = JsonParser.Serialize(x.DisconnectedPlayers);
                                    bmsg = MessageConnector.FormMessage(Codes.RequestPlayers, players,
                                                                        disconnectedplayers);
                                }
                                catch (InvalidSquadPlayerListException ex)
                                {
                                    Logger.LogError("[PlayerListRequest Error] " + ex.Message);
                                }
                            }

                            if (s.Connected)
                            {
                                byte[] messagebyte = asen.GetBytes(bmsg);
                                byte[] intBytes    = BitConverter.GetBytes(messagebyte.Length);
                                if (BitConverter.IsLittleEndian)
                                {
                                    Array.Reverse(intBytes);
                                }
                                ssl.Write(intBytes);
                                ssl.Write(messagebyte);
                            }
                        }
                        else
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        break;
                    }

                    case Codes.Disconnect:
                    {
                        if (otherdata.Length != 1)
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        string token = otherdata[0].Substring(0, Math.Min(otherdata[0].Length, 50));

                        if (string.IsNullOrEmpty(token))
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        if (currentuser != null)
                        {
                            // If token is no longer valid, or doesn't equal with the current one something is wrong.
                            if (currentuser.Token != token || !TokenHandler.HasValidToken(currentuser.UserName) || !currentuser.IsLoggedIn)
                            {
                                if (s.Connected)
                                {
                                    s.Close();
                                }
                                return;
                            }

                            if (currentuser.Token != null)
                            {
                                TokenHandler.RemoveToken(currentuser.Token);
                            }

                            currentuser.IsLoggedIn = false;
                            currentuser.Token      = null;

                            bmsg = (int)Codes.RequestPlayers + Constants.MainSeparator + "Ok";

                            if (s.Connected)
                            {
                                byte[] messagebyte = asen.GetBytes(bmsg);
                                byte[] intBytes    = BitConverter.GetBytes(messagebyte.Length);
                                if (BitConverter.IsLittleEndian)
                                {
                                    Array.Reverse(intBytes);
                                }
                                ssl.Write(intBytes);
                                ssl.Write(messagebyte);
                                s.Close();
                            }
                        }
                        else
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        break;
                    }
                    }
                }
            }
            catch (Exception ex)
            {
                if (ex is ObjectDisposedException)
                {
                    return;
                }

                Logger.LogError("[HandleConnection] General Error: " + ex);
            }
            finally
            {
                if (currentuser != null)
                {
                    if (currentuser.Token != null)
                    {
                        TokenHandler.RemoveToken(currentuser.Token);
                    }

                    currentuser.IsLoggedIn = false;
                    currentuser.Token      = null;
                }
            }
        }