Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,6 @@ httpjail --config rules.txt -- ./my-application
### Advanced Options

```bash
# Dry run - log what would be blocked without blocking
httpjail --dry-run --config rules.txt -- ./app

# Verbose logging
httpjail -vvv -r "allow: .*" -- curl https://example.com

Expand Down
24 changes: 3 additions & 21 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ struct Args {
#[arg(short = 'c', long = "config", value_name = "FILE")]
config: Option<String>,

/// Log actions without blocking
#[arg(long = "dry-run")]
dry_run: bool,

/// Monitor without filtering
#[arg(long = "log-only")]
log_only: bool,
Expand Down Expand Up @@ -304,7 +300,7 @@ async fn main() -> Result<()> {

// Build rules from command line arguments
let rules = build_rules(&args)?;
let rule_engine = RuleEngine::new(rules, args.dry_run, args.log_only);
let rule_engine = RuleEngine::new(rules, args.log_only);

// Get ports from env vars (optional)
let http_port = std::env::var("HTTPJAIL_HTTP_BIND")
Expand Down Expand Up @@ -461,7 +457,7 @@ mod tests {
Rule::new(Action::Deny, r".*").unwrap(),
];

let engine = RuleEngine::new(rules, false, false);
let engine = RuleEngine::new(rules, false);

// Test allow rule
assert!(matches!(
Expand All @@ -482,24 +478,11 @@ mod tests {
));
}

#[test]
fn test_dry_run_mode() {
let rules = vec![Rule::new(Action::Deny, r".*").unwrap()];

let engine = RuleEngine::new(rules, true, false);

// In dry-run mode, everything should be allowed
assert!(matches!(
engine.evaluate(Method::GET, "https://example.com"),
Action::Allow
));
}

#[test]
fn test_log_only_mode() {
let rules = vec![Rule::new(Action::Deny, r".*").unwrap()];

let engine = RuleEngine::new(rules, false, true);
let engine = RuleEngine::new(rules, true);

// In log-only mode, everything should be allowed
assert!(matches!(
Expand All @@ -523,7 +506,6 @@ mod tests {
let args = Args {
rules: vec![],
config: Some(file.path().to_str().unwrap().to_string()),
dry_run: false,
log_only: false,
interactive: false,
weak: false,
Expand Down
4 changes: 2 additions & 2 deletions src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ mod tests {
Rule::new(Action::Deny, r".*").unwrap(),
];

let rule_engine = RuleEngine::new(rules, false, false);
let rule_engine = RuleEngine::new(rules, false);
let proxy = ProxyServer::new(Some(8080), Some(8443), rule_engine, None);

assert_eq!(proxy.http_port, Some(8080));
Expand All @@ -469,7 +469,7 @@ mod tests {
async fn test_proxy_server_auto_port() {
let rules = vec![Rule::new(Action::Allow, r".*").unwrap()];

let rule_engine = RuleEngine::new(rules, false, false);
let rule_engine = RuleEngine::new(rules, false);
let mut proxy = ProxyServer::new(None, None, rule_engine, None);

let (http_port, https_port) = proxy.start().await.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion src/proxy_tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ mod tests {
Rule::new(Action::Deny, r".*").unwrap(),
]
};
Arc::new(RuleEngine::new(rules, false, false))
Arc::new(RuleEngine::new(rules, false))
}

/// Create a TLS client config that trusts any certificate (for testing)
Expand Down
42 changes: 8 additions & 34 deletions src/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,12 @@ impl Rule {
#[derive(Clone)]
pub struct RuleEngine {
pub rules: Vec<Rule>,
pub dry_run: bool,
pub log_only: bool,
}

impl RuleEngine {
pub fn new(rules: Vec<Rule>, dry_run: bool, log_only: bool) -> Self {
RuleEngine {
rules,
dry_run,
log_only,
}
pub fn new(rules: Vec<Rule>, log_only: bool) -> Self {
RuleEngine { rules, log_only }
}

pub fn evaluate(&self, method: Method, url: &str) -> Action {
Expand All @@ -77,9 +72,7 @@ impl RuleEngine {
url,
rule.pattern.as_str()
);
if !self.dry_run {
return Action::Allow;
}
return Action::Allow;
}
Action::Deny => {
warn!(
Expand All @@ -88,21 +81,15 @@ impl RuleEngine {
url,
rule.pattern.as_str()
);
if !self.dry_run {
return Action::Deny;
}
return Action::Deny;
}
}
}
}

// Default deny if no rules match
warn!("DENY: {} {} (no matching rules)", method, url);
if self.dry_run {
Action::Allow
} else {
Action::Deny
}
Action::Deny
}
}

Expand Down Expand Up @@ -138,7 +125,7 @@ mod tests {
Rule::new(Action::Deny, r".*").unwrap(),
];

let engine = RuleEngine::new(rules, false, false);
let engine = RuleEngine::new(rules, false);

// Test allow rule
assert!(matches!(
Expand Down Expand Up @@ -168,7 +155,7 @@ mod tests {
Rule::new(Action::Deny, r".*").unwrap(),
];

let engine = RuleEngine::new(rules, false, false);
let engine = RuleEngine::new(rules, false);

// GET should be allowed
assert!(matches!(
Expand All @@ -183,24 +170,11 @@ mod tests {
));
}

#[test]
fn test_dry_run_mode() {
let rules = vec![Rule::new(Action::Deny, r".*").unwrap()];

let engine = RuleEngine::new(rules, true, false);

// In dry-run mode, everything should be allowed
assert!(matches!(
engine.evaluate(Method::GET, "https://example.com"),
Action::Allow
));
}

#[test]
fn test_log_only_mode() {
let rules = vec![Rule::new(Action::Deny, r".*").unwrap()];

let engine = RuleEngine::new(rules, false, true);
let engine = RuleEngine::new(rules, true);

// In log-only mode, everything should be allowed
assert!(matches!(
Expand Down
6 changes: 0 additions & 6 deletions tests/platform_test_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ macro_rules! platform_tests {
system_integration::test_jail_log_only_mode::<$platform>();
}

#[test]
#[::serial_test::serial]
fn test_jail_dry_run_mode() {
system_integration::test_jail_dry_run_mode::<$platform>();
}

#[test]
#[::serial_test::serial]
fn test_jail_requires_command() {
Expand Down
28 changes: 0 additions & 28 deletions tests/system_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,34 +224,6 @@ pub fn test_jail_log_only_mode<P: JailTestPlatform>() {
);
}

/// Test dry-run mode
pub fn test_jail_dry_run_mode<P: JailTestPlatform>() {
P::require_privileges();

let mut cmd = httpjail_cmd();
cmd.arg("--dry-run")
.arg("-r")
.arg("deny: .*") // Deny everything
.arg("--");
curl_http_status_args(&mut cmd, "http://ifconfig.me");

let output = cmd.output().expect("Failed to execute httpjail");

let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.is_empty() {
eprintln!("[{}] stderr: {}", P::platform_name(), stderr);
}

// In dry-run mode, even deny rules should not block
assert_eq!(
stdout.trim(),
"200",
"Request should be allowed in dry-run mode"
);
assert!(output.status.success());
}

/// Test that jail requires a command
pub fn test_jail_requires_command<P: JailTestPlatform>() {
// This test doesn't require root
Expand Down