diff --git a/src/main.rs b/src/main.rs index d32b6c592d..00662a0f59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use crate::provider::presence; use crate::provider::ServiceProvider; use clap::{App, Arg, ArgMatches, SubCommand}; +use nym_client::identity::mixnet::KeyPair; use std::net::ToSocketAddrs; use std::path::PathBuf; use std::process; @@ -40,20 +41,12 @@ fn main() { .help("The port on which the service provider will be listening for client sfw-provider-requests") .takes_value(true) ) - .arg( - Arg::with_name("keyfile") - .short("k") - .long("keyfile") - .help("Optional path to the persistent keyfile of the node") - .takes_value(true), - ) .arg( Arg::with_name("storeDir") .short("s") .long("storeDir") .help("Directory storing all packets for the clients") .takes_value(true) - .required(true), ) .arg( Arg::with_name("registeredLedger") @@ -61,7 +54,6 @@ fn main() { .long("registeredLedger") .help("Directory of the ledger of registered clients") .takes_value(true) - .required(true), ).arg(Arg::with_name("local") .long("local") .help("Flag to indicate whether the provider should run on a local deployment.") @@ -89,13 +81,6 @@ fn run(matches: &ArgMatches) { provider.start().unwrap() } -fn execute(matches: ArgMatches) -> Result<(), String> { - match matches.subcommand() { - ("run", Some(m)) => Ok(run(m)), - _ => Err(usage()), - } -} - fn new_config(matches: &ArgMatches) -> provider::Config { println!("Running the service provider!"); let is_local = matches.is_present("local"); @@ -109,7 +94,7 @@ fn new_config(matches: &ArgMatches) -> provider::Config { let mix_host = matches.value_of("mixHost").unwrap_or("0.0.0.0"); let mix_port = match matches.value_of("mixPort").unwrap_or("8085").parse::() { Ok(n) => n, - Err(err) => panic!("Invalid port value provided - {:?}", err), + Err(err) => panic!("Invalid mix host port value provided - {:?}", err), }; let client_host = matches.value_of("clientHost").unwrap_or("0.0.0.0"); @@ -119,18 +104,26 @@ fn new_config(matches: &ArgMatches) -> provider::Config { .parse::() { Ok(n) => n, - Err(err) => panic!("Invalid port value provided - {:?}", err), + Err(err) => panic!("Invalid client port value provided - {:?}", err), }; - let store_dir = PathBuf::from(matches.value_of("storeDir").unwrap_or("/tmp/nym-provider")); - let registered_client_ledger_dir = PathBuf::from(matches.value_of("registeredLedger").unwrap()); - let (secret_key, public_key) = sphinx::crypto::keygen(); + let key_pair = KeyPair::new(); // TODO: persist this so keypairs don't change every restart + let store_dir = PathBuf::from( + matches + .value_of("storeDir") + .unwrap_or("/tmp/nym-provider/inboxes"), + ); + let registered_client_ledger_dir = PathBuf::from( + matches + .value_of("registeredLedger") + .unwrap_or("/tmp/nym-provider/registered_clients"), + ); println!("The value of mix_host is: {:?}", mix_host); println!("The value of mix_port is: {:?}", mix_port); println!("The value of client_host is: {:?}", client_host); println!("The value of client_port is: {:?}", client_port); - println!("The value of key is: {:?}", secret_key); + println!("The value of key is: {:?}", key_pair.private.clone()); println!("The value of store_dir is: {:?}", store_dir); println!( "The value of registered_client_ledger_dir is: {:?}", @@ -159,15 +152,22 @@ fn new_config(matches: &ArgMatches) -> provider::Config { ); provider::Config { - directory_server, - public_key, - client_socket_address, mix_socket_address, - secret_key, + directory_server, + public_key: key_pair.public, + client_socket_address, + secret_key: key_pair.private, store_dir: PathBuf::from(store_dir), } } +fn execute(matches: ArgMatches) -> Result<(), String> { + match matches.subcommand() { + ("run", Some(m)) => Ok(run(m)), + _ => Err(usage()), + } +} + fn usage() -> String { banner() + "usage: --help to see available options.\n\n" } diff --git a/src/provider/client_handling/mod.rs b/src/provider/client_handling/mod.rs index 06a2421f23..6d22cad3d2 100644 --- a/src/provider/client_handling/mod.rs +++ b/src/provider/client_handling/mod.rs @@ -4,15 +4,14 @@ use curve25519_dalek::scalar::Scalar; use futures::lock::Mutex as FMutex; use hmac::{Hmac, Mac}; use sfw_provider_requests::requests::{ - ProviderRequestError, ProviderRequests, PullRequest, - RegisterRequest, + ProviderRequestError, ProviderRequests, PullRequest, RegisterRequest, }; use sfw_provider_requests::responses::{ProviderResponse, PullResponse, RegisterResponse}; +use sfw_provider_requests::AuthToken; use sha2::Sha256; use std::io; use std::path::{Path, PathBuf}; use std::sync::Arc; -use sfw_provider_requests::AuthToken; type HmacSha256 = Hmac; @@ -88,11 +87,14 @@ impl ClientRequestProcessor { ProviderRequests::Register(req) => Ok(ClientRequestProcessor::register_new_client( req, processing_data, - ).await?.to_bytes()), - ProviderRequests::PullMessages(req) => Ok(ClientRequestProcessor::process_pull_messages_request( - req, - processing_data, - ).await?.to_bytes()) + ) + .await? + .to_bytes()), + ProviderRequests::PullMessages(req) => Ok( + ClientRequestProcessor::process_pull_messages_request(req, processing_data) + .await? + .to_bytes(), + ), } } @@ -109,8 +111,10 @@ impl ClientRequestProcessor { let store_dir_clone = unlocked.store_dir.clone(); // drop the mutex so that we could do IO without blocking others wanting to get the lock drop(unlocked); - let retrieved_messages = - ClientStorage::retrieve_client_files(req.destination_address, store_dir_clone.as_path())?; + let retrieved_messages = ClientStorage::retrieve_client_files( + req.destination_address, + store_dir_clone.as_path(), + )?; Ok(PullResponse::new(retrieved_messages)) } else { Err(ClientProcessingError::WrongToken) @@ -129,8 +133,13 @@ impl ClientRequestProcessor { unlocked.secret_key, ); if !unlocked.registered_clients_ledger.has_token(auth_token) { - unlocked.registered_clients_ledger.insert_token(auth_token, req.destination_address); - ClientRequestProcessor::create_storage_dir(req.destination_address, unlocked.store_dir.as_path())?; + unlocked + .registered_clients_ledger + .insert_token(auth_token, req.destination_address); + ClientRequestProcessor::create_storage_dir( + req.destination_address, + unlocked.store_dir.as_path(), + )?; } Ok(RegisterResponse::new(auth_token)) } @@ -156,66 +165,66 @@ impl ClientRequestProcessor { #[cfg(test)] mod register_new_client { - use super::*; + // use super::*; // TODO: those tests require being called in async context. we need to research how to test this stuff... -// #[test] -// fn registers_new_auth_token_for_each_new_client() { -// let req1 = RegisterRequest { -// destination_address: [1u8; 32], -// }; -// let registered_client_ledger = ClientLedger::new(); -// let store_dir = PathBuf::from("./foo/"); -// let key = Scalar::from_bytes_mod_order([1u8; 32]); -// let client_processing_data = ClientProcessingData::new(store_dir, registered_client_ledger, key).add_arc_futures_mutex(); -// -// -// // need to do async.... -// client_processing_data.lock().await; -// assert_eq!(0, registered_client_ledger.0.len()); -// ClientRequestProcessor::register_new_client( -// req1, -// client_processing_data.clone(), -// ); -// -// assert_eq!(1, registered_client_ledger.0.len()); -// -// let req2 = RegisterRequest { -// destination_address: [2u8; 32], -// }; -// ClientRequestProcessor::register_new_client( -// req2, -// client_processing_data, -// ); -// assert_eq!(2, registered_client_ledger.0.len()); -// } -// -// #[test] -// fn registers_given_token_only_once() { -// let req1 = RegisterRequest { -// destination_address: [1u8; 32], -// }; -// let registered_client_ledger = ClientLedger::new(); -// let store_dir = PathBuf::from("./foo/"); -// let key = Scalar::from_bytes_mod_order([1u8; 32]); -// let client_processing_data = ClientProcessingData::new(store_dir, registered_client_ledger, key).add_arc_futures_mutex(); -// -// ClientRequestProcessor::register_new_client( -// req1, -// client_processing_data.clone(), -// ); -// let req2 = RegisterRequest { -// destination_address: [1u8; 32], -// }; -// ClientRequestProcessor::register_new_client( -// req2, -// client_processing_data.clone(), -// ); -// -// client_processing_data.lock().await; -// -// assert_eq!(1, registered_client_ledger.0.len()) -// } + // #[test] + // fn registers_new_auth_token_for_each_new_client() { + // let req1 = RegisterRequest { + // destination_address: [1u8; 32], + // }; + // let registered_client_ledger = ClientLedger::new(); + // let store_dir = PathBuf::from("./foo/"); + // let key = Scalar::from_bytes_mod_order([1u8; 32]); + // let client_processing_data = ClientProcessingData::new(store_dir, registered_client_ledger, key).add_arc_futures_mutex(); + // + // + // // need to do async.... + // client_processing_data.lock().await; + // assert_eq!(0, registered_client_ledger.0.len()); + // ClientRequestProcessor::register_new_client( + // req1, + // client_processing_data.clone(), + // ); + // + // assert_eq!(1, registered_client_ledger.0.len()); + // + // let req2 = RegisterRequest { + // destination_address: [2u8; 32], + // }; + // ClientRequestProcessor::register_new_client( + // req2, + // client_processing_data, + // ); + // assert_eq!(2, registered_client_ledger.0.len()); + // } + // + // #[test] + // fn registers_given_token_only_once() { + // let req1 = RegisterRequest { + // destination_address: [1u8; 32], + // }; + // let registered_client_ledger = ClientLedger::new(); + // let store_dir = PathBuf::from("./foo/"); + // let key = Scalar::from_bytes_mod_order([1u8; 32]); + // let client_processing_data = ClientProcessingData::new(store_dir, registered_client_ledger, key).add_arc_futures_mutex(); + // + // ClientRequestProcessor::register_new_client( + // req1, + // client_processing_data.clone(), + // ); + // let req2 = RegisterRequest { + // destination_address: [1u8; 32], + // }; + // ClientRequestProcessor::register_new_client( + // req2, + // client_processing_data.clone(), + // ); + // + // client_processing_data.lock().await; + // + // assert_eq!(1, registered_client_ledger.0.len()) + // } } #[cfg(test)] @@ -227,7 +236,7 @@ mod create_storage_dir { fn it_creates_a_correct_storage_directory() { let client_address: DestinationAddressBytes = [1u8; 32]; let store_dir = Path::new("./foo/"); - ClientRequestProcessor::create_storage_dir(client_address, store_dir); + ClientRequestProcessor::create_storage_dir(client_address, store_dir).unwrap(); } } diff --git a/src/provider/mod.rs b/src/provider/mod.rs index 1541cb771a..3bb6557a52 100644 --- a/src/provider/mod.rs +++ b/src/provider/mod.rs @@ -1,19 +1,19 @@ +use crate::provider::client_handling::{ClientProcessingData, ClientRequestProcessor}; +use crate::provider::mix_handling::{MixPacketProcessor, MixProcessingData}; +use crate::provider::storage::ClientStorage; +use curve25519_dalek::montgomery::MontgomeryPoint; +use curve25519_dalek::scalar::Scalar; +use futures::io::Error; +use futures::lock::Mutex as FMutex; +use sfw_provider_requests::AuthToken; +use sphinx::route::DestinationAddressBytes; +use std::collections::HashMap; use std::net::{Shutdown, SocketAddr}; use std::path::PathBuf; use std::sync::Arc; use std::sync::RwLock; -use curve25519_dalek::montgomery::MontgomeryPoint; -use curve25519_dalek::scalar::Scalar; use tokio::prelude::*; use tokio::runtime::Runtime; -use crate::provider::client_handling::{ClientProcessingData, ClientRequestProcessor}; -use crate::provider::mix_handling::{MixPacketProcessor, MixProcessingData}; -use crate::provider::storage::ClientStorage; -use futures::io::Error; -use sfw_provider_requests::AuthToken; -use sphinx::route::DestinationAddressBytes; -use std::collections::HashMap; -use futures::lock::Mutex as FMutex; mod client_handling; mod mix_handling; @@ -75,10 +75,14 @@ impl ClientLedger { } fn has_token(&self, auth_token: AuthToken) -> bool { - return self.0.contains_key(&auth_token) + return self.0.contains_key(&auth_token); } - fn insert_token(&mut self, auth_token: AuthToken, client_address: DestinationAddressBytes) -> Option{ + fn insert_token( + &mut self, + auth_token: AuthToken, + client_address: DestinationAddressBytes, + ) -> Option { self.0.insert(auth_token, client_address) } @@ -137,10 +141,10 @@ impl ServiceProvider { store_data, processing_data.read().unwrap().store_dir.as_path(), ) - .unwrap_or_else(|e| { - eprintln!("failed to store processed sphinx message; err = {:?}", e); - return; - }); + .unwrap_or_else(|e| { + eprintln!("failed to store processed sphinx message; err = {:?}", e); + return; + }); } Err(e) => { eprintln!("failed to read from socket; err = {:?}", e); @@ -183,7 +187,9 @@ impl ServiceProvider { match ClientRequestProcessor::process_client_request( buf[..n].as_ref(), processing_data, - ).await { + ) + .await + { Err(e) => { eprintln!("failed to process client request; err = {:?}", e); Err(()) diff --git a/src/provider/presence.rs b/src/provider/presence.rs index b197d4256a..5368214a5d 100644 --- a/src/provider/presence.rs +++ b/src/provider/presence.rs @@ -5,7 +5,6 @@ use std::thread; use std::time::Duration; use nym_client::clients::directory::presence::MixProviderPresence; - use nym_client::clients::directory::requests::presence_providers_post::PresenceMixProviderPoster; pub struct Notifier {