bool GetDirectoryEntries(out FtpDirectoryEntry[] entries) { if (currentFileSystemDirectory == null) { List <FtpDirectoryEntry> result = new List <FtpDirectoryEntry>(); foreach (KeyValuePair <string, string> root in Server.RootFolders) { result.Add(new FtpDirectoryEntry() { Name = root.Key, Type = FtpDirectoryEntryType.Directory, }); } entries = result.ToArray(); return(true); } FtpDirectoryEntry.GetEntries(currentFileSystemDirectory, utf8, out entries); FtpAccessEventArgs e = new FtpAccessEventArgs(this, FtpAccessType.ListDirectory, ".", currentFtpFolder, currentFileSystemDirectory, entries); Server.OnCheckAccess(e); if (e.Denied) { SendAnswer("550 Requested action not taken. Access denied."); entries = null; return(false); } entries = e.Entries; return(true); }
bool CheckAccess(FtpAccessType accessType, string ftpName) { bool allow = false; string fileSystemDir = null; if (ftpName.Contains("/")) { //absolute path if (ftpName == "/") { allow = true; } else { string[] parts = ftpName.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (Server.RootFolders.TryGetValue(parts.FirstOrDefault(), out string root)) { string ftpDir = FileSystem.Combine('/', currentFtpFolder, ftpName); if (!ftpDir.StartsWith("..")) { fileSystemDir = FileSystem.Combine(root, parts.SubRange(1).Join('/')); } } } } else { if (currentFileSystemDirectory == null) { if (Server.RootFolders.TryGetValue(ftpName, out string root)) { fileSystemDir = root; } } else { string ftpDir = FileSystem.Combine('/', currentFtpFolder, ftpName); if (ftpDir == "/") { fileSystemDir = null; allow = true; } else if (!ftpDir.StartsWith("..")) { fileSystemDir = FileSystem.Combine(currentFileSystemDirectory, ftpName); } } } if (fileSystemDir != null) { switch (accessType) { case FtpAccessType.CreateDirectory: { allow = !Directory.Exists(fileSystemDir); break; } case FtpAccessType.ChangeDirectory: case FtpAccessType.ListDirectory: case FtpAccessType.DeleteDirectory: { allow = Directory.Exists(fileSystemDir); break; } case FtpAccessType.UploadFile: { allow = true; break; } case FtpAccessType.DeleteFile: case FtpAccessType.DownloadFile: { allow = File.Exists(fileSystemDir); break; } case FtpAccessType.RenameFrom: { allow = File.Exists(fileSystemDir) || Directory.Exists(fileSystemDir); break; } case FtpAccessType.RenameTo: { allow = !File.Exists(fileSystemDir) && !Directory.Exists(fileSystemDir); break; } default: throw new NotImplementedException(); } } if (!allow) { SendAnswer("550 Requested action not taken."); return(false); } FtpAccessEventArgs e = new FtpAccessEventArgs(this, accessType, currentFileSystemDirectory, currentFtpFolder, ftpName, null); Server.OnCheckAccess(e); if (e.Denied) { SendAnswer("550 Requested action not taken. Access denied."); return(false); } return(true); }
/// <summary>Raises the <see cref="E:CheckAccess" /> event.</summary> /// <param name="e">The <see cref="FtpAccessEventArgs"/> instance containing the event data.</param> protected internal virtual void OnCheckAccess(FtpAccessEventArgs e) { CheckAccess?.Invoke(this, e); }