use std::str::FromStr;
use tor_interface::tor_provider::*;
#[test]
fn test_tor_provider_target_addr() -> anyhow::Result<()> {
let valid_ip_addr: &[&str] = &[
"192.168.1.1:80",
"10.0.0.1:443",
"172.16.0.1:8080",
"8.8.8.8:53",
"255.255.255.255:65535",
"0.0.0.0:22",
"192.168.0.254:21",
"127.0.0.1:3306",
"1.1.1.1:123",
"224.0.0.1:554",
"169.254.0.1:179",
"203.0.113.1:80",
"198.51.100.1:443",
"100.64.0.1:8080",
"192.0.2.1:53",
"192.88.99.1:22",
"192.0.0.1:21",
"240.0.0.1:3306",
"198.18.0.1:123",
"233.252.0.1:554",
"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80",
"[2001:db8:85a3::8a2e:370:7334]:443",
"[::1]:8080",
"[::ffff:192.168.1.1]:53",
"[2001:0db8::1]:22",
"[fe80::1ff:fe23:4567:890a]:21",
"[2001:db8::1:0:0:1]:3306",
"[2001:0db8:0000:0042:0000:8a2e:0370:7334]:123",
"[ff02::1]:554",
"[fe80::abcd:ef01:2345:6789]:179",
"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80",
"[2001:db8:85a3::8a2e:370:7334]:443",
"[::1]:8080",
"[::ffff:c0a8:101]:53",
"[2001:db8::1:0:0:1]:22",
"[fe80::1ff:fe23:4567:890a]:21",
"[2001:db8:0000:0042:0000:8a2e:0370:7334]:3306",
"[ff02::1]:123",
"[fe80::abcd:ef01:2345:6789]:554",
"[2001:db8::1]:179",
];
for target_addr_str in valid_ip_addr {
match TargetAddr::from_str(target_addr_str) {
Ok(TargetAddr::Socket(socket_addr)) => {
println!("{} => {}", target_addr_str, socket_addr)
}
Ok(TargetAddr::OnionService(onion_addr)) => panic!(
"unexpected conversion: {} => OnionService({})",
target_addr_str, onion_addr
),
Ok(TargetAddr::Domain(domain_addr)) => panic!(
"unexpected conversion: {} => DomainAddr({})",
target_addr_str, domain_addr
),
Err(err) => Err(err)?,
}
}
let valid_onion_addr: &[&str] = &[
"6l62fw7tqctlu5fesdqukvpoxezkaxbzllrafa2ve6ewuhzphxczsjyd.onion:65535",
"6L62FW7TQCTLU5FESDQUKVPOXEZKAXBZLLRAFA2VE6EWUHZPHXCZSJYD.onion:1",
];
for target_addr_str in valid_onion_addr {
match TargetAddr::from_str(target_addr_str) {
Ok(TargetAddr::Socket(socket_addr)) => panic!(
"unexpected conversion: {} => Ip({})",
target_addr_str, socket_addr
),
Ok(TargetAddr::OnionService(onion_addr)) => {
println!("{} => {}", target_addr_str, onion_addr)
}
Ok(TargetAddr::Domain(domain_addr)) => panic!(
"unexpected conversion: {} => DomainAddr({})",
target_addr_str, domain_addr
),
Err(err) => Err(err)?,
}
}
let valid_domain_addr: &[&str] = &[
"example.com:80",
"subdomain.example.com:443",
"xn--e1afmkfd.xn--p1ai:8080", "xn--fsqu00a.xn--0zwm56d:53", "münich.com:22", "xn--mnich-kva.com:21", "exämple.com:3306", "xn--exmple-cua.com:123", "例子.com:554", "xn--fsqu00a.com:179", "täst.de:80", "xn--tst-qla.de:443", "xn--fiqs8s:80", "xn--wgbh1c:8080", "münster.de:22", "xn--mnster-3ya.de:21", "bücher.com:3306", "xn--bcher-kva.com:123", "xn--vermgensberatung-pwb.com:554", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:65535"
];
for target_addr_str in valid_domain_addr {
match TargetAddr::from_str(target_addr_str) {
Ok(TargetAddr::Socket(socket_addr)) => panic!(
"unexpected conversion: {} => SocketAddr({})",
target_addr_str, socket_addr
),
Ok(TargetAddr::OnionService(onion_addr)) => panic!(
"unexpected conversion: {} => OnionService({})",
target_addr_str, onion_addr
),
Ok(TargetAddr::Domain(domain_addr)) => {
println!("{} => {}", target_addr_str, domain_addr)
}
Err(err) => Err(err)?,
}
}
let invalid_target_addr: &[&str] = &[
"192.168.1.1:99999", "192.168.1.1:abc", "192.168.1.1:", "192.168.1.1: 80", "192.168.1.1:80a", "[2001:db8:::1]:80", "[2001:db8:85a3::8a2e:370:7334:1234::abcd]:80", "[2001:db8:85a3::8a2e:370g:7334]:80", "[2001:db8:85a3::8a2e:370:7334]:99999", "[2001:db8:85a3:8a2e:370:7334]:80", "[::12345]:80", "[2001:db8:85a3::8a2e:370:7334:]:80", "[2001:db8:85a3::8a2e:370:7334]", "2001:db8:85a3::8a2e:370:7334:80", "[2001:db8:85a3::8a2e:370:7334]: 80", "[2001:db8:85a3::8a2e:370:7334]:80a", "6l62fw7tqctlu5fesdqukvpoxezkaxbzllrafa2ve6ewuhzphxczsjyd234567.onion:80", "6l62fw7tqctlu5fesdqukvpoxezkaxbzllrafa2ve6ewuhzphxcz.onion:443", "6l62fw7tqctlu5fesdqukvpoxezkaxbzllrafa2ve6ewuhzphxczsjyd.onion:99999", "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrst.onion:21", "6l62fw7tqctlu5fesdqukvpoxezkaxbzllrafa2ve6ewuhzphxczsjyd.onion:abc", "6l62fw7tqctlu5fesdqukvpoxezkaxbzllrafa2ve6ewuhzphxczsjyd.onion: 80", "6l62fw7tqctlu5fesdqukvpoxezkaxbzllrafa2ve6ewuhzphxczsjyd.onion:80a", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.onion:80", "example..com:80", "exa mple.com:53", "example.com:99999", "exaample.com:abc", "exaample.com:", "exaample.com: 80", "ex@mple.com:80", "example.com:80a", "exämple..com:80", "xn--exmple-cua.com: 80", "xn--exmple-cua.com:80a", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com:65535", ];
for target_addr_str in invalid_target_addr {
match TargetAddr::from_str(target_addr_str) {
Ok(TargetAddr::Socket(socket_addr)) => panic!(
"unexpected conversion: {} => SocketAddr({})",
target_addr_str, socket_addr
),
Ok(TargetAddr::OnionService(onion_addr)) => panic!(
"unexpected conversion: {} => OnionService({})",
target_addr_str, onion_addr
),
Ok(TargetAddr::Domain(domain_addr)) => panic!(
"unexpected conversion: {} => DomainAddr({})",
target_addr_str, domain_addr
),
Err(_) => (),
}
}
let valid_host_port_tuple: &[(String, u16)] = &[
("127.0.0.1".to_string(), 443u16),
("[::1]".to_string(), 8080u16),
("[2001:db8:0000:0042:0000:8a2e:0370:7334]".to_string(), 3306u16),
("6l62fw7tqctlu5fesdqukvpoxezkaxbzllrafa2ve6ewuhzphxczsjyd.onion".to_string(), 1234u16),
("example.com".to_string(), 80u16),
];
for host_port_tuple in valid_host_port_tuple {
match TargetAddr::try_from(host_port_tuple.clone()) {
Ok(target_addr) => println!("{host_port_tuple:?} => {target_addr}"),
Err(err) => Err(err)?,
}
}
Ok(())
}
#[test]
#[cfg(feature = "legacy-tor-provider")]
fn test_tor_provider_system_tor_auth_from_environment() -> anyhow::Result<()> {
use std::net::SocketAddr;
use tor_interface::legacy_tor_client::LegacyTorClientConfig;
use tor_interface::legacy_tor_client::TorAuth;
const TOR_SOCKS_HOST: &str = "TOR_SOCKS_HOST";
const TOR_SOCKS_PORT: &str = "TOR_SOCKS_PORT";
const TOR_CONTROL_HOST: &str = "TOR_CONTROL_HOST";
const TOR_CONTROL_PORT: &str = "TOR_CONTROL_PORT";
const TOR_CONTROL_COOKIE_AUTH_FILE: &str = "TOR_CONTROL_COOKIE_AUTH_FILE";
const TOR_CONTROL_PASSWD: &str = "TOR_CONTROL_PASSWD";
const ENV_VARIABLES: [&str; 6] = [
TOR_SOCKS_HOST,
TOR_SOCKS_PORT,
TOR_CONTROL_HOST,
TOR_CONTROL_PORT,
TOR_CONTROL_COOKIE_AUTH_FILE,
TOR_CONTROL_PASSWD,
];
for var in ENV_VARIABLES {
unsafe { std::env::remove_var(var) };
}
assert!(LegacyTorClientConfig::try_from_environment().is_err());
std::env::set_var(TOR_SOCKS_HOST, "1.1.1.1");
std::env::set_var(TOR_SOCKS_PORT, "9050");
std::env::set_var(TOR_CONTROL_HOST, "2.2.2.2");
std::env::set_var(TOR_CONTROL_PORT, "9051");
if let LegacyTorClientConfig::SystemTor {
tor_socks_addr,
tor_control_addr,
tor_control_auth,
} = LegacyTorClientConfig::try_from_environment()?
{
assert_eq!(tor_socks_addr, SocketAddr::from(([1, 1, 1, 1], 9050)));
assert_eq!(tor_control_addr, SocketAddr::from(([2, 2, 2, 2], 9051)));
assert_eq!(tor_control_auth, TorAuth::Null);
};
let cookie_file = std::env::temp_dir().join("cookie");
std::env::set_var(
TOR_CONTROL_COOKIE_AUTH_FILE,
cookie_file.clone().into_os_string(),
);
if let LegacyTorClientConfig::SystemTor {
tor_socks_addr,
tor_control_addr,
tor_control_auth,
} = LegacyTorClientConfig::try_from_environment()?
{
assert_eq!(tor_socks_addr, SocketAddr::from(([1, 1, 1, 1], 9050)));
assert_eq!(tor_control_addr, SocketAddr::from(([2, 2, 2, 2], 9051)));
assert_eq!(tor_control_auth, TorAuth::CookieFile(cookie_file));
};
unsafe { std::env::remove_var(TOR_CONTROL_COOKIE_AUTH_FILE) }
std::env::set_var(TOR_CONTROL_PASSWD, "pass");
if let LegacyTorClientConfig::SystemTor {
tor_socks_addr,
tor_control_addr,
tor_control_auth,
} = LegacyTorClientConfig::try_from_environment()?
{
assert_eq!(tor_socks_addr, SocketAddr::from(([1, 1, 1, 1], 9050)));
assert_eq!(tor_control_addr, SocketAddr::from(([2, 2, 2, 2], 9051)));
assert_eq!(tor_control_auth, TorAuth::Password("pass".to_string()));
};
Ok(())
}