From 00b2ce18c8bc13d2f05d5f17ee89ae770c24d359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 3 Nov 2020 14:58:47 +0000 Subject: [PATCH] Feature/controlled reinit (#410) * Allowing init with existing id but keeps existing keys * Removed unused imports --- clients/native/src/commands/init.rs | 61 ++++++++++++++++------------- clients/socks5/src/commands/init.rs | 61 ++++++++++++++++------------- gateway/src/commands/init.rs | 54 +++++++++++++------------ mixnode/src/commands/init.rs | 55 ++++++++++++++------------ 4 files changed, 125 insertions(+), 106 deletions(-) diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index 4a0bc71326..5fcde7d7d8 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -23,7 +23,6 @@ use gateway_client::GatewayClient; use gateway_requests::registration::handshake::SharedKeys; use rand::rngs::OsRng; use rand::seq::SliceRandom; -use std::process; use std::sync::Arc; use std::time::Duration; use topology::{gateway, NymTopology}; @@ -131,10 +130,12 @@ pub fn execute(matches: &ArgMatches) { let id = matches.value_of("id").unwrap(); // required for now - if Config::default_config_file_path(id).exists() { - eprintln!("Client \"{}\" was already initialised before! If you wanted to upgrade your client to most recent version, try `upgrade` command instead!", id); - process::exit(1); - } + let already_init = if Config::default_config_file_path(id).exists() { + println!("Client \"{}\" was already initialised before! Config information will be overwritten (but keys will be kept)!", id); + true + } else { + false + }; let mut config = Config::new(id); @@ -147,33 +148,37 @@ pub fn execute(matches: &ArgMatches) { config.get_base_mut().set_high_default_traffic_volume(); } - // create identity, encryption and ack keys. - let mut key_manager = KeyManager::new(&mut rng); + // if client was already initialised, don't generate new keys, not re-register with gateway + // (because this would create new shared key) + if !already_init { + // create identity, encryption and ack keys. + let mut key_manager = KeyManager::new(&mut rng); - let gateway_id = select_gateway(matches.value_of("gateway")); - config.get_base_mut().with_gateway_id(gateway_id); + let gateway_id = select_gateway(matches.value_of("gateway")); + config.get_base_mut().with_gateway_id(gateway_id); - let registration_fut = async { - let gate_details = - gateway_details(&config.get_base().get_validator_rest_endpoint(), gateway_id).await; - let shared_keys = - register_with_gateway(&gate_details, key_manager.identity_keypair()).await; - (shared_keys, gate_details.client_listener) - }; + let registration_fut = async { + let gate_details = + gateway_details(&config.get_base().get_validator_rest_endpoint(), gateway_id).await; + let shared_keys = + register_with_gateway(&gate_details, key_manager.identity_keypair()).await; + (shared_keys, gate_details.client_listener) + }; - // TODO: is there perhaps a way to make it work without having to spawn entire runtime? - let mut rt = tokio::runtime::Runtime::new().unwrap(); - let (shared_keys, gateway_listener) = rt.block_on(registration_fut); - config - .get_base_mut() - .with_gateway_listener(gateway_listener); - key_manager.insert_gateway_shared_key(shared_keys); + // TODO: is there perhaps a way to make it work without having to spawn entire runtime? + let mut rt = tokio::runtime::Runtime::new().unwrap(); + let (shared_keys, gateway_listener) = rt.block_on(registration_fut); + config + .get_base_mut() + .with_gateway_listener(gateway_listener); + key_manager.insert_gateway_shared_key(shared_keys); - let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base()); - key_manager - .store_keys(&pathfinder) - .expect("Failed to generated keys"); - println!("Saved all generated keys"); + let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base()); + key_manager + .store_keys(&pathfinder) + .expect("Failed to generated keys"); + println!("Saved all generated keys"); + } let config_save_location = config.get_config_file_save_location(); config diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index 9e5cccf08e..adde52fe53 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -22,7 +22,6 @@ use crypto::asymmetric::identity; use gateway_client::GatewayClient; use gateway_requests::registration::handshake::SharedKeys; use rand::{prelude::SliceRandom, rngs::OsRng}; -use std::process; use std::sync::Arc; use std::time::Duration; use topology::{gateway, NymTopology}; @@ -133,10 +132,12 @@ pub fn execute(matches: &ArgMatches) { let id = matches.value_of("id").unwrap(); // required for now let provider_address = matches.value_of("provider").unwrap(); - if Config::default_config_file_path(id).exists() { - eprintln!("Socks5 client \"{}\" was already initialised before! If you wanted to upgrade your client to most recent version, try `upgrade` command instead!", id); - process::exit(1); - } + let already_init = if Config::default_config_file_path(id).exists() { + println!("Socks5 client \"{}\" was already initialised before! Config information will be overwritten (but keys will be kept)!", id); + true + } else { + false + }; let mut config = Config::new(id, provider_address); @@ -149,33 +150,37 @@ pub fn execute(matches: &ArgMatches) { config.get_base_mut().set_high_default_traffic_volume(); } - // create identity, encryption and ack keys. - let mut key_manager = KeyManager::new(&mut rng); + // if client was already initialised, don't generate new keys, not re-register with gateway + // (because this would create new shared key) + if !already_init { + // create identity, encryption and ack keys. + let mut key_manager = KeyManager::new(&mut rng); - let gateway_id = select_gateway(matches.value_of("gateway")); - config.get_base_mut().with_gateway_id(gateway_id); + let gateway_id = select_gateway(matches.value_of("gateway")); + config.get_base_mut().with_gateway_id(gateway_id); - let registration_fut = async { - let gate_details = - gateway_details(&config.get_base().get_validator_rest_endpoint(), gateway_id).await; - let shared_keys = - register_with_gateway(&gate_details, key_manager.identity_keypair()).await; - (shared_keys, gate_details.client_listener) - }; + let registration_fut = async { + let gate_details = + gateway_details(&config.get_base().get_validator_rest_endpoint(), gateway_id).await; + let shared_keys = + register_with_gateway(&gate_details, key_manager.identity_keypair()).await; + (shared_keys, gate_details.client_listener) + }; - // TODO: is there perhaps a way to make it work without having to spawn entire runtime? - let mut rt = tokio::runtime::Runtime::new().unwrap(); - let (shared_keys, gateway_listener) = rt.block_on(registration_fut); - config - .get_base_mut() - .with_gateway_listener(gateway_listener); - key_manager.insert_gateway_shared_key(shared_keys); + // TODO: is there perhaps a way to make it work without having to spawn entire runtime? + let mut rt = tokio::runtime::Runtime::new().unwrap(); + let (shared_keys, gateway_listener) = rt.block_on(registration_fut); + config + .get_base_mut() + .with_gateway_listener(gateway_listener); + key_manager.insert_gateway_shared_key(shared_keys); - let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base()); - key_manager - .store_keys(&pathfinder) - .expect("Failed to generated keys"); - println!("Saved all generated keys"); + let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base()); + key_manager + .store_keys(&pathfinder) + .expect("Failed to generated keys"); + println!("Saved all generated keys"); + } let config_save_location = config.get_config_file_save_location(); config diff --git a/gateway/src/commands/init.rs b/gateway/src/commands/init.rs index 001794f3b7..f73af09924 100644 --- a/gateway/src/commands/init.rs +++ b/gateway/src/commands/init.rs @@ -18,7 +18,6 @@ use crate::config::Config; use clap::{App, Arg, ArgMatches}; use config::NymConfig; use crypto::asymmetric::{encryption, identity}; -use std::process; pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> { App::new("init") @@ -118,37 +117,42 @@ pub fn execute(matches: &ArgMatches) { let id = matches.value_of("id").unwrap(); println!("Initialising gateway {}...", id); - if Config::default_config_file_path(id).exists() { - eprintln!("Gateway \"{}\" was already initialised before! If you wanted to upgrade your gateway to most recent version, try `upgrade` command instead!", id); - process::exit(1); - } + let already_init = if Config::default_config_file_path(id).exists() { + println!("Gateway \"{}\" was already initialised before! Config information will be overwritten (but keys will be kept)!", id); + true + } else { + false + }; let mut config = Config::new(id); config = override_config(config, matches); - let identity_keys = identity::KeyPair::new(); - let sphinx_keys = encryption::KeyPair::new(); - let pathfinder = GatewayPathfinder::new_from_config(&config); - pemstore::store_keypair( - &sphinx_keys, - &pemstore::KeyPairPath::new( - pathfinder.private_encryption_key().to_owned(), - pathfinder.public_encryption_key().to_owned(), - ), - ) - .expect("Failed to save sphinx keys"); + // if gateway was already initialised, don't generate new keys + if !already_init { + let identity_keys = identity::KeyPair::new(); + let sphinx_keys = encryption::KeyPair::new(); + let pathfinder = GatewayPathfinder::new_from_config(&config); + pemstore::store_keypair( + &sphinx_keys, + &pemstore::KeyPairPath::new( + pathfinder.private_encryption_key().to_owned(), + pathfinder.public_encryption_key().to_owned(), + ), + ) + .expect("Failed to save sphinx keys"); - pemstore::store_keypair( - &identity_keys, - &pemstore::KeyPairPath::new( - pathfinder.private_identity_key().to_owned(), - pathfinder.public_identity_key().to_owned(), - ), - ) - .expect("Failed to save identity keys"); + pemstore::store_keypair( + &identity_keys, + &pemstore::KeyPairPath::new( + pathfinder.private_identity_key().to_owned(), + pathfinder.public_identity_key().to_owned(), + ), + ) + .expect("Failed to save identity keys"); - println!("Saved identity and mixnet sphinx keypairs"); + println!("Saved identity and mixnet sphinx keypairs"); + } let config_save_location = config.get_config_file_save_location(); config diff --git a/mixnode/src/commands/init.rs b/mixnode/src/commands/init.rs index 0bf7edfdc3..bbef492965 100644 --- a/mixnode/src/commands/init.rs +++ b/mixnode/src/commands/init.rs @@ -20,7 +20,6 @@ use config::NymConfig; use crypto::asymmetric::{encryption, identity}; use log::*; use nymsphinx::params::DEFAULT_NUM_MIX_HOPS; -use std::process; use tokio::runtime::Runtime; use topology::NymTopology; @@ -140,10 +139,12 @@ pub fn execute(matches: &ArgMatches) { let id = matches.value_of("id").unwrap(); println!("Initialising mixnode {}...", id); - if Config::default_config_file_path(id).exists() { - eprintln!("Mixnode \"{}\" was already initialised before! If you wanted to upgrade your node to most recent version, try `upgrade` command instead!", id); - process::exit(1); - } + let already_init = if Config::default_config_file_path(id).exists() { + println!("Mixnode \"{}\" was already initialised before! Config information will be overwritten (but keys will be kept)!", id); + true + } else { + false + }; let mut config = Config::new(id); config = override_config(config, matches); @@ -153,28 +154,32 @@ pub fn execute(matches: &ArgMatches) { config = config.with_layer(layer); debug!("Choosing layer {}", config.get_layer()); - let identity_keys = identity::KeyPair::new(); - let sphinx_keys = encryption::KeyPair::new(); - let pathfinder = MixNodePathfinder::new_from_config(&config); - pemstore::store_keypair( - &identity_keys, - &pemstore::KeyPairPath::new( - pathfinder.private_identity_key().to_owned(), - pathfinder.public_identity_key().to_owned(), - ), - ) - .expect("Failed to save identity keys"); + // if node was already initialised, don't generate new keys + if !already_init { + let identity_keys = identity::KeyPair::new(); + let sphinx_keys = encryption::KeyPair::new(); + let pathfinder = MixNodePathfinder::new_from_config(&config); + pemstore::store_keypair( + &identity_keys, + &pemstore::KeyPairPath::new( + pathfinder.private_identity_key().to_owned(), + pathfinder.public_identity_key().to_owned(), + ), + ) + .expect("Failed to save identity keys"); - pemstore::store_keypair( - &sphinx_keys, - &pemstore::KeyPairPath::new( - pathfinder.private_encryption_key().to_owned(), - pathfinder.public_encryption_key().to_owned(), - ), - ) - .expect("Failed to save sphinx keys"); + pemstore::store_keypair( + &sphinx_keys, + &pemstore::KeyPairPath::new( + pathfinder.private_encryption_key().to_owned(), + pathfinder.public_encryption_key().to_owned(), + ), + ) + .expect("Failed to save sphinx keys"); + + println!("Saved mixnet identity and sphinx keypairs"); + } - println!("Saved mixnet identity and sphinx keypairs"); let config_save_location = config.get_config_file_save_location(); config .save_to_file(None)