From f81c3c6f8760b3b5407a8a2e230ee70714d9711b Mon Sep 17 00:00:00 2001 From: Rostyslav Romanets Date: Mon, 21 Sep 2026 11:51:18 +0200 Subject: [PATCH] feat(credssp): use the `KdcResolution` enum instead of KDC url --- Cargo.lock | 203 ++++++------------ Cargo.toml | 7 + crates/ironrdp-acceptor/src/credssp.rs | 2 +- crates/ironrdp-client/src/config.rs | 5 +- crates/ironrdp-connector/Cargo.toml | 4 +- crates/ironrdp-connector/src/credssp.rs | 35 ++- crates/ironrdp-mstsgu/Cargo.toml | 4 +- .../tests/client/config.rs | 9 +- crates/ironrdp-web/src/session.rs | 21 +- crates/ironrdp/Cargo.toml | 2 +- ffi/Cargo.toml | 2 +- 11 files changed, 124 insertions(+), 170 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9cccb13816..bdc8a2139e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,17 +18,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" -[[package]] -name = "addchain" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e33f6a175ec6a9e0aca777567f9ff7c3deefc255660df887e7fa3585e9801d8" -dependencies = [ - "num-bigint 0.3.3", - "num-integer", - "num-traits", -] - [[package]] name = "adler2" version = "2.0.1" @@ -93,16 +82,16 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.11.0-rc.4" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da8c919c118108f144adecad74b425b804ad075580d605d9b33c2d6d1c62a2f8" +checksum = "7f2b8006a0c83f52b62ba44a97b58bf76fe2f70a329e588f67f89691d93d498f" dependencies = [ "aead 0.6.1", "aes 0.9.1", "cipher 0.5.2", "ctr 0.10.1", + "ctutils", "ghash 0.6.0", - "subtle", ] [[package]] @@ -433,6 +422,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64ct" version = "1.8.3" @@ -1235,15 +1230,16 @@ checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" [[package]] name = "curve25519-dalek" -version = "5.0.0-rc.1" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c906a87e53a36ff795d72e06e8162a83c5436e3ea89e942a9cb9fc083f0a384f" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", "cpufeatures 0.3.0", "curve25519-dalek-derive", "digest 0.11.3", "fiat-crypto", + "rand_core 0.10.1", "rustc_version", "subtle", "zeroize", @@ -1304,7 +1300,7 @@ dependencies = [ "asn1-rs", "displaydoc", "nom 7.1.3", - "num-bigint 0.4.8", + "num-bigint", "num-traits", "rusticata-macros 4.1.0", ] @@ -1551,9 +1547,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ecdsa" -version = "0.17.0-rc.22" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c72d1455753a703ad4b90ed2a759f2bc4562024a303176439cf6e593b5ade4" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der 0.8.1", "digest 0.11.3", @@ -1575,14 +1571,15 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "3.0.0-rc.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1685663e23882cd8517dcbcb1c23a6ebff4433c22dfb681d760219b62cd1b849" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", "rand_core 0.10.1", "sha2 0.11.0", + "signature", "subtle", "zeroize", ] @@ -2319,7 +2316,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -2608,7 +2605,7 @@ name = "ironrdp-activex" version = "0.1.0" dependencies = [ "anyhow", - "base64", + "base64 0.22.1", "embed-resource", "ironrdp-cfg", "ironrdp-client", @@ -3023,7 +3020,7 @@ dependencies = [ name = "ironrdp-mstsgu" version = "0.0.1" dependencies = [ - "base64", + "base64 0.22.1", "bitflags 2.13.1", "futures-util", "http-body-util", @@ -3066,7 +3063,7 @@ dependencies = [ "ironrdp-core 0.2.1", "ironrdp-error 0.2.0", "md-5 0.10.6", - "num-bigint 0.4.8", + "num-bigint", "num-derive 0.5.1", "num-integer", "num-traits", @@ -3542,7 +3539,7 @@ name = "ironrdp-web" version = "0.0.0" dependencies = [ "anyhow", - "base64", + "base64 0.22.1", "chrono", "futures-channel", "futures-util", @@ -3869,11 +3866,11 @@ dependencies = [ [[package]] name = "md4" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da5ac363534dce5fabf69949225e174fbf111a498bf0ff794c8ea1fba9f3dda" +checksum = "bd76fb0fd6b2e4be62a73f8e0858ca97f81babcb1af322dcaca196f735f17f80" dependencies = [ - "digest 0.10.7", + "digest 0.11.3", ] [[package]] @@ -4065,17 +4062,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "num-bigint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-bigint" version = "0.4.8" @@ -4627,9 +4613,9 @@ dependencies = [ [[package]] name = "p256" -version = "0.14.0-rc.14" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c855a8d2ffd346aa03122626f22e96e3aa75e3bfe64e6bf6cb82f71821ed6ae7" +checksum = "d2c9239b2dbc807adbbe147e8cf72ea7450c3a0aabe62cb8e75ff4ec22e1f72a" dependencies = [ "ecdsa", "elliptic-curve", @@ -4640,9 +4626,9 @@ dependencies = [ [[package]] name = "p384" -version = "0.14.0-rc.14" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62941b68907ddf996ac20f0debf700c236ccc3d874637731a93c631129ca042f" +checksum = "d17b851e6b3e378ab4ecb07fa2ed23f4d15f075735f8fec9fa1e7bdce5f8301f" dependencies = [ "ecdsa", "elliptic-curve", @@ -4654,9 +4640,9 @@ dependencies = [ [[package]] name = "p521" -version = "0.14.0-rc.14" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd6f2fe6e76c8d5e8828e92aafa463777d1e72e70b78acc724214757e92479a" +checksum = "4ad64cc32c2dc466317c12ee5853e61f159f9eab1fe7efade0395dc2e7b43449" dependencies = [ "base16ct", "ecdsa", @@ -4732,7 +4718,7 @@ version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ - "base64", + "base64 0.22.1", "serde_core", ] @@ -4753,22 +4739,18 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "picky" -version = "7.0.0-rc.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ae9cd78eb1d61be4790713d28368cf71c844218fcd91542768805423f02666" +version = "7.0.0-rc.26" dependencies = [ "aes 0.9.1", - "aes-gcm 0.11.0-rc.4", + "aes-gcm 0.11.1", "aes-kw", - "base64", + "base64 0.23.1", "cbc", "crypto-bigint", "crypto-common 0.2.2", "ctr 0.10.1", - "curve25519-dalek", "des", "digest 0.11.3", - "ecdsa", "ed25519-dalek", "hex", "hmac 0.13.0", @@ -4783,14 +4765,10 @@ dependencies = [ "picky-asn1-der", "picky-asn1-x509", "pkcs1 0.8.0-rc.4", - "primeorder", "rand 0.10.2", "rand_core 0.10.1", "rc2", "rsa", - "rustcrypto-ff", - "rustcrypto-ff_derive", - "rustcrypto-group", "serde", "serde_json", "sha1 0.11.0", @@ -4804,8 +4782,6 @@ dependencies = [ [[package]] name = "picky-asn1" version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ff038f9360b934342fb3c0a1d6e82c438a2624b51c3c6e3e6d7cf252b6f3ee3" dependencies = [ "oid", "serde", @@ -4817,8 +4793,6 @@ dependencies = [ [[package]] name = "picky-asn1-der" version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d413165e4bf7f808b9a27cbaba657657a2921f0965db833f488c4d4be96dcd2e" dependencies = [ "picky-asn1", "serde", @@ -4828,10 +4802,8 @@ dependencies = [ [[package]] name = "picky-asn1-x509" version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d4117bd1b1dc5646359ee7243c50c5000c0920ea2d1fb120335a2f4c684b8" dependencies = [ - "base64", + "base64 0.23.1", "crypto-bigint", "oid", "picky-asn1", @@ -4844,8 +4816,6 @@ dependencies = [ [[package]] name = "picky-krb" version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d188f3192356068dbdba54bddbca6fd0f7a09565d3861eeb8efe1ab77ae8e97" dependencies = [ "aes 0.9.1", "block-padding", @@ -5112,14 +5082,15 @@ dependencies = [ [[package]] name = "primeorder" -version = "0.14.0-rc.14" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e56e6d67fdf5744e9e245ae571450fe584b91f5af261d0e40163b618e53a1f6" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ "elliptic-curve", "once_cell", "primefield", "serdect", + "wnaf", ] [[package]] @@ -5489,7 +5460,7 @@ version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", @@ -5544,11 +5515,11 @@ checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" [[package]] name = "rfc6979" -version = "0.6.0-pre.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9935425142ac6e252364413291d96c8bc9898d0876a801824c7af4eae397b689" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ - "ctutils", + "crypto-bigint", "hmac 0.13.0", ] @@ -5648,44 +5619,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustcrypto-ff" -version = "0.14.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd2a8adb347447693cd2ba0d218c4b66c62da9b0a5672b17b981e4291ec65ff6" -dependencies = [ - "bitvec", - "rand_core 0.10.1", - "rustcrypto-ff_derive", - "subtle", -] - -[[package]] -name = "rustcrypto-ff_derive" -version = "0.14.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cda22ea03582974ab5687fc131eba2dc78e258e7eef4d7e01bcd0522ed79f66" -dependencies = [ - "addchain", - "num-bigint 0.3.3", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rustcrypto-group" -version = "0.14.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "369f9b61aa45933c062c9f6b5c3c50ab710687eca83dd3802653b140b43f85ed" -dependencies = [ - "rand_core 0.10.1", - "rustcrypto-ff", - "subtle", -] - [[package]] name = "rusticata-macros" version = "4.1.0" @@ -6268,9 +6201,7 @@ checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] name = "sspi" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3bd2a45e7e24fd72eba100ced3fd847e05fe4657d7f067eb06d1a894f0d4e5" +version = "0.22.0" dependencies = [ "async-dnssd", "async-recursion", @@ -6281,8 +6212,6 @@ dependencies = [ "crypto-bigint", "crypto-mac", "cryptoki", - "curve25519-dalek", - "ed25519-dalek", "futures", "getrandom 0.3.4", "hickory-proto", @@ -6290,12 +6219,9 @@ dependencies = [ "hmac 0.13.0", "md-5 0.11.0", "md4", - "num-derive 0.4.2", + "num-derive 0.5.1", "num-traits", "oid", - "p256", - "p384", - "p521", "picky", "picky-asn1", "picky-asn1-der", @@ -6303,14 +6229,10 @@ dependencies = [ "picky-krb", "pkcs1 0.8.0-rc.4", "portpicker", - "primeorder", "rand 0.10.2", "rand_core 0.10.1", "reqwest", "rsa", - "rustcrypto-ff", - "rustcrypto-ff_derive", - "rustcrypto-group", "rustls", "rustls-native-certs", "serde", @@ -6368,17 +6290,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.118" @@ -7758,16 +7669,14 @@ dependencies = [ [[package]] name = "winscard" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dafb3c1468d0a3f5440e21e51614b53d1fdc62c9f82cc861c447906d09c69a" +version = "0.3.4" dependencies = [ "bitflags 2.13.1", "crypto-bigint", "flate2", "iso7816", "iso7816-tlv", - "num-derive 0.4.2", + "num-derive 0.5.1", "num-traits", "picky", "picky-asn1-x509", @@ -7785,6 +7694,18 @@ version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +[[package]] +name = "wnaf" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795ca18b3fdb5e62bf982199278341ddcf7ebf7d32e25e212ad05d496e95f6fa" +dependencies = [ + "ff", + "group", + "hybrid-array", + "primefield", +] + [[package]] name = "writeable" version = "0.6.3" @@ -7834,9 +7755,9 @@ checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" [[package]] name = "x25519-dalek" -version = "3.0.0-rc.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee64e8620caa64914d669b1f68f858aaff54e2d0f9ad3b30a613b58a1baa83e" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" dependencies = [ "curve25519-dalek", "rand_core 0.10.1", diff --git a/Cargo.toml b/Cargo.toml index 1502734461..34dd9cf632 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -209,3 +209,10 @@ opt-level = 3 # FIXME: We need to catch up with Diplomat upstream again, but this is a significant amount of work. # In the meantime, we use this forked version which fixes an undefined behavior in the code expanded by the bridge macro. diplomat = { git = "https://github.com/CBenoit/diplomat", rev = "6dc806e80162b6b39509a04a2835744236cd2396" } + +sspi = { path = "../sspi-rs" } +picky = { path = "../picky-rs/picky" } +picky-asn1 = { path = "../picky-rs/picky-asn1" } +picky-asn1-der = { path = "../picky-rs/picky-asn1-der" } +picky-asn1-x509 = { path = "../picky-rs/picky-asn1-x509" } +picky-krb = { path = "../picky-rs/picky-krb" } diff --git a/crates/ironrdp-acceptor/src/credssp.rs b/crates/ironrdp-acceptor/src/credssp.rs index e665724dbf..04c3a426b2 100644 --- a/crates/ironrdp-acceptor/src/credssp.rs +++ b/crates/ironrdp-acceptor/src/credssp.rs @@ -166,7 +166,7 @@ impl<'a> CredsspSequence<'a> { self.state = next_state; if let Some(ts_request) = ts_request { debug!(?ts_request, "Send"); - let length = usize::from(ts_request.buffer_len()); + let length = usize::from(ts_request.buffer_len().map_err(|e| custom_err!("TsRequest", e))?); let unfilled_buffer = output.unfilled_to(length); ts_request diff --git a/crates/ironrdp-client/src/config.rs b/crates/ironrdp-client/src/config.rs index 4c79ab8ebe..5119e5ad5f 100644 --- a/crates/ironrdp-client/src/config.rs +++ b/crates/ironrdp-client/src/config.rs @@ -7,6 +7,7 @@ use std::sync::Arc; use anyhow::Context as _; use ironrdp_cfg::PropertySetExt as _; +use ironrdp_connector::credssp::KdcResolution; use ironrdp_propertyset::PropertySet; use ironrdp_rail::pdu::ExecutePdu; use url::Url; @@ -1340,7 +1341,7 @@ impl ConfigBuilder { /// has no KDC proxy URL); `hostname` is derived from the client name and not stored separately. #[must_use] pub fn with_kerberos_config(mut self, cfg: ironrdp_connector::credssp::KerberosConfig) -> Self { - if let Some(url) = &cfg.kdc_proxy_url { + if let KdcResolution::KdcUrl(Some(url)) = &cfg.kdc_resolution { self.properties.set_kdc_proxy_url(url.to_string()); } else { self.properties.clear_kdc_proxy_url(); @@ -2381,7 +2382,7 @@ fn kerberos_config_from_properties( Url::parse(&kdc_proxy_url) .ok() .map(|url| ironrdp_connector::credssp::KerberosConfig { - kdc_proxy_url: Some(url), + kdc_resolution: KdcResolution::KdcUrl(Some(url)), hostname: client_name.to_owned(), }) } diff --git a/crates/ironrdp-connector/Cargo.toml b/crates/ironrdp-connector/Cargo.toml index 5507ea81c1..4a2ab355c5 100644 --- a/crates/ironrdp-connector/Cargo.toml +++ b/crates/ironrdp-connector/Cargo.toml @@ -26,13 +26,13 @@ ironrdp-svc = { path = "../ironrdp-svc", version = "0.8" } # public ironrdp-core = { path = "../ironrdp-core", version = "0.2" } # public ironrdp-error = { path = "../ironrdp-error", version = "0.2" } # public ironrdp-pdu = { path = "../ironrdp-pdu", version = "0.9", features = ["std"] } # public -sspi = { version = "0.21", features = ["scard"] } +sspi = { version = "0.22", features = ["scard"] } url = "2.5" # public rand = { version = "0.9", features = ["std"] } # TODO: dependency injection? tracing = { version = "0.1", features = ["log"] } picky-asn1-der = "0.5" picky-asn1-x509 = "0.15" -picky = "=7.0.0-rc.25" # FIXME: We are pinning with = because the candidate version number counts as the minor number by Cargo, and will be automatically bumped in the Cargo.lock. +picky = "=7.0.0-rc.26" # FIXME: We are pinning with = because the candidate version number counts as the minor number by Cargo, and will be automatically bumped in the Cargo.lock. [lints] workspace = true diff --git a/crates/ironrdp-connector/src/credssp.rs b/crates/ironrdp-connector/src/credssp.rs index 413023260d..28acfec3cf 100644 --- a/crates/ironrdp-connector/src/credssp.rs +++ b/crates/ironrdp-connector/src/credssp.rs @@ -11,29 +11,54 @@ use crate::{ ConnectorError, ConnectorErrorKind, ConnectorResult, Credentials, ServerName, Written, custom_err, general_err, }; +/// Strategy for resolving the KDC to use for Kerberos authentication. +#[derive(Debug, Clone)] +pub enum KdcResolution { + /// Use IAKerb extension to proxy KDC communication through the server to the LocalKDC. + IAKerb, + /// External KDC URL. + KdcUrl(Option), +} + +impl From for sspi::KdcResolution { + fn from(val: KdcResolution) -> Self { + match val { + KdcResolution::IAKerb => sspi::KdcResolution::IAKerb, + KdcResolution::KdcUrl(url) => sspi::KdcResolution::KdcUrl(url), + } + } +} + #[derive(Debug, Clone)] pub struct KerberosConfig { - pub kdc_proxy_url: Option, + pub kdc_resolution: KdcResolution, pub hostname: String, } impl KerberosConfig { - pub fn new(kdc_proxy_url: Option, hostname: String) -> ConnectorResult { + pub fn new_with_kdc_url(kdc_proxy_url: Option, hostname: String) -> ConnectorResult { let kdc_proxy_url = kdc_proxy_url .map(|url| url::Url::parse(&url)) .transpose() .map_err(|e| custom_err!("invalid KDC URL", e))?; Ok(Self { - kdc_proxy_url, + kdc_resolution: KdcResolution::KdcUrl(kdc_proxy_url), hostname, }) } + + pub fn new_with_iakerb(hostname: String) -> Self { + Self { + kdc_resolution: KdcResolution::IAKerb, + hostname, + } + } } impl From for sspi::KerberosConfig { fn from(val: KerberosConfig) -> Self { sspi::KerberosConfig { - kdc_url: val.kdc_proxy_url, + kdc_resolution: val.kdc_resolution.into(), client_computer_name: val.hostname, } } @@ -262,7 +287,7 @@ fn extract_user_principal_name(cert: &Certificate) -> Option { } fn write_credssp_request(ts_request: credssp::TsRequest, output: &mut WriteBuf) -> ConnectorResult { - let length = usize::from(ts_request.buffer_len()); + let length = usize::from(ts_request.buffer_len().map_err(|e| custom_err!("TsRequest", e))?); let unfilled_buffer = output.unfilled_to(length); diff --git a/crates/ironrdp-mstsgu/Cargo.toml b/crates/ironrdp-mstsgu/Cargo.toml index 6eba63e274..aab102b4ff 100644 --- a/crates/ironrdp-mstsgu/Cargo.toml +++ b/crates/ironrdp-mstsgu/Cargo.toml @@ -97,13 +97,13 @@ ironrdp-core = { path = "../ironrdp-core", version = "0.2", features = ["std"] } ironrdp-error = { path = "../ironrdp-error", version = "0.2" } ironrdp-tls = { path = "../ironrdp-tls", version = "0.2.2" } # public log = "0.4" -sspi = { version = "0.21", features = ["network_client"] } +sspi = { version = "0.22", features = ["network_client"] } tokio-tungstenite = { version = "0.29" } tokio-util = { version = "0.7" } tokio = { version = "1.52", features = ["macros", "rt", "io-util"] } tokio-socks = "0.5.3" uuid = { version = "1", features = ["v4"] } # public, exposed by RpcSyntaxIdentifier -picky = { version = "=7.0.0-rc.25", optional = true } +picky = { version = "=7.0.0-rc.26", optional = true } picky-asn1-der = { version = "0.5", optional = true } picky-asn1-x509 = { version = "0.15", optional = true } diff --git a/crates/ironrdp-testsuite-extra/tests/client/config.rs b/crates/ironrdp-testsuite-extra/tests/client/config.rs index 147c5a4dde..a3e1b83e49 100644 --- a/crates/ironrdp-testsuite-extra/tests/client/config.rs +++ b/crates/ironrdp-testsuite-extra/tests/client/config.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use std::sync::Arc; +use ironrdp::connector::sspi::KdcResolution; #[cfg(windows)] use ironrdp_cfg::GatewayCredentialsSource; use ironrdp_cfg::PropertySetExt as _; @@ -435,10 +436,10 @@ fn kdc_proxy_name_is_normalized_to_https_url() { ); let kerberos = config.kerberos_config().expect("kerberos config should be present"); - let kdc_proxy_url = kerberos - .kdc_proxy_url - .as_ref() - .expect("kdc proxy url should be present"); + let kdc_proxy_url = match &kerberos.kdc_resolution { + KdcResolution::KdcUrl(Some(url)) => url, + _ => panic!("kdc proxy url should be present"), + }; assert_eq!(kdc_proxy_url.as_str(), "https://kdc.example.com/KdcProxy"); } diff --git a/crates/ironrdp-web/src/session.rs b/crates/ironrdp-web/src/session.rs index a47bd3d0c0..076fc9da14 100644 --- a/crates/ironrdp-web/src/session.rs +++ b/crates/ironrdp-web/src/session.rs @@ -5,6 +5,14 @@ use core::time::Duration; use std::borrow::Cow; use std::rc::Rc; +use crate::canvas::Canvas; +use crate::clipboard; +use crate::clipboard::{ClipboardData, FileMetadata, WasmClipboard, WasmClipboardBackend, WasmClipboardBackendMessage}; +use crate::error::IronError; +use crate::image::extract_partial_image; +use crate::input::InputTransaction; +use crate::network_client::WasmNetworkClient; +use crate::printer::{JsPrinterStreamCallbacks, WasmPrinter, WasmPrinterBackend, wasm_printer_pair}; use anyhow::Context as _; use base64::Engine as _; use futures_channel::mpsc; @@ -18,7 +26,7 @@ use ironrdp::cliprdr::CliprdrClient; use ironrdp::cliprdr::backend::ClipboardMessage; use ironrdp::cliprdr::pdu::{FileContentsFlags, FileContentsRequest, FileContentsResponse, FileDescriptor}; use ironrdp::connector::connection_activation::ConnectionActivationState; -use ironrdp::connector::credssp::KerberosConfig; +use ironrdp::connector::credssp::{KdcResolution, KerberosConfig}; use ironrdp::connector::{self, ClientConnector, Credentials}; use ironrdp::displaycontrol::client::DisplayControlClient; use ironrdp::dvc::DrdynvcClient; @@ -40,15 +48,6 @@ use wasm_bindgen::{JsCast as _, JsValue}; use wasm_bindgen_futures::spawn_local; use web_sys::HtmlCanvasElement; -use crate::canvas::Canvas; -use crate::clipboard; -use crate::clipboard::{ClipboardData, FileMetadata, WasmClipboard, WasmClipboardBackend, WasmClipboardBackendMessage}; -use crate::error::IronError; -use crate::image::extract_partial_image; -use crate::input::InputTransaction; -use crate::network_client::WasmNetworkClient; -use crate::printer::{JsPrinterStreamCallbacks, WasmPrinter, WasmPrinterBackend, wasm_printer_pair}; - const DEFAULT_WIDTH: u16 = 1280; const DEFAULT_HEIGHT: u16 = 720; @@ -1670,7 +1669,7 @@ async fn connect( let kerberos_config = url::Url::parse(kdc_proxy_url.unwrap_or_default().as_str()) .ok() .map(|url| KerberosConfig { - kdc_proxy_url: Some(url), + kdc_resolution: KdcResolution::KdcUrl(Some(url)), // HACK: It's supposed to be the computer name of the client, but since it's not easy to retrieve this information in the browser, // we set the destination hostname instead because it happens to work. hostname: destination.clone(), diff --git a/crates/ironrdp/Cargo.toml b/crates/ironrdp/Cargo.toml index c4595af206..0456b38650 100644 --- a/crates/ironrdp/Cargo.toml +++ b/crates/ironrdp/Cargo.toml @@ -87,7 +87,7 @@ async-trait = "0.1" image = { version = "0.25", default-features = false, features = ["png"] } pico-args = "0.5" x509-cert = { version = "0.3", default-features = false, features = ["std"] } -sspi = { version = "0.21", features = ["network_client"] } +sspi = { version = "0.22", features = ["network_client"] } tracing = { version = "0.1", features = ["log"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } tokio = { version = "1", features = ["macros", "rt", "sync", "time"] } diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index a791979fc6..a9500b024f 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -20,7 +20,7 @@ ironrdp-dvc-pipe-proxy.path = "../crates/ironrdp-dvc-pipe-proxy" ironrdp-core = { path = "../crates/ironrdp-core", features = ["alloc"] } ironrdp-vmconnect = { path = "../crates/ironrdp-vmconnect" } ironrdp-rdcleanpath.path = "../crates/ironrdp-rdcleanpath" -sspi = { version = "0.21", features = ["network_client"] } +sspi = { version = "0.22", features = ["network_client"] } thiserror = "2" tracing = { version = "0.1", features = ["log"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] }