Merge branch 'readmes' into 'main'
Abolish maint/readme and use doc include Closes #603 See merge request tpo/core/arti!768
This commit is contained in:
commit
b4cc98b21b
|
@ -53,7 +53,7 @@ This state gets persisted to the locations specified in the
|
|||
(This method requires you to initialize the client in an `async fn`.
|
||||
Consider using the builder method, below, if that doesn't work for you.)
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
// The client configuration describes how to connect to the Tor network,
|
||||
// and what directories to use for storing persistent state.
|
||||
let config = TorClientConfig::default();
|
||||
|
@ -74,7 +74,7 @@ bootstrap (or having to use an `await`). This can be done by making a
|
|||
The returned client can be made to bootstrap when it is first used (the
|
||||
default), or not; see [`BootstrapBehavior`] for more details.
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
// Specifying `BootstrapBehavior::OnDemand` means the client will automatically
|
||||
// bootstrap when it is used. `Manual` exists if you'd rather have full control.
|
||||
let tor_client = TorClient::builder()
|
||||
|
@ -93,7 +93,7 @@ those traits if the `tokio` crate feature is enabled.
|
|||
|
||||
### Example: making connections over Tor
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
#
|
||||
// Initiate a connection over Tor to example.com, port 80.
|
||||
let mut stream = tor_client.connect(("example.com", 80)).await?;
|
||||
|
|
|
@ -1,242 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! High-level functionality for accessing the Tor network as a client.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The `arti-client` crate aims to provide a safe, easy-to-use API for
|
||||
//! applications that want to use the Tor network to anonymize their traffic.
|
||||
//!
|
||||
//! This crate is part of [Arti](https://gitlab.torproject.org/tpo/core/arti/),
|
||||
//! a project to implement [Tor](https://www.torproject.org/) in Rust. It is the
|
||||
//! highest-level library crate in Arti, and the one that nearly all client-only
|
||||
//! programs should use. Most of its functionality is provided by lower-level
|
||||
//! crates in Arti.
|
||||
//!
|
||||
//! ## Shape of the API, and relationship to other crates
|
||||
//!
|
||||
//! The API here is great if you are building an application in async Rust
|
||||
//! and want your Tor connections as async streams (`AsyncRead`/`AsyncWrite`).
|
||||
//! If you are wanting to make HTTP requests,
|
||||
//! look at [arti_hyper](https://tpo.pages.torproject.net/core/doc/rust/arti_hyper/index.html)).
|
||||
//!
|
||||
//! If you are trying to glue Arti to some other programming language,
|
||||
//! right now your best bet is probably to spawn the
|
||||
//! [`arti` CLI](https://tpo.pages.torproject.net/core/doc/rust/arti/index.html)
|
||||
//! SOCKS proxy,
|
||||
//! as a subprocess.
|
||||
//! We don't yet offer an API that would be nice to expose via FFI;
|
||||
//! we intend to add this in the future.
|
||||
//!
|
||||
//! ## ⚠ Warnings ⚠
|
||||
//!
|
||||
//! Also note that the APIs for this crate are not all yet completely stable.
|
||||
//! We'll try not to break things without good reason, and we'll follow semantic
|
||||
//! versioning when we do, but please expect a certain amount of breakage
|
||||
//! between now and us declaring `arti-client` 1.x.
|
||||
//!
|
||||
//! The APIs exposed by lower-level crates in Arti are _even more unstable_;
|
||||
//! they will break more often than those from `arti-client`, for less reason.
|
||||
//!
|
||||
//! # Using `arti-client`
|
||||
//!
|
||||
//! The main entry point for this crate is the [`TorClient`], an object that
|
||||
//! lets you make connections over the Tor network.
|
||||
//!
|
||||
//! ## Connecting to Tor
|
||||
//!
|
||||
//! Calling [`TorClient::create_bootstrapped`] establishes a connection to the
|
||||
//! Tor network, pulling in necessary state about network consensus as required.
|
||||
//! This state gets persisted to the locations specified in the
|
||||
//! [`TorClientConfig`].
|
||||
//!
|
||||
//! (This method requires you to initialize the client in an `async fn`.
|
||||
//! Consider using the builder method, below, if that doesn't work for you.)
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # use anyhow::Result;
|
||||
//! # use arti_client::{TorClient, TorClientConfig};
|
||||
//! # use tokio_crate as tokio;
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() -> Result<()> {
|
||||
//! // The client configuration describes how to connect to the Tor network,
|
||||
//! // and what directories to use for storing persistent state.
|
||||
//! let config = TorClientConfig::default();
|
||||
//!
|
||||
//! // Start the Arti client, and let it bootstrap a connection to the Tor network.
|
||||
//! // (This takes a while to gather the necessary directory information.
|
||||
//! // It uses cached information when possible.)
|
||||
//! let tor_client = TorClient::create_bootstrapped(config).await?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Creating a client and connecting later
|
||||
//!
|
||||
//! You might wish to create a Tor client immediately, without waiting for it to
|
||||
//! bootstrap (or having to use an `await`). This can be done by making a
|
||||
//! [`TorClientBuilder`] with [`TorClient::builder`], and calling
|
||||
//! [`TorClientBuilder::create_unbootstrapped`].
|
||||
//!
|
||||
//! The returned client can be made to bootstrap when it is first used (the
|
||||
//! default), or not; see [`BootstrapBehavior`] for more details.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # use anyhow::Result;
|
||||
//! # use arti_client::{TorClient, TorClientConfig};
|
||||
//! # use tokio_crate as tokio;
|
||||
//! # use arti_client::BootstrapBehavior;
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() -> Result<()> {
|
||||
//! // Specifying `BootstrapBehavior::OnDemand` means the client will automatically
|
||||
//! // bootstrap when it is used. `Manual` exists if you'd rather have full control.
|
||||
//! let tor_client = TorClient::builder()
|
||||
//! .bootstrap_behavior(BootstrapBehavior::OnDemand)
|
||||
//! .create_unbootstrapped()?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Using the client
|
||||
//!
|
||||
//! A client can then be used to make connections over Tor with
|
||||
//! [`TorClient::connect`], which accepts anything implementing [`IntoTorAddr`].
|
||||
//! This returns a [`DataStream`], an anonymized TCP stream type that implements
|
||||
//! [`AsyncRead`](futures::io::AsyncRead) and
|
||||
//! [`AsyncWrite`](futures::io::AsyncWrite), as well as the Tokio versions of
|
||||
//! those traits if the `tokio` crate feature is enabled.
|
||||
//!
|
||||
//! ## Example: making connections over Tor
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # use anyhow::Result;
|
||||
//! # use arti_client::{TorClient, TorClientConfig};
|
||||
//! # use tokio_crate as tokio;
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() -> Result<()> {
|
||||
//! # let config = TorClientConfig::default();
|
||||
//! # let tor_client = TorClient::create_bootstrapped(config).await?;
|
||||
//! #
|
||||
//! // Initiate a connection over Tor to example.com, port 80.
|
||||
//! let mut stream = tor_client.connect(("example.com", 80)).await?;
|
||||
//!
|
||||
//! use futures::io::{AsyncReadExt, AsyncWriteExt};
|
||||
//!
|
||||
//! // Write out an HTTP request.
|
||||
//! stream
|
||||
//! .write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n")
|
||||
//! .await?;
|
||||
//!
|
||||
//! // IMPORTANT: Make sure the request was written.
|
||||
//! // Arti buffers data, so flushing the buffer is usually required.
|
||||
//! stream.flush().await?;
|
||||
//!
|
||||
//! // Read and print the result.
|
||||
//! let mut buf = Vec::new();
|
||||
//! stream.read_to_end(&mut buf).await?;
|
||||
//!
|
||||
//! println!("{}", String::from_utf8_lossy(&buf));
|
||||
//! #
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## More advanced usage
|
||||
//!
|
||||
//! This version of Arti includes basic support for "stream isolation": the
|
||||
//! ability to ensure that different TCP connections ('streams') go over
|
||||
//! different Tor circuits (and thus different exit nodes, making them originate
|
||||
//! from different IP addresses).
|
||||
//!
|
||||
//! This is useful to avoid deanonymizing users by correlation: for example, you
|
||||
//! might want a Tor connection to your bank and a Tor connection to an online
|
||||
//! forum to use different circuits, to avoid the possibility of the two
|
||||
//! identities being linked by having the same source IP.
|
||||
//!
|
||||
//! Streams can be isolated in two ways:
|
||||
//!
|
||||
//! - by calling [`TorClient::isolated_client`], which returns a new
|
||||
//! [`TorClient`] whose streams will use a different circuit
|
||||
//! - by generating [`IsolationToken`]s, and passing them in via [`StreamPrefs`]
|
||||
//! to [`TorClient::connect`].
|
||||
//!
|
||||
//! # Multiple runtime support
|
||||
//!
|
||||
//! Arti uses the [`tor_rtcompat`] crate to support multiple asynchronous
|
||||
//! runtimes; currently, both [Tokio](https://tokio.rs) and
|
||||
//! [async-std](https://async.rs) are supported.
|
||||
//!
|
||||
//! The backend Arti uses for TCP connections ([`tor_rtcompat::TcpProvider`])
|
||||
//! and for creating TLS sessions ([`tor_rtcompat::TlsProvider`]) is also
|
||||
//! configurable using this crate. This can be used to embed Arti in custom
|
||||
//! environments where you want lots of control over how it uses the network.
|
||||
//!
|
||||
//! [**View the `tor_rtcompat` crate documentation**](tor_rtcompat) for more
|
||||
//! about these features.
|
||||
//!
|
||||
//! # Feature flags
|
||||
//!
|
||||
//! ## Additive features
|
||||
//!
|
||||
//! * `tokio` (default) -- build with [Tokio](https://tokio.rs/) support
|
||||
//! * `native-tls` (default) -- build with the
|
||||
//! [native-tls](https://github.com/sfackler/rust-native-tls) crate for TLS
|
||||
//! support
|
||||
//! * `async-std` -- build with [async-std](https://async.rs/) support
|
||||
//!
|
||||
//! * `full` -- Build with all features above, along with all stable additive
|
||||
//! features from other arti crates. (This does not include experimental
|
||||
//! features. It also does not include features that select a particular
|
||||
//! implementation to the exclusion of another, or those that set a build
|
||||
//! flag.)
|
||||
//!
|
||||
//! * `rustls` -- build with the [rustls](https://github.com/rustls/rustls)
|
||||
//! crate for TLS support. This is not included in `full`, since it uses the
|
||||
//! `ring` crate, which uses the old (3BSD/SSLEay) OpenSSL license, which may
|
||||
//! introduce licensing compatibility issues.
|
||||
//!
|
||||
//! Note that flags `tokio`, `native-tls`, `async-std`, `rustls` and `static`
|
||||
//! will enable the flags of the same name on the [`tor_rtcompat`] crate.
|
||||
//!
|
||||
//! ## Build-flag related features
|
||||
//!
|
||||
//! * `static` -- link with static versions of Arti's system dependencies, like
|
||||
//! SQLite and OpenSSL (⚠ Warning ⚠: this feature will include a dependency on
|
||||
//! native-tls, even if you weren't planning to use native-tls. If you only
|
||||
//! want to build with a static sqlite library, enable the `static-sqlite`
|
||||
//! feature. We'll look for better solutions here in the future.)
|
||||
//! * `static-sqlite` -- link with a static version of sqlite.
|
||||
//! * `static-native-tls` -- link with a static version of `native-tls`. Enables
|
||||
//! `native-tls`.
|
||||
//!
|
||||
//! ## Cryptographic acceleration features
|
||||
//!
|
||||
//! Libraries should not enable these by default, since they replace one
|
||||
//! implementation with another.
|
||||
//!
|
||||
//! * `accel-sha1-asm` -- Accelerate cryptography by using an assembly
|
||||
//! implementation of SHA1, if one is available.
|
||||
//! * `accel-openssl` -- Accelerate cryptography by using openssl as a backend.
|
||||
//!
|
||||
//! ## Experimental and unstable features
|
||||
//!
|
||||
//! Note that the APIs enabled by these features are NOT covered by semantic
|
||||
//! versioning[^1] guarantees: we might break them or remove them between patch
|
||||
//! versions.
|
||||
//!
|
||||
//! * `bridge-client` -- Build with (as yet unimplemented) support for bridges
|
||||
//! * `pt-client` -- Build with (as yet unimplemented) support for pluggable transports
|
||||
//! * `experimental-api` -- build with experimental, unstable API support.
|
||||
//! * `error_detail` -- expose the `arti_client::Error` inner error type.
|
||||
//! * `dirfilter` -- expose the `DirFilter` API, which lets you modify a network
|
||||
//! directory before it is used.
|
||||
//!
|
||||
//! * `experimental` -- Build with all experimental features above, along with
|
||||
//! all experimental features from other arti crates.
|
||||
//!
|
||||
//! [^1]: Remember, semantic versioning is what makes various `cargo` features
|
||||
//! work reliably. To be explicit: if you want `cargo update` to _only_ make safe
|
||||
//! changes, then you cannot enable these features.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `arti-config`: Removed crate. (Tools for configuration management in Arti)
|
||||
//!
|
||||
//! This crate was part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! The project continues, but this particular crate is now superseded.
|
||||
//! This empty crate is published as a tombstone.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! High-level layer for making http(s) requests the Tor network as a client.
|
||||
//!
|
||||
//! This can be used by applications which embed Arti,
|
||||
//! and could also be used as an example of how to build on top of [`arti_client`].
|
||||
//!
|
||||
//! There is an example program [`hyper.rs`] which uses `arti-hyper`
|
||||
//! to connect to Tor and make a single HTTP\[S] request.
|
||||
//!
|
||||
//! [`hyper.rs`]: <https://gitlab.torproject.org/tpo/core/arti/-/blob/main/crates/arti-hyper/examples/hyper.rs>
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -63,7 +63,7 @@ To do so, we will launch arti independently from Tor Browser. Build arti with
|
|||
`cargo build --release`. After that launch it with some basic
|
||||
configuration parameters:
|
||||
|
||||
```
|
||||
```text
|
||||
$ ./target/release/arti proxy -l debug -p 9150
|
||||
```
|
||||
|
||||
|
@ -72,13 +72,13 @@ Tor Browser and instruct it to use that SOCKS port.
|
|||
|
||||
#### Linux
|
||||
|
||||
```
|
||||
```text
|
||||
$ TOR_SKIP_LAUNCH=1 TOR_SOCKS_PORT=9150 TOR_SKIP_CONTROLPORTTEST=1 ./start-tor-browser.desktop
|
||||
```
|
||||
|
||||
#### OS X
|
||||
|
||||
```
|
||||
```text
|
||||
$ TOR_SKIP_LAUNCH=1 TOR_SOCKS_PORT=9150 TOR_SKIP_CONTROLPORTTEST=1 /path/to/Tor\ Browser/Contents/MacOS/firefox
|
||||
```
|
||||
|
||||
|
@ -86,13 +86,13 @@ $ TOR_SKIP_LAUNCH=1 TOR_SOCKS_PORT=9150 TOR_SKIP_CONTROLPORTTEST=1 /path/to/Tor\
|
|||
|
||||
Create a shortcut with the `Target` set to:
|
||||
|
||||
```
|
||||
```text
|
||||
C:\Windows\System32\cmd.exe /c "SET TOR_SKIP_LAUNCH=1&& SET TOR_SOCKS_PORT=9150&& TOR_SKIP_CONTROLPORTTEST=1&& START /D ^"C:\path\to\Tor Browser\Browser^" firefox.exe"
|
||||
```
|
||||
|
||||
and `Start in` set to:
|
||||
|
||||
```
|
||||
```text
|
||||
"C:\path\to\Tor Browser\Browser"
|
||||
```
|
||||
|
||||
|
|
|
@ -1,191 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! A minimal command line program for connecting to the Tor network
|
||||
//!
|
||||
//! (If you want a more general Tor client library interface, use
|
||||
//! [`arti_client`].)
|
||||
//!
|
||||
//! This crate is the primary command-line interface for
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to implement
|
||||
//! [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! Currently Arti can can run as a simple SOCKS proxy over the Tor network.
|
||||
//! It will listen on port 9150 by default,
|
||||
//! but you can override this in the configuration.
|
||||
//! You can direct programs to connect via that SOCKS port,
|
||||
//! and their connections will be anonymized via Tor.
|
||||
//! Note: you might not want to run a conventional web browser this way.
|
||||
//! Browsers leak much private information.
|
||||
//! To browse the web anonymously,
|
||||
//! we recommend [using Tor Browser](#using-arti-with-tor-browser).
|
||||
//!
|
||||
//! Arti is still advancing rapidly; we are adding features and eventually
|
||||
//! we hope it will be able to replace C Tor.
|
||||
//!
|
||||
//! # Command-line interface
|
||||
//!
|
||||
//! (This is not stable; future versions will break this.)
|
||||
//!
|
||||
//! `arti` uses the [`clap`](https://docs.rs/clap/) crate for command-line
|
||||
//! argument parsing; run `arti help` to get it to print its documentation.
|
||||
//!
|
||||
//! The only currently implemented subcommand is `arti proxy`; try `arti help
|
||||
//! proxy` for a list of options you can pass to it.
|
||||
//!
|
||||
//! # Configuration
|
||||
//!
|
||||
//! By default, `arti` looks for its configuration files in a platform-dependent
|
||||
//! location.
|
||||
//!
|
||||
//! | OS | Configuration File |
|
||||
//! |---------|----------------------------------------------------|
|
||||
//! | Unix | `~/.config/arti/arti.toml` |
|
||||
//! | macOS | `~/Library/Application Support/arti/arti.toml` |
|
||||
//! | Windows | `\Users\<USERNAME>\AppData\Roaming\arti\arti.toml` |
|
||||
//!
|
||||
//! The configuration file is TOML.
|
||||
//! For an example see `arti-example-config.toml`
|
||||
//! (a copy of which is in the source tree,
|
||||
//! and also
|
||||
//! [in the Arti repository](https://gitlab.torproject.org/tpo/core/arti/-/blob/main/crates/arti/src/arti-example-config.toml)).
|
||||
//! That example config file documents the configuration options.
|
||||
//!
|
||||
//! More detailed information about for the individual fields is available in the documentation
|
||||
//! for the Rust APIs [`ApplicationConfigBuilder`] and
|
||||
//! [`TorClientConfigBuilder`](arti_client::config::TorClientConfigBuilder).
|
||||
//!
|
||||
//! # Using Arti with Tor Browser
|
||||
//!
|
||||
//! It is possible to hook up Arti with
|
||||
//! [Tor Browser](https://www.torproject.org/download/).
|
||||
//!
|
||||
//! To do so, we will launch arti independently from Tor Browser. Build arti with
|
||||
//! `cargo build --release`. After that launch it with some basic
|
||||
//! configuration parameters:
|
||||
//!
|
||||
//! ```text
|
||||
//! $ ./target/release/arti proxy -l debug -p 9150
|
||||
//! ```
|
||||
//!
|
||||
//! This will ensure that arti sets its SOCKS port on 9150. Now we need to launch
|
||||
//! Tor Browser and instruct it to use that SOCKS port.
|
||||
//!
|
||||
//! ### Linux
|
||||
//!
|
||||
//! ```text
|
||||
//! $ TOR_SKIP_LAUNCH=1 TOR_SOCKS_PORT=9150 TOR_SKIP_CONTROLPORTTEST=1 ./start-tor-browser.desktop
|
||||
//! ```
|
||||
//!
|
||||
//! ### OS X
|
||||
//!
|
||||
//! ```text
|
||||
//! $ TOR_SKIP_LAUNCH=1 TOR_SOCKS_PORT=9150 TOR_SKIP_CONTROLPORTTEST=1 /path/to/Tor\ Browser/Contents/MacOS/firefox
|
||||
//! ```
|
||||
//!
|
||||
//! ### Windows
|
||||
//!
|
||||
//! Create a shortcut with the `Target` set to:
|
||||
//!
|
||||
//! ```text
|
||||
//! C:\Windows\System32\cmd.exe /c "SET TOR_SKIP_LAUNCH=1&& SET TOR_SOCKS_PORT=9150&& TOR_SKIP_CONTROLPORTTEST=1&& START /D ^"C:\path\to\Tor Browser\Browser^" firefox.exe"
|
||||
//! ```
|
||||
//!
|
||||
//! and `Start in` set to:
|
||||
//!
|
||||
//! ```text
|
||||
//! "C:\path\to\Tor Browser\Browser"
|
||||
//! ```
|
||||
//!
|
||||
//! (You may need to adjust the actual path to wherever you have put your Tor
|
||||
//! Browser.)
|
||||
//!
|
||||
//! The resulting Tor Browser should be using arti. Note that onion services
|
||||
//! and bridges won't work (Arti doesn't support them yet), and neither will
|
||||
//! any feature depending on Tor's control-port protocol. Features not depending
|
||||
//! on the control-port such as the "New circuit for this site" button should
|
||||
//! work.
|
||||
//!
|
||||
//! # Compile-time features
|
||||
//!
|
||||
//! ## Additive features
|
||||
//!
|
||||
//! * `tokio` (default): Use the tokio runtime library as our backend.
|
||||
//! * `async-std`: Use the async-std runtime library as our backend. This
|
||||
//! feature has no effect unless building with `--no-default-features` to
|
||||
//! disable tokio.
|
||||
//! * `native-tls` -- Build with support for the `native_tls` TLS backend.
|
||||
//! (default)
|
||||
//! * `journald` -- Build with support for logging to the `journald` logging
|
||||
//! backend (available as part of systemd.)
|
||||
//! * `dns-proxy` (default) -- Build with support for proxying certain simple
|
||||
//! DNS queries over the Tor network.
|
||||
//! * `harden` (default) -- Build with support for hardening the Arti process by
|
||||
//! disabling debugger attachment and other local memory-inspection vectors.
|
||||
//!
|
||||
//! * `full` -- Build with all features above, along with all stable additive
|
||||
//! features from other arti crates. (This does not include experimental
|
||||
//! features. It also does not include features that select a particular
|
||||
//! implementation to the exclusion of another, or those that set a build
|
||||
//! flag.)
|
||||
//!
|
||||
//! * `rustls` -- build with the [rustls](https://github.com/rustls/rustls)
|
||||
//! TLS backend. This is not included in `full`, since it uses the
|
||||
//! `ring` crate, which uses the old (3BSD/SSLEay) OpenSSL license, which may
|
||||
//! introduce licensing compatibility issues.
|
||||
//!
|
||||
//! ## Build-flag related features
|
||||
//!
|
||||
//! * `static` -- Link with static versions of your system dependencies,
|
||||
//! including sqlite and/or openssl. (⚠ Warning ⚠: this feature will include
|
||||
//! a dependency on native-tls, even if you weren't planning to use
|
||||
//! native-tls. If you only want to build with a static sqlite library,
|
||||
//! enable the `static-sqlite` feature. We'll look for better solutions here
|
||||
//! in the future.)
|
||||
//! * `static-sqlite` -- Link with a static version of sqlite.
|
||||
//! * `static-native-tls` -- Link with a static version of `native-tls`. Enables
|
||||
//! `native-tls`.
|
||||
//!
|
||||
//! ## Cryptographic acceleration features
|
||||
//!
|
||||
//! Libraries should not enable these by default, since they replace one
|
||||
//! implementation with another.
|
||||
//!
|
||||
//! * `accel-sha1-asm` -- Accelerate cryptography by using an assembly
|
||||
//! implementation of SHA1, if one is available.
|
||||
//! * `accel-openssl` -- Accelerate cryptography by using openssl as a backend.
|
||||
//!
|
||||
//! ## Experimental features
|
||||
//!
|
||||
//! Note that the APIs enabled by these features are NOT covered by semantic
|
||||
//! versioning[^1] guarantees: we might break them or remove them between patch
|
||||
//! versions.
|
||||
//!
|
||||
//! * `bridge-client` -- Build with (as yet unimplemented) support for bridges
|
||||
//! * `pt-client` -- Build with (as yet unimplemented) support for pluggable transports
|
||||
//! * `experimental-api` -- build with experimental, unstable API support.
|
||||
//! (Right now, most APIs in the `arti` crate are experimental, since this
|
||||
//! crate was originally written to run as a binary only.)
|
||||
//! * `experimental` -- Build with all experimental features above, along with
|
||||
//! all experimental features from other arti crates.
|
||||
//!
|
||||
//! [^1]: Remember, semantic versioning is what makes various `cargo` features
|
||||
//! work reliably. To be explicit, if you want `cargo update` to _only_ make
|
||||
//! correct changes, then you cannot enable these features.
|
||||
//!
|
||||
//! # Limitations
|
||||
//!
|
||||
//! There are many missing features. Among them: there's no onion service
|
||||
//! support yet. There's no anti-censorship support. You can't be a relay.
|
||||
//! There isn't any kind of proxy besides SOCKS.
|
||||
//!
|
||||
//! See the [repository README
|
||||
//! file](https://gitlab.torproject.org/tpo/core/arti/-/blob/main/README.md) for
|
||||
//! a more complete list of missing features.
|
||||
//!
|
||||
//! # Library for building command-line client
|
||||
//!
|
||||
//! This library crate contains code useful for making a command line program
|
||||
//! similar to `arti`. The API should not be considered stable.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,43 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `caret`: Integers with some named values.
|
||||
//!
|
||||
//! # Crikey! Another Rust Enum Tool?
|
||||
//!
|
||||
//! Suppose you have an integer type with some named values. For
|
||||
//! example, you might be implementing a protocol where "command" can
|
||||
//! be any 8-bit value, but where only a small number of commands are
|
||||
//! recognized.
|
||||
//!
|
||||
//! In that case, you can use the [`caret_int`] macro to define a
|
||||
//! wrapper around `u8` so named values are displayed with their
|
||||
//! preferred format, but you can still represent all the other values
|
||||
//! of the field:
|
||||
//!
|
||||
//! ```
|
||||
//! use caret::caret_int;
|
||||
//! caret_int!{
|
||||
//! struct Command(u8) {
|
||||
//! Get = 0,
|
||||
//! Put = 1,
|
||||
//! Swap = 2,
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! let c1: Command = 2.into();
|
||||
//! let c2: Command = 100.into();
|
||||
//!
|
||||
//! assert_eq!(c1.to_string().as_str(), "Swap");
|
||||
//! assert_eq!(c2.to_string().as_str(), "100");
|
||||
//!
|
||||
//! assert_eq!(c1, Command::Swap);
|
||||
//! ```
|
||||
//!
|
||||
//! This crate is developed as part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! Many other crates in Arti depend on it, but it should be of general
|
||||
//! use.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -111,7 +111,8 @@ match Mistrust::new().make_directory("/home/itchy/.local/hat-swap") {
|
|||
|
||||
You can adjust the [`Mistrust`] object to change what it permits:
|
||||
|
||||
```rust
|
||||
```rust,no_run
|
||||
# fn main() -> Result<(), fs_mistrust::Error> {
|
||||
use fs_mistrust::Mistrust;
|
||||
|
||||
let my_mistrust = Mistrust::builder()
|
||||
|
@ -121,6 +122,8 @@ let my_mistrust = Mistrust::builder()
|
|||
// available on Unix-like platforms).
|
||||
// .trust_group(413)
|
||||
.build()?;
|
||||
# Ok(())
|
||||
# }
|
||||
```
|
||||
|
||||
See [`Mistrust`] for more options.
|
||||
|
@ -132,7 +135,8 @@ For more fine-grained control over a specific check, you can use the
|
|||
configure for several requests, the changes in [`Verifier`] generally make
|
||||
sense only for one request at a time.
|
||||
|
||||
```rust
|
||||
```rust,no_run
|
||||
# fn main() -> Result<(), fs_mistrust::Error> {
|
||||
use fs_mistrust::Mistrust;
|
||||
let mistrust = Mistrust::new();
|
||||
|
||||
|
@ -153,6 +157,8 @@ mistrust
|
|||
.check_content()
|
||||
.all_errors()
|
||||
.make_directory("/home/trace/private_keys/");
|
||||
# Ok(())
|
||||
# }
|
||||
```
|
||||
|
||||
See [`Verifier`] for more options.
|
||||
|
@ -163,7 +169,8 @@ You can use the [`CheckedDir`] API to ensure not only that a directory is
|
|||
private, but that all of your accesses to its contents continue to verify
|
||||
and enforce _their_ permissions.
|
||||
|
||||
```rust
|
||||
```rust,no_run
|
||||
# fn main() -> Result<(), fs_mistrust::Error> {
|
||||
use fs_mistrust::{Mistrust, CheckedDir};
|
||||
use std::fs::{File, OpenOptions};
|
||||
let dir = Mistrust::new()
|
||||
|
@ -177,6 +184,8 @@ dir.make_directory("timelines")?;
|
|||
let file = dir.open("timelines/vault-destroyed.md",
|
||||
OpenOptions::new().write(true).create(true))?;
|
||||
// (... use file...)
|
||||
# Ok(())
|
||||
# }
|
||||
```
|
||||
|
||||
### Limitations
|
||||
|
|
|
@ -1,244 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! # `fs-mistrust`: check whether file permissions are private.
|
||||
//!
|
||||
//! This crate provides a set of functionality to check the permissions on files
|
||||
//! and directories to ensure that they are effectively private—that is, that
|
||||
//! they are only readable or writable by trusted[^1] users.
|
||||
//!
|
||||
//! This kind of check can protect your users' data against misconfigurations,
|
||||
//! such as cases where they've accidentally made their home directory
|
||||
//! world-writable, or where they're using a symlink stored in a directory owned
|
||||
//! by another user.
|
||||
//!
|
||||
//! The checks in this crate try to guarantee that, after a path has been shown
|
||||
//! to be private, no action by a _non-trusted user_ can make that path private.
|
||||
//! It's still possible for a _trusted user_ to change a path after it has been
|
||||
//! checked. Because of that, you may want to use other mechanisms if you are
|
||||
//! concerned about time-of-check/time-of-use issues caused by _trusted_ users
|
||||
//! altering the filesystem.
|
||||
//!
|
||||
//! Also see the [Limitations](#limitations) section below.
|
||||
//!
|
||||
//! [^1]: we define "trust" here in the computer-security sense of the word: a
|
||||
//! user is "trusted" if they have the opportunity to break our security
|
||||
//! guarantees. For example, `root` on a Unix environment is "trusted",
|
||||
//! whether you actually trust them or not.
|
||||
//!
|
||||
//! ## What's so hard about checking permissions?
|
||||
//!
|
||||
//! Suppose that we want to know whether a given path can be read or modified by
|
||||
//! an untrusted user. That's trickier than it sounds:
|
||||
//!
|
||||
//! * Even if the permissions on the file itself are correct, we also need to
|
||||
//! check the permissions on the directory holding it, since they might allow
|
||||
//! an untrusted user to replace the file, or change its permissions.
|
||||
//! * Similarly, we need to check the permissions on the parent of _that_
|
||||
//! directory, since they might let an untrusted user replace the directory or
|
||||
//! change _its_ permissions. (And so on!)
|
||||
//! * It can be tricky to define "a trusted user". On Unix systems, we usually
|
||||
//! say that each user is trusted by themself, and that root (UID 0) is
|
||||
//! trusted. But it's hard to say which _groups_ are trusted: even if a given
|
||||
//! group contains only trusted users today, there's no OS-level guarantee
|
||||
//! that untrusted users won't be added to that group in the future.
|
||||
//! * Symbolic links add another layer of confusion. If there are any symlinks
|
||||
//! in the path you're checking, then you need to check permissions on the
|
||||
//! directory containing the symlink, and then the permissions on the target
|
||||
//! path, _and all of its ancestors_ too.
|
||||
//! * Many programs first canonicalize the path being checked, removing all
|
||||
//! `..`s and symlinks. That's sufficient for telling whether the _final_
|
||||
//! file can be modified by an untrusted user, but not for whether the _path_
|
||||
//! can be modified by an untrusted user. If there is a modifiable symlink in
|
||||
//! the middle of the path, or at any stage of the path resolution, somebody
|
||||
//! who can modify that symlink can change which file the path points to.
|
||||
//! * Even if you have checked a directory as being writeable only by a trusted
|
||||
//! user, that doesn't mean that the objects _in_ that directory are only
|
||||
//! writeable by trusted users. Those objects might be symlinks to some other
|
||||
//! (more writeable) place on the file system; or they might be accessible
|
||||
//! with hard links stored elsewhere on the file system.
|
||||
//!
|
||||
//! Different programs try to solve this problem in different ways, often with
|
||||
//! very little rationale. This crate tries to give a reasonable implementation
|
||||
//! for file privacy checking and enforcement, along with clear justifications
|
||||
//! in its source for why it behaves that way.
|
||||
//!
|
||||
//!
|
||||
//! ## What we actually do
|
||||
//!
|
||||
//! To make sure that every step in the file resolution process is checked, we
|
||||
//! emulate that process on our own. We inspect each component in the provided
|
||||
//! path, to see whether it is modifiable by an untrusted user. If we encounter
|
||||
//! one or more symlinks, then we resolve every component of the path added by
|
||||
//! those symlink, until we finally reach the target.
|
||||
//!
|
||||
//! In effect, we are emulating `realpath` (or `fs::canonicalize` if you
|
||||
//! prefer), and looking at the permissions on every part of the filesystem we
|
||||
//! touch in doing so, to see who has permissions to change our target file or
|
||||
//! the process that led us to it.
|
||||
//!
|
||||
//! For groups, we use the following heuristic: If there is a group with the
|
||||
//! same name as the current user, and the current user belongs to that group,
|
||||
//! we assume that group is trusted. Otherwise, we treat all groups as
|
||||
//! untrusted.
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ### Simple cases
|
||||
//!
|
||||
//! Make sure that a directory is only readable or writeable by us (simple
|
||||
//! case):
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use fs_mistrust::Mistrust;
|
||||
//! match Mistrust::new().check_directory("/home/itchy/.local/hat-swap") {
|
||||
//! Ok(()) => println!("directory is good"),
|
||||
//! Err(e) => println!("problem with our hat-swap directory: {}", e),
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! As above, but create the directory, and its parents if they do not already
|
||||
//! exist.
|
||||
//!
|
||||
//! ```
|
||||
//! use fs_mistrust::Mistrust;
|
||||
//! match Mistrust::new().make_directory("/home/itchy/.local/hat-swap") {
|
||||
//! Ok(()) => println!("directory exists (or was created without trouble"),
|
||||
//! Err(e) => println!("problem with our hat-swap directory: {}", e),
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ### Configuring a [`Mistrust`]
|
||||
//!
|
||||
//! You can adjust the [`Mistrust`] object to change what it permits:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # fn example() -> fs_mistrust::Result<()> {
|
||||
//! use fs_mistrust::Mistrust;
|
||||
//!
|
||||
//! let my_mistrust = Mistrust::builder()
|
||||
//! // Assume that our home directory and its parents are all well-configured.
|
||||
//! .ignore_prefix("/home/doze/")
|
||||
//! // Assume that a given group will only contain trusted users (this feature is only
|
||||
//! // available on Unix-like platforms).
|
||||
//! // .trust_group(413)
|
||||
//! .build()?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! See [`Mistrust`] for more options.
|
||||
//!
|
||||
//! ### Using [`Verifier`] for more fine-grained checks
|
||||
//!
|
||||
//! For more fine-grained control over a specific check, you can use the
|
||||
//! [`Verifier`] API. Unlike [`Mistrust`], which generally you'll want to
|
||||
//! configure for several requests, the changes in [`Verifier`] generally make
|
||||
//! sense only for one request at a time.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # fn example() -> fs_mistrust::Result<()> {
|
||||
//! use fs_mistrust::Mistrust;
|
||||
//! let mistrust = Mistrust::new();
|
||||
//!
|
||||
//! // Require that an object is a regular file; allow it to be world-
|
||||
//! // readable.
|
||||
//! mistrust
|
||||
//! .verifier()
|
||||
//! .permit_readable()
|
||||
//! .require_file()
|
||||
//! .check("/home/trace/.path_cfg")?;
|
||||
//!
|
||||
//! // Make sure that a directory _and all of its contents_ are private.
|
||||
//! // Create the directory if it does not exist.
|
||||
//! // Return an error object containing _all_ of the problems discovered.
|
||||
//! mistrust
|
||||
//! .verifier()
|
||||
//! .require_directory()
|
||||
//! .check_content()
|
||||
//! .all_errors()
|
||||
//! .make_directory("/home/trace/private_keys/");
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! See [`Verifier`] for more options.
|
||||
//!
|
||||
//! ### Using [`CheckedDir`] for safety.
|
||||
//!
|
||||
//! You can use the [`CheckedDir`] API to ensure not only that a directory is
|
||||
//! private, but that all of your accesses to its contents continue to verify
|
||||
//! and enforce _their_ permissions.
|
||||
//!
|
||||
//! ```
|
||||
//! # fn example() -> anyhow::Result<()> {
|
||||
//! use fs_mistrust::{Mistrust, CheckedDir};
|
||||
//! use std::fs::{File, OpenOptions};
|
||||
//! let dir = Mistrust::new()
|
||||
//! .verifier()
|
||||
//! .secure_dir("/Users/clover/riddles")?;
|
||||
//!
|
||||
//! // You can use the CheckedDir object to access files and directories.
|
||||
//! // All of these must be relative paths within the path you used to
|
||||
//! // build the CheckedDir.
|
||||
//! dir.make_directory("timelines")?;
|
||||
//! let file = dir.open("timelines/vault-destroyed.md",
|
||||
//! OpenOptions::new().write(true).create(true))?;
|
||||
//! // (... use file...)
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Limitations
|
||||
//!
|
||||
//! As noted above, this crate only checks whether a path can be changed by
|
||||
//! _non-trusted_ users. After the path has been checked, a _trusted_ user can
|
||||
//! still change its permissions. (For example, the user could make their home
|
||||
//! directory world-writable.) This crate does not try to defend against _that
|
||||
//! kind_ of time-of-check/time-of-use issue.
|
||||
//!
|
||||
//! We currently assume a fairly vanilla Unix environment: we'll tolerate other
|
||||
//! systems, but we don't actually look at the details of any of these:
|
||||
//! * Windows security (ACLs, SecurityDescriptors, etc)
|
||||
//! * SELinux capabilities
|
||||
//! * POSIX (and other) ACLs.
|
||||
//!
|
||||
//! We use a somewhat inaccurate heuristic when we're checking the permissions
|
||||
//! of items _inside_ a target directory (using [`Verifier::check_content`] or
|
||||
//! [`CheckedDir`]): we continue to forbid untrusted-writeable directories and
|
||||
//! files, but we still allow readable ones, even if we insisted that the target
|
||||
//! directory itself was required to to be unreadable. This is too permissive
|
||||
//! in the case of readable objects with hard links: if there is a hard link to
|
||||
//! the file somewhere else, then an untrusted user can read it. It is also too
|
||||
//! restrictive in the case of writeable objects _without_ hard links: if
|
||||
//! untrusted users have no path to those objects, they can't actually write
|
||||
//! them.
|
||||
//!
|
||||
//! On Windows, we accept all file permissions and owners.
|
||||
//!
|
||||
//! We don't check for mount-points and the privacy of filesystem devices
|
||||
//! themselves. (For example, we don't distinguish between our local
|
||||
//! administrator and the administrator of a remote filesystem. We also don't
|
||||
//! distinguish between local filesystems and insecure networked filesystems.)
|
||||
//!
|
||||
//! This code has not been audited for correct operation in a setuid
|
||||
//! environment; there are almost certainly security holes in that case.
|
||||
//!
|
||||
//! This is fairly new software, and hasn't been audited yet.
|
||||
//!
|
||||
//! All of the above issues are considered "good to fix, if practical".
|
||||
//!
|
||||
//! ## Acknowledgements
|
||||
//!
|
||||
//! The list of checks performed here was inspired by the lists from OpenSSH's
|
||||
//! [safe_path], GnuPG's [check_permissions], and Tor's [check_private_dir]. All
|
||||
//! errors are my own.
|
||||
//!
|
||||
//! [safe_path]:
|
||||
//! https://github.com/openssh/openssh-portable/blob/master/misc.c#L2177
|
||||
//! [check_permissions]:
|
||||
//! https://github.com/gpg/gnupg/blob/master/g10/gpg.c#L1551
|
||||
//! [check_private_dir]:
|
||||
//! https://gitlab.torproject.org/tpo/core/tor/-/blob/main/src/lib/fs/dir.c#L70
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// TODO: Stuff to add before this crate is ready....
|
||||
// - Test the absolute heck out of it.
|
||||
|
||||
|
|
|
@ -1,40 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! An error attempt to represent multiple failures.
|
||||
//!
|
||||
//! This crate implements [`RetryError`], a type to use when you
|
||||
//! retry something a few times, and all those attempts can fail differently
|
||||
//! each time. Instead of returning only a single error, it records
|
||||
//! _all of the errors received_, in case they are different.
|
||||
//!
|
||||
//! This crate is developed as part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! It's used by higher-level crates that retry
|
||||
//! operations.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ```rust
|
||||
//!use retry_error::RetryError;
|
||||
//!
|
||||
//!fn some_operation() -> anyhow::Result<bool> {
|
||||
//! unimplemented!(); // example
|
||||
//!}
|
||||
//!
|
||||
//!fn example() -> Result<(), RetryError<anyhow::Error>> {
|
||||
//! const N_ATTEMPTS: usize = 10;
|
||||
//! let mut err = RetryError::in_attempt_to("perform an example operation");
|
||||
//! for _ in 0..N_ATTEMPTS {
|
||||
//! match some_operation() {
|
||||
//! Ok(val) => return Ok(()),
|
||||
//! Err(e) => err.push(e),
|
||||
//! }
|
||||
//! }
|
||||
//! // All attempts failed; return all the errors.
|
||||
//! return Err(err);
|
||||
//!}
|
||||
//! ```
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -35,6 +35,9 @@ You can disable safe-logging globally (across all threads) or locally
|
|||
(across a single thread).
|
||||
|
||||
```rust
|
||||
# let debug_mode = true;
|
||||
# let log_encrypted_data = |_|();
|
||||
# let big_secret = ();
|
||||
use safelog::{disable_safe_logging, with_safe_logging_suppressed};
|
||||
|
||||
// If we're running in debug mode, turn off safe logging
|
||||
|
|
|
@ -1,74 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! # `safelog`: Mark data as sensitive for logging purposes.
|
||||
//!
|
||||
//! Some information is too sensitive to routinely write to system logs, but
|
||||
//! must nonetheless sometimes be displayed. This crate provides a way to mark
|
||||
//! such information, and log it conditionally, but not by default.
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! There are two main ways to mark a piece of data as sensitive: by storing it
|
||||
//! within a [`Sensitive`] object long-term, or by wrapping it in a
|
||||
//! [`Sensitive`] object right before passing it to a formatter:
|
||||
//!
|
||||
//! ```
|
||||
//! use safelog::{Sensitive, sensitive};
|
||||
//!
|
||||
//! // With this declaration, a student's name and gpa will be suppressed by default
|
||||
//! // when passing the student to Debug.
|
||||
//! #[derive(Debug)]
|
||||
//! struct Student {
|
||||
//! name: Sensitive<String>,
|
||||
//! grade: u8,
|
||||
//! homeroom: String,
|
||||
//! gpa: Sensitive<f32>,
|
||||
//! }
|
||||
//!
|
||||
//! // In this function, a user's IP will not be printed by default.
|
||||
//! fn record_login(username: &str, ip: &std::net::IpAddr) {
|
||||
//! println!("Login from {} at {}", username, sensitive(ip));
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! You can disable safe-logging globally (across all threads) or locally
|
||||
//! (across a single thread).
|
||||
//!
|
||||
//! ```
|
||||
//! use safelog::{disable_safe_logging, with_safe_logging_suppressed};
|
||||
//! # let debug_mode = false;
|
||||
//! # fn log_encrypted_data(s: &str) {}
|
||||
//! # let big_secret = "swordfish";
|
||||
//!
|
||||
//! // If we're running in debug mode, turn off safe logging
|
||||
//! // globally. Safe logging will remain disabled until the
|
||||
//! // guard object is dropped.
|
||||
//! let guard = if debug_mode {
|
||||
//! // This call can fail if safe logging has already been enforced.
|
||||
//! disable_safe_logging().ok()
|
||||
//! } else {
|
||||
//! None
|
||||
//! };
|
||||
//!
|
||||
//! // If we know that it's safe to record sensitive data with a given API,
|
||||
//! // we can disable safe logging temporarily. This affects only the current thread.
|
||||
//! with_safe_logging_suppressed(|| log_encrypted_data(big_secret));
|
||||
//! ```
|
||||
//!
|
||||
//! ## An example deployment
|
||||
//!
|
||||
//! This crate was originally created for use in the `arti` project, which tries
|
||||
//! to implements the Tor anonymity protocol in Rust. In `arti`, we want to
|
||||
//! avoid logging information by default if it could compromise users'
|
||||
//! anonymity, or create an incentive for attacking users and relays in order to
|
||||
//! access their logs.
|
||||
//!
|
||||
//! In general, Arti treats the following information as [`Sensitive`]:
|
||||
//! * Client addresses.
|
||||
//! * The destinations (target addresses) of client requests.
|
||||
//!
|
||||
//! Arti does _not_ label all private information as `Sensitive`: when
|
||||
//! information isn't _ever_ suitable for logging, we omit it entirely.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-basic-utils`: Utilities (low-level) for Tor
|
||||
//!
|
||||
//! Miscellaneous utilities for `tor-*` and `arti-*`.
|
||||
//!
|
||||
//! This crate lives at the *bottom* of the Tor crate stack.
|
||||
//! So it contains only utilities which have no `tor-*` (or `arti-*`) dependencies.
|
||||
//!
|
||||
//! There is no particular theme.
|
||||
//! More substantial sets of functionality with particular themes
|
||||
//! are to be found in other `tor-*` crates.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,53 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-bytes`: Utilities to decode/encode things into bytes.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The `tor-bytes` crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! Other crates in Arti use it to build and handle all the byte-encoded
|
||||
//! objects from the Tor protocol. For textual directory items, see
|
||||
//! the [`tor-netdoc`] crate.
|
||||
//!
|
||||
//! This crate is generally useful for encoding and decoding
|
||||
//! byte-oriented formats that are not regular enough to qualify for
|
||||
//! serde, and not complex enough to need a full meta-language. It is
|
||||
//! probably not suitable for handling anything bigger than a few
|
||||
//! kilobytes in size.
|
||||
//!
|
||||
//! ## Alternatives
|
||||
//!
|
||||
//! The Reader/Writer traits in std::io are more appropriate for
|
||||
//! operations that can fail because of some IO problem. This crate
|
||||
//! can't handle that: it is for handling things that are already in
|
||||
//! memory.
|
||||
//!
|
||||
//! TODO: Look into using the "bytes" crate more here.
|
||||
//!
|
||||
//! TODO: The "untrusted" crate has similar goals to our [`Reader`],
|
||||
//! but takes more steps to make sure it can never panic. Perhaps we
|
||||
//! should see if we can learn any tricks from it.
|
||||
//!
|
||||
//! TODO: Do we really want to keep `Reader` as a struct and
|
||||
//! `Writer` as a trait?
|
||||
//!
|
||||
//! # Contents and concepts
|
||||
//!
|
||||
//! This crate is structured around four key types:
|
||||
//!
|
||||
//! * [`Reader`]: A view of a byte slice, from which data can be decoded.
|
||||
//! * [`Writer`]: Trait to represent a growable buffer of bytes.
|
||||
//! (Vec<u8> and [`bytes::BytesMut`] implement this.)
|
||||
//! * [`Writeable`]: Trait for an object that can be encoded onto a [`Writer`]
|
||||
//! * [`Readable`]: Trait for an object that can be decoded from a [`Reader`].
|
||||
//!
|
||||
//! Every object you want to encode or decode should implement
|
||||
//! [`Writeable`] or [`Readable`] respectively.
|
||||
//!
|
||||
//! Once you implement these traits, you can use Reader and Writer to
|
||||
//! handle your type, and other types that are built around it.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,63 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Coding and decoding for the cell types that make up Tor's protocol
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! Tor's primary network protocol is oriented around a set of
|
||||
//! messages called "Cells". They exist at two primary layers of the
|
||||
//! protocol: the channel-cell layer, and the relay-cell layer.
|
||||
//!
|
||||
//! [Channel cells](chancell::ChanCell) are sent between relays, or
|
||||
//! between a client and a relay, over a TLS connection. Each of them
|
||||
//! encodes a single [Channel Message](chancell::msg::ChanMsg).
|
||||
//! Channel messages can affect the channel itself (such as those used
|
||||
//! to negotiate and authenticate the channel), but more frequently are
|
||||
//! used with respect to a given multi-hop circuit.
|
||||
//!
|
||||
//! Channel message that refer to a circuit do so with a channel-local
|
||||
//! identifier called a [Circuit ID](chancell::CircId). These
|
||||
//! messages include CREATE2 (used to extend a circuit to a first hop)
|
||||
//! and DESTROY (used to tear down a circuit). But the most
|
||||
//! frequently used channel message is RELAY, which is used to send a
|
||||
//! message to a given hop along a circuit.
|
||||
//!
|
||||
//! Each RELAY cell is encrypted and decrypted (according to protocols
|
||||
//! not implemented in this crate) until it reaches its target. When
|
||||
//! it does, it is decoded into a single [Relay
|
||||
//! Message](relaycell::msg::RelayMsg). Some of these relay messages
|
||||
//! are used to manipulate circuits (e.g., by extending the circuit to
|
||||
//! a new hop); others are used to manipulate anonymous data-streams
|
||||
//! (by creating them, ending them, or sending data); and still others
|
||||
//! are used for protocol-specific purposes (like negotiating with an
|
||||
//! onion service.)
|
||||
//!
|
||||
//! For a list of _most_ of the cell types used in Tor, see
|
||||
//! [tor-spec.txt](https://spec.torproject.org/tor-spec). Other cell
|
||||
//! types are defined in [rend-spec-v3.txt (for onion
|
||||
//! services)](https://spec.torproject.org/tor-spec) and
|
||||
//! [padding-spec.txt (for padding
|
||||
//! negotiation)](https://spec.torproject.org/padding-spec).
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! # Futureproofing note
|
||||
//!
|
||||
//! There are two pending proposals to remove the one-to-one
|
||||
//! correspondence between relay cells and relay messages.
|
||||
//!
|
||||
//! [Proposal 319](https://gitlab.torproject.org/tpo/core/torspec/-/blob/master/proposals/319-wide-everything.md)
|
||||
//! would add a "RELAY_FRAGMENT" command that would allow larger relay
|
||||
//! messages to span multiple RELAY cells.
|
||||
//!
|
||||
//! [Proposal 325](https://gitlab.torproject.org/tpo/core/torspec/-/blob/master/proposals/325-packed-relay-cells.md),
|
||||
//! on the other hand, would allow multiple relay messages to be
|
||||
//! packed into a single RELAY cell.
|
||||
//!
|
||||
//! The distinction between RelayCell and RelayMsg is meant in part
|
||||
//! to future-proof arti against these proposals if they are adopted.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,56 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Implementation for Tor certificates
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The `tor-cert` crate implements the binary certificate types
|
||||
//! documented in Tor's cert-spec.txt, which are used when
|
||||
//! authenticating Tor channels. (Eventually, support for onion service
|
||||
//! certificate support will get added too.)
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! There are other types of certificate used by Tor as well, and they
|
||||
//! are implemented in other places. In particular, see
|
||||
//! [`tor-netdoc::doc::authcert`] for the certificate types used by
|
||||
//! authorities in the directory protocol.
|
||||
//!
|
||||
//! ## Design notes
|
||||
//!
|
||||
//! The `tor-cert` code is in its own separate crate because it is
|
||||
//! required by several other higher-level crates that do not depend
|
||||
//! upon each other. For example, [`tor-netdoc`] parses encoded
|
||||
//! certificates from router descriptors, while [`tor-proto`] uses
|
||||
//! certificates when authenticating relays.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! Parsing, validating, and inspecting a certificate:
|
||||
//!
|
||||
//! ```
|
||||
//! use base64::decode;
|
||||
//! use tor_cert::*;
|
||||
//! use tor_checkable::*;
|
||||
//! // Taken from a random relay on the Tor network.
|
||||
//! let cert_base64 =
|
||||
//! "AQQABrntAThPWJ4nFH1L77Ar+emd4GPXZTPUYzIwmR2H6Zod5TvXAQAgBAC+vzqh
|
||||
//! VFO1SGATubxcrZzrsNr+8hrsdZtyGg/Dde/TqaY1FNbeMqtAPMziWOd6txzShER4
|
||||
//! qc/haDk5V45Qfk6kjcKw+k7cPwyJeu+UF/azdoqcszHRnUHRXpiPzudPoA4=";
|
||||
//! // Remove the whitespace, so base64 doesn't choke on it.
|
||||
//! let cert_base64: String = cert_base64.split_whitespace().collect();
|
||||
//! // Decode the base64.
|
||||
//! let cert_bin = base64::decode(cert_base64).unwrap();
|
||||
//!
|
||||
//! // Decode the cert and check its signature.
|
||||
//! let cert = Ed25519Cert::decode(&cert_bin).unwrap()
|
||||
//! .check_key(None).unwrap()
|
||||
//! .check_signature().unwrap()
|
||||
//! .dangerously_assume_timely();
|
||||
//! let signed_key = cert.subject_key();
|
||||
//! ```
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,38 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-chanmgr`: Manage a set of channels on the Tor network.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! In Tor, a channel is a connection to a Tor relay. It can be
|
||||
//! direct via TLS, or indirect via TLS over a pluggable transport.
|
||||
//! (For now, only direct channels are supported.)
|
||||
//!
|
||||
//! Since a channel can be used for more than one circuit, it's
|
||||
//! important to reuse channels when possible. This crate implements
|
||||
//! a [`ChanMgr`] type that can be used to create channels on demand,
|
||||
//! and return existing channels when they already exist.
|
||||
//! # Compile-time features
|
||||
//!
|
||||
//! ## Experimental and unstable features
|
||||
//!
|
||||
//! Note that the APIs enabled by these features are NOT covered by
|
||||
//! semantic versioning[^1] guarantees: we might break them or remove
|
||||
//! them between patch versions.
|
||||
//!
|
||||
//! * `pt-client` -- Build with (as yet unimplemented) APIs to support
|
||||
//! pluggable transports.
|
||||
//!
|
||||
//! * `experimental` -- Build with all experimental features above.
|
||||
//!
|
||||
//! [^1]: Remember, semantic versioning is what makes various `cargo`
|
||||
//! features work reliably. To be explicit: if you want `cargo update`
|
||||
//! to _only_ make safe changes, then you cannot enable these
|
||||
//! features.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,48 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Traits for wrapping up signed and/or time-bound objects
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! Frequently (for testing reasons or otherwise), we want to ensure
|
||||
//! that an object can only be used if a signature is valid, or if
|
||||
//! some timestamp is recent enough.
|
||||
//!
|
||||
//! As an example, consider a self-signed certificate. You can parse
|
||||
//! it cheaply enough (and find its key by doing so), but you probably
|
||||
//! want to make sure that nobody will use that certificate unless its
|
||||
//! signature is correct and its timestamps are not expired.
|
||||
//!
|
||||
//! With the tor-checkable crate, you can instead return an object
|
||||
//! that represents the certificate in its unchecked state. The
|
||||
//! caller can access the certificate, but only after checking the
|
||||
//! signature and the time.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! Many other crates in Arti depend on it, but it should be generally
|
||||
//! useful outside of Arti.
|
||||
//!
|
||||
//! ## Design notes and alternatives
|
||||
//!
|
||||
//! The types in this crate provide functions to return the underlying
|
||||
//! objects without checking them. This is very convenient for testing,
|
||||
//! though you wouldn't want to do it in production code. To prevent
|
||||
//! mistakes, these functions all begin with the word `dangerously`.
|
||||
//!
|
||||
//! Another approach you might take is to put signature and timeliness
|
||||
//! checks inside your parsing function. But if you do that, it will
|
||||
//! get hard to test your code: you will only be able to parse
|
||||
//! certificates that are valid when the parser is running. And if
|
||||
//! you want to test parsing a new kind of certificate, you'll need to
|
||||
//! make sure to put a valid signature on it. (And all of this
|
||||
//! signature parsing will slow down any attempts to fuzz your
|
||||
//! parser.)
|
||||
//!
|
||||
//! You could have your parser take a flag to tell it whether to check
|
||||
//! signatures and timeliness, but that could be error prone: if anybody
|
||||
//! sets the flag wrong, they will skip doing the checks.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,26 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-circmgr`: circuits through the Tor network on demand.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! In Tor, a circuit is an encrypted multi-hop tunnel over multiple
|
||||
//! relays. This crate's purpose, long-term, is to manage a set of
|
||||
//! circuits for a client. It should construct circuits in response
|
||||
//! to a client's needs, and preemptively construct circuits so as to
|
||||
//! anticipate those needs. If a client request can be satisfied with
|
||||
//! an existing circuit, it should return that circuit instead of
|
||||
//! constructing a new one.
|
||||
//!
|
||||
//! # Limitations
|
||||
//!
|
||||
//! But for now, this `tor-circmgr` code is extremely preliminary; its
|
||||
//! data structures are all pretty bad, and it's likely that the API
|
||||
//! is wrong too.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,62 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-config`: Tools for configuration management in Arti
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! It provides types for handling configuration values,
|
||||
//! and general machinery for configuration management.
|
||||
//!
|
||||
//! # Configuration in Arti
|
||||
//!
|
||||
//! The configuration for the `arti` command line program,
|
||||
//! and other programs which embed Arti reusing the configuration machinery,
|
||||
//! works as follows:
|
||||
//!
|
||||
//! 1. We use [`tor_config::ConfigurationSources`](ConfigurationSources)
|
||||
//! to enumerate the various places
|
||||
//! where configuration information needs to come from,
|
||||
//! and configure how they are to be read.
|
||||
//! `arti` uses [`ConfigurationSources::from_cmdline`].
|
||||
//!
|
||||
//! 2. [`ConfigurationSources::load`] actually *reads* all of these sources,
|
||||
//! parses them (eg, as TOML files),
|
||||
//! and returns a [`config::Config`].
|
||||
//! This is a tree-structured dynamically typed data structure,
|
||||
//! mirroring the input configuration structure, largely unvalidated,
|
||||
//! and containing everything in the input config sources.
|
||||
//!
|
||||
//! 3. We call one of the [`tor_config::resolve`](resolve) family.
|
||||
//! This maps the input configuration data to concrete `ConfigBuilder `s
|
||||
//! for the configuration consumers within the program.
|
||||
//! (For `arti`, that's `TorClientConfigBuilder` and `ArtiBuilder`).
|
||||
//! This mapping is done using the `Deserialize` implementations on the `Builder`s.
|
||||
//! `resolve` then calls the `build()` method on each of these parts of the configuration
|
||||
//! which applies defaults and validates the resulting configuration.
|
||||
//!
|
||||
//! It is important to call `resolve` *once* for *all* the configuration consumers,
|
||||
//! so that it sees a unified view of which config settings in the input
|
||||
//! were unrecognized, and therefore may need to be reported to the user.
|
||||
//! See the example in the [`load`] module documentation.
|
||||
//!
|
||||
//! 4. The resulting configuration objects (eg, `TorClientConfig`, `ArtiConfig`)
|
||||
//! are provided to the code that must use them (eg, to make a `TorClient`).
|
||||
//!
|
||||
//! See the
|
||||
//! [`tor_config::load` module-level documentation](load).
|
||||
//! for an example.
|
||||
//!
|
||||
//! # ⚠ Stability Warning ⚠
|
||||
//!
|
||||
//! The design of this crate, and of the configuration system for
|
||||
//! Arti, is likely to change significantly before the release of Arti
|
||||
//! 1.0.0. For more information see ticket [#285].
|
||||
//!
|
||||
//! [#285]: https://gitlab.torproject.org/tpo/core/arti/-/issues/285
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,16 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-congestion`: algorithms for congestion control on the Tor network
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! This implements some of the algorithms needed to implement congestion control
|
||||
//! as part of
|
||||
//! [Tor proposal #324](https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/proposals/324-rtt-congestion-control.txt).
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,22 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-consdiff`: Restricted ed diff and patch formats for Tor.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! Tor uses a restricted version of the "ed-style" diff format to
|
||||
//! record the difference between a pair of consensus documents, so that
|
||||
//! clients can download only the changes since the last document they
|
||||
//! have.
|
||||
//!
|
||||
//! This crate provides a function to apply one of these diffs to an older
|
||||
//! consensus document, to get a newer one.
|
||||
//!
|
||||
//! TODO: Eventually, when we add relay support, we will need to generate
|
||||
//! these diffs as well as consume them.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,30 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-dirclient`: Implements a minimal directory client for Tor.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! Tor makes its directory requests as HTTP/1.0 requests tunneled over
|
||||
//! Tor circuits. For most objects, Tor uses a one-hop tunnel. Tor
|
||||
//! also uses a few strange and ad-hoc HTTP headers to select
|
||||
//! particular functionality, such as asking for diffs, compression,
|
||||
//! or multiple documents.
|
||||
//!
|
||||
//! This crate provides an API for downloading Tor directory resources
|
||||
//! over a Tor circuit.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! # Features
|
||||
//!
|
||||
//! `xz` -- enable XZ compression. This can be expensive in RAM and CPU,
|
||||
//! but it saves a lot of bandwidth. (On by default.)
|
||||
//!
|
||||
//! `zstd` -- enable ZSTD compression. (On by default.)
|
||||
//!
|
||||
//! `routerdesc` -- Add support for downloading router descriptors.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,56 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-dirmgr`: Code to fetch, store, and update Tor directory information.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! In its current design, Tor requires a set of up-to-date
|
||||
//! authenticated directory documents in order to build multi-hop
|
||||
//! anonymized circuits through the network.
|
||||
//!
|
||||
//! This directory manager crate is responsible for figuring out which
|
||||
//! directory information we lack, downloading what we're missing, and
|
||||
//! keeping a cache of it on disk.
|
||||
//!
|
||||
//! # Compile-time features
|
||||
//!
|
||||
//! `mmap` (default) -- Use memory mapping to reduce the memory load for
|
||||
//! reading large directory objects from disk.
|
||||
//!
|
||||
//! `static` -- Try to link with a static copy of sqlite3.
|
||||
//!
|
||||
//! `routerdesc` -- (Incomplete) support for downloading and storing
|
||||
//! router descriptors.
|
||||
//!
|
||||
//! ## Experimental features
|
||||
//!
|
||||
//! # Compile-time features
|
||||
//!
|
||||
//! ## Experimental and unstable features
|
||||
//!
|
||||
//! Note that the APIs enabled by these features are NOT covered by
|
||||
//! semantic versioning[^1] guarantees: we might break them or remove
|
||||
//! them between patch versions.
|
||||
//!
|
||||
//! * `experimental-api`: Add additional non-stable APIs to our public
|
||||
//! interfaces.
|
||||
//!
|
||||
//! * `dirfilter`: enable an experimental mechanism to modify incoming
|
||||
//! directory informatoin before it is used.
|
||||
//!
|
||||
//! * `bridge-client`: Provide (as yet unimplented) APIs used to fetch
|
||||
//! and use bridge information.
|
||||
//!
|
||||
//! * `experimental`: Enable all the above experimental features.
|
||||
//!
|
||||
//! [^1]: Remember, semantic versioning is what makes various `cargo`
|
||||
//! features work reliably. To be explicit: if you want `cargo update`
|
||||
//! to _only_ make safe changes, then you cannot enable these
|
||||
//! features.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-error` -- Support for error handling in Tor and Arti
|
||||
//!
|
||||
//! Primarily, this crate provides the [`ErrorKind`] enum,
|
||||
//! and associated [`HasKind`] trait.
|
||||
//!
|
||||
//! There is also some other miscellany, supporting error handling in
|
||||
//! crates higher up the dependency stack.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Tools for generating a stream of structured events, similar to C tor's `ControlPort`.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,97 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-guardmgr`: guard node selection for Tor network clients.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! "Guard nodes" are mechanism that Tor clients uses to limit the
|
||||
//! impact of hostile relays. Approximately: each client chooses a
|
||||
//! small set of relays to use as its "guards". Later, when the
|
||||
//! client picks its paths through network, rather than choosing a
|
||||
//! different first hop randomly for every path, it chooses the best
|
||||
//! "guard" as the first hop.
|
||||
//!
|
||||
//! This crate provides [`GuardMgr`], an object that manages a set of
|
||||
//! guard nodes, and helps the `tor-circmgr` crate know when to use
|
||||
//! them.
|
||||
//!
|
||||
//! Guard nodes are persistent across multiple process invocations.
|
||||
//!
|
||||
//! More Arti users won't need to use this crate directly.
|
||||
//!
|
||||
//! # Motivation
|
||||
//!
|
||||
//! What's the point? By restricting their first hops to a small set,
|
||||
//! clients increase their odds against traffic-correlation attacks.
|
||||
//! Since we assume that an adversary who controls both ends of a
|
||||
//! circuit can correlate its traffic, choosing many circuits with
|
||||
//! random entry points will eventually cause a client to eventually
|
||||
//! pick an attacker-controlled circuit, with probability approaching
|
||||
//! 1 over time. If entry nodes are restricted to a small set,
|
||||
//! however, then the client has a chance of never picking an
|
||||
//! attacker-controlled circuit.
|
||||
//!
|
||||
//! (The actual argument is a little more complicated here, and it
|
||||
//! relies on the assumption that, since the attacker knows
|
||||
//! statistics, exposing _any_ of your traffic is nearly as bad as
|
||||
//! exposing _all_ of your traffic.)
|
||||
//!
|
||||
//! # Complications
|
||||
//!
|
||||
//! The real algorithm for selecting and using guards can get more
|
||||
//! complicated because of a variety of factors.
|
||||
//!
|
||||
//! - In reality, we can't just "pick a few guards at random" and use
|
||||
//! them forever: relays can appear and disappear, relays can go
|
||||
//! offline and come back online, and so on. What's more, keeping
|
||||
//! guards for too long can make targeted attacks against those
|
||||
//! guards more attractive.
|
||||
//!
|
||||
//! - Further, we may have particular restrictions on where we can
|
||||
//! connect. (For example, we might be restricted to ports 80 and
|
||||
//! 443, but only when we're on a commuter train's wifi network.)
|
||||
//!
|
||||
//! - We need to resist attacks from local networks that block all but a
|
||||
//! small set of guard relays, to force us to choose those.
|
||||
//!
|
||||
//! - We need to give good, reliable performance while using the
|
||||
//! guards that we prefer.
|
||||
//!
|
||||
//! These needs complicate our API somewhat. Instead of simply asking
|
||||
//! the `GuardMgr` for a guard, the circuit-management code needs to
|
||||
//! be able to tell the `GuardMgr` that a given guard has failed (or
|
||||
//! succeeded), and that it needs a different guard in the future (or
|
||||
//! not).
|
||||
//!
|
||||
//! Further, the `GuardMgr` code needs to be able to hand out
|
||||
//! _provisional guards_, in effect saying "You can try building a
|
||||
//! circuit with this guard, but please don't actually _use_ that
|
||||
//! circuit unless I tell you it's safe."
|
||||
//!
|
||||
//! For details on the exact algorithm, see `guard-spec.txt` (link
|
||||
//! below) and comments and internal documentation in this crate.
|
||||
//!
|
||||
//! # Limitations
|
||||
//!
|
||||
//! * Our circuit blocking algorithm is simplified from the one that Tor uses.
|
||||
//! See comments in `GuardSet::circ_usability_status` for more information.
|
||||
//! See also [proposal 337](https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/proposals/337-simpler-guard-usability.md).
|
||||
//!
|
||||
//! # References
|
||||
//!
|
||||
//! Guard nodes were first proposes (as "helper nodes") in "Defending
|
||||
//! Anonymous Communications Against Passive Logging Attacks" by
|
||||
//! Matthew Wright, Micah Adler, Brian N. Levine, and Clay Shields in
|
||||
//! the Proceedings of the 2003 IEEE Symposium on Security and
|
||||
//! Privacy. (See <https://www.freehaven.net/anonbib/#wright03>)
|
||||
//!
|
||||
//! Tor's current guard selection algorithm is described in Tor's
|
||||
//! [`guard-spec.txt`](https://gitlab.torproject.org/tpo/core/torspec/-/raw/main/guard-spec.txt)
|
||||
//! document.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,60 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-linkspec`: Descriptions of Tor relays, as used to connect to them.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The `tor-linkspec` crate provides traits and data structures that
|
||||
//! describe how to connect to Tor relays.
|
||||
//!
|
||||
//! When describing the location of a Tor relay on the network, the
|
||||
//! Tor protocol uses a set of "link specifiers", each of which
|
||||
//! corresponds to a single aspect of the relay's location or
|
||||
//! identity—such as its IP address and port, its Ed25519 identity
|
||||
//! key, its (legacy) RSA identity fingerprint, or so on. This
|
||||
//! crate's [`LinkSpec`] type encodes these structures.
|
||||
//!
|
||||
//! When a client is building a circuit through the Tor network, it
|
||||
//! needs to know certain information about the relays in that
|
||||
//! circuit. This crate's [`ChanTarget`] and [`CircTarget`] traits
|
||||
//! represent objects that describe a relay on the network that a
|
||||
//! client can use as the first hop, or as any hop, in a circuit.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust. Several
|
||||
//! other crates in Arti depend on it. You will probably not need
|
||||
//! this crate yourself unless you are interacting with the Tor
|
||||
//! protocol at a fairly low level.
|
||||
//!
|
||||
//! `tor-linkspec` is a separate crate so that it can be used by other
|
||||
//! crates that expose link specifiers and by crates that consume
|
||||
//! them.
|
||||
//!
|
||||
//! ## Future work
|
||||
//!
|
||||
//! TODO: Possibly we should rename this crate. "Linkspec" is a
|
||||
//! pretty esoteric term in the Tor protocols.
|
||||
//!
|
||||
//! TODO: Possibly the link specifiers and the `*Target` traits belong in different crates.
|
||||
//!
|
||||
//! # Compile-time features
|
||||
//!
|
||||
//! ## Experimental and unstable features
|
||||
//!
|
||||
//! Note that the APIs enabled by these features are NOT covered by
|
||||
//! semantic versioning[^1] guarantees: we might break them or remove
|
||||
//! them between patch versions.
|
||||
//!
|
||||
//! * `pt-client` -- Build with enhanced data types to support pluggable
|
||||
//! transports.
|
||||
//!
|
||||
//! * `experimental` -- Build with all experimental features above.
|
||||
//!
|
||||
//! [^1]: Remember, semantic versioning is what makes various `cargo`
|
||||
//! features work reliably. To be explicit: if you want `cargo update`
|
||||
//! to _only_ make safe changes, then you cannot enable these
|
||||
//! features.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,79 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-llcrypto`: Low-level cryptographic implementations for Tor.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The `tor-llcrypto` crate wraps lower-level cryptographic primitives that Tor
|
||||
//! needs, and provides a few smaller pieces of cryptographic functionality that
|
||||
//! are commonly required to implement Tor correctly.
|
||||
//!
|
||||
//! This crate is part of [Arti](https://gitlab.torproject.org/tpo/core/arti/),
|
||||
//! a project to implement [Tor](https://www.torproject.org/) in Rust. Many
|
||||
//! other crates in Arti depend on it.
|
||||
//!
|
||||
//! You probably wouldn't want to use this crate for implementing non-Tor-based
|
||||
//! protocols; instead you should probably use the other crates that it depends
|
||||
//! on if you have a low-level protocol to implement, or a higher-level
|
||||
//! cryptographic system if you want to add security to something else. It is
|
||||
//! easy to accidentally put these functions together in ways that are unsafe.
|
||||
//!
|
||||
//! ## Why a separate crate?
|
||||
//!
|
||||
//! Why do we collect and re-export our cryptography here in `tor-llcrypto`,
|
||||
//! instead of having the different crates in Arti use underlying cryptographic
|
||||
//! crates directly?
|
||||
//!
|
||||
//! By wrapping our cryptography in this crate, we ensure that we're using the
|
||||
//! same implementations across our ecosystem, and provide a single place to
|
||||
//! upgrade and test our cryptography.
|
||||
//!
|
||||
//! ## Adding to `tor-llcrypto`
|
||||
//!
|
||||
//! Any low-level cryptographic algorithm that is used by at least two other
|
||||
//! crates in Arti is a candidate for inclusion in `tor-llcrypto`, especially if
|
||||
//! that algorithm's purpose is not specific to any single piece of the Tor
|
||||
//! algorithm.
|
||||
//!
|
||||
//! Cryptographic _traits_ (like those from RustCrypto) don't have to go in
|
||||
//! `tor-llcrypto`, since they are interfaces rather than implementations.
|
||||
//!
|
||||
//! # Contents
|
||||
//!
|
||||
//! Encryption is implemented in [`cipher`]: Currently only AES is exposed or
|
||||
//! needed.
|
||||
//!
|
||||
//! Cryptographic digests are in [`d`]: The Tor protocol uses several digests in
|
||||
//! different places, and these are all collected here.
|
||||
//!
|
||||
//! Public key cryptography (including signatures, encryption, and key
|
||||
//! agreement) are in [`pk`]. Older parts of the Tor protocol require RSA;
|
||||
//! newer parts are based on Curve25519 and Ed25519. There is also functionality
|
||||
//! here for _key manipulation_ for the keys used in these symmetric algorithms.
|
||||
//!
|
||||
//! The [`util`] module has some miscellaneous compatibility utilities for
|
||||
//! manipulating cryptography-related objects and code.
|
||||
//!
|
||||
//! # Features
|
||||
//!
|
||||
//! ## API features
|
||||
//!
|
||||
//! `relay` -- enable cryptography that's only used on relays.
|
||||
//!
|
||||
//! `hsv3-client` -- enable cryptography that's only needed when running as a v3
|
||||
//! onion service client.
|
||||
//!
|
||||
//! ## Acceleration features
|
||||
//!
|
||||
//! These features should never be enabled by default from libraries, since they
|
||||
//! are not "strictly additive": they disable one implementation in order to
|
||||
//! enable another.
|
||||
//!
|
||||
//! `with-openssl` -- Use `openssl` as the backend for those cryptographic
|
||||
//! features it supports.
|
||||
//!
|
||||
//! `with-sha1-asm` -- Use an assembly implementation of the sha1 algorithm, if
|
||||
//! one is enabled.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,31 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Represents a clients'-eye view of the Tor network.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The `tor-netdir` crate wraps objects from tor-netdoc, and combines
|
||||
//! them to provide a unified view of the relays on the network.
|
||||
//! It is responsible for representing a client's knowledge of the
|
||||
//! network's state and who is on it.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust. Its purpose
|
||||
//! is to expose an abstract view of a Tor network and the relays in
|
||||
//! it, so that higher-level crates don't need to know about the
|
||||
//! particular documents that describe the network and its properties.
|
||||
//!
|
||||
//! There are two intended users for this crate. First, producers
|
||||
//! like [`tor-dirmgr`] create [`NetDir`] objects fill them with
|
||||
//! information from the Tor network directory. Later, consumers
|
||||
//! like [`tor-circmgr`] use [`NetDir`]s to select relays for random
|
||||
//! paths through the Tor network.
|
||||
//!
|
||||
//! # Limitations
|
||||
//!
|
||||
//! Only modern consensus methods and microdescriptor consensuses are
|
||||
//! supported.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,56 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Parse and represent directory objects used in Tor.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! Tor has several "directory objects" that it uses to convey
|
||||
//! information about relays on the network. They are documented in
|
||||
//! dir-spec.txt.
|
||||
//!
|
||||
//! This crate has common code to parse and validate these documents.
|
||||
//! Currently, it can handle the metaformat, along with certain parts
|
||||
//! of the router descriptor type. We will eventually need to handle
|
||||
//! more types.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! ## Design notes
|
||||
//!
|
||||
//! The crate is derived into three main parts. In the (private) `parse`
|
||||
//! module, we have the generic code that we use to parse different
|
||||
//! kinds of network documents. In the [`types`] module we have
|
||||
//! implementations for parsing specific data structures that are used
|
||||
//! inside directory documents. Finally, the [`doc`] module defines
|
||||
//! the parsers for the documents themselves.
|
||||
//!
|
||||
//! # Features
|
||||
//!
|
||||
//! `build_docs`: enable code to construct the objects representing different
|
||||
//! network documents.
|
||||
//!
|
||||
//! `routerdesc`: enable support for the "router descriptor" document type, which
|
||||
//! is needed by bridge clients and relays.
|
||||
//!
|
||||
//! `ns-consensus`: enable support for the "ns consensus" document type, which
|
||||
//! some relays cache and serve.
|
||||
//!
|
||||
//! # Caveat haxxor: limitations and infelicities
|
||||
//!
|
||||
//! TODO: This crate requires that all of its inputs be valid UTF-8:
|
||||
//! This is fine only if we assume that proposal 285 is implemented in
|
||||
//! mainline Tor.
|
||||
//!
|
||||
//! TODO: This crate has several pieces that could probably be split out
|
||||
//! into other smaller cases, including handling for version numbers
|
||||
//! and exit policies.
|
||||
//!
|
||||
//! TODO: Many parts of this crate that should eventually be public
|
||||
//! aren't.
|
||||
//!
|
||||
//! TODO: this crate needs far more tests!
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-persist`: Persistent data storage for use with Tor.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! For now, users should construct storage objects directly with (for
|
||||
//! example) [`FsStateMgr::from_path_and_mistrust()`], but use them primarily via the
|
||||
//! interfaces of the [`StateMgr`] trait.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,104 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Implementations for the core Tor protocol
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The `tor-proto` crate lies at the core of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! Most people shouldn't use this crate directly,
|
||||
//! since its APIs are needlessly low-level for most purposes, and it is
|
||||
//! easy to misuse them in an insecure or privacy-violating way.
|
||||
//!
|
||||
//! Most people should use the [`arti-client`] crate instead. This crate is
|
||||
//! of interest mainly for those that want to access the Tor protocols at
|
||||
//! a low level.
|
||||
//!
|
||||
//! ## Core concepts
|
||||
//!
|
||||
//! At its essence, Tor makes connections called "channels" to other
|
||||
//! Tor instances. These channels are implemented using TLS. Each of
|
||||
//! these channels multiplexes a number of anonymized multihop
|
||||
//! "circuits" that act as reliable transports for "relay messages"
|
||||
//! that are sent between clients and the different relays on the
|
||||
//! circuits. Finally, each circuit multiplexes a number of "streams",
|
||||
//! each corresponding roughly to an application-level request.
|
||||
//!
|
||||
//! This crate implements the logic, protocols, and cryptography that
|
||||
//! implement these [`channel::Channel`]s, [`circuit::ClientCirc`]s, and
|
||||
//! [`stream::DataStream`]s. It uses rust async code and future-related
|
||||
//! traits, and is intended to work with (nearly) any executor
|
||||
//! implementation that complies with the futures API. It should also
|
||||
//! work with nearly any TLS implementation that exposes AsyncRead and
|
||||
//! AsyncWrite traits.
|
||||
//!
|
||||
//! ## Not in this crate
|
||||
//!
|
||||
//! This crate does _not_ implement higher level protocols, like onion
|
||||
//! services or the Tor directory protocol, that are based on the Tor
|
||||
//! protocol here. Nor does it decide _when_, _how_, or _where_ to
|
||||
//! build channels and circuits: that's the role of higher-level crates.
|
||||
//!
|
||||
//! This crate also has no support for timeouts, so every network
|
||||
//! operation here has the potential to block the current task
|
||||
//! indefinitely. Timeouts are another necessary piece that gets
|
||||
//! added at a higher level.
|
||||
//!
|
||||
//! In order to create channels and circuits, you'll need to know
|
||||
//! about some Tor relays, and expose their information via
|
||||
//! [`tor_linkspec::ChanTarget`] and [`tor_linkspec::CircTarget`].
|
||||
//! Currently, the [`tor-netdir`] crate is the easiest way to do so.
|
||||
//!
|
||||
//! For an example of this crate in action, see the [`arti-client`]
|
||||
//! library, or the `arti` CLI.
|
||||
//!
|
||||
//! # Design notes
|
||||
//!
|
||||
//! This crate's APIs are structured to limit usage of an asynchronous runtime:
|
||||
//! It doesn't launch tasks or create timers except when necessary.
|
||||
//!
|
||||
//! To the extent possible, this crate avoids doing public-key
|
||||
//! cryptography in the same functions it uses for network activity.
|
||||
//! This makes it easier for higher-level code to parallelize or yield
|
||||
//! around public-key operations.
|
||||
//!
|
||||
//! Also, this crate tries to avoid knowing or encoding information about what
|
||||
//! its objects (channels, circuits, streams) are "used for". That is, whenever
|
||||
//! possible, we encode _how an object should behave_, not _the reason that it
|
||||
//! should behave that way_. For example, the `Circuit` object in this crate
|
||||
//! remembers the path through which the circuit was built, but _not_ the
|
||||
//! purpose that the circuit serves, or what it may be used for. It's the
|
||||
//! responsibility of other crates to enforce that kind of rule.
|
||||
//!
|
||||
//! Why separate behavior from purpose in this way?
|
||||
//! We do so in order to prevent a kind of logical overloading that we ran into
|
||||
//! with the C tor implementation, where usage information is _not_ separate
|
||||
//! from behavioral settings. Since usage information is available, at all
|
||||
//! points in the codebase the C tor code has converged in many places on
|
||||
//! complex logic involving that usage information in order to set individual
|
||||
//! behaviors. Because of that, adding a new kinds usage or behavior in C tor
|
||||
//! has become quite complex. We're trying to avoid that kind of complexity in
|
||||
//! Arti.
|
||||
//!
|
||||
//! # Limitations
|
||||
//!
|
||||
//! This is all a work in progress, and will need severe refactoring
|
||||
//! before it's done.
|
||||
//!
|
||||
//! This is a client-only implementation; there is no support the
|
||||
//! operations that Relays need.
|
||||
//!
|
||||
//! There are too many missing features to list.
|
||||
//!
|
||||
//! There isn't enough documentation or examples.
|
||||
//!
|
||||
//! This crate was my first attempt to use async in rust, and is probably
|
||||
//! pretty kludgy.
|
||||
//!
|
||||
//! I bet that there are deadlocks somewhere in this code. I fixed
|
||||
//! all the ones I could find or think of, but it would be great to
|
||||
//! find a good way to eliminate every lock that we have.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,39 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Implementation of Tor's "subprotocol versioning" feature.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The Tor system is built out of numerous "subprotocols" that are
|
||||
//! versioned more or less independently. The `tor-protover` crate
|
||||
//! implements parsing and handling for these subprotocol versions, so
|
||||
//! that different Tor instances know which parts of the protocol
|
||||
//! they support.
|
||||
//!
|
||||
//! Subprotocol versions are also used to determine which versions of
|
||||
//! the protocol are required to connect to the network (or just
|
||||
//! recommended).
|
||||
//!
|
||||
//! For more details, see [tor-spec.txt](https://spec.torproject.org/tor-spec)
|
||||
//! section 9.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! It's unlikely to be of general interest
|
||||
//! unless you are writing a Tor implementation, or a program that
|
||||
//! needs to examine fine-grained details of the Tor network.
|
||||
//!
|
||||
//! ## Design notes
|
||||
//!
|
||||
//! We're giving `tor-protover` its own crate within arti because it
|
||||
//! needs to be used to multiple higher level crates that do not
|
||||
//! themselves depend on one another. (For example, [`tor-proto`]
|
||||
//! needs to know which variant of a subprotocol can be used with a
|
||||
//! given relay, whereas [`tor-netdoc`] needs to parse lists of
|
||||
//! subprotocol versions from directory documents. Eventually,
|
||||
//! [`arti-client`] will need to check its own list of supported
|
||||
//! protocols against the required list in the consensus.)
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,39 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-ptmgr`: Manage a set of anti-censorship pluggable transports.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of [Arti](https://gitlab.torproject.org/tpo/core/arti/),
|
||||
//! a project to implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//!
|
||||
//! In Tor, a "transport" is a mechanism used to avoid censorship by disguising
|
||||
//! the Tor protocol as some other kind of traffic.
|
||||
//!
|
||||
//! A "pluggable transport" is one that is not implemented by default as part of
|
||||
//! the Tor protocol, but which can instead be added later on by the packager or
|
||||
//! the user. Pluggable transports are typically provided as external binaries
|
||||
//! that implement a SOCKS proxy, along with certain other configuration
|
||||
//! protocols.
|
||||
//!
|
||||
//! This crate provides a means to manage a set of configured pluggable
|
||||
//! transports
|
||||
//!
|
||||
//! # Limitations
|
||||
//!
|
||||
//! TODO pt-client: Currently, the APIs for this crate make it quite
|
||||
//! tor-specific. Notably, it can only return Channels! It would be good
|
||||
//! instead to adapt it so that it was more generally useful by other projects
|
||||
//! that want to use pluggable transports in rust. For now, I have put the
|
||||
//! Tor-channel-specific stuff behind a `tor-channel-factory` feature, but there
|
||||
//! are no APIs for using PTs without that feature currently. That should
|
||||
//! change.
|
||||
//!
|
||||
//! TODO pt-client: Nothing in this crate is actually implemented yet.
|
||||
//!
|
||||
//! TODO pt-client: The first version of this crate will probably only conform
|
||||
//! to the old Tor pluggable transport protocol, and not to more recent variants
|
||||
//! as documented at `pluggabletransports.info`
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,144 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Compatibility between different async runtimes for Arti.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! Rust's support for asynchronous programming is powerful, but still
|
||||
//! a bit immature: there are multiple powerful runtimes you can use,
|
||||
//! but they do not expose a consistent set of interfaces.
|
||||
//!
|
||||
//! The [`futures`] API abstracts much of the differences among these
|
||||
//! runtime libraries, but there are still areas where no standard API
|
||||
//! yet exists, including:
|
||||
//! - Network programming.
|
||||
//! - Time and delays.
|
||||
//! - Launching new tasks
|
||||
//! - Blocking until a task is finished.
|
||||
//!
|
||||
//! Additionally, the `AsyncRead` and `AsyncWrite` traits provide by
|
||||
//! [`futures`] are not the same as those provided by `tokio`, and
|
||||
//! require compatibility wrappers to use.
|
||||
//!
|
||||
//! To solve these problems, the `tor-rtcompat` crate provides a set
|
||||
//! of traits that represent a runtime's ability to perform these
|
||||
//! tasks, along with implementations for these traits for the `tokio`
|
||||
//! and `async-std` runtimes. In the future we hope to add support
|
||||
//! for other runtimes as needed.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! As such, it does not currently include (or
|
||||
//! plan to include) any functionality beyond what Arti needs to
|
||||
//! implement Tor.
|
||||
//!
|
||||
//! We hope that in the future this crate can be replaced (or mostly
|
||||
//! replaced) with standardized and general-purpose versions of the
|
||||
//! traits it provides.
|
||||
//!
|
||||
//! # Using `tor-rtcompat`
|
||||
//!
|
||||
//! The `tor-rtcompat` crate provides several traits that
|
||||
//! encapsulate different runtime capabilities.
|
||||
//!
|
||||
//! * A runtime is a [`BlockOn`] if it can block on a future.
|
||||
//! * A runtime is a [`SleepProvider`] if it can make timer futures that
|
||||
//! become Ready after a given interval of time.
|
||||
//! * A runtime is a [`TcpProvider`] if it can make and receive TCP
|
||||
//! connections
|
||||
//! * A runtime is a [`TlsProvider`] if it can make TLS connections.
|
||||
//!
|
||||
//! For convenience, the [`Runtime`] trait derives from all the traits
|
||||
//! above, plus [`futures::task::Spawn`] and [`Send`].
|
||||
//!
|
||||
//! You can get a [`Runtime`] in several ways:
|
||||
//!
|
||||
//! * If you already have an asynchronous backend (for example, one
|
||||
//! that you built with tokio by running with
|
||||
//! `#[tokio::main]`), you can wrap it as a [`Runtime`] with
|
||||
//! [`PreferredRuntime::current()`].
|
||||
//!
|
||||
//! * If you want to construct a default runtime that you won't be
|
||||
//! using for anything besides Arti, you can use [`PreferredRuntime::create()`].
|
||||
//!
|
||||
//! Both of the above methods use the "preferred runtime", which is usually Tokio.
|
||||
//! However, changing the set of Cargo features available can affect this; see
|
||||
//! [`PreferredRuntime`] for more.
|
||||
//!
|
||||
//! * If you want to use a runtime with an explicitly chosen backend,
|
||||
//! name its type directly as [`async_std::AsyncStdNativeTlsRuntime`],
|
||||
//! [`async_std::AsyncStdRustlsRuntime`], [`tokio::TokioNativeTlsRuntime`],
|
||||
//! or [`tokio::TokioRustlsRuntime`]. To construct one of these runtimes,
|
||||
//! call its `create()` method. Or if you have already constructed a
|
||||
//! Tokio runtime that you want to use, you can wrap it as a
|
||||
//! [`Runtime`] explicitly with `current()`.
|
||||
//!
|
||||
//! # Advanced usage: implementing runtimes yourself
|
||||
//!
|
||||
//! You might want to implement some of the traits above (especially [`TcpProvider`] and
|
||||
//! [`TlsProvider`]) if you're embedding Arti, and want more control over the resources it uses.
|
||||
//! For example, you might want to perform actions when TCP connections open and close, replace the
|
||||
//! TLS stack with your own, or proxy TCP connections over your own custom transport.
|
||||
//!
|
||||
//! This can be more easily accomplished using the [`CompoundRuntime`] type, which lets you
|
||||
//! create a [`Runtime`] from various implementors of the various traits (which don't all need to
|
||||
//! be the same).
|
||||
//!
|
||||
//! See [`arti-client/examples/hook-tcp.rs`](https://gitlab.torproject.org/tpo/core/arti/-/blob/main/crates/arti-client/examples/hook-tcp.rs)
|
||||
//! for a full example of this.
|
||||
//!
|
||||
//! # Cargo features
|
||||
//!
|
||||
//! Features supported by this crate:
|
||||
//!
|
||||
//! * `tokio` -- build with [Tokio](https://tokio.rs/) support
|
||||
//! * `async-std` -- build with [async-std](https://async.rs/) support
|
||||
//! * `native-tls` -- build with the [native-tls](https://github.com/sfackler/rust-native-tls)
|
||||
//! crate for TLS support
|
||||
//! * `static` -- link the native TLS library statically (enables the `vendored` feature of the
|
||||
//! `native-tls` crate).
|
||||
//! * `rustls` -- build with the [rustls](https://github.com/rustls/rustls) crate for TLS support. Note that `rustls` uses the `ring` crate, which uses
|
||||
//! the old (3BSD/SSLEay) OpenSSL license, which may introduce licensing
|
||||
//! compatibility issues.
|
||||
//!
|
||||
//! By default, *this* crate doesn't enable any features. However, you're almost certainly
|
||||
//! using this as part of the `arti-client` crate, which will enable `tokio` and `native-tls` in
|
||||
//! its default configuration.
|
||||
//!
|
||||
//! # Design FAQ
|
||||
//!
|
||||
//! ## Why support `async_std`?
|
||||
//!
|
||||
//! Although Tokio currently a more popular and widely supported
|
||||
//! asynchronous runtime than `async_std` is, we believe that it's
|
||||
//! critical to build Arti against multiple runtimes.
|
||||
//!
|
||||
//! By supporting multiple runtimes, we avoid making tokio-specific
|
||||
//! assumptions in our code, which we hope will make it easier to port
|
||||
//! to other environments (like WASM) in the future.
|
||||
//!
|
||||
//! ## Why a `Runtime` trait, and not a set of functions?
|
||||
//!
|
||||
//! We could simplify this code significantly by removing most of the
|
||||
//! traits it exposes, and instead just exposing a single
|
||||
//! implementation. For example, instead of exposing a
|
||||
//! [`BlockOn`] trait to represent blocking until a task is
|
||||
//! done, we could just provide a single global `block_on` function.
|
||||
//!
|
||||
//! That simplification would come at a cost, however. First of all,
|
||||
//! it would make it harder for us to use Rust's "feature" system
|
||||
//! correctly. Current features are supposed to be _additive only_,
|
||||
//! but if had a single global runtime, then support for different
|
||||
//! backends would be _mutually exclusive_. (That is, you couldn't
|
||||
//! have both the tokio and async-std features building at the same
|
||||
//! time.)
|
||||
//!
|
||||
//! Secondly, much of our testing in the rest of Arti relies on the
|
||||
//! ability to replace [`Runtime`]s. By treating a runtime as an
|
||||
//! object, we can override a runtime's view of time, or of the
|
||||
//! network, in order to test asynchronous code effectively.
|
||||
//! (See the [`tor-rtmock`] crate for examples.)
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -58,8 +58,9 @@ Or, you could solve both of these problems by using `tor-rtmock`
|
|||
to replace the internet _and_ the passage of time. (Here we're only
|
||||
replacing the internet.)
|
||||
|
||||
```rust
|
||||
#
|
||||
```rust,no_run
|
||||
# async fn say_hi<R,A>(runtime: R, addr: A) -> Result<(), ()> { Ok(()) }
|
||||
# // TODO this test hangs for some reason? Fix it and remove no_run above
|
||||
use tor_rtmock::{MockSleepRuntime,MockNetRuntime,net::MockNetwork};
|
||||
use tor_rtcompat::{TcpProvider,TcpListener};
|
||||
use futures::io::AsyncReadExt;
|
||||
|
|
|
@ -1,113 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Support for mocking with `tor-rtcompat` asynchronous runtimes.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! The `tor-rtcompat` crate defines a `Runtime` trait that represents
|
||||
//! most of the common functionality of . This crate provides mock
|
||||
//! implementations that override a `Runtime`, in whole or in part,
|
||||
//! for testing purposes.
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! It is used to write tests for higher-level
|
||||
//! crates in Arti that rely on asynchronous runtimes.
|
||||
//!
|
||||
//! This crate should only be used for writing tests.
|
||||
//!
|
||||
//! Currently, we support mocking the passage of time (via
|
||||
//! [`MockSleepRuntime`]), and impersonating the internet (via
|
||||
//! [`MockNetRuntime`]).
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! Suppose you've written a function that relies on making a
|
||||
//! connection to the network and possibly timing out:
|
||||
//!
|
||||
//! ```
|
||||
//! use tor_rtcompat::{Runtime,SleepProviderExt};
|
||||
//! use std::{net::SocketAddr, io::Result, time::Duration, io::Error};
|
||||
//! use futures::io::AsyncWriteExt;
|
||||
//!
|
||||
//! async fn say_hi(runtime: impl Runtime, addr: &SocketAddr) -> Result<()> {
|
||||
//! let delay = Duration::new(5,0);
|
||||
//! runtime.timeout(delay, async {
|
||||
//! let mut conn = runtime.connect(addr).await?;
|
||||
//! conn.write_all(b"Hello world!\r\n").await?;
|
||||
//! conn.close().await?;
|
||||
//! Ok::<_,Error>(())
|
||||
//! }).await??;
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! But how should you test this function?
|
||||
//!
|
||||
//! You might try connecting to a well-known website to test the
|
||||
//! connection case, and to a well-known black hole to test the
|
||||
//! timeout case... but that's a bit undesirable. Your tests might be
|
||||
//! running in a container with no internet access; and even if they
|
||||
//! aren't, it isn't so great for your tests to rely on the actual
|
||||
//! state of the internet. Similarly, if you make your timeout too long,
|
||||
//! your tests might block for a long time; but if your timeout is too short,
|
||||
//! the tests might fail on a slow machine or on a slow network.
|
||||
//!
|
||||
//! Or, you could solve both of these problems by using `tor-rtmock`
|
||||
//! to replace the internet _and_ the passage of time. (Here we're only
|
||||
//! replacing the internet.)
|
||||
//!
|
||||
//! ```
|
||||
//! # use tor_rtcompat::{Runtime,SleepProviderExt};
|
||||
//! # use std::{net::SocketAddr, io::Result, time::Duration, io::Error};
|
||||
//! # use futures::io::AsyncWriteExt;
|
||||
//! #
|
||||
//! # async fn say_hi(runtime: impl Runtime, addr: &SocketAddr) -> Result<()> {
|
||||
//! # let delay = Duration::new(5,0);
|
||||
//! # runtime.timeout(delay, async {
|
||||
//! # let mut conn = runtime.connect(addr).await?;
|
||||
//! # conn.write_all(b"Hello world!\r\n").await?;
|
||||
//! # conn.close().await?;
|
||||
//! # dbg!("okay apparently");
|
||||
//! # Ok::<_,Error>(())
|
||||
//! # }).await??;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! use tor_rtmock::{MockSleepRuntime,MockNetRuntime,net::MockNetwork};
|
||||
//! use tor_rtcompat::{TcpProvider,TcpListener};
|
||||
//! use futures::io::AsyncReadExt;
|
||||
//!
|
||||
//! tor_rtcompat::test_with_all_runtimes!(|rt| async move {
|
||||
//!
|
||||
//! let addr1 = "198.51.100.7".parse().unwrap();
|
||||
//! let addr2 = "198.51.100.99".parse().unwrap();
|
||||
//! let sockaddr = "198.51.100.99:101".parse().unwrap();
|
||||
//!
|
||||
//! // Make a runtime that pretends that we are at the first address...
|
||||
//! let fake_internet = MockNetwork::new();
|
||||
//! let rt1 = fake_internet.builder().add_address(addr1).runtime(rt.clone());
|
||||
//! // ...and one that pretends we're listening at the second address.
|
||||
//! let rt2 = fake_internet.builder().add_address(addr2).runtime(rt);
|
||||
//! let listener = rt2.listen(&sockaddr).await.unwrap();
|
||||
//!
|
||||
//! // Now we can test our function!
|
||||
//! let (result1,output) = futures::join!(
|
||||
//! say_hi(rt1, &sockaddr),
|
||||
//! async {
|
||||
//! let (mut conn,addr) = listener.accept().await.unwrap();
|
||||
//! assert_eq!(addr.ip(), addr1);
|
||||
//! let mut output = Vec::new();
|
||||
//! conn.read_to_end(&mut output).await.unwrap();
|
||||
//! output
|
||||
//! });
|
||||
//!
|
||||
//! assert!(result1.is_ok());
|
||||
//! assert_eq!(&output[..], b"Hello world!\r\n");
|
||||
//! });
|
||||
//! ```
|
||||
//!
|
||||
//! (TODO: Add an example for the timeout case.)
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,62 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! Implements SOCKS in the flavors provided by Tor.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! SOCKS is an old and somewhat janky protocol for telling a TCP
|
||||
//! proxy where to connect. Versions 4, 4a, and 5 are sometimes
|
||||
//! encountered in the wild.
|
||||
//!
|
||||
//! The `tor-socksproto` crate tries to hide the actual details of the
|
||||
//! protocol, and expose a stateful handshake type that eventually
|
||||
//! provides a [`SocksRequest`] or an error. It is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! At present, it is only used to provide a
|
||||
//! SOCKS proxy _over_ the Tor network, but eventually it may be used
|
||||
//! to implement support for connecting to the Tor network over a
|
||||
//! SOCKS proxy.
|
||||
//!
|
||||
//! This crate may be a good choice for you if you need a SOCKS
|
||||
//! implementation that "behaves like Tor", but otherwise it is
|
||||
//! probably better to use some other SOCKS crate.
|
||||
//!
|
||||
//! For more information about SOCKS:
|
||||
//!
|
||||
//! * SOCKS5 (which is preferred) is specified in
|
||||
//! [RFC 1928](https://tools.ietf.org/html/rfc1928), and see also
|
||||
//! [RFC 1929](https://tools.ietf.org/html/rfc1929) for
|
||||
//! Username/Password authentication in SOCKS5.
|
||||
//! * [The wikipedia article](https://en.wikipedia.org/wiki/SOCKS)
|
||||
//! is the best surviving documentation for SOCKS4 and SOCKS4a.
|
||||
//! * See
|
||||
//! [socks-extensions.txt](https://spec.torproject.org/socks-extensions)
|
||||
//! for a description of Tor's extensions and restrictions on the
|
||||
//! SOCKS protocol.
|
||||
//!
|
||||
//! ## Design notes
|
||||
//!
|
||||
//! Arti uses this crate instead of some other SOCKS implementation,
|
||||
//! for two reasons:
|
||||
//!
|
||||
//! * First, because we need to support Tor SOCKS extensions.
|
||||
//! * Second, and because we sometimes need to see particular details
|
||||
//! of the individual handshakes that most other SOCKS
|
||||
//! implementations don't expose. (For example, if we are told to
|
||||
//! connect to a raw IP address, the type of the handshake can help
|
||||
//! us guess whether that IP address came from a DNS response–in
|
||||
//! which case we should warn about a possible DNS leak.)
|
||||
//!
|
||||
//! Currently, `tor-socksproto` does no networking code: it _only_
|
||||
//! implements the server (proxy) side of the SOCKS handshake by
|
||||
//! handling a series of bytes. We may (or may not) want to add
|
||||
//! network functionality to this crate or elsewhere in the future.
|
||||
//! We'll definitely want to add client functionality.
|
||||
//!
|
||||
//! Possibly, this approach will prove useful for other uses. If it
|
||||
//! does, We can put the tor-only functionality behind a Cargo build
|
||||
//! feature, so that others can use this crate more safely.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -1,21 +1,5 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
|
||||
//! `tor-units` -- Safe wrappers for primitive numeric types.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate is part of
|
||||
//! [Arti](https://gitlab.torproject.org/tpo/core/arti/), a project to
|
||||
//! implement [Tor](https://www.torproject.org/) in Rust.
|
||||
//! It provides safe wrappers for primitive numeric wrappers used in
|
||||
//! other parts of Arti.
|
||||
//! In particular, it provides:
|
||||
//! * a bounded i32 with both checked and clamping constructors,
|
||||
//! * an integer milliseconds wrapper with conversion to [`Duration`]
|
||||
//! * an integer seconds wrapper with conversion to [`Duration`]
|
||||
//! * a percentage wrapper, to prevent accidental failure
|
||||
//! to divide by 100.
|
||||
//! * a SendMeVersion which can be compared only.
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
// @@ begin lint list maintained by maint/add_warning @@
|
||||
#![cfg_attr(not(ci_arti_stable), allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(not(ci_arti_nightly), allow(unknown_lints))]
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
* cargo upgrade --dry-run --workspace --skip-compatible
|
||||
* ./maint/cargo_audit
|
||||
* ./maint/check_licenses
|
||||
* ./maint/readmes
|
||||
|
||||
(Note that not all of the above will make changes on their own; you'll
|
||||
need to understand the output and decide what to do.)
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
for subcargo in crates/*/Cargo.toml ; do
|
||||
|
||||
cd "$(dirname "$subcargo")"
|
||||
cargo readme > README.md
|
||||
cd ../..
|
||||
|
||||
done
|
Loading…
Reference in New Issue