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; } } }