From 1916adedcc73af0d9797767d586dfbcd59e744b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 6 Mar 2024 16:53:27 +0000 Subject: [PATCH] socks5 client compiling but definitely not working yet --- clients/socks5/src/commands/init.rs | 2 +- clients/socks5/src/commands/mod.rs | 83 ++++++++++---- clients/socks5/src/config/mod.rs | 1 + .../socks5/src/config/old_config_v1_1_20.rs | 4 +- .../socks5/src/config/old_config_v1_1_20_2.rs | 3 +- .../socks5/src/config/old_config_v1_1_30.rs | 11 +- .../socks5/src/config/old_config_v1_1_33.rs | 49 ++++++++ .../src/client/base_client/storage/mod.rs | 2 +- common/socks5-client-core/src/config/mod.rs | 9 +- .../src/config/old_config_v1_1_30.rs | 16 +-- .../src/config/old_config_v1_1_33.rs | 107 ++++++++++++++++++ common/socks5-client-core/src/lib.rs | 4 +- 12 files changed, 243 insertions(+), 48 deletions(-) create mode 100644 clients/socks5/src/config/old_config_v1_1_33.rs create mode 100644 common/socks5-client-core/src/config/old_config_v1_1_33.rs diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index ce13a1b7cc..3bc5cd098a 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -118,7 +118,7 @@ impl InitResults { Self { client_address: res.init_results.address.to_string(), client_core: res.init_results, - socks5_listening_address: res.config.core.socks5.bind_adddress, + socks5_listening_address: res.config.core.socks5.bind_address, } } } diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index da3166fd7e..24a1112781 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -5,6 +5,7 @@ use crate::config::old_config_v1_1_13::OldConfigV1_1_13; use crate::config::old_config_v1_1_20::ConfigV1_1_20; use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; use crate::config::old_config_v1_1_30::ConfigV1_1_30; +use crate::config::old_config_v1_1_33::ConfigV1_1_33; use crate::config::{BaseClientConfig, Config, SocksClientPaths}; use crate::error::Socks5ClientError; use clap::CommandFactory; @@ -172,21 +173,29 @@ fn persist_gateway_details( storage_paths: &SocksClientPaths, details: GatewayEndpointConfig, ) -> Result<(), Socks5ClientError> { - let details_store = OnDiskGatewayDetails::new(&storage_paths.common_paths.gateway_details); - let keys_store = OnDiskKeys::new(storage_paths.common_paths.keys.clone()); - let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - Socks5ClientError::ClientCoreError(ClientCoreError::KeyStoreError { - source: Box::new(source), - }) - })?; - let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - details_store - .store_to_disk(&persisted_details) - .map_err(|source| { - Socks5ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - }) - }) + todo!() + // let details_store = OnDiskGatewayDetails::new(&storage_paths.common_paths.gateway_details); + // let keys_store = OnDiskKeys::new(storage_paths.common_paths.keys.clone()); + // let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { + // Socks5ClientError::ClientCoreError(ClientCoreError::KeyStoreError { + // source: Box::new(source), + // }) + // })?; + // let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; + // details_store + // .store_to_disk(&persisted_details) + // .map_err(|source| { + // Socks5ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { + // source: Box::new(source), + // }) + // }) +} + +fn migrate_gateway_details( + config: &Config, + old_details: Option, +) -> Result<(), Socks5ClientError> { + todo!() } fn try_upgrade_v1_1_13_config(id: &str) -> Result { @@ -204,9 +213,11 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result { let updated_step1: ConfigV1_1_20 = old_config.into(); let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); let (updated_step3, gateway_config) = updated_step2.upgrade()?; - persist_gateway_details(&updated_step3.storage_paths, gateway_config)?; + let updated_step4: ConfigV1_1_33 = updated_step3.into(); + let updated = updated_step4.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; - let updated: Config = updated_step3.into(); updated.save_to_default_location()?; Ok(true) } @@ -225,9 +236,11 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result { let updated_step1: ConfigV1_1_20_2 = old_config.into(); let (updated_step2, gateway_config) = updated_step1.upgrade()?; - persist_gateway_details(&updated_step2.storage_paths, gateway_config)?; + let updated_step3: ConfigV1_1_33 = updated_step2.into(); + let updated = updated_step3.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; - let updated: Config = updated_step2.into(); updated.save_to_default_location()?; Ok(true) } @@ -243,9 +256,11 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result { info!("It is going to get updated to the current specification."); let (updated_step1, gateway_config) = old_config.upgrade()?; - persist_gateway_details(&updated_step1.storage_paths, gateway_config)?; + let updated_step2: ConfigV1_1_33 = updated_step1.into(); + let updated = updated_step2.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; - let updated: Config = updated_step1.into(); updated.save_to_default_location()?; Ok(true) } @@ -260,7 +275,28 @@ fn try_upgrade_v1_1_30_config(id: &str) -> Result { info!("It seems the client is using <= v1.1.30 config template."); info!("It is going to get updated to the current specification."); - let updated: Config = old_config.into(); + let updated_step1: ConfigV1_1_33 = old_config.into(); + let updated = updated_step1.try_upgrade()?; + migrate_gateway_details(&updated, None)?; + + updated.save_to_default_location()?; + Ok(true) +} + +fn try_upgrade_v1_1_33_config(id: &str) -> Result { + // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) + let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.33 config template."); + info!("It is going to get updated to the current specification."); + + let updated = old_config.try_upgrade()?; + + migrate_gateway_details(&updated, None)?; + updated.save_to_default_location()?; Ok(true) } @@ -278,6 +314,9 @@ fn try_upgrade_config(id: &str) -> Result<(), Socks5ClientError> { if try_upgrade_v1_1_30_config(id)? { return Ok(()); } + if try_upgrade_v1_1_33_config(id)? { + return Ok(()); + } Ok(()) } diff --git a/clients/socks5/src/config/mod.rs b/clients/socks5/src/config/mod.rs index 9df903e64b..2a04d6d66d 100644 --- a/clients/socks5/src/config/mod.rs +++ b/clients/socks5/src/config/mod.rs @@ -24,6 +24,7 @@ pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; pub mod old_config_v1_1_20_2; pub mod old_config_v1_1_30; +pub mod old_config_v1_1_33; mod persistence; mod template; diff --git a/clients/socks5/src/config/old_config_v1_1_20.rs b/clients/socks5/src/config/old_config_v1_1_20.rs index 4acc4fccbd..fbad434c68 100644 --- a/clients/socks5/src/config/old_config_v1_1_20.rs +++ b/clients/socks5/src/config/old_config_v1_1_20.rs @@ -5,8 +5,8 @@ use crate::config::old_config_v1_1_20_2::{ ConfigV1_1_20_2, CoreConfigV1_1_20_2, SocksClientPathsV1_1_20_2, }; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; +use nym_client_core::config::disk_persistence::old_v1_1_33::ClientKeysPathsV1_1_33; use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20; use nym_client_core::config::old_config_v1_1_20_2::ClientV1_1_20_2; use nym_config::legacy_helpers::nym_config::MigrationNymConfig; @@ -50,7 +50,7 @@ impl From for ConfigV1_1_20_2 { }, storage_paths: SocksClientPathsV1_1_20_2 { common_paths: CommonClientPathsV1_1_20_2 { - keys: ClientKeysPaths { + keys: ClientKeysPathsV1_1_33 { private_identity_key_file: value.base.client.private_identity_key_file, public_identity_key_file: value.base.client.public_identity_key_file, private_encryption_key_file: value.base.client.private_encryption_key_file, diff --git a/clients/socks5/src/config/old_config_v1_1_20_2.rs b/clients/socks5/src/config/old_config_v1_1_20_2.rs index 4668e3ea9d..d396082e68 100644 --- a/clients/socks5/src/config/old_config_v1_1_20_2.rs +++ b/clients/socks5/src/config/old_config_v1_1_20_2.rs @@ -14,6 +14,7 @@ use serde::{Deserialize, Serialize}; use std::io; use std::path::Path; +use crate::config::old_config_v1_1_33::SocksClientPathsV1_1_33; pub use nym_socks5_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as CoreConfigV1_1_20_2; #[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] @@ -47,7 +48,7 @@ impl ConfigV1_1_20_2 { let gateway_details = self.core.base.client.gateway_endpoint.clone().into(); let config = ConfigV1_1_30 { core: self.core.into(), - storage_paths: SocksClientPaths { + storage_paths: SocksClientPathsV1_1_33 { common_paths: self.storage_paths.common_paths.upgrade_default()?, }, logging: self.logging, diff --git a/clients/socks5/src/config/old_config_v1_1_30.rs b/clients/socks5/src/config/old_config_v1_1_30.rs index cd7a5ab9e4..7395891dc3 100644 --- a/clients/socks5/src/config/old_config_v1_1_30.rs +++ b/clients/socks5/src/config/old_config_v1_1_30.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::config::persistence::SocksClientPaths; +use crate::config::old_config_v1_1_33::{ConfigV1_1_33, SocksClientPathsV1_1_33}; use crate::config::{default_config_filepath, Config}; use nym_bin_common::logging::LoggingSettings; use nym_config::read_config_from_toml_file; @@ -15,17 +15,14 @@ use std::path::Path; pub struct ConfigV1_1_30 { pub core: CoreConfigV1_1_30, - // I'm leaving a landmine here for when the paths actually do change the next time, - // but propagating the change right now (in ALL clients) would be such a hassle..., - // so sorry for the next person looking at it : ) - pub storage_paths: SocksClientPaths, + pub storage_paths: SocksClientPathsV1_1_33, pub logging: LoggingSettings, } -impl From for Config { +impl From for ConfigV1_1_33 { fn from(value: ConfigV1_1_30) -> Self { - Config { + ConfigV1_1_33 { core: value.core.into(), storage_paths: value.storage_paths, logging: LoggingSettings::default(), diff --git a/clients/socks5/src/config/old_config_v1_1_33.rs b/clients/socks5/src/config/old_config_v1_1_33.rs new file mode 100644 index 0000000000..fb14259bf4 --- /dev/null +++ b/clients/socks5/src/config/old_config_v1_1_33.rs @@ -0,0 +1,49 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::{default_config_filepath, Config, SocksClientPaths}; +use crate::error::Socks5ClientError; +use nym_bin_common::logging::LoggingSettings; +use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; +use nym_config::read_config_from_toml_file; +use nym_socks5_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as CoreConfigV1_1_33; +use serde::{Deserialize, Serialize}; +use std::io; +use std::path::Path; + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct SocksClientPathsV1_1_33 { + #[serde(flatten)] + pub common_paths: CommonClientPathsV1_1_33, +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1_1_33 { + pub core: CoreConfigV1_1_33, + + // \/ CHANGED + pub storage_paths: SocksClientPathsV1_1_33, + // /\ CHANGED + pub logging: LoggingSettings, +} + +impl ConfigV1_1_33 { + pub fn read_from_toml_file>(path: P) -> io::Result { + read_config_from_toml_file(path) + } + + pub fn read_from_default_path>(id: P) -> io::Result { + Self::read_from_toml_file(default_config_filepath(id)) + } + + pub fn try_upgrade(self) -> Result { + Ok(Config { + core: self.core.into(), + storage_paths: SocksClientPaths { + common_paths: self.storage_paths.common_paths.upgrade_default()?, + }, + logging: self.logging, + }) + } +} diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 86180b99eb..f31370a30d 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -10,7 +10,6 @@ use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore}; use crate::client::replies::reply_storage; use crate::client::replies::reply_storage::ReplyStorageBackend; -use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage; @@ -34,6 +33,7 @@ use crate::error::ClientCoreError; use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; // fs-gateways +pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; #[deprecated] pub mod gateway_details; diff --git a/common/socks5-client-core/src/config/mod.rs b/common/socks5-client-core/src/config/mod.rs index 8c5c722093..e4b3a8b623 100644 --- a/common/socks5-client-core/src/config/mod.rs +++ b/common/socks5-client-core/src/config/mod.rs @@ -12,6 +12,7 @@ use std::str::FromStr; pub mod old_config_v1_1_20_2; pub mod old_config_v1_1_30; +pub mod old_config_v1_1_33; pub use nym_service_providers_common::interface::ProviderInterfaceVersion; pub use nym_socks5_requests::Socks5ProtocolVersion; @@ -47,13 +48,13 @@ impl Config { #[must_use] pub fn with_port(mut self, port: u16) -> Self { - self.socks5.bind_adddress = SocketAddr::new(self.socks5.bind_adddress.ip(), port); + self.socks5.bind_address = SocketAddr::new(self.socks5.bind_address.ip(), port); self } #[must_use] pub fn with_ip(mut self, ip: IpAddr) -> Self { - self.socks5.bind_adddress = SocketAddr::new(ip, self.socks5.bind_adddress.port()); + self.socks5.bind_address = SocketAddr::new(ip, self.socks5.bind_address.port()); self } @@ -112,7 +113,7 @@ impl Config { pub struct Socks5 { /// The address on which the client will be listening for incoming requests /// (default: 127.0.0.1:1080) - pub bind_adddress: SocketAddr, + pub bind_address: SocketAddr, /// The mix address of the provider to which all requests are going to be sent. pub provider_mix_address: String, @@ -141,7 +142,7 @@ pub struct Socks5 { impl Socks5 { pub fn new>(provider_mix_address: S) -> Self { Socks5 { - bind_adddress: SocketAddr::new( + bind_address: SocketAddr::new( IpAddr::V4(Ipv4Addr::LOCALHOST), DEFAULT_SOCKS5_LISTENING_PORT, ), diff --git a/common/socks5-client-core/src/config/old_config_v1_1_30.rs b/common/socks5-client-core/src/config/old_config_v1_1_30.rs index 3f3f877797..13591f7d9a 100644 --- a/common/socks5-client-core/src/config/old_config_v1_1_30.rs +++ b/common/socks5-client-core/src/config/old_config_v1_1_30.rs @@ -1,7 +1,7 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use super::{Config, Socks5, Socks5Debug}; +use super::old_config_v1_1_33::{ConfigV1_1_33, Socks5DebugV1_1_33, Socks5V1_1_33}; pub use nym_client_core::config::old_config_v1_1_30::ConfigV1_1_30 as BaseClientConfigV1_1_30; use serde::{Deserialize, Serialize}; use std::fmt::Debug; @@ -23,9 +23,9 @@ pub struct ConfigV1_1_30 { pub socks5: Socks5V1_1_30, } -impl From for Config { +impl From for ConfigV1_1_33 { fn from(value: ConfigV1_1_30) -> Self { - Config { + ConfigV1_1_33 { base: value.base.into(), socks5: value.socks5.into(), } @@ -62,11 +62,11 @@ pub struct Socks5V1_1_30 { pub socks5_debug: Socks5DebugV1_1_30, } -impl From for Socks5 { +impl From for Socks5V1_1_33 { fn from(value: Socks5V1_1_30) -> Self { - Socks5 { + Socks5V1_1_33 { // in <= 1.1.30 the address was hardcoded to 127.0.0.1 - bind_adddress: SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), value.listening_port), + bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), value.listening_port), provider_mix_address: value.provider_mix_address, provider_interface_version: value.provider_interface_version, socks5_protocol_version: value.socks5_protocol_version, @@ -86,9 +86,9 @@ pub struct Socks5DebugV1_1_30 { pub per_request_surbs: u32, } -impl From for Socks5Debug { +impl From for Socks5DebugV1_1_33 { fn from(value: Socks5DebugV1_1_30) -> Self { - Socks5Debug { + Socks5DebugV1_1_33 { connection_start_surbs: value.connection_start_surbs, per_request_surbs: value.per_request_surbs, } diff --git a/common/socks5-client-core/src/config/old_config_v1_1_33.rs b/common/socks5-client-core/src/config/old_config_v1_1_33.rs new file mode 100644 index 0000000000..c306d42888 --- /dev/null +++ b/common/socks5-client-core/src/config/old_config_v1_1_33.rs @@ -0,0 +1,107 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use super::{Config, Socks5, Socks5Debug}; +pub use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseClientConfigV1_1_33; +use serde::{Deserialize, Serialize}; +use std::fmt::Debug; +use std::net::SocketAddr; + +// TODO: those should really be redefined here in case we change them... +use nym_service_providers_common::interface::ProviderInterfaceVersion; +use nym_socks5_requests::Socks5ProtocolVersion; + +const DEFAULT_CONNECTION_START_SURBS: u32 = 20; +const DEFAULT_PER_REQUEST_SURBS: u32 = 3; + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1_1_33 { + #[serde(flatten)] + pub base: BaseClientConfigV1_1_33, + + pub socks5: Socks5V1_1_33, +} + +impl From for Config { + fn from(value: ConfigV1_1_33) -> Self { + Config { + base: value.base.into(), + socks5: value.socks5.into(), + } + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Socks5V1_1_33 { + /// The address on which the client will be listening for incoming requests + /// (default: 127.0.0.1:1080) + // there was a typo in here, so accept the wrong name for the purposes of backwards compatibility + #[serde(alias = "bind_adddress")] + pub bind_address: SocketAddr, + + /// The mix address of the provider to which all requests are going to be sent. + pub provider_mix_address: String, + + /// The version of the 'service provider' this client is going to use in its communication with the + /// specified socks5 provider. + // if in doubt, use the legacy version as initially nobody will be using the updated binaries + #[serde(default)] + pub provider_interface_version: ProviderInterfaceVersion, + + #[serde(default)] + pub socks5_protocol_version: Socks5ProtocolVersion, + + /// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. + /// While this is going to hide its actual address information, it will make the actual communication + /// slower and consume nearly double the bandwidth as it will require sending reply SURBs. + /// + /// Note that some service providers might not support this. + #[serde(default)] + pub send_anonymously: bool, + + #[serde(default)] + pub socks5_debug: Socks5DebugV1_1_33, +} + +impl From for Socks5 { + fn from(value: Socks5V1_1_33) -> Self { + Socks5 { + bind_address: value.bind_address, + provider_mix_address: value.provider_mix_address, + provider_interface_version: value.provider_interface_version, + socks5_protocol_version: value.socks5_protocol_version, + send_anonymously: value.send_anonymously, + socks5_debug: value.socks5_debug.into(), + } + } +} + +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct Socks5DebugV1_1_33 { + /// Number of reply SURBs attached to each `Request::Connect` message. + pub connection_start_surbs: u32, + + /// Number of reply SURBs attached to each `Request::Send` message. + pub per_request_surbs: u32, +} + +impl From for Socks5Debug { + fn from(value: Socks5DebugV1_1_33) -> Self { + Socks5Debug { + connection_start_surbs: value.connection_start_surbs, + per_request_surbs: value.per_request_surbs, + } + } +} + +impl Default for Socks5DebugV1_1_33 { + fn default() -> Self { + Socks5DebugV1_1_33 { + connection_start_surbs: DEFAULT_CONNECTION_START_SURBS, + per_request_surbs: DEFAULT_PER_REQUEST_SURBS, + } + } +} diff --git a/common/socks5-client-core/src/lib.rs b/common/socks5-client-core/src/lib.rs index d9d036d1a8..41a7105dad 100644 --- a/common/socks5-client-core/src/lib.rs +++ b/common/socks5-client-core/src/lib.rs @@ -78,7 +78,7 @@ where NymClient { config, storage, - setup_method: GatewaySetup::MustLoad, + setup_method: GatewaySetup::MustLoad { gateway_id: None }, custom_mixnet, } } @@ -124,7 +124,7 @@ where let authenticator = Authenticator::new(auth_methods, allowed_users); let mut sphinx_socks = NymSocksServer::new( - socks5_config.bind_adddress, + socks5_config.bind_address, authenticator, socks5_config.get_provider_mix_address(), self_address,