diff --git a/Cargo.lock b/Cargo.lock index a880398f976..320668b8b18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -996,12 +996,10 @@ dependencies = [ "multi-tcp-client", "nymsphinx", "pretty_env_logger", - "provider-client", "rand 0.7.3", "rand_os", "serde", "serde_derive", - "sfw-provider-requests", "tokio 0.2.16", "topology", ] @@ -1634,7 +1632,6 @@ dependencies = [ "pem", "pemstore", "pretty_env_logger", - "provider-client", "reqwest", "serde", "serde_json", @@ -1700,37 +1697,6 @@ dependencies = [ "topology", ] -[[package]] -name = "nym-sfw-provider" -version = "0.7.0-dev" -dependencies = [ - "bs58", - "built", - "clap", - "config", - "crypto", - "curve25519-dalek", - "directory-client", - "dirs", - "dotenv", - "futures 0.3.4", - "hmac", - "log 0.4.8", - "mix-client", - "nymsphinx", - "pemstore", - "pretty_env_logger", - "rand 0.7.3", - "serde", - "serde_json", - "sfw-provider-requests", - "sha2", - "sled", - "tempfile", - "tokio 0.2.16", - "topology", -] - [[package]] name = "nym-validator" version = "0.7.0-dev" @@ -2127,18 +2093,6 @@ dependencies = [ "protobuf-codegen", ] -[[package]] -name = "provider-client" -version = "0.1.0" -dependencies = [ - "futures 0.3.4", - "log 0.4.8", - "nymsphinx", - "pretty_env_logger", - "sfw-provider-requests", - "tokio 0.2.16", -] - [[package]] name = "publicsuffix" version = "1.5.4" @@ -2578,18 +2532,6 @@ dependencies = [ "url 1.7.2", ] -[[package]] -name = "sfw-provider-requests" -version = "0.1.0" -dependencies = [ - "bs58", - "byteorder", - "bytes 0.5.4", - "nymsphinx", - "tokio 0.2.16", - "tokio-test", -] - [[package]] name = "sha-1" version = "0.8.2" @@ -2998,17 +2940,6 @@ dependencies = [ "tokio-reactor", ] -[[package]] -name = "tokio-test" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cf9705471976fa5fc6817d3fbc9c4ff9696a6647af0e5c1870c81ca7445b05" -dependencies = [ - "bytes 0.5.4", - "futures-core", - "tokio 0.2.16", -] - [[package]] name = "tokio-threadpool" version = "0.1.18" diff --git a/Cargo.toml b/Cargo.toml index d780fecd751..50cc1f24525 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ members = [ "common/client-libs/gateway-client", "common/client-libs/mix-client", "common/client-libs/multi-tcp-client", - "common/client-libs/provider-client", "common/client-libs/validator-client", "common/config", "common/crypto", @@ -22,7 +21,5 @@ members = [ "gateway", "gateway/gateway-requests", "mixnode", - "sfw-provider", - "sfw-provider/sfw-provider-requests", "validator", ] diff --git a/clients/desktop/Cargo.toml b/clients/desktop/Cargo.toml index 56d05ef0701..5cf2d68fc6c 100644 --- a/clients/desktop/Cargo.toml +++ b/clients/desktop/Cargo.toml @@ -39,7 +39,6 @@ mix-client = { path = "../../common/client-libs/mix-client" } multi-tcp-client = { path = "../../common/client-libs/multi-tcp-client" } nymsphinx = { path = "../../common/nymsphinx" } pemstore = {path = "../../common/pemstore"} -provider-client = { path = "../../common/client-libs/provider-client" } topology = {path = "../../common/topology" } [build-dependencies] diff --git a/common/client-libs/provider-client/Cargo.toml b/common/client-libs/provider-client/Cargo.toml deleted file mode 100644 index d6958107252..00000000000 --- a/common/client-libs/provider-client/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "provider-client" -version = "0.1.0" -authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -futures = "0.3.1" -log = "0.4.8" -pretty_env_logger = "0.3" -tokio = { version = "0.2", features = ["full"] } - -## internal -nymsphinx = { path = "../../nymsphinx" } -sfw-provider-requests = { path = "../../../sfw-provider/sfw-provider-requests" } \ No newline at end of file diff --git a/common/client-libs/provider-client/src/lib.rs b/common/client-libs/provider-client/src/lib.rs deleted file mode 100644 index a77b03bce8b..00000000000 --- a/common/client-libs/provider-client/src/lib.rs +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use futures::io::Error; -use log::*; -use nymsphinx::DestinationAddressBytes; -use sfw_provider_requests::auth_token::AuthToken; -use sfw_provider_requests::requests::{ - async_io::TokioAsyncRequestWriter, ProviderRequest, PullRequest, RegisterRequest, -}; -use sfw_provider_requests::responses::{ - async_io::TokioAsyncResponseReader, ProviderResponse, ProviderResponseError, -}; -use std::net::SocketAddr; -use tokio::prelude::*; - -#[derive(Debug)] -pub enum ProviderClientError { - ClientAlreadyRegisteredError, - EmptyAuthTokenError, - NetworkError, - - InvalidRequestError, - InvalidResponseError, - InvalidResponseLengthError, -} - -impl From for ProviderClientError { - fn from(_: Error) -> Self { - use ProviderClientError::*; - - NetworkError - } -} - -impl From for ProviderClientError { - fn from(err: ProviderResponseError) -> Self { - use ProviderClientError::*; - match err { - ProviderResponseError::MarshalError => InvalidRequestError, - ProviderResponseError::UnmarshalError => InvalidResponseError, - ProviderResponseError::UnmarshalErrorInvalidLength => InvalidResponseLengthError, - ProviderResponseError::UnmarshalErrorInvalidKind => InvalidResponseLengthError, - - ProviderResponseError::TooLongResponseError => InvalidResponseError, - ProviderResponseError::TooShortResponseError => InvalidResponseError, - ProviderResponseError::IOError(_) => NetworkError, - ProviderResponseError::RemoteConnectionClosed => NetworkError, - } - } -} - -pub struct ProviderClient { - provider_network_address: SocketAddr, - our_address: DestinationAddressBytes, - auth_token: Option, - connection: Option, - max_response_size: usize, -} - -impl ProviderClient { - pub fn new( - provider_network_address: SocketAddr, - our_address: DestinationAddressBytes, - auth_token: Option, - max_response_size: usize, - ) -> Self { - ProviderClient { - provider_network_address, - our_address, - auth_token, - max_response_size, - // establish connection when it's necessary (mainly to not break current code - // as then 'new' would need to be called within async context) - connection: None, - } - } - - async fn check_connection(&mut self) -> bool { - if self.connection.is_some() { - true - } else { - // TODO: possibly also introduce timeouts here? - // However, at this point it's slightly less important as we are in full control - // of providers. - self.connection = tokio::net::TcpStream::connect(self.provider_network_address) - .await - .ok(); - self.connection.is_some() - } - } - - pub fn update_token(&mut self, auth_token: AuthToken) { - self.auth_token = Some(auth_token) - } - - pub async fn send_request( - &mut self, - request: ProviderRequest, - ) -> Result { - if !self.check_connection().await { - return Err(ProviderClientError::NetworkError); - } - - let socket = self.connection.as_mut().unwrap(); - let (mut socket_reader, mut socket_writer) = socket.split(); - - // TODO: benchmark and determine if below should be done: - // let mut socket_writer = tokio::io::BufWriter::new(socket_writer); - // let mut socket_reader = tokio::io::BufReader::new(socket_reader); - - let mut request_writer = TokioAsyncRequestWriter::new(&mut socket_writer); - let mut response_reader = - TokioAsyncResponseReader::new(&mut socket_reader, self.max_response_size); - - if let Err(e) = request_writer.try_write_request(request).await { - debug!("Failed to write the request - {:?}", e); - return Err(e.into()); - } - - Ok(response_reader.try_read_response().await?) - } - - pub async fn retrieve_messages(&mut self) -> Result>, ProviderClientError> { - let auth_token = match self.auth_token.as_ref() { - Some(token) => token.clone(), - None => { - return Err(ProviderClientError::EmptyAuthTokenError); - } - }; - - let pull_request = - ProviderRequest::Pull(PullRequest::new(self.our_address.clone(), auth_token)); - match self.send_request(pull_request).await? { - ProviderResponse::Pull(res) => Ok(res.extract_messages()), - ProviderResponse::Failure(res) => { - error!( - "We failed to get our request processed - {:?}", - res.get_message() - ); - Err(ProviderClientError::InvalidResponseError) - } - _ => { - error!("Received response of unexpected type!"); - Err(ProviderClientError::InvalidResponseError) - } - } - } - - pub async fn register(&mut self) -> Result { - if self.auth_token.is_some() { - return Err(ProviderClientError::ClientAlreadyRegisteredError); - } - - let register_request = - ProviderRequest::Register(RegisterRequest::new(self.our_address.clone())); - match self.send_request(register_request).await? { - ProviderResponse::Register(res) => Ok(res.get_token()), - ProviderResponse::Failure(res) => { - error!( - "We failed to get our request processed - {:?}", - res.get_message() - ); - Err(ProviderClientError::InvalidResponseError) - } - _ => { - error!("Received response of unexpected type!"); - Err(ProviderClientError::InvalidResponseError) - } - } - } - - pub fn is_registered(&self) -> bool { - self.auth_token.is_some() - } -} diff --git a/common/healthcheck/Cargo.toml b/common/healthcheck/Cargo.toml index d680e4f1bbf..1c52152184e 100644 --- a/common/healthcheck/Cargo.toml +++ b/common/healthcheck/Cargo.toml @@ -22,8 +22,6 @@ crypto = { path = "../crypto" } directory-client = { path = "../client-libs/directory-client" } multi-tcp-client = { path = "../client-libs/multi-tcp-client" } nymsphinx = {path = "../nymsphinx" } -provider-client = { path = "../client-libs/provider-client" } -sfw-provider-requests = { path = "../../sfw-provider/sfw-provider-requests" } topology = {path = "../topology" } [dev-dependencies] diff --git a/common/healthcheck/src/path_check.rs b/common/healthcheck/src/path_check.rs index 9f0d54ed27e..60cc6bb8459 100644 --- a/common/healthcheck/src/path_check.rs +++ b/common/healthcheck/src/path_check.rs @@ -17,8 +17,8 @@ use crypto::identity::MixIdentityKeyPair; use itertools::Itertools; use log::{debug, error, info, trace, warn}; use nymsphinx::addressing::nodes::NymNodeRoutingAddress; -use nymsphinx::{Delay, Destination, Node as SphinxNode}; -use provider_client::{ProviderClient, ProviderClientError}; +use nymsphinx::{Delay, Destination, DestinationAddressBytes, Node as SphinxNode}; +// use provider_client::{ProviderClient, ProviderClientError}; use std::collections::HashMap; use std::convert::TryFrom; use std::net::SocketAddr; @@ -27,6 +27,39 @@ use topology::provider; pub(crate) type CheckId = [u8; 16]; +// JUST TO MAKE IT COMPILE, THIS WILL NEED TO BE REPLACED WITH GATEWAY +struct ProviderClient {} + +struct AuthToken {} + +impl ProviderClient { + fn new( + _provider_network_address: SocketAddr, + _our_address: DestinationAddressBytes, + _auth_token: Option, + _max_response_size: usize, + ) -> Self { + unimplemented!() + } + fn update_token(&mut self, _auth_token: AuthToken) { + unimplemented!() + } + async fn register(&mut self) -> Result { + unimplemented!() + } + async fn retrieve_messages(&mut self) -> Result>, ProviderClientError> { + unimplemented!() + } +} + +#[derive(Debug)] +enum ProviderClientError { + #[allow(dead_code)] + ClientAlreadyRegisteredError, +} + +const DUMMY_MESSAGE_CONTENT: &[u8] = b"THIS NEEDS TO BE REDONE AS IT DOESNT EXIST ANYMORE"; + #[derive(Debug, PartialEq, Clone)] pub enum PathStatus { Healthy, @@ -73,13 +106,6 @@ impl PathChecker { info!("[Healthcheck] We were already registered"); provider_clients.insert(provider.get_pub_key_bytes(), Some(provider_client)) } - Err(err) => { - warn!( - "failed to register at provider {} - {:?}", - provider.pub_key, err - ); - provider_clients.insert(provider.get_pub_key_bytes(), None) - } }; if insertion_result.is_some() { @@ -171,7 +197,7 @@ impl PathChecker { let mut should_stop = false; for msg in messages.into_iter() { trace!("received provider response: {:?}", msg); - if msg == sfw_provider_requests::DUMMY_MESSAGE_CONTENT { + if msg == DUMMY_MESSAGE_CONTENT { // finish iterating the loop as the messages might not be ordered should_stop = true; } else if msg[..16] != check_id { diff --git a/sfw-provider/Cargo.lock b/sfw-provider/Cargo.lock deleted file mode 100644 index ee9f5c22d97..00000000000 --- a/sfw-provider/Cargo.lock +++ /dev/null @@ -1,2378 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "adler32" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "aes-ctr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aes-soft" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aesni" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aho-corasick" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "arc-swap" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "arrayref" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "atty" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "backtrace" -version = "0.3.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "blake2b_simd" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-cipher-trait" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "built" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bytes" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "c2-chacha" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cc" -version = "1.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "chrono" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clap" -version = "2.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clear_on_drop" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cookie" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cookie_store" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "publicsuffix 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "core-foundation" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crc32fast" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-queue" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ctr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "curve25519-dalek" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dirs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dirs-sys" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dtoa" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "either" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "encoding_rs" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "error-chain" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure_derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "flate2" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fnv" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-channel" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-cpupool" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-executor" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-io" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-macro" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "futures-sink" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-task" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-util" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "generic-array" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "getrandom" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "git2" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "h2" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hermit-abi" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "hkdf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "http" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "http-body" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "httparse" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "hyper" -version = "0.12.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hyper-tls" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "idna" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "indexmap" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "input_buffer" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "itoa" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "jobserver" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "keystream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libc" -version = "0.2.66" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libgit2-sys" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libz-sys" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lioness" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lock_api" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memchr" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memoffset" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mime" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "mime_guess" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miniz_oxide" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio-named-pipes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio-uds" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miow" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miow" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "native-tls" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "net2" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-integer" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num_cpus" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "nym-client" -version = "0.2.0" -dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "built 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pem 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "sfw-provider-requests 0.1.0", - "sphinx 0.1.0", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tungstenite 0.10.0 (git+https://github.com/dbcfd/tokio-tungstenite?rev=6dc2018cbfe8fe7ddd75ff977343086503135b38)", - "tungstenite 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "nym-sfw-provider" -version = "0.2.0" -dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "built 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nym-client 0.2.0", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "sfw-provider-requests 0.1.0", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sphinx 0.1.0", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl" -version = "0.10.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "openssl-probe" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl-sys" -version = "0.9.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pem" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "pin-project" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "pin-utils" -version = "0.1.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "pkg-config" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ppv-lite86" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "proc-macro-hack" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-nested" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "proc-macro2" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "publicsuffix" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "quote" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_chacha" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_distr" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_syscall" -version = "0.1.56" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_users" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "remove_dir_all" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "reqwest" -version = "0.9.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding_rs 0.8.21 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rust-argon2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ryu" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "schannel" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "scopeguard" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "security-framework" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "serde" -version = "1.0.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_derive" -version = "1.0.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_json" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_urlencoded" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sfw-provider-requests" -version = "0.1.0" -dependencies = [ - "sphinx 0.1.0", -] - -[[package]] -name = "sha-1" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "signal-hook-registry" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slab" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "smallvec" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "smallvec" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "socket2" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sphinx" -version = "0.1.0" -dependencies = [ - "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lioness 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "stream-cipher" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "string" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "subtle" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "syn" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "synstructure" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tempfile" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "time" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-buf" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-executor" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-io" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-sync" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-timer" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.10.0" -source = "git+https://github.com/dbcfd/tokio-tungstenite?rev=6dc2018cbfe8fe7ddd75ff977343086503135b38#6dc2018cbfe8fe7ddd75ff977343086503135b38" -dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tungstenite 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "toml" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "try-lock" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "try_from" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tungstenite" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "input_buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "typenum" -version = "1.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-normalization" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "url" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "utf-8" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "uuid" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "vcpkg" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "vec_map" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "version_check" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "want" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasi" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" -"checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" -"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" -"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" -"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" -"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" -"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" -"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" -"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" -"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" -"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -"checksum blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" -"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" -"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -"checksum built 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2315cfb416f86e05360edc950b1d7d25ecfb00f7f8eba60dbd7882a0f2e944" -"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" -"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" -"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" -"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" -"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" -"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" -"checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" -"checksum cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" -"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" -"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" -"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" -"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" -"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" -"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" -"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" -"checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" -"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" -"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" -"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" -"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" -"checksum encoding_rs 0.8.21 (registry+https://github.com/rust-lang/crates.io-index)" = "f730a5068736d360795b76e8c53ef51d052a4090d281412da851f5fd6204f36d" -"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" -"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" -"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" -"checksum futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" -"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" -"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" -"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" -"checksum futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" -"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" -"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" -"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" -"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" -"checksum git2 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c1af51ea8a906616af45a4ce78eacf25860f7a13ae7bf8a814693f0f4037a26" -"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" -"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" -"checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" -"checksum hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa08a006102488bd9cd5b8013aabe84955cf5ae22e304c2caf655b633aefae3" -"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -"checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" -"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" -"checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" -"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" -"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" -"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" -"checksum input_buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e1b822cc844905551931d6f81608ed5f50a79c1078a4e2b4d42dbc7c1eedfbf" -"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" -"checksum libgit2-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4870c781f6063efb83150cd22c1ddf6ecf58531419e7570cdcced46970f64a16" -"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" -"checksum lioness 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" -"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" -"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" -"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" -"checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf" -"checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599" -"checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" -"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" -"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" -"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" -"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" -"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" -"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" -"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" -"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" -"checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" -"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -"checksum pem 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a1581760c757a756a41f0ee3ff01256227bdf64cb752839779b95ffb01c59793" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" -"checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" -"checksum pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0af6cbca0e6e3ce8692ee19fb8d734b641899e07b68eb73e9bbbd32f1703991" -"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" -"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" -"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" -"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" -"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" -"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" -"checksum publicsuffix 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3bbaa49075179162b49acac1c6aa45fb4dafb5f13cf6794276d77bc7fd95757b" -"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" -"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" -"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" -"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" -"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" -"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -"checksum reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" -"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" -"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" -"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" -"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" -"checksum security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" -"checksum security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" -"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" -"checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" -"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" -"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" -"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" -"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" -"checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" -"checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" -"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" -"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" -"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" -"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" -"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" -"checksum tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bcced6bb623d4bff3739c176c415f13c418f426395c169c9c3cd9a492c715b16" -"checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -"checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" -"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5795a71419535c6dcecc9b6ca95bdd3c2d6142f7e8343d7beb9923f129aa87e" -"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" -"checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" -"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" -"checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" -"checksum tokio-tungstenite 0.10.0 (git+https://github.com/dbcfd/tokio-tungstenite?rev=6dc2018cbfe8fe7ddd75ff977343086503135b38)" = "" -"checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" -"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" -"checksum tungstenite 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a0c2bd5aeb7dcd2bb32e472c8872759308495e5eccc942e929a513cd8d36110" -"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" -"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" -"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" -"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" -"checksum utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" -"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" -"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" -"checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/sfw-provider/Cargo.toml b/sfw-provider/Cargo.toml deleted file mode 100644 index 9318a980c75..00000000000 --- a/sfw-provider/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -build = "build.rs" -name = "nym-sfw-provider" -version = "0.7.0-dev" -authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bs58 = "0.3.0" -clap = "2.33.0" -curve25519-dalek = "2.0.0" -dirs = "2.0.2" -dotenv = "0.15.0" -futures = "0.3.1" -log = "0.4" -pretty_env_logger = "0.3" -rand = "0.7.2" -tokio = { version = "0.2.4", features = ["full"] } -sha2 = "0.8.0" -serde = { version = "1.0.104", features = ["derive"] } -serde_json = "1.0.44" -sled = "0.31" -hmac = "0.7.1" - -## internal -crypto = { path = "../common/crypto" } -config = { path = "../common/config" } -directory-client = { path = "../common/client-libs/directory-client" } -nymsphinx = { path = "../common/nymsphinx" } -pemstore = { path = "../common/pemstore" } -sfw-provider-requests = { path = "./sfw-provider-requests" } -topology = { path = "../common/topology"} - -# this dependency is due to requiring to know content of loop message. however, mix-client module itself -# is going to be removed or renamed at some point as it no longer servers its purpose of sending traffic to mix network -# and only provides utility functions -mix-client = { path = "../common/client-libs/mix-client" } - - -[build-dependencies] -built = "0.3.2" - -[dev-dependencies] -tempfile = "3.1.0" - -[features] -qa = [] -local = [] \ No newline at end of file diff --git a/sfw-provider/README.md b/sfw-provider/README.md deleted file mode 100644 index d052ad38851..00000000000 --- a/sfw-provider/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# nym-sfw-provider -A store-and-forward provider for Nym, implemented in Rust diff --git a/sfw-provider/build.rs b/sfw-provider/build.rs deleted file mode 100644 index 56d753472cf..00000000000 --- a/sfw-provider/build.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use built; - -fn main() { - built::write_built_file().expect("Failed to acquire build-time information"); -} diff --git a/sfw-provider/sfw-provider-requests/Cargo.lock b/sfw-provider/sfw-provider-requests/Cargo.lock deleted file mode 100644 index a6ad35debe0..00000000000 --- a/sfw-provider/sfw-provider-requests/Cargo.lock +++ /dev/null @@ -1,462 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "aes-ctr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aes-soft" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aesni" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "arrayref" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-cipher-trait" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "c2-chacha" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cc" -version = "1.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clear_on_drop" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ctr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "curve25519-dalek" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "generic-array" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "getrandom" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hkdf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "keystream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libc" -version = "0.2.66" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lioness" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ppv-lite86" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rand" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_chacha" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_distr" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sfw-provider-requests" -version = "0.1.0" -dependencies = [ - "sphinx 0.1.0", -] - -[[package]] -name = "sha2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sphinx" -version = "0.1.0" -dependencies = [ - "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lioness 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "stream-cipher" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "subtle" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "typenum" -version = "1.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "wasi" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" -"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" -"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" -"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" -"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" -"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" -"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" -"checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" -"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" -"checksum hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa08a006102488bd9cd5b8013aabe84955cf5ae22e304c2caf655b633aefae3" -"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -"checksum keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" -"checksum lioness 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" -"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" -"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" -"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" -"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" -"checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" -"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" -"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" -"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/sfw-provider/sfw-provider-requests/Cargo.toml b/sfw-provider/sfw-provider-requests/Cargo.toml deleted file mode 100644 index fe0c52ad3e6..00000000000 --- a/sfw-provider/sfw-provider-requests/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "sfw-provider-requests" -version = "0.1.0" -authors = ["Jedrzej Stuczynski "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bs58 = "0.3" -bytes = "0.5" -byteorder = "1" -nymsphinx = { path = "../../common/nymsphinx" } -tokio = { version = "0.2", features = ["io-util"] } - -[dev-dependencies] -tokio = { version = "0.2", features = ["rt-threaded", "time"] } -tokio-test = "0.2" diff --git a/sfw-provider/sfw-provider-requests/src/auth_token.rs b/sfw-provider/sfw-provider-requests/src/auth_token.rs deleted file mode 100644 index 92768c1dbe1..00000000000 --- a/sfw-provider/sfw-provider-requests/src/auth_token.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub const AUTH_TOKEN_SIZE: usize = 32; - -#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] -pub struct AuthToken([u8; AUTH_TOKEN_SIZE]); - -#[derive(Debug)] -pub enum AuthTokenConversionError { - InvalidStringError, - StringOfInvalidLengthError, -} - -impl AuthToken { - pub fn from_bytes(bytes: [u8; AUTH_TOKEN_SIZE]) -> Self { - AuthToken(bytes) - } - - pub fn to_bytes(&self) -> [u8; AUTH_TOKEN_SIZE] { - self.0 - } - - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } - - pub fn try_from_base58_string>( - val: S, - ) -> Result { - let decoded = match bs58::decode(val.into()).into_vec() { - Ok(decoded) => decoded, - Err(_) => return Err(AuthTokenConversionError::InvalidStringError), - }; - - if decoded.len() != AUTH_TOKEN_SIZE { - return Err(AuthTokenConversionError::StringOfInvalidLengthError); - } - - let mut token = [0u8; AUTH_TOKEN_SIZE]; - token.copy_from_slice(&decoded[..]); - Ok(AuthToken(token)) - } - - pub fn to_base58_string(&self) -> String { - bs58::encode(self.0).into_string() - } -} - -impl Into for AuthToken { - fn into(self) -> String { - self.to_base58_string() - } -} - -#[cfg(test)] -mod auth_token_conversion { - use super::*; - - #[test] - fn it_is_possible_to_recover_it_from_valid_b58_string() { - let auth_token = AuthToken([42; AUTH_TOKEN_SIZE]); - let auth_token_string = auth_token.to_base58_string(); - assert_eq!( - auth_token, - AuthToken::try_from_base58_string(auth_token_string).unwrap() - ) - } - - #[test] - fn it_is_possible_to_recover_it_from_valid_b58_str_ref() { - let auth_token = AuthToken([42; AUTH_TOKEN_SIZE]); - let auth_token_string = auth_token.to_base58_string(); - let auth_token_str_ref: &str = &auth_token_string; - assert_eq!( - auth_token, - AuthToken::try_from_base58_string(auth_token_str_ref).unwrap() - ) - } - - #[test] - fn it_returns_error_on_b58_with_invalid_characters() { - let auth_token = AuthToken([42; AUTH_TOKEN_SIZE]); - let auth_token_string = auth_token.to_base58_string(); - - let mut chars = auth_token_string.chars(); - let _consumed_first_char = chars.next().unwrap(); - - let invalid_chars_token = "=".to_string() + chars.as_str(); - assert!(AuthToken::try_from_base58_string(invalid_chars_token).is_err()) - } - - #[test] - fn it_returns_error_on_too_long_b58_string() { - let auth_token = AuthToken([42; AUTH_TOKEN_SIZE]); - let mut auth_token_string = auth_token.to_base58_string(); - auth_token_string.push('f'); - - assert!(AuthToken::try_from_base58_string(auth_token_string).is_err()) - } - - #[test] - fn it_returns_error_on_too_short_b58_string() { - let auth_token = AuthToken([42; AUTH_TOKEN_SIZE]); - let auth_token_string = auth_token.to_base58_string(); - - let mut chars = auth_token_string.chars(); - let _consumed_first_char = chars.next().unwrap(); - let _consumed_second_char = chars.next().unwrap(); - let invalid_chars_token = chars.as_str(); - - assert!(AuthToken::try_from_base58_string(invalid_chars_token).is_err()) - } -} diff --git a/sfw-provider/sfw-provider-requests/src/lib.rs b/sfw-provider/sfw-provider-requests/src/lib.rs deleted file mode 100644 index c18d3554dc3..00000000000 --- a/sfw-provider/sfw-provider-requests/src/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub mod auth_token; -pub mod requests; -pub mod responses; - -pub const DUMMY_MESSAGE_CONTENT: &[u8] = - b"[DUMMY MESSAGE] Wanting something does not give you the right to have it."; - -// TODO: consideration for the future: should all request/responses have associated IDs -// for "async" API? However, TCP should ensure packets are received in order, so maybe -// it's not really required? diff --git a/sfw-provider/sfw-provider-requests/src/requests/async_io.rs b/sfw-provider/sfw-provider-requests/src/requests/async_io.rs deleted file mode 100644 index ff070f7a166..00000000000 --- a/sfw-provider/sfw-provider-requests/src/requests/async_io.rs +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::requests::serialization::{RequestDeserializer, RequestSerializer}; -use crate::requests::{ProviderRequest, ProviderRequestError}; -use std::io; -use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; - -// TODO: way down the line, mostly for learning purposes, combine this with responses::async_io -// via procedural macros - -// Ideally I would have used futures::AsyncRead for even more generic approach, but unfortunately -// tokio::io::AsyncRead differs from futures::AsyncRead -pub struct TokioAsyncRequestReader<'a, R: AsyncRead + Unpin> { - max_allowed_len: usize, - reader: &'a mut R, -} - -impl<'a, R: AsyncRead + Unpin> TokioAsyncRequestReader<'a, R> { - pub fn new(reader: &'a mut R, max_allowed_len: usize) -> Self { - TokioAsyncRequestReader { - reader, - max_allowed_len, - } - } - - pub async fn try_read_request(&mut self) -> Result { - let req_len = self.reader.read_u32().await?; - if req_len == 0 { - return Err(ProviderRequestError::RemoteConnectionClosed); - } - if req_len as usize > self.max_allowed_len { - // TODO: should reader be drained or just assume caller will close the - // underlying reader and/or deal with the issue itself? - return Err(ProviderRequestError::TooLongRequestError); - } - - let mut req_buf = vec![0; req_len as usize]; - if let Err(e) = self.reader.read_exact(&mut req_buf).await { - return Err(ProviderRequestError::IOError(e)); - } - - RequestDeserializer::new_with_len(req_len, &req_buf)?.try_to_parse() - } -} - -// Ideally I would have used futures::AsyncWrite for even more generic approach, but unfortunately -// tokio::io::AsyncWrite differs from futures::AsyncWrite -pub struct TokioAsyncRequestWriter<'a, W: AsyncWrite + Unpin> { - writer: &'a mut W, -} - -impl<'a, W: AsyncWrite + Unpin> TokioAsyncRequestWriter<'a, W> { - pub fn new(writer: &'a mut W) -> Self { - TokioAsyncRequestWriter { writer } - } - - pub async fn try_write_request(&mut self, res: ProviderRequest) -> io::Result<()> { - let res_bytes = RequestSerializer::new(res).into_bytes(); - self.writer.write_all(&res_bytes).await - } -} - -#[cfg(test)] -mod request_writer { - use super::*; - use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; - use crate::requests::{PullRequest, RegisterRequest}; - use nymsphinx::DestinationAddressBytes; - - // TODO: what else to test here? - - #[test] - fn writes_all_bytes_to_underlying_writer_for_register_request() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - let expected_bytes = RequestSerializer::new(register_request.clone().into()).into_bytes(); - - let mut writer = Vec::new(); - - let mut request_writer = TokioAsyncRequestWriter::new(&mut writer); - rt.block_on(request_writer.try_write_request(register_request.into())) - .unwrap(); - - // to finish the mutable borrow since we don't need request_writer anymore anyway - drop(request_writer); - - assert_eq!(writer, expected_bytes); - } - - #[test] - fn writes_all_bytes_to_underlying_writer_for_pull_request() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let pull_request = PullRequest::new(address, auth_token); - let expected_bytes = RequestSerializer::new(pull_request.clone().into()).into_bytes(); - - let mut writer = Vec::new(); - - let mut request_writer = TokioAsyncRequestWriter::new(&mut writer); - rt.block_on(request_writer.try_write_request(pull_request.into())) - .unwrap(); - - // to finish the mutable borrow since we don't need request_writer anymore anyway - drop(request_writer); - - assert_eq!(writer, expected_bytes); - } -} - -#[cfg(test)] -mod request_reader { - use super::*; - use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; - use crate::requests::{PullRequest, RegisterRequest, RequestKind}; - use nymsphinx::DestinationAddressBytes; - use std::io::Cursor; - use std::time; - - #[test] - fn correctly_reads_valid_register_request() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - let serialized_bytes = RequestSerializer::new(register_request.clone().into()).into_bytes(); - - let mut reader = Cursor::new(serialized_bytes); - let mut request_reader = - TokioAsyncRequestReader::new(&mut reader, u32::max_value() as usize); - - let read_request = rt.block_on(request_reader.try_read_request()).unwrap(); - match read_request { - ProviderRequest::Register(req) => assert_eq!(register_request, req), - _ => panic!("read incorrect request!"), - } - } - - #[test] - fn correctly_reads_valid_pull_request() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let pull_request = PullRequest::new(address, auth_token); - let serialized_bytes = RequestSerializer::new(pull_request.clone().into()).into_bytes(); - - let mut reader = Cursor::new(serialized_bytes); - let mut request_reader = - TokioAsyncRequestReader::new(&mut reader, u32::max_value() as usize); - - let read_request = rt.block_on(request_reader.try_read_request()).unwrap(); - match read_request { - ProviderRequest::Pull(req) => assert_eq!(pull_request, req), - _ => panic!("read incorrect request!"), - } - } - - #[test] - fn correctly_reads_valid_register_request_even_if_more_random_bytes_follow() { - // note that if read was called again, it would have failed - - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - let serialized_bytes = RequestSerializer::new(register_request.clone().into()).into_bytes(); - - let serialized_bytes_with_garbage: Vec<_> = serialized_bytes - .into_iter() - .chain(vec![1, 2, 3, 4, 5, 6, 7, 8, 9].into_iter()) - .collect(); - - let mut reader = Cursor::new(serialized_bytes_with_garbage); - let mut request_reader = - TokioAsyncRequestReader::new(&mut reader, u32::max_value() as usize); - - let read_request = rt.block_on(request_reader.try_read_request()).unwrap(); - match read_request { - ProviderRequest::Register(req) => assert_eq!(register_request, req), - _ => panic!("read incorrect request!"), - } - } - - #[test] - fn correctly_reads_two_consecutive_requests() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - - let pull_request = PullRequest::new(address.clone(), auth_token); - let register_request = RegisterRequest::new(address); - - let register_serialized_bytes = - RequestSerializer::new(register_request.clone().into()).into_bytes(); - let pull_serialized_bytes = - RequestSerializer::new(pull_request.clone().into()).into_bytes(); - - let combined_requests: Vec<_> = register_serialized_bytes - .into_iter() - .chain(pull_serialized_bytes.into_iter()) - .collect(); - - let mut reader = Cursor::new(combined_requests); - let mut request_reader = - TokioAsyncRequestReader::new(&mut reader, u32::max_value() as usize); - - let first_read_request = rt.block_on(request_reader.try_read_request()).unwrap(); - match first_read_request { - ProviderRequest::Register(req) => assert_eq!(register_request, req), - _ => panic!("read incorrect request!"), - } - - let second_read_request = rt.block_on(request_reader.try_read_request()).unwrap(); - match second_read_request { - ProviderRequest::Pull(req) => assert_eq!(pull_request, req), - _ => panic!("read incorrect request!"), - } - } - - #[test] - fn correctly_reads_valid_request_even_if_written_with_delay() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - let serialized_bytes = RequestSerializer::new(register_request.clone().into()).into_bytes(); - - let (first_half, second_half) = serialized_bytes.split_at(30); // 30 is an arbitrary value - - let mut mock = tokio_test::io::Builder::new() - .read(&first_half) - .wait(time::Duration::from_millis(300)) - .read(&second_half) - .build(); - - let mut request_reader = TokioAsyncRequestReader::new(&mut mock, u32::max_value() as usize); - - let read_request = rt.block_on(request_reader.try_read_request()).unwrap(); - match read_request { - ProviderRequest::Register(req) => assert_eq!(register_request, req), - _ => panic!("read incorrect request!"), - } - } - - #[test] - fn fails_to_read_invalid_request() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let mut invalid_request = 9u32.to_be_bytes().to_vec(); - invalid_request.push(RequestKind::Register as u8); // to have a 'valid' kind - invalid_request.push(0); - invalid_request.push(1); - invalid_request.push(2); - invalid_request.push(3); - invalid_request.push(4); - invalid_request.push(5); - invalid_request.push(6); - invalid_request.push(7); - - let mut reader = Cursor::new(invalid_request); - let mut request_reader = - TokioAsyncRequestReader::new(&mut reader, u32::max_value() as usize); - - assert!(rt.block_on(request_reader.try_read_request()).is_err()); - } - - #[test] - fn fails_to_read_too_long_request() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - let serialized_bytes = RequestSerializer::new(register_request.clone().into()).into_bytes(); - let serialized_bytes_len = serialized_bytes.len(); - - let mut reader = Cursor::new(serialized_bytes); - // note our reader accepts fewer bytes than what we have - let mut request_reader = - TokioAsyncRequestReader::new(&mut reader, serialized_bytes_len - 10); - - assert!(rt.block_on(request_reader.try_read_request()).is_err()); - } -} diff --git a/sfw-provider/sfw-provider-requests/src/requests/mod.rs b/sfw-provider/sfw-provider-requests/src/requests/mod.rs deleted file mode 100644 index 0fb5bd65cec..00000000000 --- a/sfw-provider/sfw-provider-requests/src/requests/mod.rs +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; -use nymsphinx::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH}; -use std::convert::TryFrom; -use std::io; -use std::io::Error; - -pub mod async_io; -pub mod serialization; - -#[derive(Debug)] -pub enum ProviderRequestError { - MarshalError, - UnmarshalError, - UnmarshalErrorInvalidKind, - UnmarshalErrorInvalidLength, - TooLongRequestError, - TooShortRequestError, - IOError(io::Error), - RemoteConnectionClosed, -} - -impl From for ProviderRequestError { - fn from(e: Error) -> Self { - ProviderRequestError::IOError(e) - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -#[repr(u8)] -pub enum RequestKind { - Pull = 1, - Register = 2, -} - -impl TryFrom for RequestKind { - type Error = ProviderRequestError; - - fn try_from(value: u8) -> Result { - match value { - _ if value == (RequestKind::Pull as u8) => Ok(Self::Pull), - _ if value == (RequestKind::Register as u8) => Ok(Self::Register), - _ => Err(Self::Error::UnmarshalErrorInvalidKind), - } - } -} - -#[derive(Debug, Clone, PartialEq)] -pub enum ProviderRequest { - Pull(PullRequest), - Register(RegisterRequest), -} - -#[derive(Debug, Clone, PartialEq)] -pub struct PullRequest { - pub auth_token: AuthToken, - pub destination_address: nymsphinx::DestinationAddressBytes, -} - -impl Into for PullRequest { - fn into(self) -> ProviderRequest { - ProviderRequest::Pull(self) - } -} - -impl PullRequest { - pub fn new( - destination_address: nymsphinx::DestinationAddressBytes, - auth_token: AuthToken, - ) -> Self { - PullRequest { - auth_token, - destination_address, - } - } - - pub fn get_kind(&self) -> RequestKind { - RequestKind::Pull - } - - fn to_bytes(&self) -> Vec { - self.destination_address - .to_bytes() - .iter() - .cloned() - .chain(self.auth_token.as_bytes().iter().cloned()) - .collect() - } - - fn try_from_bytes(bytes: &[u8]) -> Result { - if bytes.len() != DESTINATION_ADDRESS_LENGTH + AUTH_TOKEN_SIZE { - return Err(ProviderRequestError::UnmarshalErrorInvalidLength); - } - - let mut destination_address = [0u8; DESTINATION_ADDRESS_LENGTH]; - destination_address.copy_from_slice(&bytes[..DESTINATION_ADDRESS_LENGTH]); - - let mut auth_token = [0u8; AUTH_TOKEN_SIZE]; - auth_token.copy_from_slice(&bytes[DESTINATION_ADDRESS_LENGTH..]); - - Ok(PullRequest { - auth_token: AuthToken::from_bytes(auth_token), - destination_address: DestinationAddressBytes::from_bytes(destination_address), - }) - } -} - -#[derive(Debug, Clone, PartialEq)] -pub struct RegisterRequest { - pub destination_address: DestinationAddressBytes, -} - -impl Into for RegisterRequest { - fn into(self) -> ProviderRequest { - ProviderRequest::Register(self) - } -} - -impl RegisterRequest { - pub fn new(destination_address: DestinationAddressBytes) -> Self { - RegisterRequest { - destination_address, - } - } - - pub fn get_kind(&self) -> RequestKind { - RequestKind::Register - } - - fn to_bytes(&self) -> Vec { - self.destination_address - .to_bytes() - .iter() - .cloned() - .collect() - } - - fn try_from_bytes(bytes: &[u8]) -> Result { - if bytes.len() != DESTINATION_ADDRESS_LENGTH { - return Err(ProviderRequestError::UnmarshalErrorInvalidLength); - } - - let mut destination_address = [0u8; DESTINATION_ADDRESS_LENGTH]; - destination_address.copy_from_slice(&bytes[..DESTINATION_ADDRESS_LENGTH]); - - Ok(RegisterRequest { - destination_address: DestinationAddressBytes::from_bytes(destination_address), - }) - } -} - -#[cfg(test)] -mod request_kind { - use super::*; - - #[test] - fn try_from_u8_is_defined_for_all_variants() { - // it is crucial this match statement is never removed as it ensures at compilation - // time that new variants of RequestKind weren't added; the actual code is not as - // important - let dummy_kind = RequestKind::Register; - match dummy_kind { - RequestKind::Register | RequestKind::Pull => (), - }; - - assert_eq!( - RequestKind::try_from(RequestKind::Register as u8).unwrap(), - RequestKind::Register - ); - assert_eq!( - RequestKind::try_from(RequestKind::Pull as u8).unwrap(), - RequestKind::Pull - ); - } -} - -#[cfg(test)] -mod pull_request { - use super::*; - - #[test] - fn returns_correct_kind() { - let pull_request = PullRequest::new( - DestinationAddressBytes::from_bytes(Default::default()), - AuthToken::from_bytes(Default::default()), - ); - assert_eq!(pull_request.get_kind(), RequestKind::Pull) - } - - #[test] - fn can_be_converted_to_and_from_bytes() { - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let pull_request = PullRequest::new(address, auth_token); - let bytes = pull_request.to_bytes(); - - let recovered = PullRequest::try_from_bytes(&bytes).unwrap(); - assert_eq!(recovered, pull_request); - } -} - -#[cfg(test)] -mod register_request { - use super::*; - - #[test] - fn returns_correct_kind() { - let register_request = - RegisterRequest::new(DestinationAddressBytes::from_bytes(Default::default())); - assert_eq!(register_request.get_kind(), RequestKind::Register) - } - - #[test] - fn can_be_converted_to_and_from_bytes() { - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - let bytes = register_request.to_bytes(); - - let recovered = RegisterRequest::try_from_bytes(&bytes).unwrap(); - assert_eq!(recovered, register_request); - } -} diff --git a/sfw-provider/sfw-provider-requests/src/requests/serialization.rs b/sfw-provider/sfw-provider-requests/src/requests/serialization.rs deleted file mode 100644 index 69ecfbe6101..00000000000 --- a/sfw-provider/sfw-provider-requests/src/requests/serialization.rs +++ /dev/null @@ -1,300 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::requests::*; -use std::convert::TryFrom; - -// TODO: way down the line, mostly for learning purposes, combine this with responses::serialization -// via procedural macros - -/// Responsible for taking a request and converting it into bytes that can be sent -/// over the wire, such that a `RequestDeserializer` can recover it. -pub struct RequestSerializer { - req: ProviderRequest, -} - -impl RequestSerializer { - pub fn new(req: ProviderRequest) -> Self { - RequestSerializer { req } - } - - /// Serialized requests in general have the following structure: - /// 4 byte len (be u32) || 1-byte kind prefix || request-specific data - pub fn into_bytes(self) -> Vec { - let (kind, req_bytes) = match self.req { - ProviderRequest::Pull(req) => (req.get_kind(), req.to_bytes()), - ProviderRequest::Register(req) => (req.get_kind(), req.to_bytes()), - }; - let req_len = req_bytes.len() as u32 + 1; // 1 is to accommodate for 'kind' - let req_len_bytes = req_len.to_be_bytes(); - req_len_bytes - .iter() - .cloned() - .chain(std::iter::once(kind as u8)) - .chain(req_bytes.into_iter()) - .collect() - } -} - -/// Responsible for taking raw bytes extracted from a stream that have been serialized -/// with `RequestSerializer` and eventually return original Request written. -pub struct RequestDeserializer<'a> { - kind: RequestKind, - data: &'a [u8], -} - -impl<'a> RequestDeserializer<'a> { - // perform initial parsing and validation - pub fn new(raw_bytes: &'a [u8]) -> Result { - if raw_bytes.len() < 1 + 4 { - Err(ProviderRequestError::UnmarshalErrorInvalidLength) - } else { - let data_len = - u32::from_be_bytes([raw_bytes[0], raw_bytes[1], raw_bytes[2], raw_bytes[3]]); - - Self::new_with_len(data_len, &raw_bytes[4..]) - } - } - - pub fn new_with_len(len: u32, raw_bytes: &'a [u8]) -> Result { - if raw_bytes.len() != len as usize { - Err(ProviderRequestError::UnmarshalErrorInvalidLength) - } else { - let kind = RequestKind::try_from(raw_bytes[0])?; - let data = &raw_bytes[1..]; - Ok(RequestDeserializer { kind, data }) - } - } - - pub fn get_kind(&self) -> RequestKind { - self.kind - } - - pub fn get_data(&self) -> &'a [u8] { - self.data - } - - pub fn try_to_parse(self) -> Result { - match self.get_kind() { - RequestKind::Pull => Ok(ProviderRequest::Pull(PullRequest::try_from_bytes( - self.data, - )?)), - RequestKind::Register => Ok(ProviderRequest::Register( - RegisterRequest::try_from_bytes(self.data)?, - )), - } - } -} - -#[cfg(test)] -mod request_serialization { - use super::*; - use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; - use byteorder::{BigEndian, ByteOrder}; - use nymsphinx::DestinationAddressBytes; - use std::convert::TryInto; - - #[test] - fn correctly_serializes_pull_request() { - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let pull_request = PullRequest::new(address, auth_token); - - let raw_request_bytes = pull_request.to_bytes(); - let serializer = RequestSerializer::new(pull_request.clone().into()); - let bytes = serializer.into_bytes(); - - // we expect first four bytes to represent length then kind and finally raw data - let len = BigEndian::read_u32(&bytes); - let kind: RequestKind = bytes[4].try_into().unwrap(); - let data = &bytes[5..]; - assert_eq!(len as usize, data.len() + 1); - assert_eq!(data.to_vec(), raw_request_bytes); - - let recovered_request = PullRequest::try_from_bytes(data).unwrap(); - assert_eq!(pull_request, recovered_request); - assert_eq!(kind, pull_request.get_kind()); - } - - #[test] - fn correctly_serializes_register_request() { - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - - let raw_request_bytes = register_request.to_bytes(); - let serializer = RequestSerializer::new(register_request.clone().into()); - let bytes = serializer.into_bytes(); - - // we expect first four bytes to represent length then kind and finally raw data - let len = BigEndian::read_u32(&bytes); - let kind: RequestKind = bytes[4].try_into().unwrap(); - let data = &bytes[5..]; - assert_eq!(len as usize, data.len() + 1); - assert_eq!(data.to_vec(), raw_request_bytes); - - let recovered_request = RegisterRequest::try_from_bytes(data).unwrap(); - assert_eq!(register_request, recovered_request); - assert_eq!(kind, register_request.get_kind()); - } -} - -#[cfg(test)] -mod request_deserialization { - use super::*; - use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; - use byteorder::{BigEndian, ByteOrder}; - use nymsphinx::DestinationAddressBytes; - - #[test] - fn correctly_deserializes_pull_request() { - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let pull_request = PullRequest::new(address, auth_token); - - let raw_request_bytes = pull_request.to_bytes(); - let bytes = RequestSerializer::new(pull_request.clone().into()).into_bytes(); - - let deserializer_new = RequestDeserializer::new(&bytes).unwrap(); - assert_eq!(deserializer_new.get_kind(), pull_request.get_kind()); - assert_eq!(deserializer_new.get_data().to_vec(), raw_request_bytes); - - assert_eq!( - ProviderRequest::Pull(pull_request.clone()), - deserializer_new.try_to_parse().unwrap() - ); - - // simulate consuming first 4 bytes to read len - let len = BigEndian::read_u32(&bytes); - let bytes_without_len = &bytes[4..]; - let deserializer_new_with_len = - RequestDeserializer::new_with_len(len, bytes_without_len).unwrap(); - assert_eq!( - deserializer_new_with_len.get_kind(), - pull_request.get_kind() - ); - assert_eq!( - deserializer_new_with_len.get_data().to_vec(), - raw_request_bytes - ); - - assert_eq!( - ProviderRequest::Pull(pull_request), - deserializer_new_with_len.try_to_parse().unwrap() - ); - } - - #[test] - fn correctly_deserializes_register_request() { - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - - let raw_request_bytes = register_request.to_bytes(); - let bytes = RequestSerializer::new(register_request.clone().into()).into_bytes(); - - let deserializer_new = RequestDeserializer::new(&bytes).unwrap(); - assert_eq!(deserializer_new.get_kind(), register_request.get_kind()); - assert_eq!(deserializer_new.get_data().to_vec(), raw_request_bytes); - - assert_eq!( - ProviderRequest::Register(register_request.clone()), - deserializer_new.try_to_parse().unwrap() - ); - - // simulate consuming first 4 bytes to read len - let len = BigEndian::read_u32(&bytes); - let bytes_without_len = &bytes[4..]; - let deserializer_new_with_len = - RequestDeserializer::new_with_len(len, bytes_without_len).unwrap(); - assert_eq!( - deserializer_new_with_len.get_kind(), - register_request.get_kind() - ); - assert_eq!( - deserializer_new_with_len.get_data().to_vec(), - raw_request_bytes - ); - - assert_eq!( - ProviderRequest::Register(register_request), - deserializer_new_with_len.try_to_parse().unwrap() - ); - } - - #[test] - fn returns_error_on_too_short_messages() { - // no matter the request, it must be AT LEAST 5 byte long (for length and 'kind') - let mut len_bytes = 1u32.to_be_bytes().to_vec(); - len_bytes.push(RequestKind::Register as u8); // to have a 'valid' kind - - // bare minimum should return no error - assert!(RequestDeserializer::new(&len_bytes).is_ok()); - - // but shorter should - assert!(RequestDeserializer::new(&0u32.to_be_bytes().to_vec()).is_err()); - } - - #[test] - fn returns_error_on_messages_of_contradictory_length() { - let data = vec![RequestKind::Register as u8, 1, 2, 3]; - - // it shouldn't fail if it matches up - assert!(RequestDeserializer::new_with_len(4, &data).is_ok()); - - assert!(RequestDeserializer::new_with_len(3, &data).is_err()); - } - - #[test] - fn returns_error_on_messages_of_unknown_kind() { - // perform proper serialization but change 'kind' byte to some invalid value - let address = DestinationAddressBytes::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_request = RegisterRequest::new(address); - let mut bytes = RequestSerializer::new(register_request.clone().into()).into_bytes(); - - let invalid_kind = 42u8; - // sanity check to ensure it IS invalid - assert!(RequestKind::try_from(invalid_kind).is_err()); - bytes[4] = invalid_kind; - assert!(RequestDeserializer::new(&bytes).is_err()); - } - - #[test] - fn returns_error_on_parsing_invalid_data() { - // kind exists, length is correct, but data is unparsable - // no matter the request, it must be AT LEAST 5 byte long (for length and 'kind') - let mut len_bytes = 5u32.to_be_bytes().to_vec(); - len_bytes.push(RequestKind::Register as u8); // to have a 'valid' kind - len_bytes.push(1); - len_bytes.push(2); - len_bytes.push(3); - len_bytes.push(4); - - let deserializer = RequestDeserializer::new(&len_bytes).unwrap(); - assert!(deserializer.try_to_parse().is_err()); - } -} diff --git a/sfw-provider/sfw-provider-requests/src/responses/async_io.rs b/sfw-provider/sfw-provider-requests/src/responses/async_io.rs deleted file mode 100644 index 4c68589a584..00000000000 --- a/sfw-provider/sfw-provider-requests/src/responses/async_io.rs +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::responses::serialization::{ResponseDeserializer, ResponseSerializer}; -use crate::responses::{ProviderResponse, ProviderResponseError}; -use std::io; -use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; - -// TODO: way down the line, mostly for learning purposes, combine this with requests::async_io -// via procedural macros - -// Ideally I would have used futures::AsyncRead for even more generic approach, but unfortunately -// tokio::io::AsyncRead differs from futures::AsyncRead -pub struct TokioAsyncResponseReader<'a, R: AsyncRead + Unpin> { - max_allowed_len: usize, - reader: &'a mut R, -} - -impl<'a, R: AsyncRead + Unpin> TokioAsyncResponseReader<'a, R> { - pub fn new(reader: &'a mut R, max_allowed_len: usize) -> Self { - TokioAsyncResponseReader { - reader, - max_allowed_len, - } - } - - pub async fn try_read_response(&mut self) -> Result { - let res_len = self.reader.read_u32().await?; - if res_len == 0 { - return Err(ProviderResponseError::RemoteConnectionClosed); - } - if res_len as usize > self.max_allowed_len { - // TODO: should reader be drained or just assume caller will close the - // underlying reader and/or deal with the issue itself? - return Err(ProviderResponseError::TooLongResponseError); - } - - let mut res_buf = vec![0; res_len as usize]; - if let Err(e) = self.reader.read_exact(&mut res_buf).await { - return Err(ProviderResponseError::IOError(e)); - } - - ResponseDeserializer::new_with_len(res_len, &res_buf)?.try_to_parse() - } -} - -// Ideally I would have used futures::AsyncWrite for even more generic approach, but unfortunately -// tokio::io::AsyncWrite differs from futures::AsyncWrite -pub struct TokioAsyncResponseWriter<'a, W: AsyncWrite + Unpin> { - writer: &'a mut W, -} - -impl<'a, W: AsyncWrite + Unpin> TokioAsyncResponseWriter<'a, W> { - pub fn new(writer: &'a mut W) -> Self { - TokioAsyncResponseWriter { writer } - } - - pub async fn try_write_response(&mut self, res: ProviderResponse) -> io::Result<()> { - let res_bytes = ResponseSerializer::new(res).into_bytes(); - self.writer.write_all(&res_bytes).await - } -} - -#[cfg(test)] -mod response_writer { - use super::*; - use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; - use crate::responses::{FailureResponse, PullResponse, RegisterResponse}; - - // TODO: what else to test here? - - #[test] - fn writes_all_bytes_to_underlying_writer_for_register_response() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let register_response = RegisterResponse::new(auth_token); - let expected_bytes = ResponseSerializer::new(register_response.clone().into()).into_bytes(); - - let mut writer = Vec::new(); - - let mut response_writer = TokioAsyncResponseWriter::new(&mut writer); - rt.block_on(response_writer.try_write_response(register_response.into())) - .unwrap(); - - // to finish the mutable borrow since we don't need response_writer anymore anyway - drop(response_writer); - - assert_eq!(writer, expected_bytes); - } - - #[test] - fn writes_all_bytes_to_underlying_writer_for_pull_response() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let msg1 = vec![ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]; - let msg2 = vec![1, 2, 3, 4, 5, 6, 7]; - let pull_response = PullResponse::new(vec![msg1, msg2]); - - let expected_bytes = ResponseSerializer::new(pull_response.clone().into()).into_bytes(); - - let mut writer = Vec::new(); - - let mut response_writer = TokioAsyncResponseWriter::new(&mut writer); - rt.block_on(response_writer.try_write_response(pull_response.into())) - .unwrap(); - - // to finish the mutable borrow since we don't need response_writer anymore anyway - drop(response_writer); - - assert_eq!(writer, expected_bytes); - } - - #[test] - fn writes_all_bytes_to_underlying_writer_for_failure_response() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let msg1 = "hello nym"; - let failure_response = FailureResponse::new(msg1); - - let expected_bytes = ResponseSerializer::new(failure_response.clone().into()).into_bytes(); - - let mut writer = Vec::new(); - - let mut response_writer = TokioAsyncResponseWriter::new(&mut writer); - rt.block_on(response_writer.try_write_response(failure_response.into())) - .unwrap(); - - // to finish the mutable borrow since we don't need response_writer anymore anyway - drop(response_writer); - - assert_eq!(writer, expected_bytes); - } -} - -#[cfg(test)] -mod response_reader { - use super::*; - use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; - use crate::responses::{PullResponse, RegisterResponse, ResponseKind}; - use std::io::Cursor; - use std::time; - - #[test] - fn correctly_reads_valid_register_response() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let register_response = RegisterResponse::new(auth_token); - let serialized_bytes = - ResponseSerializer::new(register_response.clone().into()).into_bytes(); - - let mut reader = Cursor::new(serialized_bytes); - let mut response_reader = - TokioAsyncResponseReader::new(&mut reader, u32::max_value() as usize); - - let read_response = rt.block_on(response_reader.try_read_response()).unwrap(); - match read_response { - ProviderResponse::Register(req) => assert_eq!(register_response, req), - _ => panic!("read incorrect response!"), - } - } - - #[test] - fn correctly_reads_valid_pull_response() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let msg1 = vec![ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]; - let msg2 = vec![1, 2, 3, 4, 5, 6, 7]; - let pull_response = PullResponse::new(vec![msg1, msg2]); - let serialized_bytes = ResponseSerializer::new(pull_response.clone().into()).into_bytes(); - - let mut reader = Cursor::new(serialized_bytes); - let mut response_reader = - TokioAsyncResponseReader::new(&mut reader, u32::max_value() as usize); - - let read_response = rt.block_on(response_reader.try_read_response()).unwrap(); - match read_response { - ProviderResponse::Pull(req) => assert_eq!(pull_response, req), - _ => panic!("read incorrect response!"), - } - } - - #[test] - fn correctly_reads_valid_register_response_even_if_more_random_bytes_follow() { - // note that if read was called again, it would have failed - - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let register_response = RegisterResponse::new(auth_token); - let serialized_bytes = - ResponseSerializer::new(register_response.clone().into()).into_bytes(); - - let serialized_bytes_with_garbage: Vec<_> = serialized_bytes - .into_iter() - .chain(vec![1, 2, 3, 4, 5, 6, 7, 8, 9].into_iter()) - .collect(); - - let mut reader = Cursor::new(serialized_bytes_with_garbage); - let mut response_reader = - TokioAsyncResponseReader::new(&mut reader, u32::max_value() as usize); - - let read_response = rt.block_on(response_reader.try_read_response()).unwrap(); - match read_response { - ProviderResponse::Register(req) => assert_eq!(register_response, req), - _ => panic!("read incorrect response!"), - } - } - - #[test] - fn correctly_reads_two_consecutive_responses() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let msg1 = vec![ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]; - let msg2 = vec![1, 2, 3, 4, 5, 6, 7]; - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - - let pull_response = PullResponse::new(vec![msg1, msg2]); - let register_response = RegisterResponse::new(auth_token); - - let register_serialized_bytes = - ResponseSerializer::new(register_response.clone().into()).into_bytes(); - let pull_serialized_bytes = - ResponseSerializer::new(pull_response.clone().into()).into_bytes(); - - let combined_responses: Vec<_> = register_serialized_bytes - .into_iter() - .chain(pull_serialized_bytes.into_iter()) - .collect(); - - let mut reader = Cursor::new(combined_responses); - let mut response_reader = - TokioAsyncResponseReader::new(&mut reader, u32::max_value() as usize); - - let first_read_response = rt.block_on(response_reader.try_read_response()).unwrap(); - match first_read_response { - ProviderResponse::Register(req) => assert_eq!(register_response, req), - _ => panic!("read incorrect response!"), - } - - let second_read_response = rt.block_on(response_reader.try_read_response()).unwrap(); - match second_read_response { - ProviderResponse::Pull(req) => assert_eq!(pull_response, req), - _ => panic!("read incorrect response!"), - } - } - - #[test] - fn correctly_reads_valid_response_even_if_written_with_delay() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let register_response = RegisterResponse::new(auth_token); - let serialized_bytes = - ResponseSerializer::new(register_response.clone().into()).into_bytes(); - - let (first_half, second_half) = serialized_bytes.split_at(30); // 30 is an arbitrary value - - let mut mock = tokio_test::io::Builder::new() - .read(&first_half) - .wait(time::Duration::from_millis(300)) - .read(&second_half) - .build(); - - let mut response_reader = - TokioAsyncResponseReader::new(&mut mock, u32::max_value() as usize); - - let read_response = rt.block_on(response_reader.try_read_response()).unwrap(); - match read_response { - ProviderResponse::Register(req) => assert_eq!(register_response, req), - _ => panic!("read incorrect response!"), - } - } - - #[test] - fn fails_to_read_invalid_response() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let mut invalid_response = 9u32.to_be_bytes().to_vec(); - invalid_response.push(ResponseKind::Register as u8); // to have a 'valid' kind - invalid_response.push(0); - invalid_response.push(1); - invalid_response.push(2); - invalid_response.push(3); - invalid_response.push(4); - invalid_response.push(5); - invalid_response.push(6); - invalid_response.push(7); - - let mut reader = Cursor::new(invalid_response); - let mut response_reader = - TokioAsyncResponseReader::new(&mut reader, u32::max_value() as usize); - - assert!(rt.block_on(response_reader.try_read_response()).is_err()); - } - - #[test] - fn fails_to_read_too_long_response() { - let mut rt = tokio::runtime::Runtime::new().unwrap(); - - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let register_response = RegisterResponse::new(auth_token); - let serialized_bytes = - ResponseSerializer::new(register_response.clone().into()).into_bytes(); - let serialized_bytes_len = serialized_bytes.len(); - - let mut reader = Cursor::new(serialized_bytes); - // note our reader accepts fewer bytes than what we have - let mut response_reader = - TokioAsyncResponseReader::new(&mut reader, serialized_bytes_len - 10); - - assert!(rt.block_on(response_reader.try_read_response()).is_err()); - } -} diff --git a/sfw-provider/sfw-provider-requests/src/responses/mod.rs b/sfw-provider/sfw-provider-requests/src/responses/mod.rs deleted file mode 100644 index 80bc0d5085c..00000000000 --- a/sfw-provider/sfw-provider-requests/src/responses/mod.rs +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; -use std::convert::{TryFrom, TryInto}; -use std::io; -use std::io::Error; - -pub mod async_io; -pub mod serialization; - -#[derive(Debug)] -pub enum ProviderResponseError { - MarshalError, - UnmarshalError, - UnmarshalErrorInvalidKind, - UnmarshalErrorInvalidLength, - TooShortResponseError, - TooLongResponseError, - IOError(io::Error), - RemoteConnectionClosed, -} - -impl From for ProviderResponseError { - fn from(e: Error) -> Self { - ProviderResponseError::IOError(e) - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -#[repr(u8)] -pub enum ResponseKind { - Failure = 0, // perhaps Error would have been a better name, but it'd clash with Self::TryFrom::Error - Pull = 1, - Register = 2, -} - -impl TryFrom for ResponseKind { - type Error = ProviderResponseError; - - fn try_from(value: u8) -> Result { - match value { - _ if value == (ResponseKind::Failure as u8) => Ok(Self::Failure), - _ if value == (ResponseKind::Pull as u8) => Ok(Self::Pull), - _ if value == (ResponseKind::Register as u8) => Ok(Self::Register), - _ => Err(Self::Error::UnmarshalErrorInvalidKind), - } - } -} - -#[derive(Debug, Clone, PartialEq)] -pub enum ProviderResponse { - Failure(FailureResponse), - Pull(PullResponse), - Register(RegisterResponse), -} - -#[derive(Debug, Clone, PartialEq)] -pub struct PullResponse { - messages: Vec>, -} - -impl Into for PullResponse { - fn into(self) -> ProviderResponse { - ProviderResponse::Pull(self) - } -} - -impl PullResponse { - pub fn new(messages: Vec>) -> Self { - PullResponse { messages } - } - - pub fn extract_messages(self) -> Vec> { - self.messages - } - - pub fn get_kind(&self) -> ResponseKind { - ResponseKind::Pull - } - - // TODO: currently this allows for maximum 64kB payload (max value of u16) - - // if we go over that in sphinx we need to update this code. - // num_msgs || len1 || len2 || ... || msg1 || msg2 || ... - pub fn to_bytes(&self) -> Vec { - let num_msgs = self.messages.len() as u16; - let msgs_lens: Vec = self - .messages - .iter() - .map(|msg| { - assert!(msg.len() <= u16::max_value() as usize); - msg.len() as u16 - }) - .collect(); - - num_msgs - .to_be_bytes() - .iter() - .cloned() - .chain( - msgs_lens - .into_iter() - .flat_map(|len| len.to_be_bytes().to_vec().into_iter()), - ) - .chain(self.messages.iter().flat_map(|msg| msg.clone().into_iter())) - .collect() - } - - pub fn try_from_bytes(bytes: &[u8]) -> Result { - // can we read number of messages? - if bytes.len() < 2 { - return Err(ProviderResponseError::UnmarshalErrorInvalidLength); - } - - let mut bytes_copy = bytes; - let num_msgs = extract_be_u16(&mut bytes_copy); - - // can we read all lengths of messages? - if bytes_copy.len() < (num_msgs * 2) as usize { - return Err(ProviderResponseError::UnmarshalErrorInvalidLength); - } - - let msgs_lens: Vec<_> = (0..num_msgs) - .map(|_| extract_be_u16(&mut bytes_copy)) - .collect(); - - let required_remaining_len = msgs_lens - .iter() - .fold(0usize, |acc, &len| acc + (len as usize)); - - // can we read messages themselves? - if bytes_copy.len() != required_remaining_len { - return Err(ProviderResponseError::UnmarshalErrorInvalidLength); - } - - let msgs = msgs_lens - .iter() - .scan(0usize, |i, &len| { - let j = *i + (len as usize); - let msg = bytes_copy[*i..j].to_vec(); - *i = j; - Some(msg) - }) - .collect(); - - Ok(PullResponse { messages: msgs }) - } -} - -#[derive(Debug, Clone, PartialEq)] -pub struct RegisterResponse { - auth_token: AuthToken, -} - -impl Into for RegisterResponse { - fn into(self) -> ProviderResponse { - ProviderResponse::Register(self) - } -} - -impl RegisterResponse { - pub fn new(auth_token: AuthToken) -> Self { - RegisterResponse { auth_token } - } - - pub fn get_token(&self) -> AuthToken { - self.auth_token - } - - pub fn get_kind(&self) -> ResponseKind { - ResponseKind::Register - } - - pub fn to_bytes(&self) -> Vec { - self.auth_token.to_bytes().to_vec() - } - - pub fn try_from_bytes(bytes: &[u8]) -> Result { - if bytes.len() != AUTH_TOKEN_SIZE { - return Err(ProviderResponseError::UnmarshalErrorInvalidLength); - } - - let mut auth_token = [0u8; AUTH_TOKEN_SIZE]; - auth_token.copy_from_slice(&bytes[..AUTH_TOKEN_SIZE]); - Ok(RegisterResponse { - auth_token: AuthToken::from_bytes(auth_token), - }) - } -} - -#[derive(Debug, Clone, PartialEq)] -pub struct FailureResponse { - message: String, -} - -impl Into for FailureResponse { - fn into(self) -> ProviderResponse { - ProviderResponse::Failure(self) - } -} - -impl FailureResponse { - pub fn new>(message: S) -> Self { - FailureResponse { - message: message.into(), - } - } - - pub fn get_message(&self) -> &str { - &self.message - } - - pub fn get_kind(&self) -> ResponseKind { - ResponseKind::Failure - } - - pub fn to_bytes(&self) -> Vec { - self.message.clone().into_bytes() - } - - pub fn try_from_bytes(bytes: &[u8]) -> Result { - match String::from_utf8(bytes.to_vec()) { - Err(_) => Err(ProviderResponseError::UnmarshalError), - Ok(message) => Ok(FailureResponse { message }), - } - } -} - -/// Takes first 2 bytes of slice, REMOVES THEM and reads it as u16 -fn extract_be_u16(input: &mut &[u8]) -> u16 { - let (int_bytes, rest) = input.split_at(std::mem::size_of::()); - *input = rest; - u16::from_be_bytes(int_bytes.try_into().unwrap()) -} - -#[cfg(test)] -mod response_kind { - use super::*; - - #[test] - fn try_from_u8_is_defined_for_all_variants() { - // it is crucial this match statement is never removed as it ensures at compilation - // time that new variants of ResponseKind weren't added; the actual code is not as - // important - let dummy_kind = ResponseKind::Register; - match dummy_kind { - ResponseKind::Register | ResponseKind::Pull | ResponseKind::Failure => (), - }; - - assert_eq!( - ResponseKind::try_from(ResponseKind::Register as u8).unwrap(), - ResponseKind::Register - ); - assert_eq!( - ResponseKind::try_from(ResponseKind::Pull as u8).unwrap(), - ResponseKind::Pull - ); - assert_eq!( - ResponseKind::try_from(ResponseKind::Failure as u8).unwrap(), - ResponseKind::Failure - ); - } -} - -#[cfg(test)] -mod pull_response { - use super::*; - - #[test] - fn returns_correct_kind() { - let pull_response = PullResponse::new(Default::default()); - assert_eq!(pull_response.get_kind(), ResponseKind::Pull) - } - - #[test] - fn can_be_converted_to_and_from_bytes() { - let msg1 = vec![1, 2, 3, 4, 5]; - let msg2 = vec![]; - let msg3 = vec![ - 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, - 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, - 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, - 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, - 2, 3, 4, 5, 1, 2, 3, 4, 5, - ]; - let msg4 = vec![1, 2, 3, 4, 5, 6, 7]; - - let msgs = vec![msg1, msg2, msg3, msg4]; - let pull_response = PullResponse::new(msgs); - let bytes = pull_response.to_bytes(); - - let recovered = PullResponse::try_from_bytes(&bytes).unwrap(); - assert_eq!(recovered, pull_response); - } - - #[test] - #[should_panic] - fn panics_if_message_is_longer_than_u16_max_when_converted_to_bytes() { - let msg = [1u8; u16::max_value() as usize + 1].to_vec(); - - let pull_response = PullResponse::new(vec![msg]); - pull_response.to_bytes(); - } -} - -#[cfg(test)] -mod register_response { - use super::*; - - #[test] - fn returns_correct_kind() { - let register_response = RegisterResponse::new(AuthToken::from_bytes(Default::default())); - assert_eq!(register_response.get_kind(), ResponseKind::Register) - } - - #[test] - fn can_be_converted_to_and_from_bytes() { - let address = AuthToken::from_bytes([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]); - let register_response = RegisterResponse::new(address); - let bytes = register_response.to_bytes(); - - let recovered = RegisterResponse::try_from_bytes(&bytes).unwrap(); - assert_eq!(recovered, register_response); - } -} - -#[cfg(test)] -mod failure_response { - use super::*; - - #[test] - fn returns_correct_kind() { - let failure_response = FailureResponse::new("hello nym"); - assert_eq!(failure_response.get_kind(), ResponseKind::Failure) - } - - #[test] - fn can_be_converted_to_and_from_bytes() { - let failure_response = FailureResponse::new("hello nym"); - let bytes = failure_response.to_bytes(); - - let recovered = FailureResponse::try_from_bytes(&bytes).unwrap(); - assert_eq!(recovered, failure_response); - } -} diff --git a/sfw-provider/sfw-provider-requests/src/responses/serialization.rs b/sfw-provider/sfw-provider-requests/src/responses/serialization.rs deleted file mode 100644 index d059beb58ad..00000000000 --- a/sfw-provider/sfw-provider-requests/src/responses/serialization.rs +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::responses::*; -use std::convert::TryFrom; - -// TODO: way down the line, mostly for learning purposes, combine this with requests::serialization -// via procedural macros - -/// Responsible for taking a response and converting it into bytes that can be sent -/// over the wire, such that a `ResponseDeserializer` can recover it. -pub struct ResponseSerializer { - res: ProviderResponse, -} - -impl ResponseSerializer { - pub fn new(res: ProviderResponse) -> Self { - ResponseSerializer { res } - } - - /// Serialized responses in general have the following structure: - /// 4 byte len (be u32) || 1-byte kind prefix || response-specific data - pub fn into_bytes(self) -> Vec { - let (kind, res_bytes) = match self.res { - // again, perhaps some extra macros/generics here? - ProviderResponse::Failure(res) => (res.get_kind(), res.to_bytes()), - ProviderResponse::Pull(res) => (res.get_kind(), res.to_bytes()), - ProviderResponse::Register(res) => (res.get_kind(), res.to_bytes()), - }; - let res_len = res_bytes.len() as u32 + 1; // 1 is to accommodate for 'kind' - let res_len_bytes = res_len.to_be_bytes(); - res_len_bytes - .iter() - .cloned() - .chain(std::iter::once(kind as u8)) - .chain(res_bytes.into_iter()) - .collect() - } -} - -/// Responsible for taking raw bytes extracted from a stream that have been serialized -/// with `ResponseSerializer` and eventually return original Response written. -pub struct ResponseDeserializer<'a> { - kind: ResponseKind, - data: &'a [u8], -} - -impl<'a> ResponseDeserializer<'a> { - // perform initial parsing and validation - pub fn new(raw_bytes: &'a [u8]) -> Result { - if raw_bytes.len() < 1 + 4 { - Err(ProviderResponseError::UnmarshalErrorInvalidLength) - } else { - let data_len = - u32::from_be_bytes([raw_bytes[0], raw_bytes[1], raw_bytes[2], raw_bytes[3]]); - - Self::new_with_len(data_len, &raw_bytes[4..]) - } - } - - pub fn new_with_len(len: u32, raw_bytes: &'a [u8]) -> Result { - if raw_bytes.len() != len as usize { - Err(ProviderResponseError::UnmarshalErrorInvalidLength) - } else { - let kind = ResponseKind::try_from(raw_bytes[0])?; - let data = &raw_bytes[1..]; - Ok(ResponseDeserializer { kind, data }) - } - } - - pub fn get_kind(&self) -> ResponseKind { - self.kind - } - - pub fn get_data(&self) -> &'a [u8] { - self.data - } - - pub fn try_to_parse(self) -> Result { - match self.get_kind() { - ResponseKind::Failure => Ok(ProviderResponse::Failure( - FailureResponse::try_from_bytes(self.data)?, - )), - ResponseKind::Pull => Ok(ProviderResponse::Pull(PullResponse::try_from_bytes( - self.data, - )?)), - ResponseKind::Register => Ok(ProviderResponse::Register( - RegisterResponse::try_from_bytes(self.data)?, - )), - } - } -} - -#[cfg(test)] -mod response_serialization { - use super::*; - use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; - use byteorder::{BigEndian, ByteOrder}; - use std::convert::TryInto; - - #[test] - fn correctly_serializes_pull_response() { - let msg1 = vec![ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]; - let msg2 = vec![1, 2, 3, 4, 5, 6, 7]; - let pull_response = PullResponse::new(vec![msg1, msg2]); - - let raw_response_bytes = pull_response.to_bytes(); - let serializer = ResponseSerializer::new(pull_response.clone().into()); - let bytes = serializer.into_bytes(); - - // we expect first four bytes to represent length then kind and finally raw data - let len = BigEndian::read_u32(&bytes); - let kind: ResponseKind = bytes[4].try_into().unwrap(); - let data = &bytes[5..]; - assert_eq!(len as usize, data.len() + 1); - assert_eq!(data.to_vec(), raw_response_bytes); - - let recovered_response = PullResponse::try_from_bytes(data).unwrap(); - assert_eq!(pull_response, recovered_response); - assert_eq!(kind, pull_response.get_kind()); - } - - #[test] - fn correctly_serializes_register_response() { - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let register_response = RegisterResponse::new(auth_token); - - let raw_response_bytes = register_response.to_bytes(); - let serializer = ResponseSerializer::new(register_response.clone().into()); - let bytes = serializer.into_bytes(); - - // we expect first four bytes to represent length then kind and finally raw data - let len = BigEndian::read_u32(&bytes); - let kind: ResponseKind = bytes[4].try_into().unwrap(); - let data = &bytes[5..]; - assert_eq!(len as usize, data.len() + 1); - assert_eq!(data.to_vec(), raw_response_bytes); - - let recovered_response = RegisterResponse::try_from_bytes(data).unwrap(); - assert_eq!(register_response, recovered_response); - assert_eq!(kind, register_response.get_kind()); - } -} - -#[cfg(test)] -mod response_deserialization { - use super::*; - use crate::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; - use byteorder::{BigEndian, ByteOrder}; - - #[test] - fn correctly_deserializes_pull_response() { - let msg1 = vec![ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 1, 2, - ]; - let msg2 = vec![1, 2, 3, 4, 5, 6, 7]; - let pull_response = PullResponse::new(vec![msg1, msg2]); - - let raw_response_bytes = pull_response.to_bytes(); - let bytes = ResponseSerializer::new(pull_response.clone().into()).into_bytes(); - - let deserializer_new = ResponseDeserializer::new(&bytes).unwrap(); - assert_eq!(deserializer_new.get_kind(), pull_response.get_kind()); - assert_eq!(deserializer_new.get_data().to_vec(), raw_response_bytes); - - assert_eq!( - ProviderResponse::Pull(pull_response.clone()), - deserializer_new.try_to_parse().unwrap() - ); - - // simulate consuming first 4 bytes to read len - let len = BigEndian::read_u32(&bytes); - let bytes_without_len = &bytes[4..]; - let deserializer_new_with_len = - ResponseDeserializer::new_with_len(len, bytes_without_len).unwrap(); - assert_eq!( - deserializer_new_with_len.get_kind(), - pull_response.get_kind() - ); - assert_eq!( - deserializer_new_with_len.get_data().to_vec(), - raw_response_bytes - ); - - assert_eq!( - ProviderResponse::Pull(pull_response), - deserializer_new_with_len.try_to_parse().unwrap() - ); - } - - #[test] - fn correctly_deserializes_register_response() { - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let register_response = RegisterResponse::new(auth_token); - - let raw_response_bytes = register_response.to_bytes(); - let bytes = ResponseSerializer::new(register_response.clone().into()).into_bytes(); - - let deserializer_new = ResponseDeserializer::new(&bytes).unwrap(); - assert_eq!(deserializer_new.get_kind(), register_response.get_kind()); - assert_eq!(deserializer_new.get_data().to_vec(), raw_response_bytes); - - assert_eq!( - ProviderResponse::Register(register_response.clone()), - deserializer_new.try_to_parse().unwrap() - ); - - // simulate consuming first 4 bytes to read len - let len = BigEndian::read_u32(&bytes); - let bytes_without_len = &bytes[4..]; - let deserializer_new_with_len = - ResponseDeserializer::new_with_len(len, bytes_without_len).unwrap(); - assert_eq!( - deserializer_new_with_len.get_kind(), - register_response.get_kind() - ); - assert_eq!( - deserializer_new_with_len.get_data().to_vec(), - raw_response_bytes - ); - - assert_eq!( - ProviderResponse::Register(register_response), - deserializer_new_with_len.try_to_parse().unwrap() - ); - } - - #[test] - fn returns_error_on_too_short_messages() { - // no matter the response, it must be AT LEAST 5 byte long (for length and 'kind') - let mut len_bytes = 1u32.to_be_bytes().to_vec(); - len_bytes.push(ResponseKind::Register as u8); // to have a 'valid' kind - - // bare minimum should return no error - assert!(ResponseDeserializer::new(&len_bytes).is_ok()); - - // but shorter should - assert!(ResponseDeserializer::new(&0u32.to_be_bytes().to_vec()).is_err()); - } - - #[test] - fn returns_error_on_messages_of_contradictory_length() { - let data = vec![ResponseKind::Register as u8, 1, 2, 3]; - - // it shouldn't fail if it matches up - assert!(ResponseDeserializer::new_with_len(4, &data).is_ok()); - - assert!(ResponseDeserializer::new_with_len(3, &data).is_err()); - } - - #[test] - fn returns_error_on_messages_of_unknown_kind() { - // perform proper serialization but change 'kind' byte to some invalid value - let auth_token = AuthToken::from_bytes([1u8; AUTH_TOKEN_SIZE]); - let register_response = RegisterResponse::new(auth_token); - - let mut bytes = ResponseSerializer::new(register_response.clone().into()).into_bytes(); - - let invalid_kind = 42u8; - // sanity check to ensure it IS invalid - assert!(ResponseKind::try_from(invalid_kind).is_err()); - bytes[4] = invalid_kind; - assert!(ResponseDeserializer::new(&bytes).is_err()); - } - - #[test] - fn returns_error_on_parsing_invalid_data() { - // kind exists, length is correct, but data is unparsable - // no matter the response, it must be AT LEAST 5 byte long (for length and 'kind') - let mut len_bytes = 5u32.to_be_bytes().to_vec(); - len_bytes.push(ResponseKind::Register as u8); // to have a 'valid' kind - len_bytes.push(1); - len_bytes.push(2); - len_bytes.push(3); - len_bytes.push(4); - - let deserializer = ResponseDeserializer::new(&len_bytes).unwrap(); - assert!(deserializer.try_to_parse().is_err()); - } -} diff --git a/sfw-provider/src/built_info.rs b/sfw-provider/src/built_info.rs deleted file mode 100644 index 38b46d59e64..00000000000 --- a/sfw-provider/src/built_info.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// The file has been placed there by the build script. -include!(concat!(env!("OUT_DIR"), "/built.rs")); diff --git a/sfw-provider/src/commands/init.rs b/sfw-provider/src/commands/init.rs deleted file mode 100644 index 12d0f98dfa5..00000000000 --- a/sfw-provider/src/commands/init.rs +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::commands::override_config; -use crate::config::persistence::pathfinder::ProviderPathfinder; -use clap::{App, Arg, ArgMatches}; -use config::NymConfig; -use crypto::encryption; -use pemstore::pemstore::PemStore; - -pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> { - App::new("init") - .about("Initialise the store and forward service provider") - .arg( - Arg::with_name("id") - .long("id") - .help("Id of the sfw-provider we want to create config for.") - .takes_value(true) - .required(true), - ) - .arg( - Arg::with_name("location") - .long("location") - .help("Optional geographical location of this provider") - .takes_value(true), - ) - .arg( - Arg::with_name("mix-host") - .long("mix-host") - .help("The custom host on which the service provider will be running for receiving sphinx packets") - .takes_value(true) - .required(true), - ) - .arg( - Arg::with_name("mix-port") - .long("mix-port") - .help("The port on which the service provider will be listening for sphinx packets") - .takes_value(true) - ) - .arg( - Arg::with_name("clients-host") - .long("clients-host") - .help("The custom host on which the service provider will be running for receiving clients sfw-provider-requests") - .takes_value(true) - .required(true), - ) - .arg( - Arg::with_name("clients-port") - .long("clients-port") - .help("The port on which the service provider will be listening for clients sfw-provider-requests") - .takes_value(true) - ) - .arg( - Arg::with_name("mix-announce-host") - .long("mix-announce-host") - .help("The host that will be reported to the directory server") - .takes_value(true), - ) - .arg( - Arg::with_name("mix-announce-port") - .long("mix-announce-port") - .help("The port that will be reported to the directory server") - .takes_value(true), - ) - .arg( - Arg::with_name("clients-announce-host") - .long("clients-announce-host") - .help("The host that will be reported to the directory server") - .takes_value(true), - ) - .arg( - Arg::with_name("clients-announce-port") - .long("clients-announce-port") - .help("The port that will be reported to the directory server") - .takes_value(true), - ) - .arg( - Arg::with_name("inboxes") - .long("inboxes") - .help("Directory with inboxes where all packets for the clients are stored") - .takes_value(true) - ) - .arg( - Arg::with_name("clients-ledger") - .long("clients-ledger") - .help("Ledger file containing registered clients") - .takes_value(true) - ) - .arg( - Arg::with_name("directory") - .long("directory") - .help("Address of the directory server the node is sending presence data to") - .takes_value(true), - ) -} - -pub fn execute(matches: &ArgMatches) { - let id = matches.value_of("id").unwrap(); - println!("Initialising sfw service provider {}...", id); - - let mut config = crate::config::Config::new(id); - - config = override_config(config, matches); - - let sphinx_keys = encryption::KeyPair::new(); - let pathfinder = ProviderPathfinder::new_from_config(&config); - let pem_store = PemStore::new(pathfinder); - pem_store - .write_encryption_keys(sphinx_keys) - .expect("Failed to save sphinx keys"); - println!("Saved mixnet sphinx keypair"); - - let config_save_location = config.get_config_file_save_location(); - config - .save_to_file(None) - .expect("Failed to save the config file"); - println!("Saved configuration file to {:?}", config_save_location); - - println!("Service provider configuration completed.\n\n\n") -} diff --git a/sfw-provider/src/commands/mod.rs b/sfw-provider/src/commands/mod.rs deleted file mode 100644 index 4a8c3eeff81..00000000000 --- a/sfw-provider/src/commands/mod.rs +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::config::Config; -use clap::ArgMatches; - -pub mod init; -pub mod run; - -pub(crate) fn override_config(mut config: Config, matches: &ArgMatches) -> Config { - let mut was_mix_host_overridden = false; - if let Some(mix_host) = matches.value_of("mix-host") { - config = config.with_mix_listening_host(mix_host); - was_mix_host_overridden = true; - } - - if let Some(mix_port) = matches.value_of("mix-port").map(|port| port.parse::()) { - if let Err(err) = mix_port { - // if port was overridden, it must be parsable - panic!("Invalid port value provided - {:?}", err); - } - config = config.with_mix_listening_port(mix_port.unwrap()); - } - let mut was_clients_host_overridden = false; - if let Some(clients_host) = matches.value_of("clients-host") { - config = config.with_clients_listening_host(clients_host); - was_clients_host_overridden = true; - } - - if let Some(clients_port) = matches - .value_of("clients-port") - .map(|port| port.parse::()) - { - if let Err(err) = clients_port { - // if port was overridden, it must be parsable - panic!("Invalid port value provided - {:?}", err); - } - config = config.with_clients_listening_port(clients_port.unwrap()); - } - - if let Some(mix_announce_host) = matches.value_of("mix-announce-host") { - config = config.with_mix_announce_host(mix_announce_host); - } else if was_mix_host_overridden { - // make sure our 'mix-announce-host' always defaults to 'mix-host' - config = config.mix_announce_host_from_listening_host() - } - - if let Some(mix_announce_port) = matches - .value_of("mix-announce-port") - .map(|port| port.parse::()) - { - if let Err(err) = mix_announce_port { - // if port was overridden, it must be parsable - panic!("Invalid port value provided - {:?}", err); - } - config = config.with_mix_announce_port(mix_announce_port.unwrap()); - } - - if let Some(clients_announce_host) = matches.value_of("clients-announce-host") { - config = config.with_clients_announce_host(clients_announce_host); - } else if was_clients_host_overridden { - // make sure our 'clients-announce-host' always defaults to 'clients-host' - config = config.clients_announce_host_from_listening_host() - } - - if let Some(clients_announce_port) = matches - .value_of("clients-announce-port") - .map(|port| port.parse::()) - { - if let Err(err) = clients_announce_port { - // if port was overridden, it must be parsable - panic!("Invalid port value provided - {:?}", err); - } - config = config.with_clients_announce_port(clients_announce_port.unwrap()); - } - - if let Some(directory) = matches.value_of("directory") { - config = config.with_custom_directory(directory); - } - - if let Some(inboxes_dir) = matches.value_of("inboxes") { - config = config.with_custom_clients_inboxes(inboxes_dir); - } - - if let Some(clients_ledger) = matches.value_of("clients-ledger") { - config = config.with_custom_clients_ledger(clients_ledger); - } - - if let Some(location) = matches.value_of("location") { - config = config.with_location(location); - } - - config -} diff --git a/sfw-provider/src/commands/run.rs b/sfw-provider/src/commands/run.rs deleted file mode 100644 index 446ae73fa66..00000000000 --- a/sfw-provider/src/commands/run.rs +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::commands::override_config; -use crate::config::Config; -use crate::provider::ServiceProvider; -use clap::{App, Arg, ArgMatches}; -use config::NymConfig; - -pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> { - App::new("run") - .about("Starts the service provider") - .arg( - Arg::with_name("id") - .long("id") - .help("Id of the nym-provider we want to run") - .takes_value(true) - .required(true), - ) - // the rest of arguments are optional, they are used to override settings in config file - .arg( - Arg::with_name("location") - .long("location") - .help("Optional geographical location of this node") - .takes_value(true), - ) - .arg( - Arg::with_name("config") - .long("config") - .help("Custom path to the nym-provider configuration file") - .takes_value(true), - ) - .arg( - Arg::with_name("mix-host") - .long("mix-host") - .help("The custom host on which the service provider will be running for receiving sphinx packets") - .takes_value(true) - ) - .arg( - Arg::with_name("mix-port") - .long("mix-port") - .help("The port on which the service provider will be listening for sphinx packets") - .takes_value(true) - ) - .arg( - Arg::with_name("clients-host") - .long("clients-host") - .help("The custom host on which the service provider will be running for receiving clients sfw-provider-requests") - .takes_value(true) - ) - .arg( - Arg::with_name("clients-port") - .long("clients-port") - .help("The port on which the service provider will be listening for clients sfw-provider-requests") - .takes_value(true) - ) - .arg( - Arg::with_name("mix-announce-host") - .long("mix-announce-host") - .help("The host that will be reported to the directory server") - .takes_value(true), - ) - .arg( - Arg::with_name("mix-announce-port") - .long("mix-announce-port") - .help("The port that will be reported to the directory server") - .takes_value(true), - ) - .arg( - Arg::with_name("clients-announce-host") - .long("clients-announce-host") - .help("The host that will be reported to the directory server") - .takes_value(true), - ) - .arg( - Arg::with_name("clients-announce-port") - .long("clients-announce-port") - .help("The port that will be reported to the directory server") - .takes_value(true), - ) - .arg( - Arg::with_name("inboxes") - .long("inboxes") - .help("Directory with inboxes where all packets for the clients are stored") - .takes_value(true) - ) - .arg( - Arg::with_name("clients-ledger") - .long("clients-ledger") - .help("Ledger file containing registered clients") - .takes_value(true) - ) - .arg( - Arg::with_name("directory") - .long("directory") - .help("Address of the directory server the node is sending presence data to") - .takes_value(true), - ) -} - -fn show_binding_warning(address: String) { - println!("\n##### NOTE #####"); - println!( - "\nYou are trying to bind to {} - you might not be accessible to other nodes\n\ - You can ignore this warning if you're running setup on a local network \n\ - or have set a custom 'announce-host'", - address - ); - println!("\n\n"); -} - -fn special_addresses() -> Vec<&'static str> { - vec!["localhost", "127.0.0.1", "0.0.0.0", "::1", "[::1]"] -} - -pub fn execute(matches: &ArgMatches) { - let id = matches.value_of("id").unwrap(); - - println!("Starting sfw-provider {}...", id); - - let mut config = - Config::load_from_file(matches.value_of("config").map(|path| path.into()), Some(id)) - .expect("Failed to load config file"); - - config = override_config(config, matches); - - let mix_listening_ip_string = config.get_mix_listening_address().ip().to_string(); - if special_addresses().contains(&mix_listening_ip_string.as_ref()) { - show_binding_warning(mix_listening_ip_string); - } - - let clients_listening_ip_string = config.get_clients_listening_address().ip().to_string(); - if special_addresses().contains(&clients_listening_ip_string.as_ref()) { - show_binding_warning(clients_listening_ip_string); - } - - println!( - "Directory server [presence]: {}", - config.get_presence_directory_server() - ); - - println!( - "Listening for incoming sphinx packets on {}", - config.get_mix_listening_address() - ); - println!( - "Announcing the following socket address for sphinx packets: {}", - config.get_mix_announce_address() - ); - - println!( - "Listening for incoming clients packets on {}", - config.get_clients_listening_address() - ); - println!( - "Announcing the following socket address for clients packets: {}", - config.get_clients_announce_address() - ); - - println!( - "Inboxes directory is: {:?}", - config.get_clients_inboxes_dir() - ); - - ServiceProvider::new(config).run(); -} diff --git a/sfw-provider/src/config/mod.rs b/sfw-provider/src/config/mod.rs deleted file mode 100644 index 68a2f001685..00000000000 --- a/sfw-provider/src/config/mod.rs +++ /dev/null @@ -1,554 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::config::template::config_template; -use config::NymConfig; -use log::*; -use serde::{Deserialize, Serialize}; -use std::net::{IpAddr, SocketAddr}; -use std::path::PathBuf; -use std::str::FromStr; -use std::time; - -pub mod persistence; -mod template; - -// 'PROVIDER' -const DEFAULT_MIX_LISTENING_PORT: u16 = 1789; -const DEFAULT_CLIENT_LISTENING_PORT: u16 = 9000; -// 'DEBUG' -// where applicable, the below are defined in milliseconds -const DEFAULT_PRESENCE_SENDING_DELAY: u64 = 1500; - -const DEFAULT_STORED_MESSAGE_FILENAME_LENGTH: u16 = 16; -const DEFAULT_MESSAGE_RETRIEVAL_LIMIT: u16 = 5; -const DEFAULT_MAX_REQUEST_SIZE: u32 = 16 * 1024; - -#[derive(Debug, Default, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct Config { - provider: Provider, - - mixnet_endpoint: MixnetEndpoint, - - clients_endpoint: ClientsEndpoint, - - #[serde(default)] - logging: Logging, - #[serde(default)] - debug: Debug, -} - -impl NymConfig for Config { - fn template() -> &'static str { - config_template() - } - - fn config_file_name() -> String { - "config.toml".to_string() - } - - fn default_root_directory() -> PathBuf { - dirs::home_dir() - .expect("Failed to evaluate $HOME value") - .join(".nym") - .join("sfw-providers") - } - - fn root_directory(&self) -> PathBuf { - self.provider.nym_root_directory.clone() - } - - fn config_directory(&self) -> PathBuf { - self.provider - .nym_root_directory - .join(&self.provider.id) - .join("config") - } - - fn data_directory(&self) -> PathBuf { - self.provider - .nym_root_directory - .join(&self.provider.id) - .join("data") - } -} - -impl Config { - pub fn new>(id: S) -> Self { - Config::default().with_id(id) - } - - // builder methods - pub fn with_id>(mut self, id: S) -> Self { - let id = id.into(); - if self.provider.private_sphinx_key_file.as_os_str().is_empty() { - self.provider.private_sphinx_key_file = - self::Provider::default_private_sphinx_key_file(&id); - } - if self.provider.public_sphinx_key_file.as_os_str().is_empty() { - self.provider.public_sphinx_key_file = - self::Provider::default_public_sphinx_key_file(&id); - } - if self - .clients_endpoint - .inboxes_directory - .as_os_str() - .is_empty() - { - self.clients_endpoint.inboxes_directory = - self::ClientsEndpoint::default_inboxes_directory(&id); - } - if self.clients_endpoint.ledger_path.as_os_str().is_empty() { - self.clients_endpoint.ledger_path = self::ClientsEndpoint::default_ledger_path(&id); - } - - self.provider.id = id; - self - } - - pub fn with_custom_directory>(mut self, directory_server: S) -> Self { - self.debug.presence_directory_server = directory_server.into(); - self - } - - pub fn with_location>(mut self, location: S) -> Self { - self.provider.location = location.into(); - self - } - - pub fn with_mix_listening_host>(mut self, host: S) -> Self { - // see if the provided `host` is just an ip address or ip:port - let host = host.into(); - - // is it ip:port? - match SocketAddr::from_str(host.as_ref()) { - Ok(socket_addr) => { - self.mixnet_endpoint.listening_address = socket_addr; - self - } - // try just for ip - Err(_) => match IpAddr::from_str(host.as_ref()) { - Ok(ip_addr) => { - self.mixnet_endpoint.listening_address.set_ip(ip_addr); - self - } - Err(_) => { - error!( - "failed to make any changes to config - invalid host {}", - host - ); - self - } - }, - } - } - - pub fn with_mix_listening_port(mut self, port: u16) -> Self { - self.mixnet_endpoint.listening_address.set_port(port); - self - } - - pub fn with_mix_announce_host>(mut self, host: S) -> Self { - // this is slightly more complicated as we store announce information as String, - // since it might not necessarily be a valid SocketAddr (say `nymtech.net:8080` is a valid - // announce address, yet invalid SocketAddr` - - // first lets see if we received host:port or just host part of an address - let host = host.into(); - let split_host: Vec<_> = host.split(':').collect(); - match split_host.len() { - 1 => { - // we provided only 'host' part so we are going to reuse existing port - self.mixnet_endpoint.announce_address = - format!("{}:{}", host, self.mixnet_endpoint.listening_address.port()); - self - } - 2 => { - // we provided 'host:port' so just put the whole thing there - self.mixnet_endpoint.announce_address = host; - self - } - _ => { - // we provided something completely invalid, so don't try to parse it - error!( - "failed to make any changes to config - invalid announce host {}", - host - ); - self - } - } - } - - pub fn mix_announce_host_from_listening_host(mut self) -> Self { - self.mixnet_endpoint.announce_address = self.mixnet_endpoint.listening_address.to_string(); - self - } - - pub fn with_mix_announce_port(mut self, port: u16) -> Self { - let current_host: Vec<_> = self.mixnet_endpoint.announce_address.split(':').collect(); - debug_assert_eq!(current_host.len(), 2); - self.mixnet_endpoint.announce_address = format!("{}:{}", current_host[0], port); - self - } - - pub fn with_clients_listening_host>(mut self, host: S) -> Self { - // see if the provided `host` is just an ip address or ip:port - let host = host.into(); - - // is it ip:port? - match SocketAddr::from_str(host.as_ref()) { - Ok(socket_addr) => { - self.clients_endpoint.listening_address = socket_addr; - self - } - // try just for ip - Err(_) => match IpAddr::from_str(host.as_ref()) { - Ok(ip_addr) => { - self.clients_endpoint.listening_address.set_ip(ip_addr); - self - } - Err(_) => { - error!( - "failed to make any changes to config - invalid host {}", - host - ); - self - } - }, - } - } - - pub fn clients_announce_host_from_listening_host(mut self) -> Self { - self.clients_endpoint.announce_address = - self.clients_endpoint.listening_address.to_string(); - self - } - - pub fn with_clients_listening_port(mut self, port: u16) -> Self { - self.clients_endpoint.listening_address.set_port(port); - self - } - - pub fn with_clients_announce_host>(mut self, host: S) -> Self { - // this is slightly more complicated as we store announce information as String, - // since it might not necessarily be a valid SocketAddr (say `nymtech.net:8080` is a valid - // announce address, yet invalid SocketAddr` - - // first lets see if we received host:port or just host part of an address - let host = host.into(); - let split_host: Vec<_> = host.split(':').collect(); - match split_host.len() { - 1 => { - // we provided only 'host' part so we are going to reuse existing port - self.clients_endpoint.announce_address = format!( - "{}:{}", - host, - self.clients_endpoint.listening_address.port() - ); - self - } - 2 => { - // we provided 'host:port' so just put the whole thing there - self.clients_endpoint.announce_address = host; - self - } - _ => { - // we provided something completely invalid, so don't try to parse it - error!( - "failed to make any changes to config - invalid announce host {}", - host - ); - self - } - } - } - - pub fn with_clients_announce_port(mut self, port: u16) -> Self { - let current_host: Vec<_> = self.clients_endpoint.announce_address.split(':').collect(); - debug_assert_eq!(current_host.len(), 2); - self.clients_endpoint.announce_address = format!("{}:{}", current_host[0], port); - self - } - - pub fn with_custom_clients_inboxes>(mut self, inboxes_dir: S) -> Self { - self.clients_endpoint.inboxes_directory = PathBuf::from(inboxes_dir.into()); - self - } - - pub fn with_custom_clients_ledger>(mut self, ledger_path: S) -> Self { - self.clients_endpoint.ledger_path = PathBuf::from(ledger_path.into()); - self - } - - // getters - pub fn get_config_file_save_location(&self) -> PathBuf { - self.config_directory().join(Self::config_file_name()) - } - - pub fn get_location(&self) -> String { - self.provider.location.clone() - } - - pub fn get_private_sphinx_key_file(&self) -> PathBuf { - self.provider.private_sphinx_key_file.clone() - } - - pub fn get_public_sphinx_key_file(&self) -> PathBuf { - self.provider.public_sphinx_key_file.clone() - } - - pub fn get_presence_directory_server(&self) -> String { - self.debug.presence_directory_server.clone() - } - - pub fn get_presence_sending_delay(&self) -> time::Duration { - time::Duration::from_millis(self.debug.presence_sending_delay) - } - - pub fn get_mix_listening_address(&self) -> SocketAddr { - self.mixnet_endpoint.listening_address - } - - pub fn get_mix_announce_address(&self) -> String { - self.mixnet_endpoint.announce_address.clone() - } - - pub fn get_clients_listening_address(&self) -> SocketAddr { - self.clients_endpoint.listening_address - } - - pub fn get_clients_announce_address(&self) -> String { - self.clients_endpoint.announce_address.clone() - } - - pub fn get_clients_inboxes_dir(&self) -> PathBuf { - self.clients_endpoint.inboxes_directory.clone() - } - - pub fn get_clients_ledger_path(&self) -> PathBuf { - self.clients_endpoint.ledger_path.clone() - } - - pub fn get_message_retrieval_limit(&self) -> u16 { - self.debug.message_retrieval_limit - } - - pub fn get_stored_messages_filename_length(&self) -> u16 { - self.debug.stored_messages_filename_length - } - - pub fn get_max_request_size(&self) -> usize { - self.debug.max_request_size as usize - } -} - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct Provider { - /// ID specifies the human readable ID of this particular provider. - id: String, - - /// Completely optional value specifying geographical location of this particular provider. - /// Currently it's used entirely for debug purposes, as there are no mechanisms implemented - /// to verify correctness of the information provided. However, feel free to fill in - /// this field with as much accuracy as you wish to share. - location: String, - - /// Path to file containing private sphinx key. - private_sphinx_key_file: PathBuf, - - /// Path to file containing public sphinx key. - public_sphinx_key_file: PathBuf, - - /// nym_home_directory specifies absolute path to the home nym service providers directory. - /// It is expected to use default value and hence .toml file should not redefine this field. - nym_root_directory: PathBuf, -} - -impl Provider { - fn default_private_sphinx_key_file(id: &str) -> PathBuf { - Config::default_data_directory(Some(id)).join("private_sphinx.pem") - } - - fn default_public_sphinx_key_file(id: &str) -> PathBuf { - Config::default_data_directory(Some(id)).join("public_sphinx.pem") - } - - fn default_location() -> String { - "unknown".into() - } -} - -impl Default for Provider { - fn default() -> Self { - Provider { - id: "".to_string(), - location: Self::default_location(), - private_sphinx_key_file: Default::default(), - public_sphinx_key_file: Default::default(), - nym_root_directory: Config::default_root_directory(), - } - } -} - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct MixnetEndpoint { - /// Socket address to which this service provider will bind to - /// and will be listening for sphinx packets coming from the mixnet. - listening_address: SocketAddr, - - /// Optional address announced to the directory server for the clients to connect to. - /// It is useful, say, in NAT scenarios or wanting to more easily update actual IP address - /// later on by using name resolvable with a DNS query, such as `nymtech.net:8080`. - /// Additionally a custom port can be provided, so both `nymtech.net:8080` and `nymtech.net` - /// are valid announce addresses, while the later will default to whatever port is used for - /// `listening_address`. - announce_address: String, -} - -impl Default for MixnetEndpoint { - fn default() -> Self { - MixnetEndpoint { - listening_address: format!("0.0.0.0:{}", DEFAULT_MIX_LISTENING_PORT) - .parse() - .unwrap(), - announce_address: format!("127.0.0.1:{}", DEFAULT_MIX_LISTENING_PORT), - } - } -} - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct ClientsEndpoint { - /// Socket address to which this service provider will bind to - /// and will be listening for data packets coming from the clients. - listening_address: SocketAddr, - - /// Optional address announced to the directory server for the clients to connect to. - /// It is useful, say, in NAT scenarios or wanting to more easily update actual IP address - /// later on by using name resolvable with a DNS query, such as `nymtech.net:8080`. - /// Additionally a custom port can be provided, so both `nymtech.net:8080` and `nymtech.net` - /// are valid announce addresses, while the later will default to whatever port is used for - /// `listening_address`. - announce_address: String, - - /// Path to the directory with clients inboxes containing messages stored for them. - inboxes_directory: PathBuf, - - /// [TODO: implement its storage] Full path to a file containing mapping of - /// client addresses to their access tokens. - ledger_path: PathBuf, -} - -impl ClientsEndpoint { - fn default_inboxes_directory(id: &str) -> PathBuf { - Config::default_data_directory(Some(id)).join("inboxes") - } - - fn default_ledger_path(id: &str) -> PathBuf { - Config::default_data_directory(Some(id)).join("client_ledger.sled") - } -} - -impl Default for ClientsEndpoint { - fn default() -> Self { - ClientsEndpoint { - listening_address: format!("0.0.0.0:{}", DEFAULT_CLIENT_LISTENING_PORT) - .parse() - .unwrap(), - announce_address: format!("127.0.0.1:{}", DEFAULT_CLIENT_LISTENING_PORT), - inboxes_directory: Default::default(), - ledger_path: Default::default(), - } - } -} - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct Logging {} - -impl Default for Logging { - fn default() -> Self { - Logging {} - } -} - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct Debug { - /// Directory server to which the server will be reporting their presence data. - presence_directory_server: String, - - /// Delay between each subsequent presence data being sent. - presence_sending_delay: u64, - - /// Length of filenames for new client messages. - stored_messages_filename_length: u16, - - /// Number of messages client gets on each request - /// if there are no real messages, dummy ones are create to always return - /// `message_retrieval_limit` total messages - message_retrieval_limit: u16, - - /// Maximum allowed length for requests received. - /// Anything declaring bigger size than that will be regarded as an error and - /// is going to be rejected. - max_request_size: u32, -} - -impl Debug { - fn default_directory_server() -> String { - if cfg!(feature = "qa") { - "https://qa-directory.nymtech.net".to_string() - } else if cfg!(feature = "local") { - "http://localhost:8080".to_string() - } else { - "https://directory.nymtech.net".to_string() - } - } -} - -impl Default for Debug { - fn default() -> Self { - Debug { - presence_directory_server: Self::default_directory_server(), - presence_sending_delay: DEFAULT_PRESENCE_SENDING_DELAY, - stored_messages_filename_length: DEFAULT_STORED_MESSAGE_FILENAME_LENGTH, - message_retrieval_limit: DEFAULT_MESSAGE_RETRIEVAL_LIMIT, - max_request_size: DEFAULT_MAX_REQUEST_SIZE, - } - } -} - -#[cfg(test)] -mod provider_config { - use super::*; - - #[test] - fn after_saving_default_config_the_loaded_one_is_identical() { - // need to figure out how to do something similar but without touching the disk - // or the file system at all... - let temp_location = tempfile::tempdir().unwrap().path().join("config.toml"); - let default_config = Config::default().with_id("foomp".to_string()); - default_config - .save_to_file(Some(temp_location.clone())) - .unwrap(); - - let loaded_config = Config::load_from_file(Some(temp_location), None).unwrap(); - - assert_eq!(default_config, loaded_config); - } -} diff --git a/sfw-provider/src/config/persistence/mod.rs b/sfw-provider/src/config/persistence/mod.rs deleted file mode 100644 index 97f4c000a4d..00000000000 --- a/sfw-provider/src/config/persistence/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub mod pathfinder; diff --git a/sfw-provider/src/config/persistence/pathfinder.rs b/sfw-provider/src/config/persistence/pathfinder.rs deleted file mode 100644 index 103b6be66ee..00000000000 --- a/sfw-provider/src/config/persistence/pathfinder.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::config::Config; -use pemstore::pathfinder::PathFinder; -use std::path::PathBuf; - -#[derive(Debug)] -pub struct ProviderPathfinder { - pub config_dir: PathBuf, - pub private_sphinx_key: PathBuf, - pub public_sphinx_key: PathBuf, -} - -impl ProviderPathfinder { - pub fn new_from_config(config: &Config) -> Self { - ProviderPathfinder { - config_dir: config.get_config_file_save_location(), - private_sphinx_key: config.get_private_sphinx_key_file(), - public_sphinx_key: config.get_public_sphinx_key_file(), - } - } -} - -impl PathFinder for ProviderPathfinder { - fn config_dir(&self) -> PathBuf { - self.config_dir.clone() - } - - fn private_identity_key(&self) -> PathBuf { - // TEMPORARILY USE SAME KEYS AS ENCRYPTION - self.private_sphinx_key.clone() - } - - fn public_identity_key(&self) -> PathBuf { - // TEMPORARILY USE SAME KEYS AS ENCRYPTION - self.public_sphinx_key.clone() - } - - fn private_encryption_key(&self) -> Option { - Some(self.private_sphinx_key.clone()) - } - - fn public_encryption_key(&self) -> Option { - Some(self.public_sphinx_key.clone()) - } -} diff --git a/sfw-provider/src/config/template.rs b/sfw-provider/src/config/template.rs deleted file mode 100644 index 6a3666ca5ab..00000000000 --- a/sfw-provider/src/config/template.rs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub(crate) fn config_template() -> &'static str { - // While using normal toml marshalling would have been way simpler with less overhead, - // I think it's useful to have comments attached to the saved config file to explain behaviour of - // particular fields. - // Note: any changes to the template must be reflected in the appropriate structs in mod.rs. - r#" -# This is a TOML config file. -# For more information, see https://github.com/toml-lang/toml - -##### main base mixnode config options ##### - -[provider] -# Human readable ID of this particular service provider. -id = '{{ provider.id }}' - -# Completely optional value specifying geographical location of this particular node. -# Currently it's used entirely for debug purposes, as there are no mechanisms implemented -# to verify correctness of the information provided. However, feel free to fill in -# this field with as much accuracy as you wish to share. -location = '{{ provider.location }}' - -# Path to file containing private sphinx key. -private_sphinx_key_file = '{{ provider.private_sphinx_key_file }}' - -# Path to file containing public sphinx key. -public_sphinx_key_file = '{{ provider.public_sphinx_key_file }}' - -# nym_home_directory specifies absolute path to the home nym service providers directory. -# It is expected to use default value and hence .toml file should not redefine this field. -nym_root_directory = '{{ provider.nym_root_directory }}' - - -##### Mixnet endpoint config options ##### - -[mixnet_endpoint] -# Socket address to which this service provider will bind to -# and will be listening for sphinx packets coming from the mixnet. -listening_address = '{{ mixnet_endpoint.listening_address }}' - -# Optional address announced to the directory server for the clients to connect to. -# It is useful, say, in NAT scenarios or wanting to more easily update actual IP address -# later on by using name resolvable with a DNS query, such as `nymtech.net:8080`. -# Additionally a custom port can be provided, so both `nymtech.net:8080` and `nymtech.net` -# are valid announce addresses, while the later will default to whatever port is used for -# `listening_address`. -announce_address = '{{ mixnet_endpoint.announce_address }}' - - -#### Clients endpoint config options ##### - -[clients_endpoint] -# Socket address to which this service provider will bind to -# and will be listening for sphinx packets coming from the mixnet. -listening_address = '{{ clients_endpoint.listening_address }}' - -# Optional address announced to the directory server for the clients to connect to. -# It is useful, say, in NAT scenarios or wanting to more easily update actual IP address -# later on by using name resolvable with a DNS query, such as `nymtech.net:8080`. -# Additionally a custom port can be provided, so both `nymtech.net:8080` and `nymtech.net` -# are valid announce addresses, while the later will default to whatever port is used for -# `listening_address`. -announce_address = '{{ clients_endpoint.announce_address }}' - -# Path to the directory with clients inboxes containing messages stored for them. -inboxes_directory = '{{ clients_endpoint.inboxes_directory }}' - -# [TODO: implement its storage] Full path to a file containing mapping of -# client addresses to their access tokens. -ledger_path = '{{ clients_endpoint.ledger_path }}' - - -##### logging configuration options ##### - -[logging] - -# TODO - -"# -} diff --git a/sfw-provider/src/main.rs b/sfw-provider/src/main.rs deleted file mode 100644 index 7c46b7550af..00000000000 --- a/sfw-provider/src/main.rs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use clap::{App, ArgMatches}; - -pub mod built_info; -mod commands; -mod config; -pub mod provider; - -fn main() { - dotenv::dotenv().ok(); - setup_logging(); - println!("{}", banner()); - - let arg_matches = App::new("Nym Service Provider") - .version(built_info::PKG_VERSION) - .author("Nymtech") - .about("Implementation of the Loopix-based Service Provider") - .subcommand(commands::init::command_args()) - .subcommand(commands::run::command_args()) - .get_matches(); - - execute(arg_matches); -} - -fn execute(matches: ArgMatches) { - match matches.subcommand() { - ("init", Some(m)) => commands::init::execute(m), - ("run", Some(m)) => commands::run::execute(m), - _ => println!("{}", usage()), - } -} - -fn usage() -> &'static str { - "usage: --help to see available options.\n\n" -} - -fn banner() -> String { - format!( - r#" - - _ __ _ _ _ __ ___ - | '_ \| | | | '_ \ _ \ - | | | | |_| | | | | | | - |_| |_|\__, |_| |_| |_| - |___/ - - (store-and-forward provider - version {:}) - - "#, - built_info::PKG_VERSION - ) -} - -fn setup_logging() { - let mut log_builder = pretty_env_logger::formatted_timed_builder(); - if let Ok(s) = ::std::env::var("RUST_LOG") { - log_builder.parse_filters(&s); - } else { - // default to 'Info' - log_builder.filter(None, log::LevelFilter::Info); - } - - log_builder - .filter_module("hyper", log::LevelFilter::Warn) - .filter_module("tokio_reactor", log::LevelFilter::Warn) - .filter_module("reqwest", log::LevelFilter::Warn) - .filter_module("mio", log::LevelFilter::Warn) - .filter_module("want", log::LevelFilter::Warn) - .filter_module("sled", log::LevelFilter::Warn) - .init(); -} diff --git a/sfw-provider/src/provider/client_handling/ledger.rs b/sfw-provider/src/provider/client_handling/ledger.rs deleted file mode 100644 index b2bb5b20e81..00000000000 --- a/sfw-provider/src/provider/client_handling/ledger.rs +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use directory_client::presence::providers::MixProviderClient; -use log::*; -use nymsphinx::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH}; -use sfw_provider_requests::auth_token::{AuthToken, AUTH_TOKEN_SIZE}; -use std::path::PathBuf; - -#[derive(Debug)] -pub(crate) enum ClientLedgerError { - DbReadError(sled::Error), - DbWriteError(sled::Error), - DbOpenError(sled::Error), -} - -#[derive(Debug, Clone)] -// Note: you should NEVER create more than a single instance of this using 'new()'. -// You should always use .clone() to create additional instances -pub(crate) struct ClientLedger { - db: sled::Db, -} - -impl ClientLedger { - pub(crate) fn load(file: PathBuf) -> Result { - let db = match sled::open(file) { - Err(e) => return Err(ClientLedgerError::DbOpenError(e)), - Ok(db) => db, - }; - - let ledger = ClientLedger { db }; - - ledger.db.iter().keys().for_each(|key| { - println!( - "key: {:?}", - ledger - .read_destination_address_bytes(key.unwrap()) - .to_base58_string() - ); - }); - - Ok(ledger) - } - - fn read_auth_token(&self, raw_token: sled::IVec) -> AuthToken { - let token_bytes_ref = raw_token.as_ref(); - // if this fails it means we have some database corruption and we - // absolutely can't continue - if token_bytes_ref.len() != AUTH_TOKEN_SIZE { - error!("CLIENT LEDGER DATA CORRUPTION - TOKEN HAS INVALID LENGTH"); - panic!("CLIENT LEDGER DATA CORRUPTION - TOKEN HAS INVALID LENGTH"); - } - - let mut token_bytes = [0u8; AUTH_TOKEN_SIZE]; - token_bytes.copy_from_slice(token_bytes_ref); - AuthToken::from_bytes(token_bytes) - } - - fn read_destination_address_bytes( - &self, - raw_destination: sled::IVec, - ) -> DestinationAddressBytes { - let destination_ref = raw_destination.as_ref(); - // if this fails it means we have some database corruption and we - // absolutely can't continue - if destination_ref.len() != DESTINATION_ADDRESS_LENGTH { - error!("CLIENT LEDGER DATA CORRUPTION - CLIENT ADDRESS HAS INVALID LENGTH"); - panic!("CLIENT LEDGER DATA CORRUPTION - CLIENT ADDRESS HAS INVALID LENGTH"); - } - - let mut destination_bytes = [0u8; DESTINATION_ADDRESS_LENGTH]; - destination_bytes.copy_from_slice(destination_ref); - DestinationAddressBytes::from_bytes(destination_bytes) - } - - pub(crate) fn verify_token( - &self, - auth_token: &AuthToken, - client_address: &DestinationAddressBytes, - ) -> Result { - match self.db.get(&client_address.to_bytes()) { - Err(e) => Err(ClientLedgerError::DbReadError(e)), - Ok(token) => match token { - Some(token_ivec) => Ok(&self.read_auth_token(token_ivec) == auth_token), - None => Ok(false), - }, - } - } - - pub(crate) fn insert_token( - &mut self, - auth_token: AuthToken, - client_address: DestinationAddressBytes, - ) -> Result, ClientLedgerError> { - let insertion_result = match self - .db - .insert(&client_address.to_bytes(), &auth_token.to_bytes()) - { - Err(e) => Err(ClientLedgerError::DbWriteError(e)), - Ok(existing_token) => { - Ok(existing_token.map(|existing_token| self.read_auth_token(existing_token))) - } - }; - - // registration doesn't happen that often so might as well flush it to the disk to be sure - self.db.flush().unwrap(); - insertion_result - } - - pub(crate) fn remove_token( - &mut self, - client_address: &DestinationAddressBytes, - ) -> Result, ClientLedgerError> { - let removal_result = match self.db.remove(&client_address.to_bytes()) { - Err(e) => Err(ClientLedgerError::DbWriteError(e)), - Ok(existing_token) => { - Ok(existing_token.map(|existing_token| self.read_auth_token(existing_token))) - } - }; - - // removing of tokens happens extremely rarely, so flush is also fine here - self.db.flush().unwrap(); - removal_result - } - - pub(crate) fn current_clients(&self) -> Result, ClientLedgerError> { - let clients = self.db.iter().keys(); - - let mut client_vec = Vec::new(); - for client in clients { - match client { - Err(e) => return Err(ClientLedgerError::DbWriteError(e)), - Ok(client_entry) => client_vec.push(MixProviderClient { - pub_key: self - .read_destination_address_bytes(client_entry) - .to_base58_string(), - }), - } - } - - Ok(client_vec) - } - - #[cfg(test)] - pub(crate) fn create_temporary() -> Self { - let cfg = sled::Config::new().temporary(true); - ClientLedger { - db: cfg.open().unwrap(), - } - } -} diff --git a/sfw-provider/src/provider/client_handling/listener.rs b/sfw-provider/src/provider/client_handling/listener.rs deleted file mode 100644 index 582953d0118..00000000000 --- a/sfw-provider/src/provider/client_handling/listener.rs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::provider::client_handling::request_processing::{ - ClientProcessingResult, RequestProcessor, -}; -use log::*; -use sfw_provider_requests::requests::{ - async_io::TokioAsyncRequestReader, ProviderRequest, ProviderRequestError, -}; -use sfw_provider_requests::responses::{ - async_io::TokioAsyncResponseWriter, FailureResponse, ProviderResponse, PullResponse, - RegisterResponse, -}; -use std::io; -use std::net::SocketAddr; -use tokio::runtime::Handle; -use tokio::task::JoinHandle; - -async fn process_request<'a>( - response_writer: &mut TokioAsyncResponseWriter<'a, tokio::net::tcp::WriteHalf<'a>>, - request: ProviderRequest, - request_processor: &mut RequestProcessor, -) { - match request_processor.process_client_request(request).await { - Err(e) => { - warn!("We failed to process client request - {:?}", e); - let failure_response = - ProviderResponse::Failure(FailureResponse::new(format!("{:?}", e))); - if let Err(e) = response_writer.try_write_response(failure_response).await { - debug!("Failed to write response to the client - {:?}", e); - } - } - Ok(res) => match res { - ClientProcessingResult::RegisterResponse(auth_token) => { - let response = ProviderResponse::Register(RegisterResponse::new(auth_token)); - if let Err(e) = response_writer.try_write_response(response).await { - debug!("Failed to write response to the client - {:?}", e); - } - } - ClientProcessingResult::PullResponse(retrieved_messages) => { - let (messages, paths): (Vec<_>, Vec<_>) = retrieved_messages - .into_iter() - .map(|c| c.into_tuple()) - .unzip(); - let response = ProviderResponse::Pull(PullResponse::new(messages)); - if response_writer.try_write_response(response).await.is_ok() { - // only delete stored messages if we managed to actually send the response - if let Err(e) = request_processor.delete_sent_messages(paths).await { - error!("Somehow failed to delete stored messages! - {:?}", e); - } - } - } - }, - } -} - -async fn process_socket_connection( - mut socket: tokio::net::TcpStream, - mut request_processor: RequestProcessor, -) { - let peer_addr = socket.peer_addr(); - let (mut socket_reader, mut socket_writer) = socket.split(); - // TODO: benchmark and determine if below should be done: - // let mut socket_writer = tokio::io::BufWriter::new(socket_writer); - // let mut socket_reader = tokio::io::BufReader::new(socket_reader); - - let mut request_reader = - TokioAsyncRequestReader::new(&mut socket_reader, request_processor.max_request_size()); - let mut response_writer = TokioAsyncResponseWriter::new(&mut socket_writer); - - loop { - match request_reader.try_read_request().await { - Err(ProviderRequestError::RemoteConnectionClosed) => { - trace!("Remote connection closed."); - return; - } - Err(ProviderRequestError::IOError(e)) => { - if e.kind() == io::ErrorKind::UnexpectedEof { - debug!("Read buffer was not fully filled. Most likely the client ({:?}) closed the connection.\ - Also closing the connection on this end.", peer_addr) - } else { - warn!( - "failed to read from socket (source: {:?}). Closing the connection; err = {:?}", - peer_addr, - e - ); - } - return; - } - Err(e) => { - // let's leave it like this for time being and see if we need to decrease - // logging level and / or close the connection - warn!("the received request was invalid - {:?}", e); - // should the connection be closed here? invalid request might imply - // the subsequent requests in the reader buffer might not be aligned anymore - // however, that might not necessarily be the case - return; - } - // in here we do not really want to process multiple requests from the same - // client concurrently as then we might end up with really weird race conditions - // plus realistically it wouldn't really introduce any speed up - Ok(request) => { - process_request(&mut response_writer, request, &mut request_processor).await - } - } - } -} - -pub(crate) fn run_client_socket_listener( - handle: &Handle, - addr: SocketAddr, - request_processor: RequestProcessor, -) -> JoinHandle> { - let handle_clone = handle.clone(); - handle.spawn(async move { - let mut listener = tokio::net::TcpListener::bind(addr).await?; - loop { - let (socket, _) = listener.accept().await?; - - let thread_request_processor = request_processor.clone(); - handle_clone.spawn(async move { - process_socket_connection(socket, thread_request_processor).await; - }); - } - }) -} diff --git a/sfw-provider/src/provider/client_handling/mod.rs b/sfw-provider/src/provider/client_handling/mod.rs deleted file mode 100644 index 6871f46790d..00000000000 --- a/sfw-provider/src/provider/client_handling/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub(crate) mod ledger; -pub(crate) mod listener; -pub(crate) mod request_processing; diff --git a/sfw-provider/src/provider/client_handling/request_processing.rs b/sfw-provider/src/provider/client_handling/request_processing.rs deleted file mode 100644 index d57d505594a..00000000000 --- a/sfw-provider/src/provider/client_handling/request_processing.rs +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::provider::client_handling::ledger::ClientLedger; -use crate::provider::storage::{ClientFile, ClientStorage}; -use crypto::encryption; -use hmac::{Hmac, Mac}; -use log::*; -use nymsphinx::DestinationAddressBytes; -use sfw_provider_requests::auth_token::AuthToken; -use sfw_provider_requests::requests::*; -use sha2::Sha256; -use std::io; -use std::path::PathBuf; -use std::sync::Arc; - -#[derive(Debug)] -pub enum ClientProcessingResult { - PullResponse(Vec), - RegisterResponse(AuthToken), -} - -#[derive(Debug)] -pub enum ClientProcessingError { - InvalidRequest, - InvalidToken, - IOError(String), -} - -impl From for ClientProcessingError { - fn from(_: ProviderRequestError) -> Self { - use ClientProcessingError::*; - - InvalidRequest - } -} - -impl From for ClientProcessingError { - fn from(e: io::Error) -> Self { - use ClientProcessingError::*; - - IOError(e.to_string()) - } -} - -// PacketProcessor contains all data required to correctly process client requests -#[derive(Clone)] -pub struct RequestProcessor { - secret_key: Arc, - client_storage: ClientStorage, - client_ledger: ClientLedger, - max_request_size: usize, -} - -impl RequestProcessor { - pub(crate) fn new( - secret_key: encryption::PrivateKey, - client_storage: ClientStorage, - client_ledger: ClientLedger, - max_request_size: usize, - ) -> Self { - RequestProcessor { - secret_key: Arc::new(secret_key), - client_storage, - client_ledger, - max_request_size, - } - } - - pub(crate) fn max_request_size(&self) -> usize { - self.max_request_size - } - - pub(crate) async fn process_client_request( - &mut self, - client_request: ProviderRequest, - ) -> Result { - match client_request { - ProviderRequest::Register(req) => self.process_register_request(req).await, - ProviderRequest::Pull(req) => self.process_pull_request(req).await, - } - } - - pub(crate) async fn process_register_request( - &mut self, - req: RegisterRequest, - ) -> Result { - debug!( - "Processing register new client request: {:?}", - req.destination_address.to_base58_string() - ); - - let auth_token = self.generate_new_auth_token(req.destination_address.clone()); - if self - .client_ledger - .insert_token(auth_token.clone(), req.destination_address.clone()) - .unwrap() - .is_some() - { - info!( - "Client {:?} was already registered before!", - req.destination_address.to_base58_string() - ) - } else if let Err(e) = self - .client_storage - .create_storage_dir(req.destination_address.clone()) - .await - { - error!("We failed to create inbox directory for the client -{:?}\nReverting issued token...", e); - // we must revert our changes if this operation failed - self.client_ledger - .remove_token(&req.destination_address) - .unwrap(); - } - - Ok(ClientProcessingResult::RegisterResponse(auth_token)) - } - - fn generate_new_auth_token(&self, client_address: DestinationAddressBytes) -> AuthToken { - type HmacSha256 = Hmac; - - // note that `new_varkey` doesn't even have an execution branch returning an error - // (true as of hmac 0.7.1) - let mut auth_token_raw = HmacSha256::new_varkey(&self.secret_key.to_bytes()).unwrap(); - auth_token_raw.input(client_address.as_bytes()); - let mut auth_token = [0u8; 32]; - auth_token.copy_from_slice(auth_token_raw.result().code().as_slice()); - AuthToken::from_bytes(auth_token) - } - - pub(crate) async fn process_pull_request( - &self, - req: PullRequest, - ) -> Result { - debug!( - "Processing a pull request from {:?}", - req.destination_address.to_base58_string() - ); - if self - .client_ledger - .verify_token(&req.auth_token, &req.destination_address) - .unwrap() - { - let retrieved_messages = self - .client_storage - .retrieve_client_files(req.destination_address) - .await?; - Ok(ClientProcessingResult::PullResponse(retrieved_messages)) - } else { - Err(ClientProcessingError::InvalidToken) - } - } - - pub(crate) async fn delete_sent_messages(&self, file_paths: Vec) -> io::Result<()> { - self.client_storage.delete_files(file_paths).await - } -} - -#[cfg(test)] -mod generating_new_auth_token { - use super::*; - - #[test] - fn for_the_same_input_generates_the_same_auth_token() { - let client_address1 = DestinationAddressBytes::from_bytes([1; 32]); - let client_address2 = DestinationAddressBytes::from_bytes([1; 32]); - let key = encryption::PrivateKey::from_bytes(&[2u8; 32]); - - let request_processor = RequestProcessor { - secret_key: Arc::new(key), - client_storage: ClientStorage::new(3, 16, Default::default()), - client_ledger: ClientLedger::create_temporary(), - max_request_size: 42, - }; - - let token1 = request_processor.generate_new_auth_token(client_address1); - let token2 = request_processor.generate_new_auth_token(client_address2); - assert_eq!(token1, token2); - } - - #[test] - fn for_different_inputs_generates_different_auth_tokens() { - let client_address1 = DestinationAddressBytes::from_bytes([1; 32]); - let client_address2 = DestinationAddressBytes::from_bytes([2; 32]); - let key1 = encryption::PrivateKey::from_bytes(&[3u8; 32]); - let key2 = encryption::PrivateKey::from_bytes(&[4u8; 32]); - - let request_processor1 = RequestProcessor { - secret_key: Arc::new(key1), - client_storage: ClientStorage::new(3, 16, Default::default()), - client_ledger: ClientLedger::create_temporary(), - max_request_size: 42, - }; - - let request_processor2 = RequestProcessor { - secret_key: Arc::new(key2), - client_storage: ClientStorage::new(3, 16, Default::default()), - client_ledger: ClientLedger::create_temporary(), - max_request_size: 42, - }; - - let token1 = request_processor1.generate_new_auth_token(client_address1.clone()); - let token2 = request_processor1.generate_new_auth_token(client_address2.clone()); - - let token3 = request_processor2.generate_new_auth_token(client_address1); - let token4 = request_processor2.generate_new_auth_token(client_address2); - - assert_ne!(token1, token2); - assert_ne!(token1, token3); - assert_ne!(token1, token4); - assert_ne!(token2, token3); - assert_ne!(token2, token4); - assert_ne!(token3, token4); - } -} diff --git a/sfw-provider/src/provider/mix_handling/listener.rs b/sfw-provider/src/provider/mix_handling/listener.rs deleted file mode 100644 index 28e6ef94ac3..00000000000 --- a/sfw-provider/src/provider/mix_handling/listener.rs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::provider::mix_handling::packet_processing::{MixProcessingResult, PacketProcessor}; -use log::*; -use std::io; -use std::net::SocketAddr; -use tokio::prelude::*; -use tokio::runtime::Handle; -use tokio::task::JoinHandle; - -async fn process_received_packet( - packet_data: [u8; nymsphinx::PACKET_SIZE], - packet_processor: PacketProcessor, -) { - match packet_processor.process_sphinx_packet(packet_data).await { - Err(e) => debug!("We failed to process received sphinx packet - {:?}", e), - Ok(res) => match res { - MixProcessingResult::ForwardHop => { - error!("Somehow processed a forward hop message - those are not implemented for providers!") - } - MixProcessingResult::FinalHop => { - trace!("successfully processed [and stored] a final hop packet") - } - }, - } -} - -async fn process_socket_connection( - mut socket: tokio::net::TcpStream, - packet_processor: PacketProcessor, -) { - let mut buf = [0u8; nymsphinx::PACKET_SIZE]; - loop { - match socket.read_exact(&mut buf).await { - // socket closed - Ok(n) if n == 0 => { - trace!("Remote connection closed."); - return; - } - Ok(n) => { - // If I understand it correctly, this if should never be executed as if `read_exact` - // does not fill buffer, it will throw UnexpectedEof? - if n != nymsphinx::PACKET_SIZE { - warn!("read data of different length than expected sphinx packet size - {} (expected {})", n, nymsphinx::PACKET_SIZE); - continue; - } - - // we must be able to handle multiple packets from same connection independently - tokio::spawn(process_received_packet(buf, packet_processor.clone())) - } - Err(e) => { - if e.kind() == io::ErrorKind::UnexpectedEof { - debug!("Read buffer was not fully filled. Most likely the client ({:?}) closed the connection.\ - Also closing the connection on this end.", socket.peer_addr()) - } else { - warn!( - "failed to read from socket (source: {:?}). Closing the connection; err = {:?}", - socket.peer_addr(), - e - ); - } - return; - } - }; - } -} - -pub(crate) fn run_mix_socket_listener( - handle: &Handle, - addr: SocketAddr, - packet_processor: PacketProcessor, -) -> JoinHandle> { - let handle_clone = handle.clone(); - handle.spawn(async move { - let mut listener = tokio::net::TcpListener::bind(addr).await?; - loop { - let (socket, _) = listener.accept().await?; - - let thread_packet_processor = packet_processor.clone(); - handle_clone.spawn(async move { - process_socket_connection(socket, thread_packet_processor).await; - }); - } - }) -} diff --git a/sfw-provider/src/provider/mix_handling/mod.rs b/sfw-provider/src/provider/mix_handling/mod.rs deleted file mode 100644 index 3cb57676235..00000000000 --- a/sfw-provider/src/provider/mix_handling/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub(crate) mod listener; -pub(crate) mod packet_processing; diff --git a/sfw-provider/src/provider/mix_handling/packet_processing.rs b/sfw-provider/src/provider/mix_handling/packet_processing.rs deleted file mode 100644 index 0ca79b4acdf..00000000000 --- a/sfw-provider/src/provider/mix_handling/packet_processing.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::provider::storage::{ClientStorage, StoreData}; -use crypto::encryption; -use log::*; -use mix_client::packet::LOOP_COVER_MESSAGE_PAYLOAD; -use nymsphinx::{ - DestinationAddressBytes, Error as SphinxError, Payload, ProcessedPacket, SURBIdentifier, - SphinxPacket, -}; -use std::io; -use std::ops::Deref; -use std::sync::Arc; - -#[derive(Debug)] -pub enum MixProcessingError { - ReceivedForwardHopError, - NonMatchingRecipient, - InvalidPayload, - SphinxProcessingError(SphinxError), - IOError(String), -} - -pub enum MixProcessingResult { - #[allow(dead_code)] - ForwardHop, - FinalHop, -} - -impl From for MixProcessingError { - // for time being just have a single error instance for all possible results of SphinxError - fn from(err: SphinxError) -> Self { - use MixProcessingError::*; - - SphinxProcessingError(err) - } -} - -impl From for MixProcessingError { - fn from(e: io::Error) -> Self { - use MixProcessingError::*; - - IOError(e.to_string()) - } -} - -// PacketProcessor contains all data required to correctly unwrap and store sphinx packets -#[derive(Clone)] -pub struct PacketProcessor { - secret_key: Arc, - client_store: ClientStorage, -} - -impl PacketProcessor { - pub(crate) fn new(secret_key: encryption::PrivateKey, client_store: ClientStorage) -> Self { - PacketProcessor { - secret_key: Arc::new(secret_key), - client_store, - } - } - - async fn process_final_hop( - &self, - client_address: DestinationAddressBytes, - surb_id: SURBIdentifier, - payload: Payload, - ) -> Result { - // TODO: should provider try to be recovering plaintext? this would potentially make client retrieve messages of non-constant length, - // perhaps provider should be re-padding them on retrieval or storing full data? - let (payload_destination, message) = payload - .try_recover_destination_and_plaintext() - .ok_or_else(|| MixProcessingError::InvalidPayload)?; - if client_address != payload_destination { - return Err(MixProcessingError::NonMatchingRecipient); - } - - // we are temporarily ignoring and not storing obvious loop cover traffic messages to - // not cause our sfw-provider to run out of disk space too quickly. - // Eventually this is going to get removed and be replaced by a quota system described in: - // https://github.com/nymtech/nym/issues/137 - if message == LOOP_COVER_MESSAGE_PAYLOAD { - debug!("Received a loop cover message - not going to store it"); - return Ok(MixProcessingResult::FinalHop); - } - - let store_data = StoreData::new(client_address, surb_id, message); - self.client_store.store_processed_data(store_data).await?; - - Ok(MixProcessingResult::FinalHop) - } - - pub(crate) async fn process_sphinx_packet( - &self, - raw_packet_data: [u8; nymsphinx::PACKET_SIZE], - ) -> Result { - let packet = SphinxPacket::from_bytes(&raw_packet_data)?; - - match packet.process(self.secret_key.deref().inner()) { - Ok(ProcessedPacket::ProcessedPacketForwardHop(_, _, _)) => { - warn!("Received a forward hop message - those are not implemented for providers"); - Err(MixProcessingError::ReceivedForwardHopError) - } - Ok(ProcessedPacket::ProcessedPacketFinalHop(client_address, surb_id, payload)) => { - self.process_final_hop(client_address, surb_id, payload) - .await - } - Err(e) => { - warn!("Failed to unwrap Sphinx packet: {:?}", e); - Err(MixProcessingError::SphinxProcessingError(e)) - } - } - } -} diff --git a/sfw-provider/src/provider/mod.rs b/sfw-provider/src/provider/mod.rs deleted file mode 100644 index 9d88f1a8e9b..00000000000 --- a/sfw-provider/src/provider/mod.rs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::config::persistence::pathfinder::ProviderPathfinder; -use crate::config::Config; -use crate::provider::client_handling::ledger::ClientLedger; -use crate::provider::storage::ClientStorage; -use crypto::encryption; -use directory_client::presence::Topology; -use log::*; -use pemstore::pemstore::PemStore; -use tokio::runtime::Runtime; -use topology::NymTopology; - -mod client_handling; -mod mix_handling; -pub mod presence; -mod storage; - -pub struct ServiceProvider { - runtime: Runtime, - config: Config, - sphinx_keypair: encryption::KeyPair, - registered_clients_ledger: ClientLedger, -} - -impl ServiceProvider { - fn load_sphinx_keys(config_file: &Config) -> encryption::KeyPair { - let sphinx_keypair = PemStore::new(ProviderPathfinder::new_from_config(&config_file)) - .read_encryption() - .expect("Failed to read stored sphinx key files"); - println!( - "Public key: {}\n", - sphinx_keypair.public_key().to_base58_string() - ); - sphinx_keypair - } - - pub fn new(config: Config) -> Self { - let sphinx_keypair = Self::load_sphinx_keys(&config); - let registered_clients_ledger = match ClientLedger::load(config.get_clients_ledger_path()) { - Err(e) => panic!(format!("Failed to load the ledger - {:?}", e)), - Ok(ledger) => ledger, - }; - ServiceProvider { - runtime: Runtime::new().unwrap(), - config, - sphinx_keypair, - registered_clients_ledger, - } - } - - fn start_presence_notifier(&self) { - info!("Starting presence notifier..."); - let notifier_config = presence::NotifierConfig::new( - self.config.get_location(), - self.config.get_presence_directory_server(), - self.config.get_mix_announce_address(), - self.config.get_clients_announce_address(), - self.sphinx_keypair.public_key().to_base58_string(), - self.config.get_presence_sending_delay(), - ); - presence::Notifier::new(notifier_config, self.registered_clients_ledger.clone()) - .start(self.runtime.handle()); - } - - fn start_mix_socket_listener(&self, client_storage: ClientStorage) { - info!("Starting mix socket listener..."); - let packet_processor = mix_handling::packet_processing::PacketProcessor::new( - self.sphinx_keypair.private_key().clone(), - client_storage, - ); - - mix_handling::listener::run_mix_socket_listener( - self.runtime.handle(), - self.config.get_mix_listening_address(), - packet_processor, - ); - } - - fn start_client_socket_listener(&self, client_storage: ClientStorage) { - info!("Starting client socket listener..."); - let packet_processor = client_handling::request_processing::RequestProcessor::new( - self.sphinx_keypair.private_key().clone(), - client_storage, - self.registered_clients_ledger.clone(), - self.config.get_max_request_size(), - ); - - client_handling::listener::run_client_socket_listener( - self.runtime.handle(), - self.config.get_clients_listening_address(), - packet_processor, - ); - } - - fn check_if_same_ip_provider_exists(&self) -> Option { - // TODO: once we change to graph topology this here will need to be updated! - let topology = Topology::new(self.config.get_presence_directory_server()); - let existing_providers_presence = topology.mix_provider_nodes; - existing_providers_presence - .iter() - .find(|node| { - node.mixnet_listener == self.config.get_mix_announce_address() - || node.client_listener == self.config.get_clients_announce_address() - }) - .map(|node| node.pub_key.clone()) - } - - pub fn run(&mut self) { - // A possible future optimisation, depending on bottlenecks and resource usage: - // considering, presumably, there will be more mix packets received than client requests: - // create 2 separate runtimes - one with bigger threadpool dedicated solely for - // the mix handling and the other one for the rest of tasks - info!("Starting nym sfw-provider"); - - if let Some(duplicate_provider_key) = self.check_if_same_ip_provider_exists() { - error!( - "Our announce-host is identical to an existing node's announce-host! (its key is {:?}", - duplicate_provider_key - ); - return; - } - - let client_storage = ClientStorage::new( - self.config.get_message_retrieval_limit() as usize, - self.config.get_stored_messages_filename_length(), - self.config.get_clients_inboxes_dir(), - ); - - self.start_presence_notifier(); - self.start_mix_socket_listener(client_storage.clone()); - self.start_client_socket_listener(client_storage); - - info!("Finished nym sfw-provider startup procedure - it should now be able to receive mix and client traffic!"); - - if let Err(e) = self.runtime.block_on(tokio::signal::ctrl_c()) { - error!( - "There was an error while capturing SIGINT - {:?}. We will terminate regardless", - e - ); - } - - println!( - "Received SIGINT - the provider will terminate now (threads are not YET nicely stopped)" - ); - } -} diff --git a/sfw-provider/src/provider/presence.rs b/sfw-provider/src/provider/presence.rs deleted file mode 100644 index f8822f13dbb..00000000000 --- a/sfw-provider/src/provider/presence.rs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::built_info; -use crate::provider::ClientLedger; -use directory_client::presence::providers::MixProviderPresence; -use directory_client::requests::presence_providers_post::PresenceMixProviderPoster; -use directory_client::DirectoryClient; -use log::{error, trace}; -use std::time::Duration; -use tokio::runtime::Handle; -use tokio::task::JoinHandle; - -pub(crate) struct NotifierConfig { - location: String, - directory_server: String, - mix_announce_host: String, - clients_announce_host: String, - pub_key_string: String, - sending_delay: Duration, -} - -impl NotifierConfig { - pub(crate) fn new( - location: String, - directory_server: String, - mix_announce_host: String, - clients_announce_host: String, - pub_key_string: String, - sending_delay: Duration, - ) -> Self { - NotifierConfig { - location, - directory_server, - mix_announce_host, - clients_announce_host, - pub_key_string, - sending_delay, - } - } -} - -pub(crate) struct Notifier { - location: String, - net_client: directory_client::Client, - client_ledger: ClientLedger, - sending_delay: Duration, - client_listener: String, - mixnet_listener: String, - pub_key_string: String, -} - -impl Notifier { - pub(crate) fn new(config: NotifierConfig, client_ledger: ClientLedger) -> Notifier { - let directory_client_cfg = directory_client::Config { - base_url: config.directory_server, - }; - let net_client = directory_client::Client::new(directory_client_cfg); - - Notifier { - client_ledger, - net_client, - location: config.location, - client_listener: config.clients_announce_host, - mixnet_listener: config.mix_announce_host, - pub_key_string: config.pub_key_string, - sending_delay: config.sending_delay, - } - } - - async fn make_presence(&self) -> MixProviderPresence { - MixProviderPresence { - location: self.location.clone(), - client_listener: self.client_listener.clone(), - mixnet_listener: self.mixnet_listener.clone(), - pub_key: self.pub_key_string.clone(), - registered_clients: self.client_ledger.current_clients().unwrap(), - last_seen: 0, - version: built_info::PKG_VERSION.to_string(), - } - } - - pub(crate) fn notify(&self, presence: MixProviderPresence) { - match self.net_client.presence_providers_post.post(&presence) { - Err(err) => error!("failed to send presence - {:?}", err), - Ok(_) => trace!("sent presence information"), - } - } - - pub fn start(self, handle: &Handle) -> JoinHandle<()> { - handle.spawn(async move { - loop { - // set the deadline in the future - let sending_delay = tokio::time::delay_for(self.sending_delay); - let presence = self.make_presence().await; - self.notify(presence); - // wait for however much is left - sending_delay.await; - } - }) - } -} diff --git a/sfw-provider/src/provider/storage/mod.rs b/sfw-provider/src/provider/storage/mod.rs deleted file mode 100644 index 43b768aaebb..00000000000 --- a/sfw-provider/src/provider/storage/mod.rs +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2020 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use futures::lock::Mutex; -use futures::StreamExt; -use log::*; -use nymsphinx::{DestinationAddressBytes, SURBIdentifier}; -use rand::Rng; -use sfw_provider_requests::DUMMY_MESSAGE_CONTENT; -use std::io; -use std::path::PathBuf; -use std::sync::Arc; -use tokio::fs; -use tokio::fs::File; -use tokio::prelude::*; - -fn dummy_message() -> ClientFile { - ClientFile { - content: DUMMY_MESSAGE_CONTENT.to_vec(), - path: Default::default(), - } -} - -#[derive(Clone, Debug)] -pub struct ClientFile { - content: Vec, - path: PathBuf, -} - -impl ClientFile { - fn new(content: Vec, path: PathBuf) -> Self { - ClientFile { content, path } - } - - pub(crate) fn into_tuple(self) -> (Vec, PathBuf) { - (self.content, self.path) - } -} - -pub struct StoreData { - client_address: DestinationAddressBytes, - #[allow(dead_code)] - client_surb_id: SURBIdentifier, - message: Vec, -} - -impl StoreData { - pub(crate) fn new( - client_address: DestinationAddressBytes, - client_surb_id: SURBIdentifier, - message: Vec, - ) -> Self { - StoreData { - client_address, - client_surb_id, - message, - } - } -} - -// TODO: replace with proper database... -// Note: you should NEVER create more than a single instance of this using 'new()'. -// You should always use .clone() to create additional instances -#[derive(Clone, Debug)] -pub struct ClientStorage { - inner: Arc>, -} - -// even though the data inside is extremely cheap to copy, we have to have a single mutex, -// so might as well store the data behind it -pub struct ClientStorageInner { - message_retrieval_limit: usize, - filename_length: u16, - main_store_path_dir: PathBuf, -} - -// TODO: change it to some generic implementation to inject fs (or even better - proper database) -impl ClientStorage { - pub(crate) fn new(message_limit: usize, filename_len: u16, main_store_dir: PathBuf) -> Self { - ClientStorage { - inner: Arc::new(Mutex::new(ClientStorageInner { - message_retrieval_limit: message_limit, - filename_length: filename_len, - main_store_path_dir: main_store_dir, - })), - } - } - - // TODO: does this method really require locking? - // The worst that can happen is client sending 2 requests: to pull messages and register - // if register does not lock, then under specific timing pull messages will fail, - // but can simply be retried with no issues - pub(crate) async fn create_storage_dir( - &self, - client_address: DestinationAddressBytes, - ) -> io::Result<()> { - let inner_data = self.inner.lock().await; - - let client_dir_name = client_address.to_base58_string(); - let full_store_dir = inner_data.main_store_path_dir.join(client_dir_name); - fs::create_dir_all(full_store_dir).await - } - - pub(crate) fn generate_random_file_name(length: usize) -> String { - rand::thread_rng() - .sample_iter(&rand::distributions::Alphanumeric) - .take(length) - .collect::() - } - - pub(crate) async fn store_processed_data(&self, store_data: StoreData) -> io::Result<()> { - let inner_data = self.inner.lock().await; - - let client_dir_name = store_data.client_address.to_base58_string(); - let full_store_dir = inner_data.main_store_path_dir.join(client_dir_name); - let full_store_path = full_store_dir.join(Self::generate_random_file_name( - inner_data.filename_length as usize, - )); - debug!( - "going to store: {:?} in file: {:?}", - store_data.message, full_store_path - ); - - // TODO: what to do with surbIDs?? - - let mut file = File::create(full_store_path).await?; - file.write_all(store_data.message.as_ref()).await - } - - pub(crate) async fn retrieve_client_files( - &self, - client_address: DestinationAddressBytes, - ) -> io::Result> { - let inner_data = self.inner.lock().await; - - let client_dir_name = client_address.to_base58_string(); - let full_store_dir = inner_data.main_store_path_dir.join(client_dir_name); - - trace!("going to lookup: {:?}!", full_store_dir); - if !full_store_dir.exists() { - return Err(io::Error::new( - io::ErrorKind::NotFound, - "Target client does not exist", - )); - } - - let mut msgs = Vec::new(); - let mut read_dir = fs::read_dir(full_store_dir).await?; - - while let Some(dir_entry) = read_dir.next().await { - if let Ok(dir_entry) = dir_entry { - if !Self::is_valid_file(&dir_entry).await { - continue; - } - // Do not delete the file itself here! - // Only do it after client has received it - let client_file = - ClientFile::new(fs::read(dir_entry.path()).await?, dir_entry.path()); - msgs.push(client_file) - } - if msgs.len() == inner_data.message_retrieval_limit { - break; - } - } - - let dummy_message = dummy_message(); - - // make sure we always return as many messages as we need - if msgs.len() != inner_data.message_retrieval_limit as usize { - msgs = msgs - .into_iter() - .chain(std::iter::repeat(dummy_message)) - .take(inner_data.message_retrieval_limit) - .collect(); - } - - Ok(msgs) - } - - async fn is_valid_file(entry: &fs::DirEntry) -> bool { - let metadata = match entry.metadata().await { - Ok(meta) => meta, - Err(e) => { - error!( - "potentially corrupted client inbox! ({:?} - failed to read its metadata - {:?}", - entry.path(), - e, - ); - return false; - } - }; - - let is_file = metadata.is_file(); - if !is_file { - error!( - "potentially corrupted client inbox! - found a non-file - {:?}", - entry.path() - ); - } - - is_file - } - - pub(crate) async fn delete_files(&self, file_paths: Vec) -> io::Result<()> { - let dummy_message = dummy_message(); - let _guard = self.inner.lock().await; - - for file_path in file_paths { - if file_path == dummy_message.path { - continue; - } - if let Err(e) = fs::remove_file(file_path).await { - error!("Failed to delete client message! - {:?}", e) - } - } - Ok(()) - } -}