From 079894806db3a0f20982bbeec5d885ba688c3a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 4 Mar 2025 13:36:27 +0000 Subject: [PATCH 1/2] remove legacy gateway authentication --- .../gateway-client/src/client/mod.rs | 100 ++++------ .../client-libs/gateway-client/src/error.rs | 2 +- .../src/authentication/encrypted_address.rs | 73 ------- .../src/authentication/mod.rs | 4 - common/gateway-requests/src/lib.rs | 15 +- .../src/types/text_request/mod.rs | 72 ++----- .../src/types/text_response.rs | 6 +- .../connection_handler/authenticated.rs | 7 +- .../websocket/connection_handler/fresh.rs | 185 +++--------------- .../websocket/connection_handler/mod.rs | 11 -- 10 files changed, 100 insertions(+), 375 deletions(-) delete mode 100644 common/gateway-requests/src/authentication/encrypted_address.rs delete mode 100644 common/gateway-requests/src/authentication/mod.rs diff --git a/common/client-libs/gateway-client/src/client/mod.rs b/common/client-libs/gateway-client/src/client/mod.rs index 88a55dd8505..4a3ebc60659 100644 --- a/common/client-libs/gateway-client/src/client/mod.rs +++ b/common/client-libs/gateway-client/src/client/mod.rs @@ -410,32 +410,28 @@ impl GatewayClient { } } - fn check_gateway_protocol( - &self, - gateway_protocol: Option, - ) -> Result<(), GatewayClientError> { + fn check_gateway_protocol(&self, gateway_protocol: u8) -> Result<(), GatewayClientError> { debug!("gateway protocol: {gateway_protocol:?}, ours: {CURRENT_PROTOCOL_VERSION}"); - // right now there are no failure cases here, but this might change in the future - match gateway_protocol { - None => { - warn!("the gateway we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); - // note: in +1.2.0 we will have to return a hard error here - Ok(()) - } - Some(v) if v > CURRENT_PROTOCOL_VERSION => { - let err = GatewayClientError::IncompatibleProtocol { - gateway: Some(v), - current: CURRENT_PROTOCOL_VERSION, - }; - error!("{err}"); - Err(err) - } + // client should reject any gateways that do not indicate they support auth v2 + if !gateway_protocol.supports_authenticate_v2() { + return Err(GatewayClientError::IncompatibleProtocol { + gateway: gateway_protocol, + current: CURRENT_PROTOCOL_VERSION, + }); + } - Some(_) => { - debug!("the gateway is using exactly the same (or older) protocol version as we are. We're good to continue!"); - Ok(()) - } + // we can't handle gateways with higher protocol than ours + if gateway_protocol <= CURRENT_PROTOCOL_VERSION { + debug!("the gateway is using exactly the same (or older) protocol version as we are. We're good to continue!"); + Ok(()) + } else { + let err = GatewayClientError::IncompatibleProtocol { + gateway: gateway_protocol, + current: CURRENT_PROTOCOL_VERSION, + }; + error!("{err}"); + Err(err) } } @@ -492,7 +488,7 @@ impl GatewayClient { } // populate the negotiated protocol for future uses - self.negotiated_protocol = gateway_protocol; + self.negotiated_protocol = Some(gateway_protocol); Ok(()) } @@ -577,7 +573,7 @@ impl GatewayClient { self.authenticated = status; self.bandwidth.update_and_maybe_log(bandwidth_remaining); - self.negotiated_protocol = protocol_version; + self.negotiated_protocol = Some(protocol_version); log::debug!("authenticated: {status}, bandwidth remaining: {bandwidth_remaining}"); self.task_client.send_status_msg(Box::new( @@ -590,27 +586,6 @@ impl GatewayClient { } } - async fn authenticate_v1(&mut self) -> Result<(), GatewayClientError> { - debug!("using v1 authentication"); - - let Some(shared_key) = self.shared_key.as_ref() else { - return Err(GatewayClientError::NoSharedKeyAvailable); - }; - - let self_address = self - .local_identity - .public_key() - .derive_destination_address(); - - let msg = ClientControlRequest::new_authenticate( - self_address, - shared_key, - self.cfg.bandwidth.require_tickets, - )?; - self.send_authenticate_request_and_handle_response(msg) - .await - } - async fn authenticate_v2(&mut self) -> Result<(), GatewayClientError> { debug!("using v2 authentication"); let Some(shared_key) = self.shared_key.as_ref() else { @@ -622,17 +597,13 @@ impl GatewayClient { .await } - async fn authenticate(&mut self, use_v2: bool) -> Result<(), GatewayClientError> { + async fn authenticate(&mut self) -> Result<(), GatewayClientError> { if !self.connection.is_established() { return Err(GatewayClientError::ConnectionNotEstablished); } debug!("authenticating with gateway"); - if use_v2 { - self.authenticate_v2().await - } else { - self.authenticate_v1().await - } + self.authenticate_v2().await } /// Helper method to either call register or authenticate based on self.shared_key value @@ -650,15 +621,9 @@ impl GatewayClient { } // 1. check gateway's protocol version - let gw_protocol = match self.get_gateway_protocol().await { - Ok(protocol) => Some(protocol), - Err(_) => { - // if we failed to send the request, it means the gateway is running the old binary, - // so it has reset our connection - we have to reconnect - self.establish_connection().await?; - None - } - }; + // if we failed to get this request resolved, it means the gateway is on an old version + // that definitely does not support auth v2, so we bail + let gw_protocol = self.get_gateway_protocol().await?; let supports_aes_gcm_siv = gw_protocol.supports_aes256_gcm_siv(); let supports_auth_v2 = gw_protocol.supports_authenticate_v2(); @@ -667,7 +632,13 @@ impl GatewayClient { warn!("this gateway is on an old version that doesn't support AES256-GCM-SIV"); } if !supports_auth_v2 { - warn!("this gateway is on an old version that doesn't support authentication v2") + warn!("this gateway is on an old version that doesn't support authentication v2"); + + // we can't continue + return Err(GatewayClientError::IncompatibleProtocol { + gateway: gw_protocol, + current: CURRENT_PROTOCOL_VERSION, + }); } if self.authenticated { @@ -683,7 +654,7 @@ impl GatewayClient { } if self.shared_key.is_some() { - self.authenticate(supports_auth_v2).await?; + self.authenticate().await?; if self.authenticated { // if we are authenticated it means we MUST have an associated shared_key @@ -1016,8 +987,7 @@ impl GatewayClient { } // if we're reconnecting, because we lost connection, we need to re-authenticate the connection - self.authenticate(self.negotiated_protocol.supports_authenticate_v2()) - .await?; + self.authenticate().await?; // this call is NON-blocking self.start_listening_for_mixnet_messages()?; diff --git a/common/client-libs/gateway-client/src/error.rs b/common/client-libs/gateway-client/src/error.rs index a9ce1755046..d062086b817 100644 --- a/common/client-libs/gateway-client/src/error.rs +++ b/common/client-libs/gateway-client/src/error.rs @@ -114,7 +114,7 @@ pub enum GatewayClientError { MixnetMsgSenderFailedToSend, #[error("Attempted to negotiate connection with gateway using incompatible protocol version. Ours is {current} and the gateway reports {gateway:?}")] - IncompatibleProtocol { gateway: Option, current: u8 }, + IncompatibleProtocol { gateway: u8, current: u8 }, #[error( "The packet router hasn't been set - are you sure you started up the client correctly?" diff --git a/common/gateway-requests/src/authentication/encrypted_address.rs b/common/gateway-requests/src/authentication/encrypted_address.rs deleted file mode 100644 index 772b8ca91b2..00000000000 --- a/common/gateway-requests/src/authentication/encrypted_address.rs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2020-2024 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::shared_key::{SharedGatewayKey, SharedKeyUsageError}; -use nym_sphinx::DestinationAddressBytes; -use thiserror::Error; - -/// Replacement for what used to be an `AuthToken`. -/// -/// Replacement for what used to be an `AuthToken`. We used to be generating an `AuthToken` based on -/// local secret and remote address in order to allow for authentication. Due to changes in registration -/// and the fact we are deriving a shared key, we are encrypting remote's address with the previously -/// derived shared key. If the value is as expected, then authentication is successful. -#[derive(Debug, PartialEq, Eq, Hash, Clone)] -// this is no longer constant size due to the differences in ciphertext between aes128ctr and aes256gcm-siv (inclusion of tag) -pub struct EncryptedAddressBytes(Vec); - -impl From> for EncryptedAddressBytes { - fn from(encrypted_address: Vec) -> Self { - EncryptedAddressBytes(encrypted_address) - } -} - -#[derive(Debug, Error)] -pub enum EncryptedAddressConversionError { - #[error("Failed to decode the encrypted address - {0}")] - DecodeError(#[from] bs58::decode::Error), -} - -impl EncryptedAddressBytes { - pub fn new( - address: &DestinationAddressBytes, - key: &SharedGatewayKey, - nonce: &[u8], - ) -> Result { - let ciphertext = key.encrypt_naive(address.as_bytes_ref(), Some(nonce))?; - - Ok(EncryptedAddressBytes(ciphertext)) - } - - pub fn verify( - &self, - address: &DestinationAddressBytes, - key: &SharedGatewayKey, - nonce: &[u8], - ) -> bool { - let Ok(reconstructed) = Self::new(address, key, nonce) else { - return false; - }; - self == &reconstructed - } - - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } - - pub fn try_from_base58_string>( - val: S, - ) -> Result { - let decoded = bs58::decode(val.into()).into_vec()?; - Ok(EncryptedAddressBytes(decoded)) - } - - pub fn to_base58_string(self) -> String { - bs58::encode(self.0).into_string() - } -} - -impl From for String { - fn from(val: EncryptedAddressBytes) -> Self { - val.to_base58_string() - } -} diff --git a/common/gateway-requests/src/authentication/mod.rs b/common/gateway-requests/src/authentication/mod.rs deleted file mode 100644 index 3e2a4c4d5a7..00000000000 --- a/common/gateway-requests/src/authentication/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2020 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -pub mod encrypted_address; diff --git a/common/gateway-requests/src/lib.rs b/common/gateway-requests/src/lib.rs index 0d300bc4a42..e45d8ca02b8 100644 --- a/common/gateway-requests/src/lib.rs +++ b/common/gateway-requests/src/lib.rs @@ -7,7 +7,6 @@ use nym_sphinx::params::GatewayIntegrityHmacAlgorithm; pub use types::*; -pub mod authentication; pub mod models; pub mod registration; pub mod shared_key; @@ -45,11 +44,21 @@ pub trait GatewayProtocolVersionExt { impl GatewayProtocolVersionExt for Option { fn supports_aes256_gcm_siv(&self) -> bool { let Some(protocol) = *self else { return false }; - protocol >= AES_GCM_SIV_PROTOCOL_VERSION + protocol.supports_aes256_gcm_siv() } fn supports_authenticate_v2(&self) -> bool { let Some(protocol) = *self else { return false }; - protocol >= AUTHENTICATE_V2_PROTOCOL_VERSION + protocol.supports_authenticate_v2() + } +} + +impl GatewayProtocolVersionExt for u8 { + fn supports_aes256_gcm_siv(&self) -> bool { + *self >= AES_GCM_SIV_PROTOCOL_VERSION + } + + fn supports_authenticate_v2(&self) -> bool { + *self >= AUTHENTICATE_V2_PROTOCOL_VERSION } } diff --git a/common/gateway-requests/src/types/text_request/mod.rs b/common/gateway-requests/src/types/text_request/mod.rs index 7182dd834e2..06fa992086b 100644 --- a/common/gateway-requests/src/types/text_request/mod.rs +++ b/common/gateway-requests/src/types/text_request/mod.rs @@ -4,13 +4,10 @@ use crate::models::CredentialSpendingRequest; use crate::text_request::authenticate::AuthenticateRequest; use crate::{ - GatewayRequestsError, SharedGatewayKey, SymmetricKey, AES_GCM_SIV_PROTOCOL_VERSION, - AUTHENTICATE_V2_PROTOCOL_VERSION, CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION, - INITIAL_PROTOCOL_VERSION, + GatewayRequestsError, SharedGatewayKey, SymmetricKey, AUTHENTICATE_V2_PROTOCOL_VERSION, }; use nym_credentials_interface::CredentialSpendingData; use nym_crypto::asymmetric::ed25519; -use nym_sphinx::DestinationAddressBytes; use serde::{Deserialize, Serialize}; use std::str::FromStr; use tungstenite::Message; @@ -64,32 +61,14 @@ impl ClientRequest { #[serde(tag = "type", rename_all = "camelCase")] #[non_exhaustive] pub enum ClientControlRequest { - // TODO: should this also contain a MAC considering that at this point we already - // have the shared key derived? - Authenticate { - #[serde(default)] - protocol_version: Option, - address: String, - enc_address: String, - iv: String, - }, - AuthenticateV2(Box), #[serde(alias = "handshakePayload")] RegisterHandshakeInitRequest { - #[serde(default)] - protocol_version: Option, + protocol_version: u8, data: Vec, }, - BandwidthCredential { - enc_credential: Vec, - iv: Vec, - }, - BandwidthCredentialV2 { - enc_credential: Vec, - iv: Vec, - }, + EcashCredential { enc_credential: Vec, iv: Vec, @@ -101,36 +80,27 @@ pub enum ClientControlRequest { }, SupportedProtocol {}, // if you're adding new variants here, consider putting them inside `ClientRequest` instead -} - -impl ClientControlRequest { - pub fn new_authenticate( - address: DestinationAddressBytes, - shared_key: &SharedGatewayKey, - uses_credentials: bool, - ) -> Result { - // if we're encrypting with non-legacy key, the remote must support AES256-GCM-SIV - let protocol_version = if !shared_key.is_legacy() { - Some(AES_GCM_SIV_PROTOCOL_VERSION) - } else if uses_credentials { - Some(CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION) - } else { - // if we're not going to be using credentials, advertise lower protocol version to allow connection - // to wider range of gateways - Some(INITIAL_PROTOCOL_VERSION) - }; - let nonce = shared_key.random_nonce_or_iv(); - let ciphertext = shared_key.encrypt_naive(address.as_bytes_ref(), Some(&nonce))?; + // NO LONGER SUPPORTED: + Authenticate { + #[serde(default)] + protocol_version: Option, + address: String, + enc_address: String, + iv: String, + }, - Ok(ClientControlRequest::Authenticate { - protocol_version, - address: address.as_base58_string(), - enc_address: bs58::encode(&ciphertext).into_string(), - iv: bs58::encode(&nonce).into_string(), - }) - } + BandwidthCredential { + enc_credential: Vec, + iv: Vec, + }, + BandwidthCredentialV2 { + enc_credential: Vec, + iv: Vec, + }, +} +impl ClientControlRequest { pub fn new_authenticate_v2( shared_key: &SharedGatewayKey, identity_keys: &ed25519::KeyPair, diff --git a/common/gateway-requests/src/types/text_response.rs b/common/gateway-requests/src/types/text_response.rs index 5c6ce668b5c..8f1de487651 100644 --- a/common/gateway-requests/src/types/text_response.rs +++ b/common/gateway-requests/src/types/text_response.rs @@ -47,14 +47,12 @@ impl SensitiveServerResponse { #[non_exhaustive] pub enum ServerResponse { Authenticate { - #[serde(default)] - protocol_version: Option, + protocol_version: u8, status: bool, bandwidth_remaining: i64, }, Register { - #[serde(default)] - protocol_version: Option, + protocol_version: u8, status: bool, }, EncryptedResponse { diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 16c5a42faad..d0588b716d2 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -428,6 +428,11 @@ impl AuthenticatedHandler { ClientControlRequest::EcashCredential { enc_credential, iv } => { self.handle_ecash_bandwidth(enc_credential, iv).await } + ClientControlRequest::Authenticate { .. } => { + Err(RequestHandlingError::IllegalRequest { + additional_context: "authentication v1 is no longer supported".into(), + }) + } ClientControlRequest::BandwidthCredential { .. } => { Err(RequestHandlingError::IllegalRequest { additional_context: "coconut credential are not longer supported".into(), @@ -446,7 +451,7 @@ impl AuthenticatedHandler { ClientControlRequest::SupportedProtocol { .. } => { Ok(self.inner.handle_supported_protocol_request()) } - other @ ClientControlRequest::Authenticate { .. } => { + other @ ClientControlRequest::AuthenticateV2 { .. } => { Err(RequestHandlingError::IllegalRequest { additional_context: format!( "received illegal message of type {} in an authenticated client", diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 4c0eb81f357..e960bfdcfaa 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -17,14 +17,11 @@ use nym_credentials_interface::AvailableBandwidth; use nym_crypto::aes::cipher::crypto_common::rand_core::RngCore; use nym_crypto::asymmetric::ed25519; use nym_gateway_requests::authenticate::AuthenticateRequest; -use nym_gateway_requests::authentication::encrypted_address::{ - EncryptedAddressBytes, EncryptedAddressConversionError, -}; use nym_gateway_requests::{ registration::handshake::{error::HandshakeError, gateway_handshake}, types::{ClientControlRequest, ServerResponse}, - AuthenticationFailure, BinaryResponse, SharedGatewayKey, CURRENT_PROTOCOL_VERSION, - INITIAL_PROTOCOL_VERSION, + AuthenticationFailure, BinaryResponse, GatewayProtocolVersionExt, SharedGatewayKey, + CURRENT_PROTOCOL_VERSION, }; use nym_gateway_storage::error::GatewayStorageError; use nym_node_metrics::events::MetricsEvent; @@ -45,6 +42,9 @@ pub(crate) enum InitialAuthenticationError { #[error(transparent)] AuthenticationFailure(#[from] AuthenticationFailure), + #[error("the legacy authentication method is no longer supported. please update your client")] + UnsupportedLegacyAuthentication, + #[error("attempted to overwrite client session with a stale authentication")] StaleSessionOverwrite, @@ -63,19 +63,9 @@ pub(crate) enum InitialAuthenticationError { #[error("Failed to perform registration handshake: {0}")] HandshakeError(#[from] HandshakeError), - #[error("Provided client address is malformed: {0}")] - // sphinx error is not used here directly as its messaging might be confusing to people - MalformedClientAddress(String), - - #[error("Provided encrypted client address is malformed: {0}")] - MalformedEncryptedAddress(#[from] EncryptedAddressConversionError), - #[error("There is already an open connection to this client")] DuplicateConnection, - #[error("provided authentication IV is malformed: {0}")] - MalformedIV(bs58::decode::Error), - #[error("Only 'Register' or 'Authenticate' requests are allowed")] InvalidRequest, @@ -86,7 +76,7 @@ pub(crate) enum InitialAuthenticationError { ConnectionError(#[from] WsError), #[error("Attempted to negotiate connection with client using incompatible protocol version. Ours is {current} and the client reports {client:?}")] - IncompatibleProtocol { client: Option, current: u8 }, + IncompatibleProtocol { client: u8, current: u8 }, #[error("failed to send authentication response: {source}")] ResponseSendFailure { @@ -377,58 +367,25 @@ impl FreshHandler { Ok(Some(keys)) } - /// Checks whether the stored shared keys match the received data, i.e. whether the upon decryption - /// the provided encrypted address matches the expected unencrypted address. - /// - /// Returns the retrieved shared keys if the check was successful. - /// - /// # Arguments - /// - /// * `client_address`: address of the client. - /// * `encrypted_address`: encrypted address of the client, presumably encrypted using the shared keys. - /// * `iv`: nonce/iv created for this particular encryption. - async fn auth_v1_verify_stored_shared_key( - &self, - client_address: DestinationAddressBytes, - encrypted_address: EncryptedAddressBytes, - nonce: &[u8], - ) -> Result, InitialAuthenticationError> { - let Some(keys) = self.retrieve_shared_key(client_address).await? else { - return Ok(None); - }; - - // LEGACY ISSUE: we're not verifying HMAC key - if encrypted_address.verify(&client_address, &keys.key, nonce) { - Ok(Some(keys)) - } else { - Ok(None) - } - } - fn negotiate_client_protocol( &self, - client_protocol: Option, + client_protocol: u8, ) -> Result { - debug!("client protocol: {client_protocol:?}, ours: {CURRENT_PROTOCOL_VERSION}"); - let Some(client_protocol_version) = client_protocol else { - warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); - // note: in +1.2.0 we will have to return a hard error here - return Ok(INITIAL_PROTOCOL_VERSION); - }; + debug!("client protocol: {client_protocol}, ours: {CURRENT_PROTOCOL_VERSION}"); - // a v2 gateway will understand v1 requests, but v1 client will not understand v2 responses - if client_protocol_version == 1 { - return Ok(1); - } - - // a v3 gateway will understand v2 requests (legacy keys) - if client_protocol_version == 2 { - return Ok(2); + // gateway will reject any requests from clients that do not support auth v2 + if !client_protocol.supports_authenticate_v2() { + let err = InitialAuthenticationError::IncompatibleProtocol { + client: client_protocol, + current: CURRENT_PROTOCOL_VERSION, + }; + error!("{err}"); + return Err(err); } // we can't handle clients with higher protocol than ours // (perhaps we could try to negotiate downgrade on our end? sounds like a nice future improvement) - if client_protocol_version <= CURRENT_PROTOCOL_VERSION { + if client_protocol <= CURRENT_PROTOCOL_VERSION { debug!("the client is using exactly the same (or older) protocol version as we are. We're good to continue!"); Ok(CURRENT_PROTOCOL_VERSION) } else { @@ -528,96 +485,6 @@ impl FreshHandler { Ok(available_bandwidth) } - /// Tries to handle the received authentication request by checking correctness of the received data. - /// - /// # Arguments - /// - /// * `client_address`: address of the client wishing to authenticate. - /// * `encrypted_address`: ciphertext of the address of the client wishing to authenticate. - /// * `iv`: fresh IV received with the request. - #[instrument(skip_all - fields( - address = %address, - ) - )] - async fn handle_legacy_authenticate( - &mut self, - client_protocol_version: Option, - address: String, - enc_address: String, - raw_nonce: String, - ) -> Result - where - S: AsyncRead + AsyncWrite + Unpin, - { - debug!("handling client authentication (v1)"); - - let negotiated_protocol = self.negotiate_client_protocol(client_protocol_version)?; - // populate the negotiated protocol for future uses - self.negotiated_protocol = Some(negotiated_protocol); - - let address = DestinationAddressBytes::try_from_base58_string(address) - .map_err(|err| InitialAuthenticationError::MalformedClientAddress(err.to_string()))?; - let encrypted_address = EncryptedAddressBytes::try_from_base58_string(enc_address)?; - let nonce = bs58::decode(&raw_nonce) - .into_vec() - .map_err(InitialAuthenticationError::MalformedIV)?; - - // validate the shared key - let Some(shared_keys) = self - .auth_v1_verify_stored_shared_key(address, encrypted_address, &nonce) - .await? - else { - // it feels weird to be returning an 'Ok' here, but I didn't want to change the existing behaviour - return Ok(InitialAuthResult::new_failed(Some(negotiated_protocol))); - }; - - // in v1 we don't have explicit data so we have to use current timestamp - // (which does nothing but just allows us to use the same codepath) - let session_request_start = OffsetDateTime::now_utc(); - - // Check for duplicate clients - if let Some(remote_client_data) = self - .shared_state - .active_clients_store - .get_remote_client(address) - { - warn!("Detected duplicate connection for client: {address}"); - self.handle_duplicate_client(address, remote_client_data, session_request_start) - .await?; - } - - let client_id = shared_keys.client_id; - - // if applicable, push stored messages - self.push_stored_messages_to_client(address, &shared_keys.key) - .await?; - - // check the bandwidth - let available_bandwidth = self.get_registered_available_bandwidth(client_id).await?; - - let bandwidth_remaining = if available_bandwidth.expired() { - self.shared_state.storage.reset_bandwidth(client_id).await?; - 0 - } else { - available_bandwidth.bytes - }; - - Ok(InitialAuthResult::new( - Some(ClientDetails::new( - client_id, - address, - shared_keys.key, - session_request_start, - )), - ServerResponse::Authenticate { - protocol_version: Some(negotiated_protocol), - status: true, - bandwidth_remaining, - }, - )) - } - async fn handle_authenticate_v2( &mut self, request: Box, @@ -628,7 +495,7 @@ impl FreshHandler { debug!("handling client authentication (v2)"); let negotiated_protocol = - self.negotiate_client_protocol(Some(request.content.protocol_version))?; + self.negotiate_client_protocol(request.content.protocol_version)?; // populate the negotiated protocol for future uses self.negotiated_protocol = Some(negotiated_protocol); @@ -697,7 +564,7 @@ impl FreshHandler { session_request_start, )), ServerResponse::Authenticate { - protocol_version: Some(negotiated_protocol), + protocol_version: negotiated_protocol, status: true, bandwidth_remaining, }, @@ -759,7 +626,7 @@ impl FreshHandler { /// * `init_data`: init payload of the registration handshake. async fn handle_register( &mut self, - client_protocol_version: Option, + client_protocol_version: u8, init_data: Vec, ) -> Result where @@ -798,7 +665,7 @@ impl FreshHandler { Ok(InitialAuthResult::new( Some(client_details), ServerResponse::Register { - protocol_version: Some(negotiated_protocol), + protocol_version: negotiated_protocol, status: true, }, )) @@ -833,14 +700,8 @@ impl FreshHandler { { // we can handle stateless client requests without prior authentication, like `ClientControlRequest::SupportedProtocol` let auth_result = match request { - ClientControlRequest::Authenticate { - protocol_version, - address, - enc_address, - iv, - } => { - self.handle_legacy_authenticate(protocol_version, address, enc_address, iv) - .await + ClientControlRequest::Authenticate { .. } => { + return Err(InitialAuthenticationError::UnsupportedLegacyAuthentication) } ClientControlRequest::AuthenticateV2(req) => self.handle_authenticate_v2(req).await, ClientControlRequest::RegisterHandshakeInitRequest { diff --git a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs index 38026fa8be9..6d079827bba 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs @@ -78,17 +78,6 @@ impl InitialAuthResult { server_response, } } - - fn new_failed(protocol_version: Option) -> Self { - InitialAuthResult { - client_details: None, - server_response: ServerResponse::Authenticate { - protocol_version, - status: false, - bandwidth_remaining: 0, - }, - } - } } // imo there's no point in including the peer address in anything higher than debug From 1c005c64099dea7be5cc5f1564495a6154969f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 4 Mar 2025 13:55:49 +0000 Subject: [PATCH 2/2] fixed test code --- .../types/registration_handshake_wrapper.rs | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/common/gateway-requests/src/types/registration_handshake_wrapper.rs b/common/gateway-requests/src/types/registration_handshake_wrapper.rs index 0dc6daa567e..6d64115cb15 100644 --- a/common/gateway-requests/src/types/registration_handshake_wrapper.rs +++ b/common/gateway-requests/src/types/registration_handshake_wrapper.rs @@ -76,25 +76,7 @@ mod tests { protocol_version, data, } => { - assert_eq!(protocol_version, Some(42)); - assert_eq!(data, handshake_data) - } - _ => unreachable!("this branch shouldn't have been reached!"), - } - - let handshake_payload_without_protocol = RegistrationHandshake::HandshakePayload { - protocol_version: None, - data: handshake_data.clone(), - }; - let serialized = serde_json::to_string(&handshake_payload_without_protocol).unwrap(); - let deserialized = ClientControlRequest::try_from(serialized).unwrap(); - - match deserialized { - ClientControlRequest::RegisterHandshakeInitRequest { - protocol_version, - data, - } => { - assert!(protocol_version.is_none()); + assert_eq!(protocol_version, 42); assert_eq!(data, handshake_data) } _ => unreachable!("this branch shouldn't have been reached!"),