Skip to content

Commit 349b21f

Browse files
sqash everything
1 parent 4dc5945 commit 349b21f

File tree

27 files changed

+1205
-364
lines changed

27 files changed

+1205
-364
lines changed

Cargo.lock

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ironrdp-async/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ test = false
1717

1818
[dependencies]
1919
ironrdp-connector = { path = "../ironrdp-connector", version = "0.5" } # public
20+
ironrdp-vmconnect.path = "../ironrdp-vmconnect" # public
2021
ironrdp-core = { path = "../ironrdp-core", version = "0.1", features = ["alloc"] } # public
2122
ironrdp-pdu = { path = "../ironrdp-pdu", version = "0.5" } # public
2223
tracing = { version = "0.1", features = ["log"] }

crates/ironrdp-async/src/connector.rs

Lines changed: 87 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use ironrdp_connector::credssp::{CredsspProcessGenerator, CredsspSequence, KerberosConfig};
1+
use ironrdp_connector::credssp::{CredsspProcessGenerator, KerberosConfig};
22
use ironrdp_connector::sspi::credssp::ClientState;
33
use ironrdp_connector::sspi::generator::GeneratorState;
44
use ironrdp_connector::{
5-
custom_err, general_err, ClientConnector, ClientConnectorState, ConnectionResult, ConnectorError, ConnectorResult,
6-
ServerName, State as _,
5+
custom_err, general_err, ClientConnector, ClientConnectorState, ConnectionResult, ConnectorCore, ConnectorError,
6+
ConnectorResult, SecurityConnector, ServerName,
77
};
88
use ironrdp_core::WriteBuf;
99

@@ -14,7 +14,10 @@ use crate::{single_sequence_step, AsyncNetworkClient};
1414
pub struct ShouldUpgrade;
1515

1616
#[instrument(skip_all)]
17-
pub async fn connect_begin<S>(framed: &mut Framed<S>, connector: &mut ClientConnector) -> ConnectorResult<ShouldUpgrade>
17+
pub async fn connect_begin<S>(
18+
framed: &mut Framed<S>,
19+
connector: &mut dyn ConnectorCore,
20+
) -> ConnectorResult<ShouldUpgrade>
1821
where
1922
S: Sync + FramedRead + FramedWrite,
2023
{
@@ -29,7 +32,7 @@ where
2932
Ok(ShouldUpgrade)
3033
}
3134

