use super::*;
#[test]
fn an_allowed_name_on_the_local_network_is_refused() {
let h = start(None, Limits::default());
for (host, range) in [
("lan.test", "10.0.0.0/8"),
("mixed-lan.test", "192.168.0.0/16"),
("x.wild.test", "fc00::/7"),
] {
let reply = h.exchange(&format!("GET http://{host}/ HTTP/1.1\r\n\r\n"));
assert!(reply.starts_with("HTTP/1.1 403"), "{host}: {reply}");
assert!(reply.contains(range), "{host}: {reply}");
let reply = h.exchange(&format!("CONNECT {host}:443 HTTP/1.1\r\n\r\n"));
assert!(reply.starts_with("HTTP/1.1 403"), "{host}: {reply}");
}
assert!(h.nothing_forwarded());
let rows = h.rows();
assert_eq!(rows.len(), 6);
assert!(
rows.iter()
.all(|r| r.verdict == Verdict::Deny && r.rules == ["proxy-address"])
);
}
#[test]
fn an_address_of_this_machine_is_refused_like_loopback() {
let Ok(probe) = std::net::UdpSocket::bind("0.0.0.0:0") else {
return;
};
if probe.connect("192.0.2.1:9").is_err() {
return; }
let Ok(own) = probe.local_addr().map(|a| a.ip()) else {
return;
};
if own.is_loopback() || own.is_unspecified() {
return;
}
let service = TcpListener::bind((own, 0)).unwrap();
let port = service.local_addr().unwrap().port();
let yaml = format!("version: 1\nallow:\n - {{ id: own, net: [\"{own}\"] }}\n");
let address = openmoat_proxy::address_policy(&Policy::parse(&yaml).unwrap());
let ctx = EvalContext {
home: "/home/u".to_owned(),
project: None,
real_home: None,
real_project: None,
moved_dirs: Vec::new(),
cwd: "/home/u".to_owned(),
case_insensitive_paths: false,
};
let addresses = CompiledPolicy::compile(&address, &ctx).unwrap();
let resolver = MapResolver(HashMap::from([("own.test", vec![own])]));
let refusal = openmoat_proxy::connect(&resolver, "own.test", port, &addresses, &[], WAIT)
.expect_err("connected to an address of this machine");
let decision = refusal.decision("own.test");
assert_eq!(decision.rules, ["proxy-address"], "{decision:?}");
assert!(decision.reasons[0].contains("this machine"), "{decision:?}");
}
#[test]
fn an_allowed_name_resolving_to_a_denied_address_is_refused() {
let h = start(None, Limits::default());
let port = h.port();
for (host, ip) in [
("denied.test", "203.0.113.7"),
("mixed-denied.test", "203.0.113.7"),
("denied-v6.test", "2001:db8::5"),
] {
let reply = h.exchange(&format!("GET http://{host}:{port}/ HTTP/1.1\r\n\r\n"));
assert!(reply.starts_with("HTTP/1.1 403"), "{host}: {reply}");
assert!(
reply.contains(ip) && reply.contains("no-doc-net"),
"{host}: {reply}"
);
let reply = h.exchange(&format!("CONNECT {host}:{port} HTTP/1.1\r\n\r\n"));
assert!(reply.starts_with("HTTP/1.1 403"), "{host}: {reply}");
}
assert!(h.nothing_forwarded());
let rows = h.rows();
assert_eq!(rows.len(), 6);
assert!(rows.iter().all(|r| r.verdict == Verdict::Deny
&& r.rules == ["proxy-address"]
&& r.reasons[0].contains("`no-doc-net`")));
}