Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for SharedDirectoryCreateRequest and SharedDirectoryCreateResponse. #34011

Merged
merged 14 commits into from
Nov 14, 2023
Merged
24 changes: 12 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 9 additions & 10 deletions lib/srv/desktop/rdp/rdpclient/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,15 @@ x509-parser = "0.14"
sspi = { git = "https://github.com/Devolutions/sspi-rs", rev="d54bdfcafa0e10d9d78224ebacc4f2a0992a6b79", features = ["network_client"] }
static_init = "1.0.3"

# Update when https://github.com/Devolutions/IronRDP/pull/235 lands
ironrdp-connector = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-tls = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-session = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-pdu = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-tokio = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-rdpsnd = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-rdpdr = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-svc = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-cliprdr = { git = "https://github.com/Devolutions/IronRDP", rev = "1dae856fface011307b5ca28be5778fd1ba41b44" }
ironrdp-connector = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }
ironrdp-tls = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }
ironrdp-session = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }
ironrdp-pdu = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }
ironrdp-tokio = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }
ironrdp-rdpsnd = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }
ironrdp-rdpdr = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }
ironrdp-svc = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }
ironrdp-cliprdr = { git = "https://github.com/Devolutions/IronRDP", rev = "9859cb7518c5aa1635abe51fd74f97eb3eefad5d" }

