From d8e21b0bd46fe3224e6a02793efb7276e0fda8eb Mon Sep 17 00:00:00 2001 From: Sandeep Bansal Date: Fri, 16 Aug 2024 10:09:02 -0700 Subject: [PATCH] fix!: remove dependency on ClientConnector in CredsspSequence (#519) --- crates/ironrdp-async/src/connector.rs | 19 ++++++++++--- crates/ironrdp-blocking/src/connector.rs | 19 ++++++++++--- crates/ironrdp-connector/src/credssp.rs | 34 +++++++++--------------- ffi/src/credssp/mod.rs | 29 +++++++++++++------- 4 files changed, 62 insertions(+), 39 deletions(-) diff --git a/crates/ironrdp-async/src/connector.rs b/crates/ironrdp-async/src/connector.rs index e2725ef0..1a2d9550 100644 --- a/crates/ironrdp-async/src/connector.rs +++ b/crates/ironrdp-async/src/connector.rs @@ -2,8 +2,8 @@ use ironrdp_connector::credssp::{CredsspProcessGenerator, CredsspSequence, Kerbe use ironrdp_connector::sspi::credssp::ClientState; use ironrdp_connector::sspi::generator::GeneratorState; use ironrdp_connector::{ - custom_err, ClientConnector, ClientConnectorState, ConnectionResult, ConnectorError, ConnectorResult, ServerName, - State as _, + custom_err, general_err, ClientConnector, ClientConnectorState, ConnectionResult, ConnectorError, ConnectorResult, + ServerName, State as _, }; use ironrdp_pdu::write_buf::WriteBuf; @@ -120,8 +120,19 @@ where { assert!(connector.should_perform_credssp()); - let (mut sequence, mut ts_request) = - CredsspSequence::init(connector, server_name, server_public_key, kerberos_config)?; + let selected_protocol = match connector.state { + ClientConnectorState::Credssp { selected_protocol, .. } => selected_protocol, + _ => return Err(general_err!("invalid connector state for CredSSP sequence")), + }; + + let (mut sequence, mut ts_request) = CredsspSequence::init( + connector.config.credentials.clone(), + connector.config.domain.as_deref(), + selected_protocol, + server_name, + server_public_key, + kerberos_config, + )?; loop { let client_state = { diff --git a/crates/ironrdp-blocking/src/connector.rs b/crates/ironrdp-blocking/src/connector.rs index e840cd03..b5951513 100644 --- a/crates/ironrdp-blocking/src/connector.rs +++ b/crates/ironrdp-blocking/src/connector.rs @@ -5,8 +5,8 @@ use ironrdp_connector::sspi::credssp::ClientState; use ironrdp_connector::sspi::generator::GeneratorState; use ironrdp_connector::sspi::network_client::NetworkClient; use ironrdp_connector::{ - ClientConnector, ClientConnectorState, ConnectionResult, ConnectorError, ConnectorResult, Sequence as _, - ServerName, State as _, + general_err, ClientConnector, ClientConnectorState, ConnectionResult, ConnectorError, ConnectorResult, + Sequence as _, ServerName, State as _, }; use ironrdp_pdu::write_buf::WriteBuf; @@ -125,8 +125,19 @@ where { assert!(connector.should_perform_credssp()); - let (mut sequence, mut ts_request) = - CredsspSequence::init(connector, server_name, server_public_key, kerberos_config)?; + let selected_protocol = match connector.state { + ClientConnectorState::Credssp { selected_protocol, .. } => selected_protocol, + _ => return Err(general_err!("invalid connector state for CredSSP sequence")), + }; + + let (mut sequence, mut ts_request) = CredsspSequence::init( + connector.config.credentials.clone(), + connector.config.domain.as_deref(), + selected_protocol, + server_name, + server_public_key, + kerberos_config, + )?; loop { let client_state = { diff --git a/crates/ironrdp-connector/src/credssp.rs b/crates/ironrdp-connector/src/credssp.rs index 2e40a6ac..cba1d554 100644 --- a/crates/ironrdp-connector/src/credssp.rs +++ b/crates/ironrdp-connector/src/credssp.rs @@ -7,10 +7,7 @@ use sspi::generator::{Generator, NetworkRequest}; use sspi::negotiate::ProtocolConfig; use sspi::Username; -use crate::{ - ClientConnector, ClientConnectorState, ConnectorError, ConnectorErrorKind, ConnectorResult, Credentials, - ServerName, Written, -}; +use crate::{ConnectorError, ConnectorErrorKind, ConnectorResult, Credentials, ServerName, Written}; #[derive(Debug, Clone, Default)] pub struct KerberosConfig { @@ -93,16 +90,16 @@ impl CredsspSequence { /// `server_name` must be the actual target server hostname (as opposed to the proxy) pub fn init( - connector: &ClientConnector, + credentials: Credentials, + domain: Option<&str>, + protocol: nego::SecurityProtocol, server_name: ServerName, server_public_key: Vec, kerberos_config: Option, ) -> ConnectorResult<(Self, credssp::TsRequest)> { - let config = &connector.config; - let credentials: sspi::Credentials = match &config.credentials { + let credentials: sspi::Credentials = match &credentials { Credentials::UsernamePassword { username, password } => { - let username = Username::new(username, config.domain.as_deref()) - .map_err(|e| custom_err!("invalid username", e))?; + let username = Username::new(username, domain).map_err(|e| custom_err!("invalid username", e))?; sspi::AuthIdentity { username, @@ -162,20 +159,15 @@ impl CredsspSequence { ) .map_err(|e| ConnectorError::new("CredSSP", ConnectorErrorKind::Credssp(e)))?; - match connector.state { - ClientConnectorState::Credssp { selected_protocol } => { - let sequence = Self { - client, - state: CredsspState::Ongoing, - selected_protocol, - }; + let sequence = Self { + client, + state: CredsspState::Ongoing, + selected_protocol: protocol, + }; - let initial_request = credssp::TsRequest::default(); + let initial_request = credssp::TsRequest::default(); - Ok((sequence, initial_request)) - } - _ => Err(general_err!("invalid connector state for CredSSP sequence")), - } + Ok((sequence, initial_request)) } /// Returns Some(ts_request) when a TS request is received from server, diff --git a/ffi/src/credssp/mod.rs b/ffi/src/credssp/mod.rs index 42762e19..da22739f 100644 --- a/ffi/src/credssp/mod.rs +++ b/ffi/src/credssp/mod.rs @@ -4,6 +4,8 @@ pub mod network; #[diplomat::bridge] pub mod ffi { + use ironrdp::connector::ClientConnectorState; + use crate::{ connector::{ ffi::{ClientConnector, PduHint}, @@ -61,17 +63,24 @@ pub mod ffi { return Err(ValueConsumedError::for_item("connector").into()); }; - let (credssp_sequence, ts_request) = ironrdp::connector::credssp::CredsspSequence::init( - connector, - server_name.into(), - server_public_key.to_owned(), - kerbero_configs.map(|config| config.0.clone()), - )?; + match connector.state { + ClientConnectorState::Credssp { selected_protocol } => { + let (credssp_sequence, ts_request) = ironrdp::connector::credssp::CredsspSequence::init( + connector.config.credentials.clone(), + connector.config.domain.as_deref(), + selected_protocol, + server_name.into(), + server_public_key.to_owned(), + kerbero_configs.map(|config| config.0.clone()), + )?; - Ok(Box::new(CredsspSequenceInitResult { - credssp_sequence: Some(Box::new(CredsspSequence(credssp_sequence))), - ts_request: Some(Box::new(TsRequest(ts_request))), - })) + Ok(Box::new(CredsspSequenceInitResult { + credssp_sequence: Some(Box::new(CredsspSequence(credssp_sequence))), + ts_request: Some(Box::new(TsRequest(ts_request))), + })) + } + _ => Err(ironrdp::connector::general_err!("invalid connector state for CredSSP sequence").into()), + } } pub fn decode_server_message(&mut self, pdu: &[u8]) -> Result>, Box> {