Skip to content

Commit d940bc8

Browse files
authored
Feature/double init prevention (#386)
* Updated NymConfig trait making id always obligatory. Also added extra default method implementations * Preventing init on mixnodes that were initialised before * Quotes before mix id * Preventing init on gateways that were initialised before * Preventing init on native clients that were initialised before * Preventing init on socks5 clients that were initialised before
1 parent 2f7b3ee commit d940bc8

File tree

10 files changed

+70
-44
lines changed

10 files changed

+70
-44
lines changed

clients/client-core/src/config/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -360,31 +360,31 @@ impl<T: NymConfig> Default for Client<T> {
360360

361361
impl<T: NymConfig> Client<T> {
362362
fn default_private_identity_key_file(id: &str) -> PathBuf {
363-
T::default_data_directory(Some(id)).join("private_identity.pem")
363+
T::default_data_directory(id).join("private_identity.pem")
364364
}
365365

366366
fn default_public_identity_key_file(id: &str) -> PathBuf {
367-
T::default_data_directory(Some(id)).join("public_identity.pem")
367+
T::default_data_directory(id).join("public_identity.pem")
368368
}
369369

370370
fn default_private_encryption_key_file(id: &str) -> PathBuf {
371-
T::default_data_directory(Some(id)).join("private_encryption.pem")
371+
T::default_data_directory(id).join("private_encryption.pem")
372372
}
373373

374374
fn default_public_encryption_key_file(id: &str) -> PathBuf {
375-
T::default_data_directory(Some(id)).join("public_encryption.pem")
375+
T::default_data_directory(id).join("public_encryption.pem")
376376
}
377377

378378
fn default_gateway_shared_key_file(id: &str) -> PathBuf {
379-
T::default_data_directory(Some(id)).join("gateway_shared.pem")
379+
T::default_data_directory(id).join("gateway_shared.pem")
380380
}
381381

382382
fn default_ack_key_file(id: &str) -> PathBuf {
383-
T::default_data_directory(Some(id)).join("ack_key.pem")
383+
T::default_data_directory(id).join("ack_key.pem")
384384
}
385385

386386
fn default_reply_encryption_key_store_path(id: &str) -> PathBuf {
387-
T::default_data_directory(Some(id)).join("reply_key_store")
387+
T::default_data_directory(id).join("reply_key_store")
388388
}
389389
}
390390

clients/native/src/client/config/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ impl NymConfig for Config {
5555
config_template()
5656
}
5757

58-
fn config_file_name() -> String {
59-
"config.toml".to_string()
60-
}
61-
6258
fn default_root_directory() -> PathBuf {
6359
dirs::home_dir()
6460
.expect("Failed to evaluate $HOME value")

clients/native/src/commands/init.rs

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use gateway_requests::registration::handshake::SharedKeys;
2525
use rand::rngs::OsRng;
2626
use rand::seq::SliceRandom;
2727
use std::convert::TryInto;
28+
use std::process;
2829
use std::sync::Arc;
2930
use std::time::Duration;
3031
use topology::{gateway, NymTopology};
@@ -131,7 +132,14 @@ pub fn execute(matches: &ArgMatches) {
131132
println!("Initialising client...");
132133

133134
let id = matches.value_of("id").unwrap(); // required for now
135+
136+
if Config::default_config_file_path(id).exists() {
137+
eprintln!("Client \"{}\" was already initialised before! If you wanted to upgrade your client to most recent version, try `upgrade` command instead!", id);
138+
process::exit(1);
139+
}
140+
134141
let mut config = Config::new(id);
142+
135143
let mut rng = OsRng;
136144

137145
// TODO: ideally that should be the last thing that's being done to config.

clients/socks5/src/client/config/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ impl NymConfig for Config {
3838
config_template()
3939
}
4040

41-
fn config_file_name() -> String {
42-
"config.toml".to_string()
43-
}
44-
4541
fn default_root_directory() -> PathBuf {
4642
dirs::home_dir()
4743
.expect("Failed to evaluate $HOME value")

clients/socks5/src/commands/init.rs

+7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use gateway_client::GatewayClient;
2424
use gateway_requests::registration::handshake::SharedKeys;
2525
use rand::{prelude::SliceRandom, rngs::OsRng};
2626
use std::convert::TryInto;
27+
use std::process;
2728
use std::sync::Arc;
2829
use std::time::Duration;
2930
use topology::{gateway, NymTopology};
@@ -134,7 +135,13 @@ pub fn execute(matches: &ArgMatches) {
134135
let id = matches.value_of("id").unwrap(); // required for now
135136
let provider_address = matches.value_of("provider").unwrap();
136137

138+
if Config::default_config_file_path(id).exists() {
139+
eprintln!("Socks5 client \"{}\" was already initialised before! If you wanted to upgrade your client to most recent version, try `upgrade` command instead!", id);
140+
process::exit(1);
141+
}
142+
137143
let mut config = Config::new(id, provider_address);
144+
138145
let mut rng = OsRng;
139146

140147
// TODO: ideally that should be the last thing that's being done to config.

common/config/src/lib.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,23 @@ use std::{fs, io};
2121
pub trait NymConfig: Default + Serialize + DeserializeOwned {
2222
fn template() -> &'static str;
2323

24-
fn config_file_name() -> String;
24+
fn config_file_name() -> String {
25+
"config.toml".to_string()
26+
}
2527

2628
fn default_root_directory() -> PathBuf;
2729

2830
// default, most probable, implementations; can be easily overridden where required
29-
fn default_config_directory(id: Option<&str>) -> PathBuf {
30-
Self::default_root_directory()
31-
.join(id.unwrap_or(""))
32-
.join("config")
31+
fn default_config_directory(id: &str) -> PathBuf {
32+
Self::default_root_directory().join(id).join("config")
33+
}
34+
35+
fn default_data_directory(id: &str) -> PathBuf {
36+
Self::default_root_directory().join(id).join("data")
3337
}
3438

35-
fn default_data_directory(id: Option<&str>) -> PathBuf {
36-
Self::default_root_directory()
37-
.join(id.unwrap_or(""))
38-
.join("data")
39+
fn default_config_file_path(id: &str) -> PathBuf {
40+
Self::default_config_directory(id).join(Self::config_file_name())
3941
}
4042

4143
fn root_directory(&self) -> PathBuf;
@@ -66,10 +68,20 @@ pub trait NymConfig: Default + Serialize + DeserializeOwned {
6668
)
6769
}
6870

71+
// Hopefully should get simplified by https://github.com/nymtech/nym/issues/385
72+
// so that `custom_location` could be completely removed
6973
fn load_from_file(custom_location: Option<PathBuf>, id: Option<&str>) -> io::Result<Self> {
74+
if custom_location.is_none() && id.is_none() {
75+
return Err(io::Error::new(
76+
io::ErrorKind::InvalidInput,
77+
"Both custom location and id are unspecified!",
78+
));
79+
}
80+
81+
// unwrap on id can't fail as we just checked whether at least one of custom location or id
82+
// is not None
7083
let config_contents = fs::read_to_string(
71-
custom_location
72-
.unwrap_or_else(|| Self::default_config_directory(id).join("config.toml")),
84+
custom_location.unwrap_or_else(|| Self::default_config_file_path(id.unwrap())),
7385
)?;
7486

7587
toml::from_str(&config_contents)

gateway/src/commands/init.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414

1515
use crate::commands::override_config;
1616
use crate::config::persistence::pathfinder::GatewayPathfinder;
17+
use crate::config::Config;
1718
use clap::{App, Arg, ArgMatches};
1819
use config::NymConfig;
1920
use crypto::asymmetric::{encryption, identity};
21+
use std::process;
2022

2123
pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
2224
App::new("init")
@@ -116,7 +118,12 @@ pub fn execute(matches: &ArgMatches) {
116118
let id = matches.value_of("id").unwrap();
117119
println!("Initialising gateway {}...", id);
118120

119-
let mut config = crate::config::Config::new(id);
121+
if Config::default_config_file_path(id).exists() {
122+
eprintln!("Gateway \"{}\" was already initialised before! If you wanted to upgrade your gateway to most recent version, try `upgrade` command instead!", id);
123+
process::exit(1);
124+
}
125+
126+
let mut config = Config::new(id);
120127

121128
config = override_config(config, matches);
122129

gateway/src/config/mod.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,6 @@ impl NymConfig for Config {
6262
config_template()
6363
}
6464

65-
fn config_file_name() -> String {
66-
"config.toml".to_string()
67-
}
68-
6965
fn default_root_directory() -> PathBuf {
7066
dirs::home_dir()
7167
.expect("Failed to evaluate $HOME value")
@@ -457,19 +453,19 @@ pub struct Gateway {
457453

458454
impl Gateway {
459455
fn default_private_sphinx_key_file(id: &str) -> PathBuf {
460-
Config::default_data_directory(Some(id)).join("private_sphinx.pem")
456+
Config::default_data_directory(id).join("private_sphinx.pem")
461457
}
462458

463459
fn default_public_sphinx_key_file(id: &str) -> PathBuf {
464-
Config::default_data_directory(Some(id)).join("public_sphinx.pem")
460+
Config::default_data_directory(id).join("public_sphinx.pem")
465461
}
466462

467463
fn default_private_identity_key_file(id: &str) -> PathBuf {
468-
Config::default_data_directory(Some(id)).join("private_identity.pem")
464+
Config::default_data_directory(id).join("private_identity.pem")
469465
}
470466

471467
fn default_public_identity_key_file(id: &str) -> PathBuf {
472-
Config::default_data_directory(Some(id)).join("public_identity.pem")
468+
Config::default_data_directory(id).join("public_identity.pem")
473469
}
474470

475471
fn default_location() -> String {
@@ -545,11 +541,11 @@ pub struct ClientsEndpoint {
545541

546542
impl ClientsEndpoint {
547543
fn default_inboxes_directory(id: &str) -> PathBuf {
548-
Config::default_data_directory(Some(id)).join("inboxes")
544+
Config::default_data_directory(id).join("inboxes")
549545
}
550546

551547
fn default_ledger_path(id: &str) -> PathBuf {
552-
Config::default_data_directory(Some(id)).join("client_ledger.sled")
548+
Config::default_data_directory(id).join("client_ledger.sled")
553549
}
554550
}
555551

mixnode/src/commands/init.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414

1515
use crate::commands::override_config;
1616
use crate::config::persistence::pathfinder::MixNodePathfinder;
17+
use crate::config::Config;
1718
use clap::{App, Arg, ArgMatches};
1819
use config::NymConfig;
1920
use crypto::asymmetric::{encryption, identity};
2021
use directory_client::DirectoryClient;
2122
use log::*;
2223
use nymsphinx::params::DEFAULT_NUM_MIX_HOPS;
2324
use std::convert::TryInto;
25+
use std::process;
2426
use tokio::runtime::Runtime;
2527
use topology::NymTopology;
2628

@@ -134,7 +136,13 @@ pub fn execute(matches: &ArgMatches) {
134136
rt.block_on(async {
135137
let id = matches.value_of("id").unwrap();
136138
println!("Initialising mixnode {}...", id);
137-
let mut config = crate::config::Config::new(id);
139+
140+
if Config::default_config_file_path(id).exists() {
141+
eprintln!("Mixnode \"{}\" was already initialised before! If you wanted to upgrade your node to most recent version, try `upgrade` command instead!", id);
142+
process::exit(1);
143+
}
144+
145+
let mut config = Config::new(id);
138146
config = override_config(config, matches);
139147
let layer = choose_layer(matches, config.get_presence_directory_server()).await;
140148
// TODO: I really don't like how we override config and are presumably done with it

mixnode/src/config/mod.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ impl NymConfig for Config {
5656
config_template()
5757
}
5858

59-
fn config_file_name() -> String {
60-
"config.toml".to_string()
61-
}
62-
6359
fn default_root_directory() -> PathBuf {
6460
dirs::home_dir()
6561
.expect("Failed to evaluate $HOME value")
@@ -377,11 +373,11 @@ impl MixNode {
377373
}
378374

379375
fn default_private_sphinx_key_file(id: &str) -> PathBuf {
380-
Config::default_data_directory(Some(id)).join("private_sphinx.pem")
376+
Config::default_data_directory(id).join("private_sphinx.pem")
381377
}
382378

383379
fn default_public_sphinx_key_file(id: &str) -> PathBuf {
384-
Config::default_data_directory(Some(id)).join("public_sphinx.pem")
380+
Config::default_data_directory(id).join("public_sphinx.pem")
385381
}
386382

387383
fn default_location() -> String {

0 commit comments

Comments
 (0)