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

Removes a bunch of old deprecated code #33786

Merged
merged 2 commits into from
Oct 23, 2023
Merged
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
452 changes: 36 additions & 416 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 0 additions & 7 deletions lib/srv/desktop/rdp/rdpclient/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,13 @@ num-traits = "0.2.17"
rand = { version = "0.8.5", features = ["getrandom"] }
rand_chacha = "0.3.1"
rsa = "0.9.2"
rdp-rs = { git = "https://github.com/gravitational/rdp-rs", rev = "75eb6a30b83e7152ee6213964b5ac6e783304840" }
uuid = { version = "1.4.1", features = ["v4"] }
utf16string = "0.2.0"
png = "0.17.10"
parking_lot = "0.12.1"

bytes = "1"
futures-util = "0.3"
tokio = { version = "1.32", features = ["full"]}
tokio-util = { version = "0.7.4", features = ["compat"] }
tokio-rustls = { version = "0.24", features = ["dangerous_configuration"] }
x509-parser = "0.14"
sspi = { version = "0.10.1", features = ["network_client", "dns_resolver"] }
static_init = "1.0.3"
Expand Down Expand Up @@ -67,6 +63,3 @@ ironrdp-cliprdr = { git = "https://github.com/Devolutions/IronRDP", rev = "47bc4
[build-dependencies]
cbindgen = "0.26.0"
tempfile = "3.8.0"

[features]
fips = ["rdp-rs/fips"]
10 changes: 4 additions & 6 deletions lib/srv/desktop/rdp/rdpclient/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use bitflags::Flags;
use bytes::BytesMut;
use ironrdp_cliprdr::{Cliprdr, CliprdrSvcMessages};
use ironrdp_connector::{Config, ConnectorError, Credentials};
Expand All @@ -7,7 +6,6 @@ use ironrdp_pdu::input::mouse::PointerFlags;
use ironrdp_pdu::input::{InputEventError, MousePdu};
use ironrdp_pdu::nego::SecurityProtocol;
use ironrdp_pdu::rdp::capability_sets::MajorPlatformType;
use ironrdp_pdu::rdp::client_info::ClientInfoFlags;
use ironrdp_pdu::rdp::RdpError;
use ironrdp_pdu::{PduError, PduParsing};
use ironrdp_rdpdr::pdu::RdpdrPdu;
Expand All @@ -32,12 +30,12 @@ use tokio::task::JoinError;
pub(crate) use global::call_function_on_handle;

use crate::{
cliprdr, handle_fastpath_pdu, handle_rdp_channel_ids, handle_remote_copy, CGOErrCode,
CGOKeyboardEvent, CGOMousePointerEvent, CGOPointerButton, CGOPointerWheel, CgoHandle,
handle_fastpath_pdu, handle_rdp_channel_ids, handle_remote_copy, CGOErrCode, CGOKeyboardEvent,
CGOMousePointerEvent, CGOPointerButton, CGOPointerWheel, CgoHandle,
};
// Export this for crate level use.
use crate::cliprdr::{available_formats, ClipboardFn, TeleportCliprdrBackend};
use crate::rdpdr::consts::SCARD_DEVICE_ID;
use crate::cliprdr::{ClipboardFn, TeleportCliprdrBackend};
use crate::rdpdr::scard::SCARD_DEVICE_ID;
use crate::rdpdr::TeleportRdpdrBackend;

pub mod global;
Expand Down
323 changes: 0 additions & 323 deletions lib/srv/desktop/rdp/rdpclient/src/cliprdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use futures_util::future::err;
use std::fmt::{Debug, Formatter};

use ironrdp_cliprdr::backend::CliprdrBackend;
Expand Down Expand Up @@ -292,329 +291,7 @@ fn convert_string(data: &String, format_id: ClipboardFormatId) -> Option<Vec<u8>
mod tests {
use ironrdp_cliprdr::pdu::ClipboardFormatId;

use super::*;
use crate::cliprdr::convert_string;
use std::io::Cursor;
use std::sync::mpsc::channel;

#[test]
fn decode_clipboard_overflow() {
// a single byte is invalid for CF_UNICODETEXT
let result = decode_clipboard(vec![54u8], ClipboardFormat::CF_UNICODETEXT).unwrap();
assert!(result.is_empty());
}

#[test]
fn encode_format_list_short() {
let client = Client::default();
let msg = client
.add_headers_and_chunkify(
ClipboardPDUType::CB_FORMAT_LIST,
FormatListPDU {
format_names: vec![ShortFormatName::id(ClipboardFormat::CF_TEXT as u32)],
}
.encode()
.unwrap(),
)
.unwrap();

assert_eq!(
msg[0],
vec![
// virtual channel header
0x2C, 0x00, 0x00, 0x00, // length (44 bytes)
0x13, 0x00, 0x00, 0x00, // flags (first + last + show protocol)
// Clipboard PDU Header
0x02, 0x00, // message type
0x00, 0x00, // message flags (CB_ASCII_NAMES not set)
0x24, 0x00, 0x00, 0x00, // message length (36 bytes after header)
// Format List PDU starts here
0x01, 0x00, 0x00, 0x00, // format ID (CF_TEXT)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // format name (bytes 1-8)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // format name (bytes 9-16)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // format name (bytes 17-24)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // format name (bytes 25-32)
]
);
}

#[test]
fn encode_format_list_long() {
let empty = FormatListPDU::<LongFormatName> {
format_names: vec![LongFormatName::id(0)],
};

let client = Client::default();

let encoded = client
.add_headers_and_chunkify(ClipboardPDUType::CB_FORMAT_LIST, empty.encode().unwrap())
.unwrap();

assert_eq!(
encoded[0],
vec![
0x0e, 0x00, 0x00, 0x00, // message length (14 bytes)
0x13, 0x00, 0x00, 0x00, // flags (first + last + show protocol)
0x02, 0x00, 0x00, 0x00, // message type (format list), and flags (0)
0x06, 0x00, 0x00, 0x00, // message length (6 bytes)
0x00, 0x00, 0x00, 0x00, // format id 0
0x00, 0x00 // null terminator
]
);
}

#[test]
fn encode_clipboard_capabilities() {
let msg = ClipboardCapabilitiesPDU {
general: Some(GeneralClipboardCapabilitySet {
version: CB_CAPS_VERSION_2,
flags: ClipboardGeneralCapabilityFlags::from_bits_truncate(0),
}),
}
.encode()
.unwrap();

assert_eq!(
msg,
vec![
0x01, 0x00, 0x00, 0x00, // count, pad
0x01, 0x00, 0x0C, 0x00, // type, length
0x02, 0x00, 0x00, 0x00, // version (2)
0x00, 0x00, 0x00, 0x00, // flags (0)
]
)
}

#[test]
fn decode_clipboard_capabilities() {
let msg = ClipboardCapabilitiesPDU::decode(&mut Cursor::new(vec![
0x01, 0x00, 0x00, 0x00, // count, pad
0x01, 0x00, 0x0C, 0x00, // type, length
0x02, 0x00, 0x00, 0x00, // version (2)
0x00, 0x00, 0x00, 0x00, // flags (0)
]))
.unwrap();

let general_set = msg.general.unwrap();
assert_eq!(general_set.flags.bits(), 0);
assert_eq!(general_set.version, CB_CAPS_VERSION_2);
}

#[test]
fn decode_format_list_long() {
let no_name = vec![0x01, 0x00, 0x00, 0x00, 0x00, 0x00];
let l = no_name.len();
let decoded =
FormatListPDU::<LongFormatName>::decode(&mut Cursor::new(no_name), l as u32).unwrap();
assert_eq!(decoded.format_names.len(), 1);
assert_eq!(
decoded.format_names[0].format_id,
ClipboardFormat::CF_TEXT as u32
);
assert_eq!(decoded.format_names[0].format_name, None);

let one_name = vec![
0x01, 0x00, 0x00, 0x00, // CF_TEXT
0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, // "test"
0x00, 0x00, // null terminator
];
let l = one_name.len();
let decoded =
FormatListPDU::<LongFormatName>::decode(&mut Cursor::new(one_name), l as u32).unwrap();
assert_eq!(decoded.format_names.len(), 1);
assert_eq!(
decoded.format_names[0].format_id,
ClipboardFormat::CF_TEXT as u32
);
assert_eq!(
decoded.format_names[0].format_name,
Some(String::from("test"))
);

let two_names = vec![
0x01, 0x00, 0x00, 0x00, // CF_TEXT
0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, // "test"
0x00, 0x00, // null terminator
0x01, 0x00, 0x00, 0x00, // CF_TEXT
0x74, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x65, 0x00, // "tele"
0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x74, 0x00, // "port"
0x00, 0x00, // null terminator
];
let l = two_names.len();
let decoded =
FormatListPDU::<LongFormatName>::decode(&mut Cursor::new(two_names), l as u32).unwrap();
assert_eq!(decoded.format_names.len(), 2);
assert_eq!(
decoded.format_names[0].format_id,
ClipboardFormat::CF_TEXT as u32
);
assert_eq!(
decoded.format_names[0].format_name,
Some(String::from("test"))
);
assert_eq!(
decoded.format_names[1].format_id,
ClipboardFormat::CF_TEXT as u32
);
assert_eq!(
decoded.format_names[1].format_name,
Some(String::from("teleport"))
);
}

#[test]
fn responds_to_monitor_ready() {
let c: Client = Default::default();
let responses = c
.handle_monitor_ready(&mut Cursor::new(Vec::new()))
.unwrap();
assert_eq!(2, responses.len());

// First response - our client capabilities:
let mut payload = Cursor::new(responses[0].clone());
let _pdu_header = vchan::ChannelPDUHeader::decode(&mut payload).unwrap();
let header = ClipboardPDUHeader::decode(&mut payload).unwrap();
assert_eq!(header.msg_type, ClipboardPDUType::CB_CLIP_CAPS);

let capabilities = ClipboardCapabilitiesPDU::decode(&mut payload).unwrap();
let general = capabilities.general.unwrap();
assert_eq!(
general.flags,
ClipboardGeneralCapabilityFlags::CB_USE_LONG_FORMAT_NAMES
);

// Second response - the format list PDU:
let mut payload = Cursor::new(responses[1].clone());
let _pdu_header = vchan::ChannelPDUHeader::decode(&mut payload).unwrap();
let header = ClipboardPDUHeader::decode(&mut payload).unwrap();
assert_eq!(header.msg_type, ClipboardPDUType::CB_FORMAT_LIST);
assert_eq!(header.msg_flags.bits(), 0);
assert_eq!(header.data_len, 6);

let format_list =
FormatListPDU::<LongFormatName>::decode(&mut payload, header.data_len).unwrap();
assert_eq!(format_list.format_names.len(), 1);
assert_eq!(format_list.format_names[0].format_id, 0);
assert_eq!(format_list.format_names[0].format_name, None);
}

#[test]
fn encodes_large_format_data_response() {
let mut data = vec![0; vchan::CHANNEL_CHUNK_LEGNTH + 2];
for (i, item) in data.iter_mut().enumerate() {
*item = (i % 256) as u8;
}
let pdu = FormatDataResponsePDU { data };
let encoded = pdu.encode().unwrap();
let client = Client::default();
let messages = client
.add_headers_and_chunkify(ClipboardPDUType::CB_FORMAT_DATA_RESPONSE, encoded)
.unwrap();
assert_eq!(2, messages.len());

let header0 =
vchan::ChannelPDUHeader::decode(&mut Cursor::new(messages[0].clone())).unwrap();
assert_eq!(
ChannelPDUFlags::CHANNEL_FLAG_FIRST | ChannelPDUFlags::CHANNEL_FLAG_SHOW_PROTOCOL,
header0.flags
);
let header1 =
vchan::ChannelPDUHeader::decode(&mut Cursor::new(messages[1].clone())).unwrap();
assert_eq!(
ChannelPDUFlags::CHANNEL_FLAG_LAST | ChannelPDUFlags::CHANNEL_FLAG_SHOW_PROTOCOL,
header1.flags
);
}

#[test]
fn responds_to_format_data_request_hasdata() {
// a null-terminated utf-16 string, represented as a Vec<u8>
let test_data = util::to_unicode("test", true);

let mut c: Client = Default::default();
c.clipboard
.insert(ClipboardFormat::CF_UNICODETEXT as u32, test_data.clone());

let req = FormatDataRequestPDU::for_id(ClipboardFormat::CF_UNICODETEXT as u32);
let responses = c
.handle_format_data_request(&mut Cursor::new(req.encode().unwrap()))
.unwrap();

// expect one FormatDataResponsePDU
assert_eq!(responses.len(), 1);
let mut payload = Cursor::new(responses[0].clone());
let _pdu_header = vchan::ChannelPDUHeader::decode(&mut payload).unwrap();
let header = ClipboardPDUHeader::decode(&mut payload).unwrap();
assert_eq!(header.msg_type, ClipboardPDUType::CB_FORMAT_DATA_RESPONSE);
assert_eq!(header.msg_flags, ClipboardHeaderFlags::CB_RESPONSE_OK);
assert_eq!(header.data_len, 10);
let resp = FormatDataResponsePDU::decode(&mut payload, header.data_len).unwrap();
assert_eq!(resp.data, test_data);
}

#[test]
fn invokes_callback_with_clipboard_data() {
let (send, recv) = channel();

let mut c = Client::new(Box::new(move |vec| {
send.send(vec).unwrap();
Ok(())
}));

let data_format_list = FormatListPDU {
format_names: vec![LongFormatName {
format_id: ClipboardFormat::CF_TEXT as u32,
format_name: None,
}],
}
.encode()
.unwrap();

let data_resp = FormatDataResponsePDU {
data: String::from("abc\0").into_bytes(),
}
.encode()
.unwrap();

let mut len = data_format_list.len() as u32;
c.handle_format_list(&mut Cursor::new(data_format_list), len)
.unwrap();

len = data_resp.len() as u32;
c.handle_format_data_response(&mut Cursor::new(data_resp), len)
.unwrap();

// ensure that the null terminator was trimmed
let received = recv.try_recv().unwrap();
assert_eq!(received, String::from("abc").into_bytes());
}

#[test]
fn update_clipboard_returns_format_list_pdu() {
let mut c: Client = Default::default();
let messages = c.update_clipboard("abc".to_owned()).unwrap();
let bytes = messages[0].clone();

// verify that it returns a properly encoded format list PDU
let mut payload = Cursor::new(bytes);
let _pdu_header = vchan::ChannelPDUHeader::decode(&mut payload).unwrap();
let header = ClipboardPDUHeader::decode(&mut payload).unwrap();
let format_list =
FormatListPDU::<LongFormatName>::decode(&mut payload, header.data_len).unwrap();
assert_eq!(ClipboardPDUType::CB_FORMAT_LIST, header.msg_type);
assert_eq!(1, format_list.format_names.len());
assert_eq!(
ClipboardFormat::CF_TEXT as u32,
format_list.format_names[0].format_id
);

// verify that the clipboard data is now cached
// (with a null-terminating character)
assert_eq!(
String::from("abc\0").into_bytes(),
*c.clipboard.get(&(ClipboardFormat::CF_TEXT as u32)).unwrap()
);
}

#[test]
fn update_clipboard_conversion() {
Expand Down
Loading