pub struct Config {Show 26 fields
pub desktop_size: DesktopSize,
pub desktop_scale_factor: u32,
pub enable_tls: bool,
pub enable_credssp: bool,
pub credentials: Credentials,
pub domain: Option<String>,
pub client_build: u32,
pub client_name: String,
pub keyboard_type: KeyboardType,
pub keyboard_subtype: u32,
pub keyboard_functional_keys_count: u32,
pub keyboard_layout: u32,
pub ime_file_name: String,
pub bitmap: Option<BitmapConfig>,
pub dig_product_id: String,
pub client_dir: String,
pub platform: MajorPlatformType,
pub hardware_id: Option<[u32; 4]>,
pub request_data: Option<NegoRequestData>,
pub autologon: bool,
pub enable_audio_playback: bool,
pub performance_flags: PerformanceFlags,
pub license_cache: Option<Arc<dyn LicenseCache>>,
pub timezone_info: TimezoneInfo,
pub enable_server_pointer: bool,
pub pointer_software_rendering: bool,
}
Fields§
§desktop_size: DesktopSize
The initial desktop size to request
desktop_scale_factor: u32
The initial desktop scale factor to request.
This becomes the desktop_scale_factor
in the TS_UD_CS_CORE
structure.
enable_tls: bool
TLS + Graphical login (legacy)
Also called SSL or TLS security protocol. The PROTOCOL_SSL flag will be set.
When this security protocol is negotiated, the RDP server will show a graphical login screen. For Windows, it means that the login subsystem (winlogon.exe) and the GDI graphics subsystem will be initiated and the user will authenticate himself using LogonUI.exe, as if using the physical machine directly.
This security protocol is being phased out because it’s not great security-wise. Indeed, the whole RDP connection sequence will be performed, allowing anyone to effectively open a RDP session session with all static channels joined and active (e.g.: I/O, clipboard, sound, drive redirection, etc). This exposes a wide attack surface with many impacts on both the client and the server.
- Man-in-the-middle (MITM)
- Server-side takeover
- Client-side file stealing
- Client-side takeover
Recommended reads on this topic:
- https://www.gosecure.net/blog/2018/12/19/rdp-man-in-the-middle-smile-youre-on-camera/
- https://www.gosecure.net/divi_overlay/mitigating-the-risks-of-remote-desktop-protocols/
- https://gosecure.github.io/presentations/2021-08-05_blackhat-usa/BlackHat-USA-21-Arsenal-PyRDP-OlivierBilodeau.pdf
- https://gosecure.github.io/presentations/2022-10-06_sector/OlivierBilodeau-Purple_RDP.pdf
By setting this option to false
, it’s possible to effectively enforce usage of NLA on client side.
enable_credssp: bool
TLS + Network Level Authentication (NLA) using CredSSP
The PROTOCOL_HYBRID and PROTOCOL_HYBRID_EX flags will be set.
NLA is allowing authentication to be performed before session establishment.
This option includes the extended CredSSP early user authorization result PDU. This PDU is used by the server to deny access before any credentials (except for the username) have been submitted, e.g.: typically if the user does not have the necessary remote access privileges.
The attack surface is considerably reduced in comparison to the legacy “TLS” security protocol.
For this reason, it is recommended to set enable_tls
to false
when connecting to NLA-capable
computers.
credentials: Credentials
§domain: Option<String>
§client_build: u32
The build number of the client.
client_name: String
Name of the client computer
The name will be truncated to the 15 first characters.
keyboard_type: KeyboardType
§keyboard_subtype: u32
§keyboard_functional_keys_count: u32
§keyboard_layout: u32
§ime_file_name: String
§bitmap: Option<BitmapConfig>
§dig_product_id: String
§client_dir: String
§platform: MajorPlatformType
§hardware_id: Option<[u32; 4]>
Unique identifier for the computer
Each 32-bit integer contains client hardware-specific data helping the server uniquely identify the client.
request_data: Option<NegoRequestData>
Optional data for the x224 connection request.
Fallbacks to a sensible default depending on the provided credentials:
- A cookie containing the username for a username/password.
- Nothing for a smart card.
autologon: bool
If true, the INFO_AUTOLOGON flag is set in the ClientInfoPdu
enable_audio_playback: bool
If true, the INFO_NOAUDIOPLAYBACK flag is set in the ClientInfoPdu
performance_flags: PerformanceFlags
§license_cache: Option<Arc<dyn LicenseCache>>
§timezone_info: TimezoneInfo
§enable_server_pointer: bool
§pointer_software_rendering: bool
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Config
impl RefUnwindSafe for Config
impl Send for Config
impl Sync for Config
impl Unpin for Config
impl UnwindSafe for Config
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.