Skip to content

Commit

Permalink
tor-interface: add support for manually specifying socks address, con…
Browse files Browse the repository at this point in the history
…trol port address, and control password
  • Loading branch information
Richard Pospesel committed Jun 17, 2024
1 parent da80320 commit 36d5c19
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 4 deletions.
8 changes: 8 additions & 0 deletions source/gosling/crates/tor-interface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ if (ENABLE_TESTS)
COMMAND env CARGO_TARGET_DIR=${CARGO_TARGET_DIR} RUSTFLAGS=${RUSTFLAGS} RUST_BACKTRACE=full cargo test test_legacy_authenticated_onion_service ${CARGO_FLAGS} ${TOR_INTERFACE_FEATURES} -- --nocapture
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_test(NAME tor_interface_system_legacy_onion_service_cargo_test
COMMAND env CARGO_TARGET_DIR=${CARGO_TARGET_DIR} RUSTFLAGS=${RUSTFLAGS} RUST_BACKTRACE=full cargo test test_system_legacy_onion_service ${CARGO_FLAGS} ${TOR_INTERFACE_FEATURES} -- --nocapture
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_test(NAME tor_interface_system_legacy_authenticated_onion_service_cargo_test
COMMAND env CARGO_TARGET_DIR=${CARGO_TARGET_DIR} RUSTFLAGS=${RUSTFLAGS} RUST_BACKTRACE=full cargo test test_system_legacy_authenticated_onion_service ${CARGO_FLAGS} ${TOR_INTERFACE_FEATURES} -- --nocapture
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif()

if (ENABLE_ARTI_CLIENT_TOR_PROVIDER)
Expand Down
24 changes: 20 additions & 4 deletions source/gosling/crates/tor-interface/src/legacy_tor_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ pub struct LegacyTorClient {

impl LegacyTorClient {
pub fn new(config: LegacyTorClientConfig) -> Result<LegacyTorClient, Error> {
let (daemon, mut controller, password, bootstrapped, socks_listener) = match config {
let (daemon, mut controller, password, socks_listener) = match config {
LegacyTorClientConfig::BundledTor{tor_bin_path, data_directory} => {
// launch tor
let daemon = LegacyTorProcess::new(tor_bin_path.as_path(), data_directory.as_path())
Expand All @@ -210,9 +210,20 @@ impl LegacyTorClient {
.map_err(Error::LegacyTorControllerCreationFailed)?;

let password = daemon.get_password().to_string();
(Some(daemon), controller, password, false, None)
(Some(daemon), controller, password, None)
},
LegacyTorClientConfig::SystemTor{tor_socks_addr, tor_control_addr, tor_control_passwd} => {
// open a control stream
let control_stream =
LegacyControlStream::new(&tor_control_addr, Duration::from_millis(16))
.map_err(Error::LegacyControlStreamCreationFailed)?;

// create a controler
let controller = LegacyTorController::new(control_stream)
.map_err(Error::LegacyTorControllerCreationFailed)?;

(None, controller, tor_control_passwd, Some(tor_socks_addr))
},
LegacyTorClientConfig::SystemTor{..} => return Err(Error::NotImplemented())
};

// authenticate
Expand Down Expand Up @@ -250,7 +261,7 @@ impl LegacyTorClient {
daemon,
version,
controller,
bootstrapped,
bootstrapped: false,
socks_listener,
onion_services: Default::default(),
circuit_token_counter: 0usize,
Expand Down Expand Up @@ -334,11 +345,16 @@ impl TorProvider for LegacyTorClient {
}

if let Some(daemon) = &mut self.daemon {
// bundled tor gives us log-lines
for log_line in daemon.wait_log_lines().iter_mut() {
events.push(TorEvent::LogReceived {
line: std::mem::take(log_line),
});
}
} else if !self.bootstrapped {
// system tor needs to send a bootstrap complete event *once*
events.push(TorEvent::BootstrapComplete);
self.bootstrapped = true;
}

Ok(events)
Expand Down
125 changes: 125 additions & 0 deletions source/gosling/crates/tor-interface/tests/tor_provider.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// stanndard
#[cfg(feature = "legacy-tor-provider")]
use std::fs::File;
use std::io::{Read, Write};
#[cfg(feature = "legacy-tor-provider")]
use std::process;
#[cfg(feature = "legacy-tor-provider")]
use std::process::{Child, Command, Stdio};
use std::str::FromStr;
#[cfg(feature = "arti-client-tor-provider")]
use std::sync::Arc;
Expand Down Expand Up @@ -410,6 +416,125 @@ fn test_legacy_authenticated_onion_service() -> anyhow::Result<()> {
authenticated_onion_service_test(server_provider, client_provider)
}

//
// System Legacy TorProvider tests
//

#[cfg(test)]
fn start_system_tor_daemon(tor_path: &std::ffi::OsStr, name: &str, control_port: u16, socks_port: u16) -> anyhow::Result<Child> {

let mut data_path = std::env::temp_dir();
data_path.push(name);
std::fs::create_dir_all(&data_path)?;
let default_torrc = data_path.join("default_torrc");
{ let _ = File::create(&default_torrc)?; }
let torrc = data_path.join("torrc");
{ let _ = File::create(&torrc)?; }

let tor_daemon = Command::new(tor_path)
.stdout(Stdio::null())
.stdin(Stdio::null())
.stderr(Stdio::null())
// point to our above written torrc file
.arg("--defaults-torrc")
.arg(default_torrc)
// location of torrc
.arg("--torrc-file")
.arg(torrc)
// enable networking
.arg("DisableNetwork")
.arg("0")
// root data directory
.arg("DataDirectory")
.arg(data_path)
// daemon will assign us a port, and we will
// read it from the control port file
.arg("ControlPort")
.arg(control_port.to_string())
// password: foobar1
.arg("HashedControlPassword")
.arg("16:E807DCE69AFE9979600760C9758B95ADB2F95E8740478AEA5356C95358")
// socks port
.arg("SocksPort")
.arg(socks_port.to_string())
// tor process will shut down after this process shuts down
// to avoid orphaned tor daemon
.arg("__OwningControllerProcess")
.arg(process::id().to_string())
.spawn()?;


Ok(tor_daemon)
}

#[test]
#[serial]
#[cfg(feature = "legacy-tor-provider")]
fn test_system_legacy_onion_service() -> anyhow::Result<()> {
let tor_path = which::which(format!("tor{}", std::env::consts::EXE_SUFFIX))?;

let mut server_tor_daemon = start_system_tor_daemon(tor_path.as_os_str(), "test_system_legacy_onion_service_server", 9251u16, 9250u16)?;
let mut client_tor_daemon = start_system_tor_daemon(tor_path.as_os_str(), "test_system_legacy_onion_service_client", 9351u16, 9350u16)?;

// give daemons time to start
std::thread::sleep(std::time::Duration::from_secs(5));

let tor_config = LegacyTorClientConfig::SystemTor{
tor_socks_addr: std::net::SocketAddr::from_str("127.0.0.1:9250")?,
tor_control_addr: std::net::SocketAddr::from_str("127.0.0.1:9251")?,
tor_control_passwd: "password".to_string(),
};
let server_provider = Box::new(LegacyTorClient::new(tor_config)?);

let tor_config = LegacyTorClientConfig::SystemTor{
tor_socks_addr: std::net::SocketAddr::from_str("127.0.0.1:9350")?,
tor_control_addr: std::net::SocketAddr::from_str("127.0.0.1:9351")?,
tor_control_passwd: "password".to_string(),
};
let client_provider = Box::new(LegacyTorClient::new(tor_config)?);

basic_onion_service_test(server_provider, client_provider)?;

server_tor_daemon.kill()?;
client_tor_daemon.kill()?;

Ok(())
}

#[test]
#[serial]
#[cfg(feature = "legacy-tor-provider")]
fn test_system_legacy_authenticated_onion_service() -> anyhow::Result<()> {
let tor_path = which::which(format!("tor{}", std::env::consts::EXE_SUFFIX))?;

let mut server_tor_daemon = start_system_tor_daemon(tor_path.as_os_str(), "test_system_legacy_authenticated_onion_service_server", 9251u16, 9250u16)?;
let mut client_tor_daemon = start_system_tor_daemon(tor_path.as_os_str(), "test_system_legacy_authenticated_onion_service_client", 9351u16, 9350u16)?;

// give daemons time to start
std::thread::sleep(std::time::Duration::from_secs(5));

let tor_config = LegacyTorClientConfig::SystemTor{
tor_socks_addr: std::net::SocketAddr::from_str("127.0.0.1:9250")?,
tor_control_addr: std::net::SocketAddr::from_str("127.0.0.1:9251")?,
tor_control_passwd: "password".to_string(),
};
let server_provider = Box::new(LegacyTorClient::new(tor_config)?);

let tor_config = LegacyTorClientConfig::SystemTor{
tor_socks_addr: std::net::SocketAddr::from_str("127.0.0.1:9350")?,
tor_control_addr: std::net::SocketAddr::from_str("127.0.0.1:9351")?,
tor_control_passwd: "password".to_string(),
};
let client_provider = Box::new(LegacyTorClient::new(tor_config)?);

authenticated_onion_service_test(server_provider, client_provider)?;

server_tor_daemon.kill()?;
client_tor_daemon.kill()?;

Ok(())
}

//
// Arti TorProvider tests
//
Expand Down

0 comments on commit 36d5c19

Please sign in to comment.