Skip to content

Commit 8d0b480

Browse files
committed
feat: Implement file transfer filtering infrastructure
Add a complete filtering infrastructure for SFTP and SCP file transfer operations: - TransferFilter trait with check() and check_with_dest() methods - Operation enum: Upload, Download, Delete, Rename, CreateDir, ListDir, Stat, SetStat, Symlink, ReadLink - FilterResult: Allow, Deny, Log actions - FilterPolicy engine with first-match-wins rule evaluation - Matcher trait for extensible path matching Built-in matchers: - GlobMatcher: wildcard patterns (*.key, *.pem) - RegexMatcher: full regex support - PrefixMatcher: directory tree matching (/etc/*) - ExactMatcher: specific file matching - ComponentMatcher: match path components (.git, .ssh) - ExtensionMatcher: file extension matching - CombinedMatcher: OR-combine multiple matchers - NotMatcher: invert matcher results Configuration: - Extended FilterConfig with default_action, rule names, operations, and users - FilterRule supports per-user and per-operation restrictions - YAML configuration via existing config loader Closes #138
1 parent 0862853 commit 8d0b480

6 files changed

Lines changed: 1882 additions & 1 deletion

File tree

src/server/config/types.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ pub struct FilterConfig {
275275
#[serde(default)]
276276
pub enabled: bool,
277277

278+
/// Default action when no rules match.
279+
///
280+
/// Default: allow
281+
#[serde(default)]
282+
pub default_action: Option<FilterAction>,
283+
278284
/// Filter rules to apply.
279285
///
280286
/// Rules are evaluated in order. First matching rule determines action.
@@ -285,25 +291,47 @@ pub struct FilterConfig {
285291
/// A single file transfer filter rule.
286292
#[derive(Debug, Clone, Deserialize, Serialize)]
287293
pub struct FilterRule {
294+
/// Rule name (for logging and debugging).
295+
///
296+
/// Example: "block-keys"
297+
#[serde(default)]
298+
pub name: Option<String>,
299+
288300
/// Glob pattern to match against file paths.
289301
///
290302
/// Example: "*.exe" matches all executable files
303+
#[serde(default)]
291304
pub pattern: Option<String>,
292305

293306
/// Path prefix to match.
294307
///
295308
/// Example: "/tmp/" matches all files in /tmp
309+
#[serde(default)]
296310
pub path_prefix: Option<String>,
297311

298312
/// Action to take when rule matches.
299313
pub action: FilterAction,
314+
315+
/// Operations this rule applies to.
316+
///
317+
/// If not specified, the rule applies to all operations.
318+
/// Valid values: upload, download, delete, rename, createdir, listdir
319+
#[serde(default)]
320+
pub operations: Option<Vec<String>>,
321+
322+
/// Users this rule applies to.
323+
///
324+
/// If not specified, the rule applies to all users.
325+
#[serde(default)]
326+
pub users: Option<Vec<String>>,
300327
}
301328

302329
/// Action to take when a filter rule matches.
303-
#[derive(Debug, Clone, Deserialize, Serialize)]
330+
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
304331
#[serde(rename_all = "lowercase")]
305332
pub enum FilterAction {
306333
/// Allow the file transfer.
334+
#[default]
307335
Allow,
308336

309337
/// Deny the file transfer.

0 commit comments

Comments
 (0)