32-
pub fn skip_connect_begin(connector: &mut ClientConnector) -> ShouldUpgrade {
35+
pub fn skip_connect_begin(connector: &dyn SecurityConnector) -> ShouldUpgrade {
3336
assert!(connector.should_perform_security_upgrade());
3437
ShouldUpgrade
3538
}
@@ -38,22 +41,26 @@ pub fn skip_connect_begin(connector: &mut ClientConnector) -> ShouldUpgrade {
3841
pub struct Upgraded;
3942

4043
#[instrument(skip_all)]
41-
pub fn mark_as_upgraded(_: ShouldUpgrade, connector: &mut ClientConnector) -> Upgraded {
44+
pub fn mark_as_upgraded(_: ShouldUpgrade, connector: &mut dyn SecurityConnector) -> Upgraded {
4245
trace!("Marked as upgraded");
4346
connector.mark_security_upgrade_as_done();
4447
Upgraded
4548
}
4649

47-
#[instrument(skip_all)]
48-
pub async fn connect_finalize<S>(
50+
#[non_exhaustive]
51+
pub struct CredSSPFinished {
52+
pub(crate) write_buf: WriteBuf,
53+
}
54+
55+
pub async fn perform_credssp<S>(
4956
_: Upgraded,
57+
connector: &mut dyn ConnectorCore,
5058
framed: &mut Framed<S>,
51-
mut connector: ClientConnector,
5259
server_name: ServerName,
5360
server_public_key: Vec<u8>,
5461
network_client: Option<&mut dyn AsyncNetworkClient>,
5562
kerberos_config: Option<KerberosConfig>,
56-
) -> ConnectorResult<ConnectionResult>
63+
) -> ConnectorResult<CredSSPFinished>
5764
where
5865
S: FramedRead + FramedWrite,
5966
{
@@ -62,7 +69,7 @@ where
6269
if connector.should_perform_credssp() {
6370
perform_credssp_step(
6471
framed,
65-
&mut connector,
72+
connector,
6673
&mut buf,
6774
server_name,
6875
server_public_key,
@@ -72,6 +79,19 @@ where
7279
.await?;
7380
}
7481

82+
Ok(CredSSPFinished { write_buf: buf })
83+
}
84+
85+
#[instrument(skip_all)]
86+
pub async fn connect_finalize<S>(
87+
CredSSPFinished { write_buf: mut buf }: CredSSPFinished,
88+
framed: &mut Framed<S>,
89+
mut connector: ClientConnector,
90+
) -> ConnectorResult<ConnectionResult>
91+
where
92+
S: FramedRead + FramedWrite,
93+
{
94+
buf.clear();
7595
let result = loop {
7696
single_sequence_step(framed, &mut connector, &mut buf).await?;
7797

@@ -108,7 +128,7 @@ async fn resolve_generator(
108128
#[instrument(level = "trace", skip_all)]
109129
async fn perform_credssp_step<S>(
110130
framed: &mut Framed<S>,
111-
connector: &mut ClientConnector,
131+
connector: &mut dyn ConnectorCore,
112132
buf: &mut WriteBuf,
113133
server_name: ServerName,
114134
server_public_key: Vec<u8>,
@@ -120,70 +140,70 @@ where
120140
{
121141
assert!(connector.should_perform_credssp());
122142

123-
let selected_protocol = match connector.state {
124-
ClientConnectorState::Credssp { selected_protocol, .. } => selected_protocol,
125-
_ => return Err(general_err!("invalid connector state for CredSSP sequence")),
126-
};
127-
128-
let (mut sequence, mut ts_request) = CredsspSequence::init(
129-
connector.config.credentials.clone(),
130-
connector.config.domain.as_deref(),
131-
selected_protocol,
132-
server_name,
133-
server_public_key,
134-
kerberos_config,
135-
)?;
136-
137-
loop {
138-
let client_state = {
139-
let mut generator = sequence.process_ts_request(ts_request);
143+
let selected_protocol = connector
144+
.selected_protocol()
145+
.ok_or_else(|| general_err!("CredSSP protocol not selected, cannot perform CredSSP step"))?;
140146

141-
if let Some(network_client_ref) = network_client.as_deref_mut() {
142-
trace!("resolving network");
143-
resolve_generator(&mut generator, network_client_ref).await?
144-
} else {
145-
generator
146-
.resolve_to_result()
147-
.map_err(|e| custom_err!("resolve without network client", e))?
147+
{
148+
let (mut sequence, mut ts_request) = connector.init_credssp(
149+
connector.config().credentials.clone(),
150+
connector.config().domain.as_deref(),
151+
selected_protocol,
152+
server_name,
153+
server_public_key,
154+
kerberos_config,
155+
)?;
156+
157+
loop {
158+
let client_state = {
159+
let mut generator = sequence.process_ts_request(ts_request);
160+
161+
if let Some(network_client_ref) = network_client.as_deref_mut() {
162+
trace!("resolving network");
163+
resolve_generator(&mut generator, network_client_ref).await?
164+
} else {
165+
generator
166+
.resolve_to_result()
167+
.map_err(|e| custom_err!("resolve without network client", e))?
168+
}
169+
}; // drop generator
170+
171+
buf.clear();
172+
let written = sequence.handle_process_result(client_state, buf)?;
173+
174+
if let Some(response_len) = written.size() {
175+
let response = &buf[..response_len];
176+
trace!(response_len, "Send response");
177+
framed
178+
.write_all(response)
179+
.await
180+
.map_err(|e| ironrdp_connector::custom_err!("write all", e))?;
148181
}
149-
}; // drop generator
150182

151-
buf.clear();
152-
let written = sequence.handle_process_result(client_state, buf)?;
183+
let Some(next_pdu_hint) = sequence.next_pdu_hint() else {
184+
break;
185+
};
153186

154-
if let Some(response_len) = written.size() {
155-
let response = &buf[..response_len];
156-
trace!(response_len, "Send response");
157-
framed
158-
.write_all(response)
159-
.await
160-
.map_err(|e| ironrdp_connector::custom_err!("write all", e))?;
161-
}
162-
163-
let Some(next_pdu_hint) = sequence.next_pdu_hint() else {
164-
break;
165-
};
166-
167-
debug!(
168-
connector.state = connector.state.name(),
169-
hint = ?next_pdu_hint,
170-
"Wait for PDU"
171-
);
187+
debug!(
188+
connector.state = connector.state().name(),
189+
hint = ?next_pdu_hint,
190+
"Wait for PDU"
191+
);
172192

173-
let pdu = framed
174-
.read_by_hint(next_pdu_hint)
175-
.await
176-
.map_err(|e| ironrdp_connector::custom_err!("read frame by hint", e))?;
193+
let pdu = framed
194+
.read_by_hint(next_pdu_hint)
195+
.await
196+
.map_err(|e| ironrdp_connector::custom_err!("read frame by hint", e))?;
177197

178-
trace!(length = pdu.len(), "PDU received");
198+
trace!(length = pdu.len(), "PDU received");
179199

180-
if let Some(next_request) = sequence.decode_server_message(&pdu)? {
181-
ts_request = next_request;
182-
} else {
183-
break;
200+
if let Some(next_request) = sequence.decode_server_message(&pdu)? {
201+
ts_request = next_request;
202+
} else {
203+
break;
204+
}
184205
}
185206
}
186-
187207
connector.mark_credssp_as_done();
188208

189209
Ok(())

crates/ironrdp-async/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub use bytes;
99
mod connector;
1010
mod framed;
1111
mod session;
12+
mod vmconnector;
1213

1314
use core::future::Future;
1415
use core::pin::Pin;
@@ -18,7 +19,7 @@ use ironrdp_connector::ConnectorResult;
1819

1920
pub use self::connector::*;
2021
pub use self::framed::*;
21-
// pub use self::session::*;
22+
pub use self::vmconnector::*;
2223

2324
pub trait AsyncNetworkClient {
2425
fn send<'a>(
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use crate::{single_sequence_step, CredSSPFinished, Framed, FramedRead, FramedWrite};
2+
use ironrdp_connector::{ClientConnector, ConnectorResult};
3+
use ironrdp_pdu::pcb::PcbVersion;
4+
5+
use ironrdp_vmconnect::VmClientConnector;
6+
7+
#[non_exhaustive]
8+
pub struct PcbSent;
9+
10+
pub async fn send_pcb<S>(framed: &mut Framed<S>, payload: String) -> ConnectorResult<PcbSent>
11+
where
12+
S: Sync + FramedRead + FramedWrite,
13+
{
14+
let pcb_pdu = ironrdp_pdu::pcb::PreconnectionBlob {
15+
id: 0,
16+
version: PcbVersion::V2,
17+
v2_payload: Some(payload),
18+
};
19+
20+
let buf = ironrdp_core::encode_vec(&pcb_pdu)
21+
.map_err(|e| ironrdp_connector::custom_err!("encode PreconnectionBlob PDU", e))?;
22+
23+
framed
24+
.write_all(&buf)
25+
.await
26+
.map_err(|e| ironrdp_connector::custom_err!("write PCB PDU", e))?;
27+
28+
Ok(PcbSent)
29+
}
30+
31+
pub fn mark_pcb_sent_by_rdclean_path() -> PcbSent {
32+
PcbSent
33+
}
34+
35+
pub fn vm_connector_take_over(_: PcbSent, connector: ClientConnector) -> ConnectorResult<VmClientConnector> {
36+
VmClientConnector::take_over(connector)
37+
}
38+
39+
pub async fn run_until_handover(
40+
credssp_finished: &mut CredSSPFinished,
41+
framed: &mut Framed<impl FramedRead + FramedWrite>,
42+
mut connector: VmClientConnector,
43+
) -> ConnectorResult<ClientConnector> {
44+
let result = loop {
45+
single_sequence_step(framed, &mut connector, &mut credssp_finished.write_buf).await?;
46+
47+
if connector.should_hand_over() {
48+
break connector.hand_over();
49+
}
50+
};
51+
52+
info!("Handover to client connector");
53+
credssp_finished.write_buf.clear();
54+
55+
Ok(result)
56+
}

0 commit comments

Comments
 (0)