# Uncomment the following lines to use local crates instead of the ones from github
# ironrdp-connector = { path = "/Users/ibeckermayer/Devolutions/IronRDP/crates/ironrdp-connector" }
Expand Down
104 changes: 82 additions & 22 deletions lib/srv/desktop/rdp/rdpclient/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,17 +218,17 @@ impl Client {
let read_stream = self
.read_stream
.take()
.ok_or_else(|| ClientError::InternalError)?;
.ok_or_else(|| ClientError::InternalError("read_stream failed".to_string()))?;

let write_stream = self
.write_stream
.take()
.ok_or_else(|| ClientError::InternalError)?;
.ok_or_else(|| ClientError::InternalError("write_stream failed".to_string()))?;

let function_receiver = self
.function_receiver
.take()
.ok_or_else(|| ClientError::InternalError)?;
.ok_or_else(|| ClientError::InternalError("function_receiver failed".to_string()))?;

let mut read_loop_handle = Client::run_read_loop(
self.cgo_handle,
Expand Down Expand Up @@ -329,6 +329,10 @@ impl Client {
Client::handle_tdp_sd_info_response(x224_processor.clone(), res)
.await?;
}
ClientFunction::HandleTdpSdCreateResponse(res) => {
Client::handle_tdp_sd_create_response(x224_processor.clone(), res)
.await?;
}
ClientFunction::WriteCliprdr(f) => {
Client::write_cliprdr(x224_processor.clone(), &mut write_stream, f)
.await?;
Expand Down Expand Up @@ -359,11 +363,7 @@ impl Client {
global::TOKIO_RT
.spawn_blocking(move || {
let mut x224_processor = Self::x224_lock(&x224_processor)?;
let cliprdr = x224_processor
.get_svc_processor_mut::<Cliprdr>()
.ok_or(ClientError::InternalError)?
.downcast_backend_mut::<TeleportCliprdrBackend>()
.ok_or(ClientError::InternalError)?;
let cliprdr = Self::cliprdr_backend(&mut x224_processor)?;
cliprdr.set_clipboard_data(data.clone());
Ok(())
})
Expand All @@ -388,9 +388,7 @@ impl Client {
let messages: ClientResult<CliprdrSvcMessages> = global::TOKIO_RT
.spawn_blocking(move || {
let mut x224_processor = Self::x224_lock(&processor)?;
let cliprdr = x224_processor
.get_svc_processor::<Cliprdr>()
.ok_or(ClientError::InternalError)?;
let cliprdr = Self::get_svc_processor::<Cliprdr>(&mut x224_processor)?;
Ok(fun.call(cliprdr)?)
})
.await?;
Expand Down Expand Up @@ -514,12 +512,23 @@ impl Client {
.spawn_blocking(move || {
debug!("received tdp: {:?}", res);
let mut x224_processor = Self::x224_lock(&x224_processor)?;
let teleport_rdpdr_backend = x224_processor
.get_svc_processor_mut::<Rdpdr>()
.ok_or(ClientError::InternalError)?
.downcast_backend_mut::<TeleportRdpdrBackend>()
.ok_or(ClientError::InternalError)?;
teleport_rdpdr_backend.handle_tdp_sd_info_response(res)?;
let rdpdr = Self::rdpdr_backend(&mut x224_processor)?;
rdpdr.handle_tdp_sd_info_response(res)?;
Ok(())
})
.await?
}

async fn handle_tdp_sd_create_response(
x224_processor: Arc<Mutex<X224Processor>>,
res: tdp::SharedDirectoryCreateResponse,
) -> ClientResult<()> {
global::TOKIO_RT
.spawn_blocking(move || {
debug!("received tdp: {:?}", res);
let mut x224_processor = Self::x224_lock(&x224_processor)?;
let rdpdr = Self::rdpdr_backend(&mut x224_processor)?;
rdpdr.handle_tdp_sd_create_response(res)?;
Ok(())
})
.await?
Expand All @@ -532,9 +541,11 @@ impl Client {
global::TOKIO_RT
.spawn_blocking(move || {
let mut x224_processor = Self::x224_lock(&x224_processor)?;
let rdpdr = x224_processor
.get_svc_processor_mut::<Rdpdr>()
.ok_or(ClientError::InternalError)?;
let rdpdr = x224_processor.get_svc_processor_mut::<Rdpdr>().ok_or(
ClientError::InternalError(
"get_svc_processor_mut::<Rdpdr>() returned None".to_string(),
),
)?;
let pdu = rdpdr.add_drive(sda.directory_id, sda.name);
Ok(pdu)
})
Expand Down Expand Up @@ -582,6 +593,53 @@ impl Client {
.lock()
.map_err(|err| reason_err!("x224_processor.lock()", "PoisonError: {:?}", err))
}

/// Returns an immutable reference to the [`StaticVirtualChannelProcessor`] of type `S`.
///
/// # Example
///
/// ```
/// let mut x224_processor = Self::x224_lock(&x224_processor)?;
/// let cliprdr = Self::get_svc_processor::<Cliprdr>(&mut x224_processor)?;
/// // Now we can call methods on the Cliprdr processor.
/// ```
fn get_svc_processor<'a, S>(
x224_processor: &'a mut MutexGuard<'_, X224Processor>,
) -> Result<&'a S, ClientError>
where
S: StaticVirtualChannelProcessor + 'static,
{
x224_processor
.get_svc_processor::<S>()
.ok_or(ClientError::InternalError(format!(
"get_svc_processor::<{}>() returned None",
std::any::type_name::<S>(),
)))
}

/// Returns a mutable reference to the [`TeleportCliprdrBackend`] of the [`Cliprdr`] processor.
fn cliprdr_backend(
x224_processor: &mut X224Processor,
) -> ClientResult<&mut TeleportCliprdrBackend> {
x224_processor
.get_svc_processor_mut::<Cliprdr>()
.and_then(|c| c.downcast_backend_mut::<TeleportCliprdrBackend>())
.ok_or(ClientError::InternalError(
"cliprdr_backend returned None".to_string(),
))
}

/// Returns a mutable reference to the [`TeleportRdpdrBackend`] of the [`Rdpdr`] processor.
fn rdpdr_backend(
x224_processor: &mut X224Processor,
) -> ClientResult<&mut TeleportRdpdrBackend> {
x224_processor
.get_svc_processor_mut::<Rdpdr>()
.and_then(|c| c.downcast_backend_mut::<TeleportRdpdrBackend>())
.ok_or(ClientError::InternalError(
"rdpdr_backend returned None".to_string(),
))
}
}

impl Drop for Client {
Expand All @@ -607,6 +665,8 @@ pub enum ClientFunction {
HandleTdpSdAnnounce(tdp::SharedDirectoryAnnounce),
/// Corresponds to [`Client::handle_tdp_sd_info_response`]
HandleTdpSdInfoResponse(tdp::SharedDirectoryInfoResponse),
/// Corresponds to [`Client::handle_tdp_sd_create_response`]
HandleTdpSdCreateResponse(tdp::SharedDirectoryCreateResponse),
/// Corresponds to [`Client::write_cliprdr`]
WriteCliprdr(Box<dyn ClipboardFn>),
/// Corresponds to [`Client::update_clipboard`]
Expand Down Expand Up @@ -679,7 +739,7 @@ pub enum ClientError {
CGOErrCode(CGOErrCode),
SendError,
JoinError(JoinError),
InternalError,
InternalError(String),
UnknownAddress,
InputEventError(InputEventError),
#[cfg(feature = "fips")]
Expand All @@ -702,7 +762,7 @@ impl Display for ClientError {
ClientError::JoinError(e) => Display::fmt(e, f),
ClientError::CGOErrCode(e) => Debug::fmt(e, f),
ClientError::SendError => Display::fmt("Couldn't send message to channel", f),
ClientError::InternalError => Display::fmt("Internal error", f),
ClientError::InternalError(msg) => Display::fmt(msg, f),
ClientError::UnknownAddress => Display::fmt("Unknown address", f),
ClientError::PduError(e) => Display::fmt(e, f),
#[cfg(feature = "fips")]
Expand Down
10 changes: 5 additions & 5 deletions lib/srv/desktop/rdp/rdpclient/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ use ironrdp_pdu::{other_err, PduError};
use ironrdp_session::image::DecodedImage;
use rdpdr::path::UnixPath;
use rdpdr::tdp::{
FileSystemObject, FileType, SharedDirectoryAcknowledge, SharedDirectoryDeleteResponse,
SharedDirectoryInfoResponse, SharedDirectoryMoveResponse, SharedDirectoryWriteResponse,
TdpErrCode,
FileSystemObject, FileType, SharedDirectoryAcknowledge, SharedDirectoryCreateResponse,
SharedDirectoryDeleteResponse, SharedDirectoryInfoResponse, SharedDirectoryMoveResponse,
SharedDirectoryWriteResponse, TdpErrCode,
};
use std::convert::TryFrom;
use std::ffi::CString;
Expand Down Expand Up @@ -209,8 +209,8 @@ pub unsafe extern "C" fn client_handle_tdp_sd_create_response(
cgo_handle: CgoHandle,
res: CGOSharedDirectoryCreateResponse,
) -> CGOErrCode {
warn!("unimplemented: client_handle_tdp_sd_create_response");
CGOErrCode::ErrCodeSuccess
let res = SharedDirectoryCreateResponse::from(res);
call_function_on_handle(cgo_handle, ClientFunction::HandleTdpSdCreateResponse(res))
}

/// client_handle_tdp_sd_delete_response handles a TDP Shared Directory Delete Response
Expand Down
20 changes: 16 additions & 4 deletions lib/srv/desktop/rdp/rdpclient/src/rdpdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub(crate) mod tdp;

use self::filesystem::FilesystemBackend;
use self::scard::ScardBackend;
use self::tdp::SharedDirectoryInfoResponse;
use self::tdp::{SharedDirectoryCreateResponse, SharedDirectoryInfoResponse};
use crate::client::{ClientFunction, ClientHandle};
use crate::CgoHandle;
use ironrdp_pdu::{custom_err, PduResult};
Expand Down Expand Up @@ -49,7 +49,7 @@ impl RdpdrBackend for TeleportRdpdrBackend {
&mut self,
pdu: ServerDeviceAnnounceResponse,
) -> PduResult<()> {
if pdu.result_code != NtStatus::Success {
if pdu.result_code != NtStatus::SUCCESS {
return Err(custom_err!(
"TeleportRdpdrBackend::handle_server_device_announce_response",
TeleportRdpdrBackendError(format!(
Expand Down Expand Up @@ -98,9 +98,21 @@ impl TeleportRdpdrBackend {

pub fn handle_tdp_sd_info_response(
&mut self,
tdp_res: SharedDirectoryInfoResponse,
tdp_resp: SharedDirectoryInfoResponse,
) -> PduResult<()> {
if let Some(resp) = self.fs.handle_tdp_sd_info_response(tdp_res)? {
if let Some(resp) = self.fs.handle_tdp_sd_info_response(tdp_resp)? {
self.write_rdpdr(resp)
} else {
// Nothing to send back to the server
Ok(())
}
}

pub fn handle_tdp_sd_create_response(
&mut self,
tdp_resp: SharedDirectoryCreateResponse,
) -> PduResult<()> {
if let Some(resp) = self.fs.handle_tdp_sd_create_response(tdp_resp)? {
self.write_rdpdr(resp)
} else {
// Nothing to send back to the server
Expand Down
Loading
Loading