Skip to content
Open
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
576 changes: 320 additions & 256 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ nom = "7.1.3"
crypto_box = "0.8.2"
libc = "0.2.142"
dirs = "5.0.0"

[patch.crates-io]
torut = { path = "vendor/torut" }
8 changes: 8 additions & 0 deletions vendor/torut/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/target
**/*.rs.bk
Cargo.lock
/fuzz
/.idea
/.devcontainer
/.vscode

13 changes: 13 additions & 0 deletions vendor/torut/.travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
language: rust
rust:
- stable
- beta
- nightly
script:
- cargo build --verbose --all
- cargo test --verbose --all
jobs:
allow_failures:
- nightly
fast_finish: true
cache: cargo
47 changes: 47 additions & 0 deletions vendor/torut/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[package]
name = "torut"
version = "0.2.1"
authors = ["teawithsand <[email protected]>"]
edition = "2018"
license = "MIT"
description = "torut is reasonable tor controller written in rust utilizing tokio for async communication"
repository = "https://github.com/teawithsand/torut"
homepage = "https://github.com/teawithsand/torut"
readme = "README.MD"
keywords = ["tor", "controller", "tokio", "onion"]

[features]
default = ["serialize", "v3", "control"]
serialize = ["serde", "serde_derive", "base32", "base64"]
control = ["tokio", "rand", "hex", "sha2", "hmac"]
v3 = ["rand", "ed25519-dalek", "base32", "base64", "sha3"]

[badges]
travis-ci = { repository = "teawithsand/torut", branch = "master" }
maintenance = { status = "passively-maintained" }

[dependencies]
serde = { version = "1.0", optional = true }
serde_derive = { version = "1.0", optional = true }

derive_more = "0.99"

sha3 = { version = "0.9", optional = true } # for onion service v3 signature
sha2 = { version = "0.9", optional = true } # for ed25519-dalek key
hmac = { version = "0.11", optional = true } # for authentication with tor controller

ed25519-dalek = { version = "1", optional = true }
rand = { version = "0.7", optional = true }
base32 = { version = "0.4", optional = true }
base64 = { version = "0.13", optional = true }
hex = { version = "0.4", optional = true }

tokio = { version = "1", features = ["io-util"], optional = true }

# for fuzzing right now
# TODO(reawithsand): fix it somehow
# tokio = { version = "0.3", optional = true, features = ["full"] }

[dev-dependencies]
serde_json = "1.0"
tokio = { version = "1", features = ["full"] }
5 changes: 5 additions & 0 deletions vendor/torut/LICENSE.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 changes: 26 additions & 0 deletions vendor/torut/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# torut
[![Build Status](https://travis-ci.org/teawithsand/torut.svg?branch=master)](https://travis-ci.org/teawithsand/torut)

Torut is tor controller written in rust similar to
[stem](https://stem.torproject.org/) or [bine](https://github.com/cretz/bine).
It tries to reasonably implement [specification of tor control port proto](https://gitweb.torproject.org/torspec.git/tree/control-spec.txt)
It works asynchronously with tokio and async/await.

It implements onion service key and address generation and serialization on its own without tor process.

Right now logic is quite tightly coupled with tokio so there is no way to
remove tokio from dependencies and make all functions synchronous.

## Status of onion service V2
Code handling V2 services has been removed in 0.2 release, since tor project removed(should have?) v2 handling code
from their codebase as well.
See [This page](https://blog.torproject.org/v2-deprecation-timeline)

# Testing
Tests in torut are split into two parts:
these which do use tor and these which do not use tor.
In order to enable tests which use tor use `RUSTFLAGS="--cfg=testtor"`
and provide `TORUT_TESTING_TOR_BINARY` environment variable containing path to tor binary.
Testing tor binary MUST be run with `--test-threads=1` for instance like:

`$ RUSTFLAGS="--cfg testtor" cargo test -- --test-threads=1`
9 changes: 9 additions & 0 deletions vendor/torut/TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Note: there are TODOs in code as well

Figure out how to make tests utilizing tor process run with CI(is this possible?)
At least create a docker container so testing with tor is reasonably predictable

Cleanup pub(crate) for fuzzing functions. Create modules exporting fuzzing stuff and then reexport them in src/fuzz.rs

Add tests for conditional compilation features on travis and some bash file
So one can test if code compiles on all configurations of features enabled not only default or all features
31 changes: 31 additions & 0 deletions vendor/torut/examples/cookie_authenticate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use torut::utils::{run_tor, AutoKillChild};
use torut::control::{UnauthenticatedConn};
use tokio::net::TcpStream;

#[tokio::main]
async fn main() {
// testing port is 47835
// it must be free

let child = run_tor(std::env::var("TORUT_TOR_BINARY").unwrap(), &mut [
"--DisableNetwork", "1",
"--ControlPort", "47835",
"--CookieAuthentication", "1",
].iter()).expect("Starting tor filed");
let _child = AutoKillChild::new(child);

let s = TcpStream::connect(&format!("127.0.0.1:{}", 47835)).await.unwrap();
let mut utc = UnauthenticatedConn::new(s);
let proto_info = utc.load_protocol_info().await.unwrap();
let ad = proto_info.make_auth_data().unwrap().unwrap();

utc.authenticate(&ad).await.unwrap();
let mut ac = utc.into_authenticated().await;
ac.set_async_event_handler(Some(|_| {
async move { Ok(()) }
}));

ac.take_ownership().await.unwrap();

println!("Now we can use tor conn. We are now forced to use cookie auth due to different tor config.");
}
39 changes: 39 additions & 0 deletions vendor/torut/examples/get_shared_random.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use torut::utils::{run_tor, AutoKillChild};
use torut::control::{UnauthenticatedConn, TorAuthMethod, TorAuthData};
use tokio::net::TcpStream;

use std::thread::sleep;
use std::time::Duration;

#[tokio::main]
async fn main() {
// testing port is 47835
// it must be free

let child = run_tor( std::env::var("TORUT_TOR_BINARY").unwrap(), &mut [
// "--DisableNetwork", "1",
"--ControlPort", "47835",
// "--CookieAuthentication", "1",
].iter()).expect("Starting tor filed");
let _child = AutoKillChild::new(child);

let s = TcpStream::connect(&format!("127.0.0.1:{}", 47835)).await.unwrap();
let mut utc = UnauthenticatedConn::new(s);
let proto_info = utc.load_protocol_info().await.unwrap();

assert!(proto_info.auth_methods.contains(&TorAuthMethod::Null), "Null authentication is not allowed");
utc.authenticate(&TorAuthData::Null).await.unwrap();
let mut ac = utc.into_authenticated().await;
ac.set_async_event_handler(Some(|_| {
async move { Ok(()) }
}));

ac.take_ownership().await.unwrap();

loop {
println!("getting shared random value...");
let shared_random = ac.get_info("sr/previous").await.unwrap();
println!("sr: {}", shared_random);
sleep(Duration::new(1, 0));
}
}
47 changes: 47 additions & 0 deletions vendor/torut/examples/make_onion_v3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use torut::utils::{run_tor, AutoKillChild};
use torut::control::{UnauthenticatedConn, TorAuthMethod, TorAuthData};
use tokio::net::TcpStream;

use std::net::{SocketAddr, IpAddr, Ipv4Addr};

#[tokio::main]
async fn main() {
// testing port is 47835
// it must be free

let child = run_tor(std::env::var("TORUT_TOR_BINARY").unwrap(), &mut [
"--DisableNetwork", "1",
"--ControlPort", "47835",
// "--CookieAuthentication", "1",
].iter()).expect("Starting tor filed");
let _child = AutoKillChild::new(child);

let s = TcpStream::connect(&format!("127.0.0.1:{}", 47835)).await.unwrap();
let mut utc = UnauthenticatedConn::new(s);
let proto_info = utc.load_protocol_info().await.unwrap();

assert!(proto_info.auth_methods.contains(&TorAuthMethod::Null), "Null authentication is not allowed");
utc.authenticate(&TorAuthData::Null).await.unwrap();
let mut ac = utc.into_authenticated().await;
ac.set_async_event_handler(Some(|_| {
async move { Ok(()) }
}));

ac.take_ownership().await.unwrap();

let key = torut::onion::TorSecretKeyV3::generate();
println!("Generated new onion service v3 key for address: {}", key.public().get_onion_address());

println!("Adding onion service v3...");
ac.add_onion_v3(&key, false, false, false, None, &mut [
(15787, SocketAddr::new(IpAddr::from(Ipv4Addr::new(127,0,0,1)), 15787)),
].iter()).await.unwrap();
println!("Added onion service v3!");

println!("Now after enabling network clients should be able to connect to this port");

println!("Deleting created onion service...");
// delete onion service so it works no more
ac.del_onion(&key.public().get_onion_address().get_address_without_dot_onion()).await.unwrap();
println!("Deleted created onion service! It runs no more!");
}
35 changes: 35 additions & 0 deletions vendor/torut/examples/run_tor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use torut::utils::{run_tor, AutoKillChild};
use torut::control::{UnauthenticatedConn, TorAuthMethod, TorAuthData};
use tokio::net::TcpStream;

#[tokio::main]
async fn main() {
// testing port is 47835
// it must be free

let child = run_tor(std::env::var("TORUT_TOR_BINARY").unwrap(), &mut [
"--DisableNetwork", "1",
"--ControlPort", "47835",
// "--CookieAuthentication", "1",
].iter()).expect("Starting tor filed");
let _child = AutoKillChild::new(child);

let s = TcpStream::connect(&format!("127.0.0.1:{}", 47835)).await.unwrap();
let mut utc = UnauthenticatedConn::new(s);
let proto_info = utc.load_protocol_info().await.unwrap();

assert!(proto_info.auth_methods.contains(&TorAuthMethod::Null), "Null authentication is not allowed");
utc.authenticate(&TorAuthData::Null).await.unwrap();
let mut ac = utc.into_authenticated().await;
ac.set_async_event_handler(Some(|_| {
async move { Ok(()) }
}));

ac.take_ownership().await.unwrap();

let socksport = ac.get_info_unquote("net/listeners/socks").await.unwrap();
println!("Tor is running now. It's socks port is listening(or not) on: {:?} but it's not connected to the network because DisableNetwork is set", socksport);

let controlport = ac.get_info_unquote("net/listeners/control").await.unwrap();
println!("Tor is running now. It's control port listening on: {:?}", controlport);
}
Loading