Skip to content

Commit 37cecc0

Browse files
authored
fix(server): pick one selected protocol (#570)
The spec says we should have "the" selected protocol, and mstsc expects that. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
1 parent 3e738a9 commit 37cecc0

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

crates/ironrdp-acceptor/src/connection.rs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use ironrdp_connector::{
88
use ironrdp_core::decode;
99
use ironrdp_core::WriteBuf;
1010
use ironrdp_pdu as pdu;
11+
use ironrdp_pdu::nego::SecurityProtocol;
1112
use ironrdp_pdu::x224::X224;
1213
use ironrdp_svc::{StaticChannelSet, SvcServerProcessor};
1314
use pdu::rdp::capability_sets::CapabilitySet;
@@ -28,7 +29,7 @@ const USER_CHANNEL_ID: u16 = 1002;
2829

2930
pub struct Acceptor {
3031
pub(crate) state: AcceptorState,
31-
security: nego::SecurityProtocol,
32+
security: SecurityProtocol,
3233
io_channel_id: u16,
3334
user_channel_id: u16,
3435
desktop_size: DesktopSize,
@@ -49,7 +50,7 @@ pub struct AcceptorResult {
4950

5051
impl Acceptor {
5152
pub fn new(
52-
security: nego::SecurityProtocol,
53+
security: SecurityProtocol,
5354
desktop_size: DesktopSize,
5455
capabilities: Vec<CapabilitySet>,
5556
creds: Option<Credentials>,
@@ -121,7 +122,7 @@ impl Acceptor {
121122
}
122123
}
123124

124-
pub fn reached_security_upgrade(&self) -> Option<nego::SecurityProtocol> {
125+
pub fn reached_security_upgrade(&self) -> Option<SecurityProtocol> {
125126
match self.state {
126127
AcceptorState::SecurityUpgrade { .. } => Some(self.security),
127128
_ => None,
@@ -173,39 +174,39 @@ pub enum AcceptorState {
173174

174175
InitiationWaitRequest,
175176
InitiationSendConfirm {
176-
requested_protocol: nego::SecurityProtocol,
177+
requested_protocol: SecurityProtocol,
177178
},
178179
SecurityUpgrade {
179-
requested_protocol: nego::SecurityProtocol,
180-
protocol: nego::SecurityProtocol,
180+
requested_protocol: SecurityProtocol,
181+
protocol: SecurityProtocol,
181182
},
182183
Credssp {
183-
requested_protocol: nego::SecurityProtocol,
184-
protocol: nego::SecurityProtocol,
184+
requested_protocol: SecurityProtocol,
185+
protocol: SecurityProtocol,
185186
},
186187
BasicSettingsWaitInitial {
187-
requested_protocol: nego::SecurityProtocol,
188-
protocol: nego::SecurityProtocol,
188+
requested_protocol: SecurityProtocol,
189+
protocol: SecurityProtocol,
189190
},
190191
BasicSettingsSendResponse {
191-
requested_protocol: nego::SecurityProtocol,
192-
protocol: nego::SecurityProtocol,
192+
requested_protocol: SecurityProtocol,
193+
protocol: SecurityProtocol,
193194
early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
194195
channels: Vec<(u16, Option<gcc::ChannelDef>)>,
195196
},
196197
ChannelConnection {
197-
protocol: nego::SecurityProtocol,
198+
protocol: SecurityProtocol,
198199
early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
199200
channels: Vec<(u16, gcc::ChannelDef)>,
200201
connection: ChannelConnectionSequence,
201202
},
202203
RdpSecurityCommencement {
203-
protocol: nego::SecurityProtocol,
204+
protocol: SecurityProtocol,
204205
early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
205206
channels: Vec<(u16, gcc::ChannelDef)>,
206207
},
207208
SecureSettingsExchange {
208-
protocol: nego::SecurityProtocol,
209+
protocol: SecurityProtocol,
209210
early_capability: Option<gcc::ClientEarlyCapabilityFlags>,
210211
channels: Vec<(u16, gcc::ChannelDef)>,
211212
},
@@ -310,7 +311,16 @@ impl Sequence for Acceptor {
310311
}
311312

312313
AcceptorState::InitiationSendConfirm { requested_protocol } => {
313-
let protocol = requested_protocol & self.security;
314+
let protocols = requested_protocol & self.security;
315+
let protocol = if protocols.intersects(SecurityProtocol::HYBRID_EX) {
316+
SecurityProtocol::HYBRID_EX
317+
} else if protocols.intersects(SecurityProtocol::HYBRID) {
318+
SecurityProtocol::HYBRID
319+
} else if protocols.intersects(SecurityProtocol::SSL) {
320+
SecurityProtocol::SSL
321+
} else {
322+
return Err(ConnectorError::general("failed to negotiate security protocol"));
323+
};
314324
let connection_confirm = nego::ConnectionConfirm::Response {
315325
flags: nego::ResponseFlags::empty(),
316326
protocol,
@@ -335,18 +345,17 @@ impl Sequence for Acceptor {
335345
protocol,
336346
} => {
337347
debug!(?requested_protocol);
338-
let next_state =
339-
if protocol.intersects(nego::SecurityProtocol::HYBRID | nego::SecurityProtocol::HYBRID_EX) {
340-
AcceptorState::Credssp {
341-
requested_protocol,
342-
protocol,
343-
}
344-
} else {
345-
AcceptorState::BasicSettingsWaitInitial {
346-
requested_protocol,
347-
protocol,
348-
}
349-
};
348+
let next_state = if protocol.intersects(SecurityProtocol::HYBRID | SecurityProtocol::HYBRID_EX) {
349+
AcceptorState::Credssp {
350+
requested_protocol,
351+
protocol,
352+
}
353+
} else {
354+
AcceptorState::BasicSettingsWaitInitial {
355+
requested_protocol,
356+
protocol,
357+
}
358+
};
350359
(Written::Nothing, next_state)
351360
}
352361

@@ -521,7 +530,7 @@ impl Sequence for Acceptor {
521530

522531
debug!(message = ?client_info, "Received");
523532

524-
if !protocol.intersects(nego::SecurityProtocol::HYBRID | nego::SecurityProtocol::HYBRID_EX) {
533+
if !protocol.intersects(SecurityProtocol::HYBRID | SecurityProtocol::HYBRID_EX) {
525534
let creds = client_info.client_info.credentials;
526535

527536
if self.creds.as_ref().map_or(true, |srv_creds| srv_creds != &creds) {
@@ -706,7 +715,7 @@ impl Sequence for Acceptor {
706715
fn create_gcc_blocks(
707716
io_channel: u16,
708717
channel_ids: Vec<u16>,
709-
requested: nego::SecurityProtocol,
718+
requested: SecurityProtocol,
710719
skip_channel_join: bool,
711720
) -> gcc::ServerGccBlocks {
712721
gcc::ServerGccBlocks {

0 commit comments

Comments
 (0)