Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/ironrdp-client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ impl Config {
domain: args.domain,
enable_tls: !args.no_tls,
enable_credssp: !args.no_credssp,
allow_encryption_level_none: false,
keyboard_type: KeyboardType::parse(args.keyboard_type),
keyboard_subtype: args.keyboard_subtype,
keyboard_layout: 0, // the server SHOULD use the default active input locale identifier
Expand Down
24 changes: 16 additions & 8 deletions crates/ironrdp-connector/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ impl Sequence for ClientConnector {
security_protocol.insert(nego::SecurityProtocol::HYBRID | nego::SecurityProtocol::HYBRID_EX);
}

if security_protocol.is_standard_rdp_security() {
return Err(reason_err!("Initiation", "standard RDP security is not supported",));
if security_protocol.is_standard_rdp_security() && !self.config.allow_encryption_level_none {
return Err(reason_err!("Initiation", "ENCRYPTION_LEVEL_NONE is not allowed",));
}

let connection_request = nego::ConnectionRequest {
Expand Down Expand Up @@ -310,17 +310,25 @@ impl Sequence for ClientConnector {

info!(?selected_protocol, ?flags, "Server confirmed connection");

if !selected_protocol.intersects(requested_protocol) {
if selected_protocol.is_standard_rdp_security() && requested_protocol.is_standard_rdp_security() {
// Both sides agreed on standard RDP security — skip the
// enhanced security upgrade and go straight to basic
// settings exchange.
(
Written::Nothing,
ClientConnectorState::BasicSettingsExchangeSendInitial { selected_protocol },
)
} else if !selected_protocol.intersects(requested_protocol) {
return Err(reason_err!(
"Initiation",
"client advertised {requested_protocol}, but server selected {selected_protocol}",
));
} else {
(
Written::Nothing,
ClientConnectorState::EnhancedSecurityUpgrade { selected_protocol },
)
}

(
Written::Nothing,
ClientConnectorState::EnhancedSecurityUpgrade { selected_protocol },
)
}

//== Upgrade to Enhanced RDP Security ==//
Expand Down
16 changes: 16 additions & 0 deletions crates/ironrdp-connector/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,22 @@ pub struct Config {
/// computers.
#[doc(alias("enable_nla", "nla"))]
pub enable_credssp: bool,
/// Allow connections with no RDP-level encryption (`ENCRYPTION_LEVEL_NONE`)
///
/// When enabled and the server selects Standard RDP Security
/// (`PROTOCOL_RDP`) with `ENCRYPTION_LEVEL_NONE` /
/// `ENCRYPTION_METHOD_NONE`, the connection proceeds without TLS
/// upgrade, CredSSP authentication, or RDP-layer encryption.
///
/// This is appropriate when the transport is already secured by other
/// means, such as a TLS WebSocket proxy or an SSH tunnel.
///
/// # Security Warning
///
/// Do **not** enable this unless the underlying transport is already
/// encrypted. Without TLS, all RDP traffic (including credentials) is
/// sent in plaintext.
pub allow_encryption_level_none: bool,
pub credentials: Credentials,
pub domain: Option<String>,
/// The build number of the client.
Expand Down
1 change: 1 addition & 0 deletions crates/ironrdp-testsuite-extra/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ fn default_client_config() -> connector::Config {
desktop_scale_factor: 0, // Default to 0 per FreeRDP
enable_tls: true,
enable_credssp: true,
allow_encryption_level_none: false,
credentials: connector::Credentials::UsernamePassword {
username: USERNAME.into(),
password: PASSWORD.into(),
Expand Down
1 change: 1 addition & 0 deletions crates/ironrdp-web/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,7 @@ fn build_config(
// TODO(#327): expose these options from the WASM module.
enable_tls: true,
enable_credssp: true,
allow_encryption_level_none: false,
keyboard_type: ironrdp::pdu::gcc::KeyboardType::IbmEnhanced,
keyboard_subtype: 0,
keyboard_layout: 0, // the server SHOULD use the default active input locale identifier
Expand Down
1 change: 1 addition & 0 deletions crates/ironrdp/examples/screenshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ fn build_config(
domain,
enable_tls: false, // This example does not expose any frontend.
enable_credssp: true,
allow_encryption_level_none: false,
keyboard_type: KeyboardType::IbmEnhanced,
keyboard_subtype: 0,
keyboard_layout: 0,
Expand Down
1 change: 1 addition & 0 deletions ffi/src/connector/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ pub mod ffi {
domain: self.domain.clone(),
enable_tls: self.enable_tls.unwrap_or(false),
enable_credssp: self.enable_credssp.unwrap_or(true),
allow_encryption_level_none: false,
keyboard_layout: self.keyboard_layout.unwrap_or(0),
keyboard_type: self
.keyboard_type
Expand Down