WIP - figure out what is not working

debug-remodel-tor
Daniel Karzel 3 years ago committed by Thomas Eizinger
parent 44dddcd6bc
commit 52bdaf2c1d
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96

@ -1,28 +1,27 @@
[package]
name = "libp2p-tor"
version = "0.1.0"
authors = ["Thomas Eizinger <thomas@eizinger.io>"]
authors = [ "Thomas Eizinger <thomas@eizinger.io>" ]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1" # TODO: Get rid of anyhow dependency
torut = { version = "0.1", default-features = false, features = ["v3", "control"] }
tokio-socks = "0.5"
libp2p = { version = "0.37", default-features = false, features = ["tcp-tokio"] }
tokio = { version = "1", features = ["sync"] }
futures = "0.3"
tracing = "0.1"
data-encoding = "2.3"
reqwest = { version = "0.11", features = ["socks", "rustls-tls"], default-features = false }
async-trait = "0.1"
data-encoding = "2.3"
futures = "0.3"
libp2p = { version = "0.37", default-features = false, features = [ "tcp-tokio" ] }
rand = { version = "0.8", optional = true }
reqwest = { version = "0.11", features = [ "socks", "rustls-tls" ], default-features = false }
tokio = { version = "1", features = [ "sync" ] }
tokio-socks = "0.5"
torut = { version = "0.1", default-features = false, features = [ "v3", "control" ] }
tracing = "0.1"
[dev-dependencies]
tempfile = "3"
tokio = { version = "1", features = ["full"] }
libp2p = { version = "0.37", default-features = false, features = [ "yamux", "noise", "ping" ] }
rand = "0.8"
libp2p = { version = "0.37", default-features = false, features = ["yamux", "noise", "ping"] }
tracing-subscriber = { version = "0.2", default-features = false, features = ["fmt", "ansi", "env-filter", "chrono", "tracing-log"] }
tempfile = "3"
testcontainers = "0.12"
tokio = { version = "1", features = [ "full" ] }
tracing-subscriber = { version = "0.2", default-features = false, features = [ "fmt", "ansi", "env-filter", "chrono", "tracing-log" ] }

@ -8,15 +8,19 @@ use std::time::Duration;
#[tokio::main]
async fn main() {
let addr_to_dial = std::env::args()
.next()
.unwrap()
let arg = std::env::args()
.last()
.unwrap();
let addr_to_dial = arg
.parse::<Multiaddr>()
.unwrap();
let mut swarm = new_swarm();
println!("Peer-ID: {}", swarm.local_peer_id());
println!("Dialing {}", addr_to_dial);
swarm.dial_addr(addr_to_dial).unwrap();
loop {
@ -41,7 +45,9 @@ async fn main() {
println!("Failed to ping {}: {}", peer, failure)
}
},
_ => {}
event => {
println!("Swarm event: {:?}", event)
}
}
}
}

