mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
feat!: update sspi dependency (#839)
Newer version of sspi adds support for server-side Kerberos. This is relevant for the ironrdp-acceptor crate.
This commit is contained in:
Generated
+2
-2
@@ -5051,9 +5051,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sspi"
|
||||
version = "0.15.14"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "214ee905dcdd4b7ab11404b616e58dc6944d80fe8592fbdc13abc87d7e2bff0a"
|
||||
checksum = "6ebd88036b841e6e50370c1d2b7711ae1fc04d4269abda80427cda4b8230a53d"
|
||||
dependencies = [
|
||||
"async-dnssd",
|
||||
"async-recursion",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use ironrdp_connector::credssp::KerberosConfig;
|
||||
use ironrdp_async::AsyncNetworkClient;
|
||||
use ironrdp_connector::sspi::credssp::{
|
||||
ClientMode, CredSspServer, CredentialsProxy, ServerError, ServerState, TsRequest,
|
||||
CredSspServer, CredentialsProxy, ServerError, ServerMode, ServerState, TsRequest,
|
||||
};
|
||||
use ironrdp_connector::sspi::generator::{Generator, GeneratorState};
|
||||
use ironrdp_connector::sspi::negotiate::ProtocolConfig;
|
||||
use ironrdp_connector::sspi::{self, AuthIdentity, Username};
|
||||
use ironrdp_connector::sspi::{self, AuthIdentity, KerberosServerConfig, NegotiateConfig, NetworkRequest, Username};
|
||||
use ironrdp_connector::{
|
||||
custom_err, general_err, ConnectorError, ConnectorErrorKind, ConnectorResult, ServerName, Written,
|
||||
};
|
||||
@@ -32,6 +33,9 @@ impl PduHint for CredsspTsRequestHint {
|
||||
}
|
||||
}
|
||||
|
||||
pub type CredsspProcessGenerator<'a> =
|
||||
Generator<'a, NetworkRequest, sspi::Result<Vec<u8>>, Result<ServerState, ServerError>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CredsspSequence<'a> {
|
||||
server: CredSspServer<CredentialsProxyImpl<'a>>,
|
||||
@@ -64,6 +68,26 @@ impl CredentialsProxy for CredentialsProxyImpl<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn resolve_generator(
|
||||
generator: &mut CredsspProcessGenerator<'_>,
|
||||
network_client: &mut dyn AsyncNetworkClient,
|
||||
) -> Result<ServerState, ServerError> {
|
||||
let mut state = generator.start();
|
||||
|
||||
loop {
|
||||
match state {
|
||||
GeneratorState::Suspended(request) => {
|
||||
let response = network_client.send(&request).await.map_err(|err| ServerError {
|
||||
ts_request: None,
|
||||
error: sspi::Error::new(sspi::ErrorKind::InternalError, err),
|
||||
})?;
|
||||
state = generator.resume(Ok(response));
|
||||
}
|
||||
GeneratorState::Completed(client_state) => break client_state,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> CredsspSequence<'a> {
|
||||
pub fn next_pdu_hint(&self) -> ConnectorResult<Option<&dyn PduHint>> {
|
||||
match &self.state {
|
||||
@@ -77,22 +101,21 @@ impl<'a> CredsspSequence<'a> {
|
||||
creds: &'a AuthIdentity,
|
||||
client_computer_name: ServerName,
|
||||
public_key: Vec<u8>,
|
||||
kerberos_config: Option<KerberosConfig>,
|
||||
krb_config: Option<KerberosServerConfig>,
|
||||
) -> ConnectorResult<Self> {
|
||||
let client_computer_name = client_computer_name.into_inner();
|
||||
let credentials = CredentialsProxyImpl::new(creds);
|
||||
let credssp_config: Box<dyn ProtocolConfig>;
|
||||
if let Some(ref krb_config) = kerberos_config {
|
||||
credssp_config = Box::new(Into::<sspi::KerberosConfig>::into(krb_config.clone()));
|
||||
} else {
|
||||
credssp_config = Box::<sspi::ntlm::NtlmConfig>::default();
|
||||
}
|
||||
|
||||
debug!(?credssp_config);
|
||||
let credssp_config: Box<dyn ProtocolConfig> = if let Some(krb_config) = krb_config {
|
||||
Box::new(krb_config)
|
||||
} else {
|
||||
Box::<sspi::ntlm::NtlmConfig>::default()
|
||||
};
|
||||
|
||||
let server = CredSspServer::new(
|
||||
public_key,
|
||||
credentials,
|
||||
ClientMode::Negotiate(sspi::NegotiateConfig {
|
||||
ServerMode::Negotiate(NegotiateConfig {
|
||||
protocol_config: credssp_config,
|
||||
package_list: None,
|
||||
client_computer_name,
|
||||
@@ -122,19 +145,22 @@ impl<'a> CredsspSequence<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_ts_request(&mut self, request: TsRequest) -> Result<ServerState, Box<ServerError>> {
|
||||
Ok(self.server.process(request)?)
|
||||
pub fn process_ts_request(&mut self, request: TsRequest) -> CredsspProcessGenerator<'_> {
|
||||
self.server.process(request)
|
||||
}
|
||||
|
||||
pub fn handle_process_result(
|
||||
&mut self,
|
||||
result: Result<ServerState, Box<ServerError>>,
|
||||
result: Result<ServerState, ServerError>,
|
||||
output: &mut WriteBuf,
|
||||
) -> ConnectorResult<Written> {
|
||||
let (ts_request, next_state) = match result {
|
||||
Ok(ServerState::ReplyNeeded(ts_request)) => (Some(ts_request), CredsspState::Ongoing),
|
||||
Ok(ServerState::Finished(_id)) => (None, CredsspState::Finished),
|
||||
Err(err) => (Some(err.ts_request), CredsspState::ServerError(err.error)),
|
||||
Err(err) => (
|
||||
err.ts_request.map(|ts_request| *ts_request),
|
||||
CredsspState::ServerError(err.error),
|
||||
),
|
||||
};
|
||||
|
||||
self.state = next_state;
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
||||
use ironrdp_async::{single_sequence_step, Framed, FramedRead, FramedWrite, StreamWrapper};
|
||||
use ironrdp_connector::credssp::KerberosConfig;
|
||||
use ironrdp_async::{single_sequence_step, AsyncNetworkClient, Framed, FramedRead, FramedWrite, StreamWrapper};
|
||||
use ironrdp_connector::sspi::credssp::EarlyUserAuthResult;
|
||||
use ironrdp_connector::sspi::{AuthIdentity, Username};
|
||||
use ironrdp_connector::sspi::{AuthIdentity, KerberosServerConfig, Username};
|
||||
use ironrdp_connector::{custom_err, general_err, ConnectorResult, ServerName};
|
||||
use ironrdp_core::WriteBuf;
|
||||
|
||||
@@ -23,6 +22,7 @@ use ironrdp_pdu::nego;
|
||||
pub use self::channel_connection::{ChannelConnectionSequence, ChannelConnectionState};
|
||||
pub use self::connection::{Acceptor, AcceptorResult, AcceptorState};
|
||||
pub use self::finalization::{FinalizationSequence, FinalizationState};
|
||||
use crate::credssp::resolve_generator;
|
||||
|
||||
pub enum BeginResult<S>
|
||||
where
|
||||
@@ -58,7 +58,8 @@ pub async fn accept_credssp<S>(
|
||||
acceptor: &mut Acceptor,
|
||||
client_computer_name: ServerName,
|
||||
public_key: Vec<u8>,
|
||||
kerberos_config: Option<KerberosConfig>,
|
||||
kerberos_config: Option<KerberosServerConfig>,
|
||||
network_client: Option<&mut dyn AsyncNetworkClient>,
|
||||
) -> ConnectorResult<()>
|
||||
where
|
||||
S: FramedRead + FramedWrite,
|
||||
@@ -73,6 +74,7 @@ where
|
||||
client_computer_name,
|
||||
public_key,
|
||||
kerberos_config,
|
||||
network_client,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
@@ -104,7 +106,8 @@ async fn perform_credssp_step<S>(
|
||||
buf: &mut WriteBuf,
|
||||
client_computer_name: ServerName,
|
||||
public_key: Vec<u8>,
|
||||
kerberos_config: Option<KerberosConfig>,
|
||||
kerberos_config: Option<KerberosServerConfig>,
|
||||
network_client: Option<&mut dyn AsyncNetworkClient>,
|
||||
) -> ConnectorResult<()>
|
||||
where
|
||||
S: FramedRead + FramedWrite,
|
||||
@@ -120,7 +123,8 @@ where
|
||||
buf: &mut WriteBuf,
|
||||
client_computer_name: ServerName,
|
||||
public_key: Vec<u8>,
|
||||
kerberos_config: Option<KerberosConfig>,
|
||||
kerberos_config: Option<KerberosServerConfig>,
|
||||
mut network_client: Option<&mut dyn AsyncNetworkClient>,
|
||||
) -> ConnectorResult<()>
|
||||
where
|
||||
S: FramedRead + FramedWrite,
|
||||
@@ -160,7 +164,16 @@ where
|
||||
break;
|
||||
};
|
||||
|
||||
let result = sequence.process_ts_request(ts_request);
|
||||
let result = {
|
||||
let mut generator = sequence.process_ts_request(ts_request);
|
||||
|
||||
if let Some(network_client_ref) = network_client.as_deref_mut() {
|
||||
resolve_generator(&mut generator, network_client_ref).await
|
||||
} else {
|
||||
generator.resolve_to_result()
|
||||
}
|
||||
}; // drop generator
|
||||
|
||||
buf.clear();
|
||||
let written = sequence.handle_process_result(result, buf)?;
|
||||
|
||||
@@ -176,7 +189,16 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let result = credssp_loop(framed, acceptor, buf, client_computer_name, public_key, kerberos_config).await;
|
||||
let result = credssp_loop(
|
||||
framed,
|
||||
acceptor,
|
||||
buf,
|
||||
client_computer_name,
|
||||
public_key,
|
||||
kerberos_config,
|
||||
network_client,
|
||||
)
|
||||
.await;
|
||||
|
||||
if protocol.intersects(nego::SecurityProtocol::HYBRID_EX) {
|
||||
trace!(?result, "HYBRID_EX");
|
||||
|
||||
@@ -24,7 +24,7 @@ ironrdp-core = { path = "../ironrdp-core", version = "0.1" } # public
|
||||
ironrdp-error = { path = "../ironrdp-error", version = "0.1" } # public
|
||||
ironrdp-pdu = { path = "../ironrdp-pdu", version = "0.5", features = ["std"] } # public
|
||||
arbitrary = { version = "1", features = ["derive"], optional = true } # public
|
||||
sspi = "0.15" # public
|
||||
sspi = "0.16" # public
|
||||
url = "2.5" # public
|
||||
rand_core = { version = "0.6", features = ["std"] } # TODO: dependency injection?
|
||||
tracing = { version = "0.1", features = ["log"] }
|
||||
|
||||
@@ -318,6 +318,7 @@ impl RdpServer {
|
||||
client_name.into(),
|
||||
pub_key.clone(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ ironrdp-async = { path = "../ironrdp-async", version = "0.5" } # public
|
||||
ironrdp-connector = { path = "../ironrdp-connector", version = "0.5", optional = true }
|
||||
tokio = { version = "1", features = ["io-util"] }
|
||||
reqwest = { version = "0.12", default-features = false, features = ["http2", "system-proxy"], optional = true }
|
||||
sspi = { version = "0.15", features = ["network_client", "dns_resolver"], optional = true }
|
||||
sspi = { version = "0.16", features = ["network_client", "dns_resolver"], optional = true }
|
||||
url = { version = "2.5", optional = true }
|
||||
|
||||
[lints]
|
||||
|
||||
@@ -59,7 +59,7 @@ async-trait = "0.1"
|
||||
image = { version = "0.25.6", default-features = false, features = ["png"] }
|
||||
pico-args = "0.5"
|
||||
x509-cert = { version = "0.2", default-features = false, features = ["std"] }
|
||||
sspi = { version = "0.15", features = ["network_client"] }
|
||||
sspi = { version = "0.16", features = ["network_client"] }
|
||||
tracing = { version = "0.1", features = ["log"] }
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
tokio-rustls = "0.26"
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ diplomat-runtime = "0.7"
|
||||
ironrdp = { path = "../crates/ironrdp", features = ["session", "connector", "dvc", "svc", "rdpdr", "rdpsnd", "graphics", "input", "cliprdr", "displaycontrol"] }
|
||||
ironrdp-cliprdr-native.path = "../crates/ironrdp-cliprdr-native"
|
||||
ironrdp-core = { path = "../crates/ironrdp-core", features = ["alloc"] }
|
||||
sspi = { version = "0.15", features = ["network_client"] }
|
||||
sspi = { version = "0.16", features = ["network_client"] }
|
||||
thiserror = "1"
|
||||
tracing = { version = "0.1", features = ["log"] }
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
|
||||
Reference in New Issue
Block a user