private string AppendOperation(NetworkStream dataStream, string pathname) { long bytes = 0; using (FileStream fs = new FileStream(pathname, FileMode.Append, FileAccess.Write, FileShare.None, 4096, FileOptions.SequentialScan)) { bytes = CopyStream(dataStream, fs); } LogEntry logEntry = new LogEntry { Date = DateTime.Now, CIP = _clientIP, CSMethod = "APPE", CSUsername = _username, SCStatus = "226", CSBytes = bytes.ToString() }; _log.Info(logEntry); return "226 Closing data connection, file transfer successful"; }
private string ListOperation(NetworkStream dataStream, string pathname) { StreamWriter dataWriter = new StreamWriter(dataStream, Encoding.ASCII); IEnumerable<string> directories = Directory.EnumerateDirectories(pathname); foreach (string dir in directories) { DirectoryInfo d = new DirectoryInfo(dir); string date = d.LastWriteTime < DateTime.Now - TimeSpan.FromDays(180) ? d.LastWriteTime.ToString("MMM dd yyyy") : d.LastWriteTime.ToString("MMM dd HH:mm"); string line = string.Format("drwxr-xr-x 2 2003 2003 {0,8} {1} {2}", "4096", date, d.Name); dataWriter.WriteLine(line); dataWriter.Flush(); } IEnumerable<string> files = Directory.EnumerateFiles(pathname); foreach (string file in files) { FileInfo f = new FileInfo(file); string date = f.LastWriteTime < DateTime.Now - TimeSpan.FromDays(180) ? f.LastWriteTime.ToString("MMM dd yyyy") : f.LastWriteTime.ToString("MMM dd HH:mm"); string line = string.Format("-rw-r--r-- 2 2003 2003 {0,8} {1} {2}", f.Length, date, f.Name); dataWriter.WriteLine(line); dataWriter.Flush(); } LogEntry logEntry = new LogEntry { Date = DateTime.Now, CIP = _clientIP, CSMethod = "LIST", CSUsername = _username, SCStatus = "226" }; _log.Info(logEntry); return "226 Transfer complete"; }
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 string[] { "AUTH", "USER", "PASS", "QUIT", "HELP", "NOOP" }); string line; _dataClient = new TcpClient(); string renameFrom = null; try { while ((line = _controlReader.ReadLine()) != null) { string response = null; string[] command = line.Split(' '); string cmd = command[0].ToUpperInvariant(); string arguments = command.Length > 1 ? line.Substring(command[0].Length + 1) : null; if (arguments != null && arguments.Trim().Length == 0) { arguments = null; } LogEntry 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(); break; case "PASV": response = Passive(); logEntry.SPort = ((IPEndPoint)_passiveListener.LocalEndpoint).Port.ToString(); 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(); 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; } else { _controlWriter.WriteLine(response); _controlWriter.Flush(); if (response.StartsWith("221")) { break; } if (cmd == "AUTH") { _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(); }