@ -2,7 +2,7 @@ use libp2p::core::muxing::StreamMuxerBox;
use libp2p::core::upgrade::Version;
use libp2p::ping::{Ping, PingEvent, PingSuccess};
use libp2p::swarm::{SwarmBuilder, SwarmEvent};
use libp2p::{identity, noise, yamux, Swarm, Transport};
use libp2p::{identity, noise, yamux, Swarm, Transport, Multiaddr};
use libp2p_tor::duplex;
use libp2p_tor::torut_ext::AuthenticatedConnectionExt;
use noise::NoiseConfig;
@ -10,23 +10,27 @@ use rand::Rng;
use std::time::Duration;
use torut::control::AuthenticatedConn;
use torut::onion::TorSecretKeyV3;
use std::str::FromStr;
#[tokio::main]
async fn main() {
let wildcard_multiaddr =
"/onion3/WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW:8080"
.parse()
.unwrap();
let mut swarm = new_swarm().await;
let key = random_onion_identity();
let onion_address = key.public().get_onion_address().get_address_without_dot_onion();
let onion_port = 7654;
println!("Peer-ID: {}", swarm.local_peer_id());
swarm.listen_on(wildcard_multiaddr).unwrap();
let mut swarm = new_swarm(key).await;
let peer_id = *swarm.local_peer_id();
println!("Peer-ID: {}", peer_id);
// TODO: Figure out what to with the port, we could also set it to 0 and then imply it from the assigned port
swarm.listen_on(Multiaddr::from_str(format!("/onion3/{}:{}", onion_address, onion_port).as_str()).unwrap()).unwrap();
loop {
match swarm.next_event().await {
SwarmEvent::NewListenAddr(addr) => {
println!("Listening on {}", addr);
println!("Connection string: {}/p2p/{}", addr, peer_id)
}
SwarmEvent::ConnectionEstablished {
peer_id, endpoint, ..
@ -48,7 +52,9 @@ async fn main() {
println!("Failed to ping {}: {}", peer, failure)
}
},
_ => {}
event => {
println!("Swarm event: {:?}", event)
}
}
}
}
@ -58,13 +64,13 @@ async fn main() {
///
/// In particular, this swarm can create ephemeral hidden services on the
/// configured Tor node.
async fn new_swarm() -> Swarm<Ping> {
async fn new_swarm(key: TorSecretKeyV3) -> Swarm<Ping> {
let identity = identity::Keypair::generate_ed25519();
SwarmBuilder::new(
duplex::TorConfig::new(
AuthenticatedConn::new(9051).await.unwrap(),
random_onion_identity,
key,
)
.await
.unwrap()

@ -15,13 +15,6 @@ use tokio::sync::Mutex;
use torut::control::{AsyncEvent, AuthenticatedConn};
use torut::onion::TorSecretKeyV3;
/// This is the hash of
/// `/onion3/WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW`.
const WILDCARD_ONION_ADDR_HASH: [u8; 35] = [
181, 173, 107, 90, 214, 181, 173, 107, 90, 214, 181, 173, 107, 90, 214, 181, 173, 107, 90, 214,
181, 173, 107, 90, 214, 181, 173, 107, 90, 214, 181, 173, 107, 90, 214,
];
type TorutAsyncEventHandler =
fn(
AsyncEvent<'_>,
@ -31,32 +24,33 @@ type TorutAsyncEventHandler =
pub struct TorConfig {
inner: MapErr<GenTcpConfig<libp2p::tcp::tokio::Tcp>, fn(std::io::Error) -> Error>, /* TODO: Make generic over async-std / tokio */
tor_client: Arc<Mutex<AuthenticatedConn<tokio::net::TcpStream, TorutAsyncEventHandler>>>,
onion_key_generator: Arc<dyn (Fn() -> TorSecretKeyV3) + Send + Sync>,
key: TorSecretKeyV3,
socks_port: u16,
}
impl TorConfig {
pub async fn new(
mut client: AuthenticatedConn<tokio::net::TcpStream, TorutAsyncEventHandler>,
onion_key_generator: impl (Fn() -> TorSecretKeyV3) + Send + Sync + 'static,
// TODO: change to key directly
key: TorSecretKeyV3,
) -> Result<Self, Error> {
let socks_port = client.get_socks_port().await?;
Ok(Self {
inner: TokioTcpConfig::new().map_err(Error::InnerTransprot),
tor_client: Arc::new(Mutex::new(client)),
onion_key_generator: Arc::new(onion_key_generator),
key,
socks_port,
})
}
pub async fn from_control_port(
control_port: u16,
key_generator: impl (Fn() -> TorSecretKeyV3) + Send + Sync + 'static,
key: TorSecretKeyV3,
) -> Result<Self, Error> {
let client = AuthenticatedConn::new(control_port).await?;
Self::new(client, key_generator).await
Self::new(client, key).await
}
}
@ -80,9 +74,9 @@ impl Transport for TorConfig {
return Err(TransportError::MultiaddrNotSupported(addr));
};
if onion.hash() != &WILDCARD_ONION_ADDR_HASH {
return Err(TransportError::Other(Error::OnlyWildcardAllowed));
}
let key: TorSecretKeyV3 = self.key;
let onion_bytes = key.public().get_onion_address().get_raw_bytes();
let onion_port = onion.port();
let localhost_tcp_random_port_addr = "/ip4/127.0.0.1/tcp/0"
.parse()
@ -90,10 +84,6 @@ impl Transport for TorConfig {
let listener = self.inner.listen_on(localhost_tcp_random_port_addr)?;
let key: TorSecretKeyV3 = (self.onion_key_generator)();
let onion_bytes = key.public().get_onion_address().get_raw_bytes();
let onion_port = onion.port();
let tor_client = self.tor_client;
let listener = listener
@ -115,6 +105,7 @@ impl Transport for TorConfig {
})
.expect("TODO: Error handling");
// TODO: Don't fully understand this part, why would we have two different multiaddresses here? the actual onion address and the multiaddress would make more sense...?
tracing::debug!(
"Setting up hidden service at {} to forward to {}",
onion_multiaddress,
@ -125,6 +116,7 @@ impl Transport for TorConfig {
.clone()
.lock()
.await
// TODO: Potentially simplify this, in our setup the onion port is always equal to the local port. Otherwise we would have the user provide an additional port for the oion service.
.add_ephemeral_service(&key, onion_port, local_port)
.await
{
@ -141,7 +133,9 @@ impl Transport for TorConfig {
local_addr,
remote_addr,
},
ListenerEvent::AddressExpired(_) => {
// TODO: why was the constructed multiaddr used here?
ListenerEvent::AddressExpired(adr) => {
// TODO: even if so, why would we ignore it? Far more logical to just use it...
// can ignore address because we only ever listened on one and we
// know which one that was
@ -156,7 +150,7 @@ impl Transport for TorConfig {
.del_onion(&onion_address_without_dot_onion)
.await
{
Ok(()) => ListenerEvent::AddressExpired(onion_multiaddress),
Ok(()) => ListenerEvent::AddressExpired(adr),
Err(e) => ListenerEvent::Error(Error::Torut(
torut_ext::Error::Connection(e),
)),

@ -42,7 +42,7 @@ async fn create_ephemeral_service() {
AuthenticatedConn::with_password(9051, "supersecret")
.await
.unwrap(),
move || onion_key_bytes.into(),
onion_key_bytes.into(),
)
.await
.unwrap()
@ -149,17 +149,16 @@ impl IntoIterator for TorArgs {
let mut args = Vec::new();
if let Some(port) = self.socks_port {
args.push(format!("SocksPort"));
args.push("SocksPort".to_string());
args.push(format!("0.0.0.0:{}", port));
}
if let Some(port) = self.control_port {
args.push(format!("ControlPort"));
args.push("ControlPort".to_string());
args.push(format!("0.0.0.0:{}", port));
args.push(format!("HashedControlPassword"));
args.push(format!(
"16:436B425404AA332A60B4F341C2023146C4B3A80548D757F0BB10DE81B4"
))
args.push("HashedControlPassword".to_string());
args.push("16:436B425404AA332A60B4F341C2023146C4B3A80548D757F0BB10DE81B4"
.to_string())
}
args.into_iter()
@ -186,7 +185,7 @@ impl Image for TorImage {
}
fn args(&self) -> Self::Args {
self.args.clone()
self.args
}
fn env_vars(&self) -> Self::EnvVars {

Loading…
Cancel
Save