public void HandleHandshakeRequest(ClientStructure client, HandshakeRequestMsgData data) { var valid = CheckServerFull(client); valid &= valid && CheckUsernameLength(client, data.PlayerName); valid &= valid && CheckUsernameCharacters(client, data.PlayerName); valid &= valid && CheckPlayerIsAlreadyConnected(client, data.PlayerName); valid &= valid && CheckUsernameIsReserved(client, data.PlayerName); valid &= valid && CheckPlayerIsBanned(client, data.UniqueIdentifier); if (!valid) { LunaLog.Normal($"Client {data.PlayerName} ({data.UniqueIdentifier}) failed to handshake: {Reason}. Disconnecting"); client.DisconnectClient = true; ClientConnectionHandler.DisconnectClient(client, Reason); } else { client.PlayerName = data.PlayerName; client.UniqueIdentifier = data.UniqueIdentifier; client.Authenticated = true; LmpPluginHandler.FireOnClientAuthenticated(client); LunaLog.Normal($"Client {data.PlayerName} ({data.UniqueIdentifier}) handshake successfully, Version: {data.MajorVersion}.{data.MinorVersion}.{data.BuildVersion}"); HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.HandshookSuccessfully, "success"); var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <PlayerConnectionJoinMsgData>(); msgData.PlayerName = client.PlayerName; MessageQueuer.RelayMessage <PlayerConnectionSrvMsg>(client, msgData); LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ClientRetriever.GetClients().Length}"); } }
private bool CheckUsernameIsReserved(ClientStructure client, string playerName) { if (playerName == "Initial" || playerName == GeneralSettings.SettingsStore.ConsoleIdentifier) { Reason = "Using reserved name"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.InvalidPlayername, Reason); return(false); } return(true); }
private bool CheckPlayerIsBanned(ClientStructure client, string uniqueId) { if (BanPlayerCommand.GetBannedPlayers().Contains(uniqueId)) { Reason = "Banned"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.PlayerBanned, Reason); return(false); } return(true); }
private bool CheckServerFull(ClientStructure client) { if (ClientRetriever.GetActiveClientCount() >= GeneralSettings.SettingsStore.MaxPlayers) { Reason = "Server full"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.ServerFull, Reason); return(false); } return(true); }
private bool CheckWhitelist(ClientStructure client, string playerName) { if (GeneralSettings.SettingsStore.Whitelisted && !WhitelistCommands.Retrieve().Contains(playerName)) { Reason = "Not on whitelist"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.NotWhitelisted, Reason); return(false); } return(true); }
private bool CheckUsernameLength(ClientStructure client, string username) { if (username.Length > GeneralSettings.SettingsStore.MaxUsernameLength) { Reason = $"Username too long. Max chars: {GeneralSettings.SettingsStore.MaxUsernameLength}"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.ServerFull, Reason); return(false); } return(true); }
private bool CheckUsernameCharacters(ClientStructure client, string playerName) { var regex = new Regex(@"^[-_a-zA-Z0-9]+$"); // Regex to only allow alphanumeric, dashes and underscore if (!regex.IsMatch(playerName)) { Reason = "Invalid username characters (only A-Z, a-z, numbers, - and _)"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.InvalidPlayername, Reason); return(false); } return(true); }
private bool CheckPlayerIsAlreadyConnected(ClientStructure client, string playerName) { var existingClient = ClientRetriever.GetClientByName(playerName); if (existingClient != null) { Reason = "Username already taken"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.InvalidPlayername, Reason); return(false); } return(true); }
private bool CheckPlayerIsBanned(ClientStructure client, string playerName, string ipAddress, string publicKey) { if (BanCommands.RetrieveBannedUsernames().Contains(playerName) || BanCommands.RetrieveBannedIps().Contains(ipAddress) || BanCommands.RetrieveBannedKeys().Contains(publicKey)) { Reason = "Banned"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.PlayerBanned, Reason); return(false); } return(true); }
private bool CheckUsernameLength(ClientStructure client, string username) { if (username.Length > GeneralSettings.SettingsStore.MaxUsernameLength) { Reason = $"Username too long. Max chars: {GeneralSettings.SettingsStore.MaxUsernameLength}"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.InvalidPlayername, Reason); return(false); } if (username.Length <= 0) { Reason = "Username too short. Min chars: 1"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.InvalidPlayername, Reason); return(false); } return(true); }
private bool CheckKey(ClientStructure client, string playerName, string playerPublicKey, byte[] playerChallangeSignature) { //Check the client matches any database entry var storedPlayerFile = Path.Combine(ServerContext.UniverseDirectory, "Players", $"{playerName}.txt"); if (FileHandler.FileExists(storedPlayerFile)) { var storedPlayerPublicKey = FileHandler.ReadFileText(storedPlayerFile); if (playerPublicKey != storedPlayerPublicKey) { Reason = "Invalid key. Username was already taken and used in the past"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.InvalidKey, Reason); return(false); } using (var rsa = new RSACryptoServiceProvider(1024)) { rsa.PersistKeyInCsp = false; rsa.FromXmlString(playerPublicKey); var result = rsa.VerifyData(client.Challenge, CryptoConfig.CreateFromName("SHA256"), playerChallangeSignature); if (!result) { Reason = "Public/priv key mismatch"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.InvalidKey, Reason); return(false); } } } else { try { FileHandler.WriteToFile(storedPlayerFile, playerPublicKey); LunaLog.Debug($"Client {playerName} registered!"); } catch { Reason = "Invalid username"; HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.InvalidPlayername, Reason); return(false); } } return(true); }
public void HandleHandshakeResponse(ClientStructure client, HandshakeResponseMsgData data) { var valid = CheckServerFull(client); valid &= valid && CheckUsernameLength(client, data.PlayerName); valid &= valid && CheckUsernameCharacters(client, data.PlayerName); valid &= valid && CheckWhitelist(client, data.PlayerName); valid &= valid && CheckPlayerIsAlreadyConnected(client, data.PlayerName); valid &= valid && CheckUsernameIsReserved(client, data.PlayerName); valid &= valid && CheckPlayerIsBanned(client, data.PlayerName, client.Endpoint.Address.ToString(), data.PublicKey); valid &= valid && CheckKey(client, data.PlayerName, data.PublicKey, data.ChallengeSignature); if (!valid) { LunaLog.Normal($"Client {data.PlayerName} failed to handshake: {Reason}. Disconnecting"); client.DisconnectClient = true; ClientConnectionHandler.DisconnectClient(client, Reason); } else { client.PlayerName = data.PlayerName; client.PublicKey = data.PublicKey; client.Id = Guid.NewGuid(); client.Authenticated = true; LmpPluginHandler.FireOnClientAuthenticated(client); LunaLog.Normal($"Client {data.PlayerName} handshook successfully, Version: {data.MajorVersion}.{data.MinorVersion}.{data.BuildVersion}"); HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.HandshookSuccessfully, "success"); var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <PlayerConnectionJoinMsgData>(); msgData.PlayerName = client.PlayerName; MessageQueuer.RelayMessage <PlayerConnectionSrvMsg>(client, msgData); LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ClientRetriever.GetClients().Length}"); } }