public void HandleClient(object obj) { _remoteEndPoint = (IPEndPoint)_controlClient.Client.RemoteEndPoint; _clientIp = _remoteEndPoint.Address.ToString(); _controlStream = _controlClient.GetStream(); _controlReader = new StreamReader(_controlStream); _controlWriter = new StreamWriter(_controlStream); _controlWriter.WriteLine("220 Service Ready."); _controlWriter.Flush(); _validCommands.AddRange(new[] { "AUTH", "USER", "PASS", "QUIT", "HELP", "NOOP" }); _dataClient = new TcpClient(); string renameFrom = null; try { string line; while ((line = _controlReader.ReadLine()) != null) { string response = null; var command = line.Split(' '); var cmd = command[0].ToUpperInvariant(); var arguments = command.Length > 1 ? line.Substring(command[0].Length + 1) : null; if (arguments != null && arguments.Trim().Length == 0) { arguments = null; } var logEntry = new LogEntry { Date = DateTime.Now, Cip = _clientIp, CsUriStem = arguments }; if (!_validCommands.Contains(cmd)) { response = CheckUser(); } if (cmd != "RNTO") { renameFrom = null; } if (response == null) { switch (cmd) { case "USER": response = User(arguments); break; case "PASS": response = Password(arguments); logEntry.CsUriStem = "******"; break; case "CWD": response = ChangeWorkingDirectory(arguments); break; case "CDUP": response = ChangeWorkingDirectory(".."); break; case "QUIT": response = "221 Service closing control connection"; break; case "REIN": _currentUser = null; _username = null; _passiveListener = null; _dataClient = null; response = "220 Service ready for new user"; break; case "PORT": response = Port(arguments); logEntry.CPort = _dataEndpoint.Port.ToString(CultureInfo.InvariantCulture); break; case "PASV": response = Passive(); logEntry.SPort = ((IPEndPoint)_passiveListener.LocalEndpoint).Port.ToString(CultureInfo.InvariantCulture); break; case "TYPE": response = Type(command[1], command.Length == 3 ? command[2] : null); logEntry.CsUriStem = command[1]; break; case "STRU": response = Structure(arguments); break; case "MODE": response = Mode(arguments); break; case "RNFR": renameFrom = arguments; response = "350 Requested file action pending further information"; break; case "RNTO": response = Rename(renameFrom, arguments); break; case "DELE": response = Delete(arguments); break; case "RMD": response = RemoveDir(arguments); break; case "MKD": response = CreateDir(arguments); break; case "PWD": response = PrintWorkingDirectory(); break; case "RETR": response = Retrieve(arguments); logEntry.Date = DateTime.Now; break; case "STOR": response = Store(arguments); logEntry.Date = DateTime.Now; break; case "STOU": response = StoreUnique(); logEntry.Date = DateTime.Now; break; case "APPE": response = Append(arguments); logEntry.Date = DateTime.Now; break; case "LIST": response = List(arguments ?? _currentDirectory); logEntry.Date = DateTime.Now; break; case "SYST": response = "215 UNIX Type: L8"; break; case "NOOP": response = "200 OK"; break; case "ACCT": response = "200 OK"; break; case "ALLO": response = "200 OK"; break; case "NLST": response = "502 Command not implemented"; break; case "SITE": response = "502 Command not implemented"; break; case "STAT": response = "502 Command not implemented"; break; case "HELP": response = "502 Command not implemented"; break; case "SMNT": response = "502 Command not implemented"; break; case "REST": response = "502 Command not implemented"; break; case "ABOR": response = "502 Command not implemented"; break; // Extensions defined by rfc 2228 case "AUTH": response = Auth(arguments); break; // Extensions defined by rfc 2389 case "FEAT": response = FeatureList(); break; case "OPTS": response = Options(arguments); break; // Extensions defined by rfc 3659 case "MDTM": response = FileModificationTime(arguments); break; case "SIZE": response = FileSize(arguments); break; // Extensions defined by rfc 2428 case "EPRT": response = EPort(arguments); logEntry.CPort = _dataEndpoint.Port.ToString(CultureInfo.InvariantCulture); break; case "EPSV": response = EPassive(); logEntry.SPort = ((IPEndPoint)_passiveListener.LocalEndpoint).Port.ToString(); break; default: response = "502 Command not implemented"; break; } } logEntry.CsMethod = cmd; logEntry.CsUsername = _username; logEntry.ScStatus = response.Substring(0, response.IndexOf(' ')); _log.Info(logEntry); if (_controlClient == null || !_controlClient.Connected) { break; } _controlWriter.WriteLine(response); _controlWriter.Flush(); if (response.StartsWith("221")) { break; } if (cmd != "AUTH") continue; _cert = new X509Certificate("server.cer"); _sslStream = new SslStream(_controlStream); _sslStream.AuthenticateAsServer(_cert); _controlReader = new StreamReader(_sslStream); _controlWriter = new StreamWriter(_sslStream); } } catch (Exception ex) { _log.Error(ex.Message); } Dispose(); }
private string Password(string password) { _currentUser = UserStore.Validate(_username, password); if (_currentUser == null) return "530 Not logged in"; _root = _currentUser.HomeDir; _currentDirectory = _root; return "230 User logged in"; }