mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
chore: remove now-proto-pdu crate (#633)
This commit is contained in:
Generated
-10
@@ -2713,7 +2713,6 @@ dependencies = [
|
||||
"ironrdp-rdpsnd",
|
||||
"ironrdp-session",
|
||||
"lazy_static",
|
||||
"now-proto-pdu",
|
||||
"paste",
|
||||
"png",
|
||||
"pretty_assertions",
|
||||
@@ -3178,15 +3177,6 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "now-proto-pdu"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"ironrdp-core",
|
||||
"ironrdp-pdu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
||||
@@ -55,7 +55,6 @@ ironrdp-testsuite-core = { path = "crates/ironrdp-testsuite-core" }
|
||||
ironrdp-tls = { version = "0.1", path = "crates/ironrdp-tls" }
|
||||
ironrdp-tokio = { version = "0.2", path = "crates/ironrdp-tokio" }
|
||||
ironrdp = { version = "0.7", path = "crates/ironrdp" }
|
||||
now-proto-pdu = { version = "0.1", path = "crates/now-proto-pdu" }
|
||||
|
||||
bitflags = "2.4"
|
||||
expect-test = "1"
|
||||
|
||||
@@ -21,7 +21,6 @@ expect-test = "1"
|
||||
ironrdp-core.workspace = true
|
||||
ironrdp-pdu.workspace = true
|
||||
lazy_static.workspace = true # TODO: remove in favor of https://doc.rust-lang.org/std/sync/struct.OnceLock.html
|
||||
now-proto-pdu.workspace = true
|
||||
paste = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -31,7 +31,5 @@ pub mod network_data;
|
||||
pub mod rdp;
|
||||
pub mod security_data;
|
||||
|
||||
pub mod now_proto;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use paste::paste;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
//! Various test utilities
|
||||
use expect_test::Expect;
|
||||
use ironrdp_core::{Decode as _, ReadCursor};
|
||||
use now_proto_pdu::NowMessage;
|
||||
|
||||
pub fn now_msg_roundtrip(msg: impl Into<NowMessage>, expected_bytes: Expect) {
|
||||
let msg = msg.into();
|
||||
|
||||
let buf = ironrdp_core::encode_vec(&msg).unwrap();
|
||||
|
||||
expected_bytes.assert_eq(&format!("{:02X?}", buf));
|
||||
|
||||
let mut cursor = ReadCursor::new(&buf);
|
||||
let decoded = NowMessage::decode(&mut cursor).unwrap();
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
@@ -17,7 +17,6 @@ mod dvc;
|
||||
mod fuzz_regression;
|
||||
mod graphics;
|
||||
mod input;
|
||||
mod now_proto;
|
||||
mod pcb;
|
||||
mod pdu;
|
||||
mod rdcleanpath;
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
use now_proto_pdu::*;
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
#[case(b"hello", &[0x05, 0x00, 0x00, 0x00, b'h', b'e', b'l', b'l', b'o'])]
|
||||
#[case(&[], &[0x00, 0x00, 0x00, 0x00])]
|
||||
fn now_lrgbuf_roundtrip(#[case] value: &[u8], #[case] expected_encoded: &[u8]) {
|
||||
let mut encoded_value = [0u8; 32];
|
||||
let encoded_size = ironrdp_core::encode(&NowLrgBuf::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<NowLrgBuf>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(b"hello", &[0x05, b'h', b'e', b'l', b'l', b'o'])]
|
||||
#[case(&[], &[0x00])]
|
||||
fn now_varbuf_roundtrip(#[case] value: &[u8], #[case] expected_encoded: &[u8]) {
|
||||
let mut encoded_value = [0u8; 32];
|
||||
let encoded_size = ironrdp_core::encode(&NowVarBuf::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<NowVarBuf>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
use expect_test::expect;
|
||||
use ironrdp_testsuite_core::now_proto::now_msg_roundtrip;
|
||||
use now_proto_pdu::*;
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_capset() {
|
||||
now_msg_roundtrip(
|
||||
NowExecCapsetMsg::new(NowExecCapsetFlags::all()),
|
||||
expect!["[00, 00, 00, 00, 13, 00, FF, 00]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_abort() {
|
||||
now_msg_roundtrip(
|
||||
NowExecAbortMsg::new(0x12345678, NowStatus::new(NowSeverity::Fatal, NowStatusCode::FAILURE)),
|
||||
expect!["[08, 00, 00, 00, 13, 01, 00, 00, 78, 56, 34, 12, C0, 00, FF, FF]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_cancel_req() {
|
||||
now_msg_roundtrip(
|
||||
NowExecCancelReqMsg::new(0x12345678),
|
||||
expect!["[04, 00, 00, 00, 13, 02, 00, 00, 78, 56, 34, 12]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_cancel_rsp() {
|
||||
now_msg_roundtrip(
|
||||
NowExecCancelRspMsg::new(0x12345678, NowStatus::new(NowSeverity::Error, NowStatusCode::FAILURE)),
|
||||
expect!["[08, 00, 00, 00, 13, 03, 00, 00, 78, 56, 34, 12, 80, 00, FF, FF]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_result() {
|
||||
now_msg_roundtrip(
|
||||
NowExecResultMsg::new(0x12345678, NowStatus::new(NowSeverity::Error, NowStatusCode::FAILURE)),
|
||||
expect!["[08, 00, 00, 00, 13, 04, 00, 00, 78, 56, 34, 12, 80, 00, FF, FF]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_data() {
|
||||
now_msg_roundtrip(
|
||||
NowExecDataMsg::new(
|
||||
NowExecDataFlags::LAST,
|
||||
0x12345678,
|
||||
NowVarBuf::new(vec![0x01, 0x02, 0x03]).unwrap(),
|
||||
),
|
||||
expect!["[08, 00, 00, 00, 13, 05, 02, 00, 78, 56, 34, 12, 03, 01, 02, 03]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_run() {
|
||||
now_msg_roundtrip(
|
||||
NowExecRunMsg::new(0x1234567, NowVarStr::new("hello".to_owned()).unwrap()).unwrap(),
|
||||
expect!["[0B, 00, 00, 00, 13, 10, 00, 00, 67, 45, 23, 01, 05, 68, 65, 6C, 6C, 6F, 00]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_process() {
|
||||
now_msg_roundtrip(
|
||||
NowExecProcessMsg::new(
|
||||
0x12345678,
|
||||
NowVarStr::new("a".to_owned()).unwrap(),
|
||||
NowVarStr::new("b".to_owned()).unwrap(),
|
||||
NowVarStr::new("c".to_owned()).unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
expect!["[0D, 00, 00, 00, 13, 12, 00, 00, 78, 56, 34, 12, 01, 61, 00, 01, 62, 00, 01, 63, 00]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_shell() {
|
||||
now_msg_roundtrip(
|
||||
NowExecShellMsg::new(
|
||||
0x12345678,
|
||||
NowVarStr::new("a".to_owned()).unwrap(),
|
||||
NowVarStr::new("b".to_owned()).unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
expect!["[0A, 00, 00, 00, 13, 13, 00, 00, 78, 56, 34, 12, 01, 61, 00, 01, 62, 00]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_batch() {
|
||||
now_msg_roundtrip(
|
||||
NowExecBatchMsg::new(0x12345678, NowVarStr::new("a".to_owned()).unwrap()),
|
||||
expect!["[07, 00, 00, 00, 13, 14, 00, 00, 78, 56, 34, 12, 01, 61, 00]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_ps() {
|
||||
now_msg_roundtrip(
|
||||
NowExecWinPsMsg::new(0x12345678, NowVarStr::new("a".to_owned()).unwrap())
|
||||
.unwrap()
|
||||
.with_flags(NowExecWinPsFlags::NO_PROFILE)
|
||||
.with_execution_policy(NowVarStr::new("b".to_owned()).unwrap())
|
||||
.unwrap()
|
||||
.with_configuration_name(NowVarStr::new("c".to_owned()).unwrap())
|
||||
.unwrap(),
|
||||
expect!["[0D, 00, 00, 00, 13, 15, D0, 00, 78, 56, 34, 12, 01, 61, 00, 01, 62, 00, 01, 63, 00]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_exec_pwsh() {
|
||||
now_msg_roundtrip(
|
||||
NowExecPwshMsg::new(0x12345678, NowVarStr::new("a".to_owned()).unwrap())
|
||||
.unwrap()
|
||||
.with_flags(NowExecWinPsFlags::NO_PROFILE)
|
||||
.with_execution_policy(NowVarStr::new("b".to_owned()).unwrap())
|
||||
.unwrap()
|
||||
.with_configuration_name(NowVarStr::new("c".to_owned()).unwrap())
|
||||
.unwrap(),
|
||||
expect!["[0D, 00, 00, 00, 13, 16, D0, 00, 78, 56, 34, 12, 01, 61, 00, 01, 62, 00, 01, 63, 00]"],
|
||||
);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
mod buffer;
|
||||
mod exec;
|
||||
mod number;
|
||||
mod session;
|
||||
mod status;
|
||||
mod string;
|
||||
mod system;
|
||||
@@ -1,127 +0,0 @@
|
||||
use now_proto_pdu::*;
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
#[case(0x00, &[0x00])]
|
||||
#[case(0x7F, &[0x7F])]
|
||||
#[case(0x80, &[0x80, 0x80])]
|
||||
fn var_u16_roundtrip(#[case] value: u16, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 4];
|
||||
let encoded_size = ironrdp_core::encode(&VarU16::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<VarU16>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0x00, &[0x00])]
|
||||
#[case(0x3F, &[0x3F])]
|
||||
#[case(0x40, &[0x80, 0x40])]
|
||||
#[case(-0x3F, &[0x7F])]
|
||||
#[case(-0x40, &[0xC0, 0x40])]
|
||||
fn var_i16_roundtrip(#[case] value: i16, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 4];
|
||||
let encoded_size = ironrdp_core::encode(&VarI16::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<VarI16>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0x00, &[0x00])]
|
||||
#[case(0x3F, &[0x3F])]
|
||||
#[case(0x40, &[0x40, 0x40])]
|
||||
#[case(0x14000, &[0x81, 0x40, 0x00])]
|
||||
#[case(0x3FFFFFFF, &[0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
fn var_u32_roundtrip(#[case] value: u32, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 4];
|
||||
let encoded_size = ironrdp_core::encode(&VarU32::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<VarU32>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0x00, &[0x00])]
|
||||
#[case(0x1F, &[0x1F])]
|
||||
#[case(0x20, &[0x40, 0x20])]
|
||||
#[case(0x14000, &[0x81, 0x40, 0x00])]
|
||||
#[case(0x1FFFFFFF, &[0xDF, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(-0x1F, &[0x3F])]
|
||||
#[case(-0x1FFFFFFF, &[0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
fn var_i32_roundtrip(#[case] value: i32, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 4];
|
||||
let encoded_size = ironrdp_core::encode(&VarI32::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<VarI32>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0x00, &[0x00])]
|
||||
#[case(0x1F, &[0x1F])]
|
||||
#[case(0x20, &[0x20, 0x20])]
|
||||
#[case(0x14000, &[0x41, 0x40, 0x00])]
|
||||
#[case(0x1FFFFFFF, &[0x7F, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(0x1FFFFFFFFF, &[0x9F, 0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(0x1FFFFFFFFFFF, &[0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(0x1FFFFFFFFFFFFF, &[0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(0x1FFFFFFFFFFFFFFF, &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
fn var_u64_roundtrip(#[case] value: u64, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 8];
|
||||
let encoded_size = ironrdp_core::encode(&VarU64::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<VarU64>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0x00, &[0x00])]
|
||||
#[case(0x0F, &[0x0F])]
|
||||
#[case(0x10, &[0x20, 0x10])]
|
||||
#[case(0x021400, &[0x42, 0x14, 0x00])]
|
||||
#[case(0x0FFFFFFF, &[0x6F, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(0x0FFFFFFFFF, &[0x8F, 0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(0x0FFFFFFFFFFF, &[0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(0x0FFFFFFFFFFFFF, &[0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(0x0FFFFFFFFFFFFFFF, &[0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])]
|
||||
#[case(-0x0F, &[0x1F])]
|
||||
#[case(-0x0FFFFFFF, &[0x7F, 0xFF, 0xFF, 0xFF])]
|
||||
fn var_i64_roundtrip(#[case] value: i64, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 8];
|
||||
let encoded_size = ironrdp_core::encode(&VarI64::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<VarI64>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constructed_var_int_too_large() {
|
||||
VarU16::new(0x8000).unwrap_err();
|
||||
VarI16::new(0x4000).unwrap_err();
|
||||
VarI16::new(-0x4000).unwrap_err();
|
||||
VarU32::new(0x40000000).unwrap_err();
|
||||
VarI32::new(0x20000000).unwrap_err();
|
||||
VarI32::new(-0x20000000).unwrap_err();
|
||||
VarU64::new(0x2000000000000000).unwrap_err();
|
||||
VarI64::new(0x1000000000000000).unwrap_err();
|
||||
VarI64::new(-0x1000000000000000).unwrap_err();
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
use expect_test::expect;
|
||||
use ironrdp_testsuite_core::now_proto::now_msg_roundtrip;
|
||||
use now_proto_pdu::*;
|
||||
|
||||
#[test]
|
||||
fn roundtrip_session_lock() {
|
||||
now_msg_roundtrip(
|
||||
NowSessionLockMsg::default(),
|
||||
expect!["[00, 00, 00, 00, 12, 01, 00, 00]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_session_logoff() {
|
||||
now_msg_roundtrip(
|
||||
NowSessionLogoffMsg::default(),
|
||||
expect!["[00, 00, 00, 00, 12, 02, 00, 00]"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtip_session_msgbox_req() {
|
||||
now_msg_roundtrip(
|
||||
NowSessionMsgBoxReqMsg::new(
|
||||
0x76543210,
|
||||
NowVarStr::new("hello".to_owned()).unwrap(),
|
||||
).unwrap().with_response().with_style(NowMessageBoxStyle::ABORT_RETRY_IGNORE)
|
||||
.with_title(NowVarStr::new("world".to_owned()).unwrap())
|
||||
.unwrap()
|
||||
.with_timeout(3),
|
||||
expect!["[1A, 00, 00, 00, 12, 03, 0F, 00, 10, 32, 54, 76, 02, 00, 00, 00, 03, 00, 00, 00, 05, 77, 6F, 72, 6C, 64, 00, 05, 68, 65, 6C, 6C, 6F, 00]"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_session_msgbox_rsp() {
|
||||
now_msg_roundtrip(
|
||||
NowSessionMsgBoxRspMsg::new(0x01234567, NowMsgBoxResponse::RETRY),
|
||||
expect!["[08, 00, 00, 00, 12, 04, 00, 00, 67, 45, 23, 01, 04, 00, 00, 00]"],
|
||||
);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
use ironrdp_core::{Decode as _, Encode as _, ReadCursor, WriteCursor};
|
||||
use now_proto_pdu::{NowSeverity, NowStatus, NowStatusCode};
|
||||
|
||||
#[test]
|
||||
fn now_status_roundtrip() {
|
||||
let status = NowStatus::new(NowSeverity::Error, NowStatusCode::FILE_NOT_FOUND)
|
||||
.with_kind(0x07)
|
||||
.unwrap();
|
||||
|
||||
let mut buf = [0; 4];
|
||||
let mut cursor = WriteCursor::new(&mut buf);
|
||||
status.encode(&mut cursor).unwrap();
|
||||
|
||||
assert_eq!(&buf, &[0x80, 0x07, 0x02, 0x00]);
|
||||
|
||||
let mut cursor = ReadCursor::new(&buf);
|
||||
let decoded = NowStatus::decode(&mut cursor).unwrap();
|
||||
|
||||
assert_eq!(status, decoded);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
use now_proto_pdu::*;
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
#[case("hello", &[0x05, 0x00, 0x00, 0x00, b'h', b'e', b'l', b'l', b'o', 0x00])]
|
||||
#[case("", &[0x00, 0x00, 0x00, 0x00, 0x00])]
|
||||
fn now_lrgstr_roundtrip(#[case] value: &str, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 32];
|
||||
let encoded_size = ironrdp_core::encode(&NowLrgStr::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<NowLrgStr>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decoded_now_lrgstr_invalid_utf8() {
|
||||
let encoded = [0x01, 0x00, 0x00, 0x00, 0xFF, 0x00];
|
||||
ironrdp_core::decode::<NowLrgStr>(&encoded).unwrap_err();
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case("hello", &[0x05, b'h', b'e', b'l', b'l', b'o', 0x00])]
|
||||
#[case("", &[0x00, 0x00])]
|
||||
fn now_varstr_roundtrip(#[case] value: &str, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 32];
|
||||
let encoded_size = ironrdp_core::encode(&NowVarStr::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<NowVarStr>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decoded_now_varstr_invalid_utf8() {
|
||||
let encoded = [0x01, 0xFF, 0x00];
|
||||
ironrdp_core::decode::<NowLrgStr>(&encoded).unwrap_err();
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case("hello", &[0x05, b'h', b'e', b'l', b'l', b'o', 0x00])]
|
||||
#[case("", &[0x00, 0x00])]
|
||||
fn now_restricted_string_roundtrip(#[case] value: &str, #[case] expected_encoded: &'static [u8]) {
|
||||
let mut encoded_value = [0u8; 32];
|
||||
let encoded_size = ironrdp_core::encode(&NowString16::new(value).unwrap(), &mut encoded_value).unwrap();
|
||||
|
||||
assert_eq!(encoded_size, expected_encoded.len());
|
||||
assert_eq!(&encoded_value[..encoded_size], expected_encoded);
|
||||
|
||||
let decoded_value = ironrdp_core::decode::<NowString16>(&encoded_value).unwrap();
|
||||
assert_eq!(decoded_value.value(), value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn now_restricted_string_too_large_constructed() {
|
||||
let value = "a".repeat(16);
|
||||
NowString16::new(value).unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decoded_now_restricted_string_invalid_utf8() {
|
||||
let encoded = [0x01, 0xFF, 0x00];
|
||||
ironrdp_core::decode::<NowString16>(&encoded).unwrap_err();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
use expect_test::expect;
|
||||
use ironrdp_testsuite_core::now_proto::now_msg_roundtrip;
|
||||
use now_proto_pdu::*;
|
||||
|
||||
#[test]
|
||||
fn roundtip_system_shutdown() {
|
||||
now_msg_roundtrip(
|
||||
NowSystemShutdownMsg::new(
|
||||
NowSystemShutdownFlags::FORCE,
|
||||
0x12345678,
|
||||
NowVarStr::new("hello".to_owned()).unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
expect!["[0B, 00, 00, 00, 11, 03, 01, 00, 78, 56, 34, 12, 05, 68, 65, 6C, 6C, 6F, 00]"],
|
||||
);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
[package]
|
||||
name = "now-proto-pdu"
|
||||
version = "0.1.0"
|
||||
readme = "README.md"
|
||||
description = "NOW protocol PDU encoding and decoding"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
authors.workspace = true
|
||||
keywords.workspace = true
|
||||
categories.workspace = true
|
||||
|
||||
# FIXME: Will be published once moved to Devolutions/proto-proto
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
test = false
|
||||
|
||||
[dependencies]
|
||||
bitflags = "2"
|
||||
ironrdp-core.workspace = true
|
||||
ironrdp-pdu = { path = "../ironrdp-pdu" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = ["ironrdp-pdu/std", "ironrdp-core/std"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -1,7 +0,0 @@
|
||||
# IronRDP now-proto-pdu
|
||||
|
||||
The NOW virtual channel protocol use an RDP dynamic virtual channel ("Devolutions::Now::Agent") as a transport type.
|
||||
|
||||
This crate is part of the [IronRDP] project.
|
||||
|
||||
[IronRDP]: https://github.com/Devolutions/IronRDP
|
||||
@@ -1,174 +0,0 @@
|
||||
//! Buffer types for NOW protocol.
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use ironrdp_core::{
|
||||
cast_length, ensure_fixed_part_size, ensure_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult,
|
||||
ReadCursor, WriteCursor,
|
||||
};
|
||||
|
||||
use crate::VarU32;
|
||||
|
||||
/// String value up to 2^32 bytes long.
|
||||
///
|
||||
/// NOW-PROTO: NOW_LRGBUF
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct NowLrgBuf(Vec<u8>);
|
||||
|
||||
impl NowLrgBuf {
|
||||
const NAME: &'static str = "NOW_LRGBUF";
|
||||
const FIXED_PART_SIZE: usize = 4;
|
||||
|
||||
/// Create a new `NowLrgBuf` instance. Returns an error if the provided value is too large.
|
||||
pub fn new(value: impl Into<Vec<u8>>) -> DecodeResult<Self> {
|
||||
let value: Vec<u8> = value.into();
|
||||
|
||||
if value.len() > VarU32::MAX as usize {
|
||||
return Err(invalid_field_err!("data", "data is too large for NOW_LRGBUF"));
|
||||
}
|
||||
|
||||
Self::ensure_message_size(value.len())?;
|
||||
|
||||
Ok(NowLrgBuf(value))
|
||||
}
|
||||
|
||||
/// Get the buffer value.
|
||||
pub fn value(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
|
||||
fn ensure_message_size(buffer_size: usize) -> DecodeResult<()> {
|
||||
if buffer_size > usize::try_from(VarU32::MAX).expect("BUG: too small usize") {
|
||||
return Err(invalid_field_err!("data", "data is too large for NOW_LRGBUF"));
|
||||
}
|
||||
|
||||
if buffer_size > usize::MAX - Self::FIXED_PART_SIZE {
|
||||
return Err(invalid_field_err!(
|
||||
"data",
|
||||
"data size is too large to fit in 32-bit usize"
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for NowLrgBuf {
|
||||
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
|
||||
let encoded_size = self.size();
|
||||
ensure_size!(in: dst, size: encoded_size);
|
||||
|
||||
let len: u32 = self.0.len().try_into().expect("BUG: validated in constructor");
|
||||
|
||||
dst.write_u32(len);
|
||||
dst.write_slice(self.0.as_slice());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
Self::NAME
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
// <u32 size> + <data bytes>
|
||||
Self::FIXED_PART_SIZE
|
||||
.checked_add(self.0.len())
|
||||
.expect("BUG: size overflow")
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode<'_> for NowLrgBuf {
|
||||
fn decode(src: &mut ReadCursor<'_>) -> DecodeResult<Self> {
|
||||
ensure_fixed_part_size!(in: src);
|
||||
|
||||
let len: usize = cast_length!("len", src.read_u32())?;
|
||||
|
||||
Self::ensure_message_size(len)?;
|
||||
|
||||
ensure_size!(in: src, size: len);
|
||||
let bytes = src.read_slice(len);
|
||||
|
||||
Ok(NowLrgBuf(bytes.to_vec()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NowLrgBuf> for Vec<u8> {
|
||||
fn from(buf: NowLrgBuf) -> Self {
|
||||
buf.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Buffer up to 2^31 bytes long (Length has compact variable length encoding).
|
||||
///
|
||||
/// NOW-PROTO: NOW_VARBUF
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct NowVarBuf(Vec<u8>);
|
||||
|
||||
impl NowVarBuf {
|
||||
const NAME: &'static str = "NOW_VARBUF";
|
||||
|
||||
/// Create a new `NowVarBuf` instance. Returns an error if the provided value is too large.
|
||||
pub fn new(value: impl Into<Vec<u8>>) -> DecodeResult<Self> {
|
||||
let value = value.into();
|
||||
|
||||
let _: u32 = value
|
||||
.len()
|
||||
.try_into()
|
||||
.ok()
|
||||
.and_then(|val| if val <= VarU32::MAX { Some(val) } else { None })
|
||||
.ok_or_else(|| invalid_field_err!("data", "too large buffer"))?;
|
||||
|
||||
Ok(NowVarBuf(value))
|
||||
}
|
||||
|
||||
/// Get the buffer value.
|
||||
pub fn value(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for NowVarBuf {
|
||||
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
|
||||
let encoded_size = self.size();
|
||||
ensure_size!(in: dst, size: encoded_size);
|
||||
|
||||
let len: u32 = self.0.len().try_into().expect("BUG: validated in constructor");
|
||||
|
||||
VarU32::new(len)?.encode(dst)?;
|
||||
dst.write_slice(self.0.as_slice());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
Self::NAME
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
// <variable-length size> + <data bytes>
|
||||
// NOTE: Wrapping add will not overflow because the size is limited by VarU32::MAX
|
||||
VarU32::new(self.0.len().try_into().unwrap())
|
||||
.unwrap()
|
||||
.size()
|
||||
.wrapping_add(self.0.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode<'_> for NowVarBuf {
|
||||
fn decode(src: &mut ReadCursor<'_>) -> DecodeResult<Self> {
|
||||
let len_u32 = VarU32::decode(src)?.value();
|
||||
let len: usize = cast_length!("len", len_u32)?;
|
||||
|
||||
ensure_size!(in: src, size: len);
|
||||
let bytes = src.read_slice(len);
|
||||
|
||||
Ok(NowVarBuf(bytes.to_vec()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NowVarBuf> for Vec<u8> {
|
||||
fn from(buf: NowVarBuf) -> Self {
|
||||
buf.0
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
use ironrdp_core::{ensure_fixed_part_size, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct NowMessageClass(pub u8);
|
||||
|
||||
impl NowMessageClass {
|
||||
/// NOW-PROTO: NOW_SYSTEM_MSG_CLASS_ID
|
||||
pub const SYSTEM: Self = Self(0x11);
|
||||
|
||||
/// NOW-PROTO: NOW_SESSION_MSG_CLASS_ID
|
||||
pub const SESSION: Self = Self(0x12);
|
||||
|
||||
/// NOW-PROTO: NOW_EXEC_MSG_CLASS_ID
|
||||
pub const EXEC: Self = Self(0x13);
|
||||
}
|
||||
|
||||
/// The NOW_HEADER structure is the header common to all NOW protocol messages.
|
||||
///
|
||||
/// NOW-PROTO: NOW_HEADER
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct NowHeader {
|
||||
pub size: u32,
|
||||
pub class: NowMessageClass,
|
||||
pub kind: u8,
|
||||
pub flags: u16,
|
||||
}
|
||||
|
||||
impl NowHeader {
|
||||
const NAME: &'static str = "NOW_HEADER";
|
||||
pub const FIXED_PART_SIZE: usize = 8;
|
||||
}
|
||||
|
||||
impl Encode for NowHeader {
|
||||
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
|
||||
ensure_fixed_part_size!(in: dst);
|
||||
|
||||
dst.write_u32(self.size);
|
||||
dst.write_u8(self.class.0);
|
||||
dst.write_u8(self.kind);
|
||||
dst.write_u16(self.flags);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
Self::NAME
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
Self::FIXED_PART_SIZE
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode<'_> for NowHeader {
|
||||
fn decode(src: &mut ReadCursor<'_>) -> DecodeResult<Self> {
|
||||
ensure_fixed_part_size!(in: src);
|
||||
|
||||
let size = src.read_u32();
|
||||
let class = NowMessageClass(src.read_u8());
|
||||
let kind = src.read_u8();
|
||||
let flags = src.read_u16();
|
||||
|
||||
Ok(NowHeader {
|
||||
size,
|
||||
class,
|
||||
kind,
|
||||
flags,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
//! This module contains `NOW-PROTO` core types definitions.
|
||||
|
||||
mod buffer;
|
||||
mod header;
|
||||
mod number;
|
||||
mod status;
|
||||
mod string;
|
||||
|
||||
pub use buffer::{NowLrgBuf, NowVarBuf};
|
||||
pub use header::{NowHeader, NowMessageClass};
|
||||
pub use number::{VarI16, VarI32, VarI64, VarU16, VarU32, VarU64};
|
||||
pub use status::{NowSeverity, NowStatus, NowStatusCode};
|
||||
pub use string::{NowLrgStr, NowString128, NowString16, NowString256, NowString32, NowString64, NowVarStr};
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user