From c75da74ecdb6a0331328f12468343d6a9bad2520 Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Tue, 17 Mar 2026 16:05:11 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20Phase=204=20complete=20=E2=80=94=20RDP?= =?UTF-8?q?=20via=20ironrdp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rust RDP service: ironrdp client with full connection handshake (TCP -> TLS -> CredSSP -> NLA), pixel buffer frame delivery, mouse/keyboard input via scancode mapping, graceful disconnect. Runs in dedicated thread with own tokio runtime to avoid Send lifetime issues with ironrdp trait objects. Vue frontend: RdpView canvas renderer with 30fps polling, mouse/keyboard capture, RdpToolbar with Ctrl+Alt+Del and clipboard. SessionContainer handles both SSH and RDP tabs. Co-Authored-By: Claude Opus 4.6 (1M context) --- src-tauri/Cargo.lock | 2460 +++++++++++++++++-- src-tauri/Cargo.toml | 8 + src-tauri/src/commands/mod.rs | 1 + src-tauri/src/commands/rdp_commands.rs | 94 + src-tauri/src/lib.rs | 11 + src-tauri/src/rdp/input.rs | 192 ++ src-tauri/src/rdp/mod.rs | 619 +++++ src/components/rdp/RdpToolbar.vue | 168 ++ src/components/rdp/RdpView.vue | 252 ++ src/components/session/SessionContainer.vue | 115 +- src/composables/useRdp.ts | 365 +++ src/stores/session.store.ts | 91 +- 12 files changed, 4205 insertions(+), 171 deletions(-) create mode 100644 src-tauri/src/commands/rdp_commands.rs create mode 100644 src-tauri/src/rdp/input.rs create mode 100644 src-tauri/src/rdp/mod.rs create mode 100644 src/components/rdp/RdpToolbar.vue create mode 100644 src/components/rdp/RdpView.vue create mode 100644 src/composables/useRdp.ts diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 4bdd44c..0294432 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -14,10 +14,20 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "generic-array", ] +[[package]] +name = "aead" +version = "0.6.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8202ab55fcbf46ca829833f347a82a2a4ce0596f0304ac322c2d100030cd56" +dependencies = [ + "crypto-common 0.2.0-rc.4", + "inout 0.2.0-rc.6", +] + [[package]] name = "aes" version = "0.8.4" @@ -25,7 +35,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "aes" +version = "0.9.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e713c57c2a2b19159e7be83b9194600d7e8eb3b7c2cd67e671adf47ce189a05" +dependencies = [ + "cfg-if", + "cipher 0.5.0-rc.1", "cpufeatures", ] @@ -35,14 +56,38 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", + "aead 0.5.2", + "aes 0.8.4", + "cipher 0.4.4", + "ctr 0.9.2", + "ghash 0.5.1", "subtle", ] +[[package]] +name = "aes-gcm" +version = "0.11.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0686ba04dc80c816104c96cd7782b748f6ad58c5dd4ee619ff3258cf68e83d54" +dependencies = [ + "aead 0.6.0-rc.2", + "aes 0.9.0-rc.1", + "cipher 0.5.0-rc.1", + "ctr 0.10.0-rc.1", + "ghash 0.6.0-rc.2", + "subtle", +] + +[[package]] +name = "aes-kw" +version = "0.3.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02eaa2d54d0fad0116e4b1efb65803ea0bf059ce970a67cd49718d87e807cb51" +dependencies = [ + "aes 0.9.0-rc.1", + "const-oid 0.10.2", +] + [[package]] name = "ahash" version = "0.8.12" @@ -157,6 +202,74 @@ dependencies = [ "password-hash", ] +[[package]] +name = "asn1-rs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 2.0.18", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "async-dnssd" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d49ffe175ab45bbfd74b548313d9d7cdfff27161a94b007b52eeeb5f9aaa15e" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-executor", + "futures-util", + "libc", + "log", + "pin-utils", + "pkg-config", + "tokio", + "winapi", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -191,6 +304,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -203,12 +325,46 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-lc-rs" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "base16ct" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base16ct" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b59d472eab27ade8d770dcb11da7201c11234bef9f82ce7aa517be028d462b" + +[[package]] +name = "base16ct" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" + [[package]] name = "base64" version = "0.21.7" @@ -234,8 +390,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" dependencies = [ "blowfish", - "pbkdf2", - "sha2", + "pbkdf2 0.12.2", + "sha2 0.10.9", ] [[package]] @@ -253,6 +409,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bit_field" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -268,13 +430,25 @@ dependencies = [ "serde_core", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake2" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -286,6 +460,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.11.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9ef36a6fcdb072aa548f3da057640ec10859eb4e91ddf526ee648d50c76a949" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -295,6 +478,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.4.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e59c1aab3e6c5e56afe1b7e8650be9b5a791cb997bdea449194ae62e4bf8c73" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block2" version = "0.6.2" @@ -311,7 +503,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" dependencies = [ "byteorder", - "cipher", + "cipher 0.4.4", ] [[package]] @@ -435,7 +627,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "cbc" +version = "0.2.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dbf9e5b071e9de872e32b73f485e8f644ff47c7011d95476733e7482ee3e5c3" +dependencies = [ + "cipher 0.5.0-rc.1", ] [[package]] @@ -445,6 +646,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -481,6 +684,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chacha20" version = "0.9.1" @@ -488,7 +697,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures", ] @@ -512,8 +721,28 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", - "inout", + "crypto-common 0.1.7", + "inout 0.1.4", +] + +[[package]] +name = "cipher" +version = "0.5.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e12a13eb01ded5d32ee9658d94f553a19e804204f2dc811df69ab4d9e0cb8c7" +dependencies = [ + "block-buffer 0.11.0-rc.5", + "crypto-common 0.2.0-rc.4", + "inout 0.2.0-rc.6", +] + +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", ] [[package]] @@ -538,6 +767,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-random" version = "0.1.18" @@ -574,6 +809,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -597,7 +842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" dependencies = [ "bitflags 2.11.0", - "core-foundation", + "core-foundation 0.10.1", "core-graphics-types", "foreign-types", "libc", @@ -610,7 +855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ "bitflags 2.11.0", - "core-foundation", + "core-foundation 0.10.1", "libc", ] @@ -632,6 +877,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -641,6 +892,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -665,6 +925,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.7.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4113edbc9f68c0a64d5b911f803eb245d04bb812680fd56776411f69c670f3e0" +dependencies = [ + "hybrid-array", + "num-traits", + "rand_core 0.9.5", + "serdect", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.7" @@ -676,6 +950,60 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8235645834fbc6832939736ce2f2d08192652269e11010a6240f61b908a1c6" +dependencies = [ + "hybrid-array", + "rand_core 0.9.5", +] + +[[package]] +name = "crypto-mac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto-primes" +version = "0.7.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f2523fbb68811c8710829417ad488086720a6349e337c38d12fa81e09e50bf" +dependencies = [ + "crypto-bigint 0.7.0-rc.8", + "libm", + "rand_core 0.9.5", +] + +[[package]] +name = "cryptoki" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "781357a7779a8e92ea985121bbf379a9adf0777f44ab6392efc6abd5aa9b67db" +dependencies = [ + "bitflags 1.3.2", + "cryptoki-sys", + "libloading 0.8.9", + "log", + "paste", + "secrecy", +] + +[[package]] +name = "cryptoki-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "753e27d860277930ae9f394c119c8c70303236aab0ffab1d51f3d207dbb2bc4b" +dependencies = [ + "libloading 0.8.9", +] + [[package]] name = "cssparser" version = "0.29.6" @@ -732,7 +1060,16 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "ctr" +version = "0.10.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27e41d01c6f73b9330177f5cf782ae5b581b5f2c7840e298e0275ceee5001434" +dependencies = [ + "cipher 0.5.0-rc.1", ] [[package]] @@ -744,8 +1081,24 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest", - "fiat-crypto", + "digest 0.10.7", + "fiat-crypto 0.2.9", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "5.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f9200d1d13637f15a6acb71e758f64624048d85b31a5fdbfd8eca1e2687d0b7" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.11.0-rc.3", + "fiat-crypto 0.3.0", "rustc_version", "subtle", "zeroize", @@ -833,11 +1186,48 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", - "pem-rfc7468", + "const-oid 0.9.6", + "der_derive", + "flagset", + "pem-rfc7468 0.7.0", "zeroize", ] +[[package]] +name = "der" +version = "0.8.0-rc.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d8dd2f26c86b27a2a8ea2767ec7f9df7a89516e4794e54ac01ee618dda3aa4" +dependencies = [ + "const-oid 0.10.2", + "pem-rfc7468 1.0.0-rc.3", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "deranged" version = "0.5.8" @@ -888,7 +1278,16 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "des" +version = "0.9.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f51594a70805988feb1c85495ddec0c2052e4fbe59d9c0bb7f94bfc164f4f90" +dependencies = [ + "cipher 0.5.0-rc.1", ] [[package]] @@ -897,9 +1296,21 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", + "block-buffer 0.10.4", + "const-oid 0.9.6", + "crypto-common 0.1.7", + "subtle", +] + +[[package]] +name = "digest" +version = "0.11.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac89f8a64533a9b0eaa73a68e424db0fb1fd6271c74cc0125336a05f090568d" +dependencies = [ + "block-buffer 0.11.0-rc.5", + "const-oid 0.10.2", + "crypto-common 0.2.0-rc.4", "subtle", ] @@ -1027,12 +1438,27 @@ version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", - "digest", - "elliptic-curve", - "rfc6979", - "signature", - "spki", + "der 0.7.10", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "ecdsa" +version = "0.17.0-rc.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ab355ec063f7a110eb627471058093aba00eb7f4e70afbd15e696b79d1077b" +dependencies = [ + "der 0.8.0-rc.9", + "digest 0.11.0-rc.3", + "elliptic-curve 0.14.0-rc.15", + "rfc6979 0.5.0-rc.1", + "signature 3.0.0-rc.4", + "spki 0.8.0-rc.4", + "zeroize", ] [[package]] @@ -1041,8 +1467,18 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", - "signature", + "pkcs8 0.10.2", + "signature 2.2.0", +] + +[[package]] +name = "ed25519" +version = "3.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef49c0b20c0ad088893ad2a790a29c06a012b3f05bcfc66661fd22a94b32129" +dependencies = [ + "pkcs8 0.11.0-rc.7", + "signature 3.0.0-rc.4", ] [[package]] @@ -1051,11 +1487,25 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ - "curve25519-dalek", - "ed25519", + "curve25519-dalek 4.1.3", + "ed25519 2.2.3", "rand_core 0.6.4", "serde", - "sha2", + "sha2 0.10.9", + "subtle", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "3.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad207ed88a133091f83224265eac21109930db09bedcad05d5252f2af2de20a1" +dependencies = [ + "curve25519-dalek 5.0.0-pre.1", + "ed25519 3.0.0-rc.1", + "rand_core 0.9.5", + "sha2 0.11.0-rc.2", "subtle", "zeroize", ] @@ -1066,17 +1516,39 @@ version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct", - "crypto-bigint", - "digest", - "ff", + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.1", "generic-array", - "group", - "hkdf", - "pem-rfc7468", - "pkcs8", + "group 0.13.0", + "hkdf 0.12.4", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.14.0-rc.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e3be87c458d756141f3b6ee188828132743bf90c7d14843e2835d6443e5fb03" +dependencies = [ + "base16ct 0.3.0", + "crypto-bigint 0.7.0-rc.8", + "digest 0.11.0-rc.3", + "ff 0.14.0-pre.0", + "group 0.14.0-pre.0", + "hkdf 0.13.0-rc.2", + "hybrid-array", + "once_cell", + "pem-rfc7468 1.0.0-rc.3", + "pkcs8 0.11.0-rc.7", + "rand_core 0.9.5", + "sec1 0.8.0-rc.10", "subtle", "zeroize", ] @@ -1092,7 +1564,7 @@ dependencies = [ "rustc_version", "toml 0.9.12+spec-1.1.0", "vswhom", - "winreg", + "winreg 0.55.0", ] [[package]] @@ -1110,6 +1582,18 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "env_filter" version = "1.0.0" @@ -1197,12 +1681,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "ff" +version = "0.14.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d42dd26f5790eda47c1a2158ea4120e32c35ddc9a7743c98a292accc01b54ef3" +dependencies = [ + "rand_core 0.9.5", + "subtle", +] + [[package]] name = "fiat-crypto" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "fiat-crypto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" + [[package]] name = "field-offset" version = "0.3.6" @@ -1219,6 +1719,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "flagset" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" + [[package]] name = "flate2" version = "1.1.9" @@ -1226,6 +1732,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", + "libz-sys", "miniz_oxide", ] @@ -1295,6 +1802,18 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futf" version = "0.1.5" @@ -1543,9 +2062,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] @@ -1568,7 +2089,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", - "polyval", + "polyval 0.6.2", +] + +[[package]] +name = "ghash" +version = "0.6.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f88107cb02ed63adcc4282942e60c4d09d80208d33b360ce7c729ce6dae1739" +dependencies = [ + "polyval 0.7.0-rc.2", ] [[package]] @@ -1673,11 +2203,22 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.1", "rand_core 0.6.4", "subtle", ] +[[package]] +name = "group" +version = "0.14.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff6a0b2dd4b981b1ae9e3e6830ab146771f3660d31d57bafd9018805a91b0f1" +dependencies = [ + "ff 0.14.0-pre.0", + "rand_core 0.9.5", + "subtle", +] + [[package]] name = "gtk" version = "0.18.2" @@ -1730,6 +2271,34 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.13.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1769,6 +2338,19 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "spin", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -1799,13 +2381,68 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "hickory-proto" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand 0.9.2", + "ring", + "thiserror 2.0.18", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "moka", + "once_cell", + "parking_lot", + "rand 0.9.2", + "resolv-conf", + "smallvec", + "thiserror 2.0.18", + "tokio", + "tracing", +] + [[package]] name = "hkdf" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "hkdf" +version = "0.13.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ef30358b03ca095a5b910547f4f8d4b9f163e4057669c5233ef595b1ecf008" +dependencies = [ + "hmac 0.13.0-rc.2", ] [[package]] @@ -1814,7 +2451,16 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", +] + +[[package]] +name = "hmac" +version = "0.13.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3fd4dc94c318c1ede8a2a48341c250d6ddecd3ba793da2820301a9f92417ad9" +dependencies = [ + "digest 0.11.0-rc.3", ] [[package]] @@ -1887,6 +2533,17 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "hybrid-array" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8655f91cd07f2b9d0c24137bd650fe69617773435ee5ec83022377777ce65ef1" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "hyper" version = "1.8.1" @@ -1897,6 +2554,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", + "h2", "http", "http-body", "httparse", @@ -1908,6 +2566,23 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + [[package]] name = "hyper-util" version = "0.1.20" @@ -1925,10 +2600,12 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.3", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -2117,10 +2794,32 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "block-padding", + "block-padding 0.3.3", "generic-array", ] +[[package]] +name = "inout" +version = "0.2.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1603f76010ff924b616c8f44815a42eb10fb0b93d308b41deaa8da6d4251fd4b" +dependencies = [ + "block-padding 0.4.0-rc.4", + "hybrid-array", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.10", + "widestring", + "windows-sys 0.48.0", + "winreg 0.50.0", +] + [[package]] name = "ipnet" version = "2.12.0" @@ -2137,6 +2836,199 @@ dependencies = [ "serde", ] +[[package]] +name = "ironrdp" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c225751e8fbfaaaac5572a80e25d0a0921e9cf408c55509526161b5609157c" +dependencies = [ + "ironrdp-connector", + "ironrdp-core", + "ironrdp-graphics", + "ironrdp-input", + "ironrdp-pdu", + "ironrdp-session", +] + +[[package]] +name = "ironrdp-async" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62813c05253206699b2c8e44e268908dafd9668e07bb46ff262ee5b42d13e8cd" +dependencies = [ + "bytes", + "ironrdp-connector", + "ironrdp-core", + "ironrdp-pdu", + "tracing", +] + +[[package]] +name = "ironrdp-connector" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a8d5c1b8f167bbd9c935b08a4d3b592fe0a163ded7e4cc8880d471f06b3e2fa" +dependencies = [ + "ironrdp-core", + "ironrdp-error", + "ironrdp-pdu", + "ironrdp-svc", + "picky", + "picky-asn1-der", + "picky-asn1-x509", + "rand 0.9.2", + "sspi", + "tracing", + "url", +] + +[[package]] +name = "ironrdp-core" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2db60a59716a84d09040d29c9e75e81545842510fccb0934c09b28e78b46680" +dependencies = [ + "ironrdp-error", +] + +[[package]] +name = "ironrdp-displaycontrol" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ea49ab58df70f3cfda6c2772c598603df02a7bfb0ddc84e563e25cd7c4e340" +dependencies = [ + "ironrdp-core", + "ironrdp-dvc", + "ironrdp-pdu", + "ironrdp-svc", + "tracing", +] + +[[package]] +name = "ironrdp-dvc" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf251c27aed3f73d4f25e86b1bee1c9d82145ec665de8317edbf2da7c42ebe8" +dependencies = [ + "ironrdp-core", + "ironrdp-pdu", + "ironrdp-svc", + "slab", + "tracing", +] + +[[package]] +name = "ironrdp-error" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9d7794e854eef2f13fdf79c8502bcc567a75a15fd0522885f37739386a4cef" + +[[package]] +name = "ironrdp-graphics" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a039574abd3303506ee93c1376fcc9ce13de660c98a38ca9b716b45c369dff8d" +dependencies = [ + "bit_field", + "bitflags 2.11.0", + "bitvec", + "byteorder", + "ironrdp-core", + "ironrdp-pdu", + "num-derive", + "num-traits", + "yuv", +] + +[[package]] +name = "ironrdp-input" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ee6904346f1bf61689b86ad0ba27bbf6254015d3b7b4c2f328a1c8c7b77775" +dependencies = [ + "bitvec", + "ironrdp-pdu", + "smallvec", +] + +[[package]] +name = "ironrdp-pdu" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "409b96a94ca1fad1bfaa41789611bbb5efc112503b27b0513a1feb243e49eb60" +dependencies = [ + "bit_field", + "bitflags 2.11.0", + "byteorder", + "der-parser", + "ironrdp-core", + "ironrdp-error", + "md-5 0.10.6", + "num-bigint", + "num-derive", + "num-integer", + "num-traits", + "pkcs1 0.7.5", + "sha1 0.10.6", + "tap", + "thiserror 2.0.18", + "x509-cert", +] + +[[package]] +name = "ironrdp-session" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "997627ed3bdcd706fe44b8fdd958763b188336c4fc29b6443121867514069ac4" +dependencies = [ + "ironrdp-connector", + "ironrdp-core", + "ironrdp-displaycontrol", + "ironrdp-dvc", + "ironrdp-error", + "ironrdp-graphics", + "ironrdp-pdu", + "ironrdp-svc", + "tracing", +] + +[[package]] +name = "ironrdp-svc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef43a3ea966070b0e12a3f49ffb863c80311bd15f26c2b3681622c85e70d729" +dependencies = [ + "bitflags 2.11.0", + "ironrdp-core", + "ironrdp-pdu", +] + +[[package]] +name = "ironrdp-tls" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a301516949e619a5bd9c4476dfeeccaf7709b9997ea5958d01c9432085dc64d8" +dependencies = [ + "tokio", + "tokio-rustls", + "x509-cert", +] + +[[package]] +name = "ironrdp-tokio" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af190b161daba5d88c614bbf5915fdb586e9a28cb4b938aaac7abf473a1109b" +dependencies = [ + "bytes", + "ironrdp-async", + "ironrdp-connector", + "reqwest 0.12.28", + "sspi", + "tokio", + "url", +] + [[package]] name = "is-docker" version = "0.2.0" @@ -2162,6 +3054,24 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "iso7816" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c7e91da489667bb054f9cd2f1c60cc2ac4478a899f403d11dbc62189215b0" +dependencies = [ + "heapless", +] + +[[package]] +name = "iso7816-tlv" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7660d28d24a831d690228a275d544654a30f3b167a8e491cf31af5fe5058b546" +dependencies = [ + "untrusted", +] + [[package]] name = "itoa" version = "1.0.17" @@ -2237,6 +3147,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.91" @@ -2269,6 +3189,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "keccak" +version = "0.2.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d546793a04a1d3049bd192856f804cfe96356e2cf36b54b4e575155babe9f41" +dependencies = [ + "cpufeatures", +] + [[package]] name = "keyboard-types" version = "0.7.0" @@ -2327,7 +3256,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" dependencies = [ "gtk-sys", - "libloading", + "libloading 0.7.4", "once_cell", ] @@ -2347,6 +3276,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link 0.2.1", +] + [[package]] name = "libm" version = "0.2.16" @@ -2373,6 +3312,17 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libz-sys" +version = "1.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52f4c29e2a68ac30c9087e1b772dc9f44a2b66ed44edf2266cf2be9b03dafc1" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "litemap" version = "0.8.1" @@ -2394,6 +3344,12 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "mac" version = "0.1.1" @@ -2442,6 +3398,35 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + +[[package]] +name = "md-5" +version = "0.11.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9ec86664728010f574d67ef01aec964e6f1299241a3402857c1a8a390a62478" +dependencies = [ + "cfg-if", + "digest 0.11.0-rc.3", +] + +[[package]] +name = "md4" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da5ac363534dce5fabf69949225e174fbf111a498bf0ff794c8ea1fba9f3dda" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "md5" version = "0.7.0" @@ -2469,6 +3454,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2490,6 +3481,23 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "moka" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85f8024e1c8e71c778968af91d43700ce1d11b219d127d79fb2934153b82b42b" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "equivalent", + "parking_lot", + "portable-atomic", + "smallvec", + "tagptr", + "uuid", +] + [[package]] name = "muda" version = "0.17.1" @@ -2553,6 +3561,16 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -2586,6 +3604,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -2771,11 +3800,24 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "oid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c19903c598813dba001b53beeae59bb77ad4892c5c1b9b3500ce4293a0d06c2" +dependencies = [ + "serde", +] + [[package]] name = "once_cell" version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +dependencies = [ + "critical-section", + "portable-atomic", +] [[package]] name = "once_cell_polyfill" @@ -2801,6 +3843,12 @@ dependencies = [ "pathdiff", ] +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "option-ext" version = "0.2.0" @@ -2823,10 +3871,23 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder 0.13.6", + "sha2 0.10.9", +] + +[[package]] +name = "p256" +version = "0.14.0-pre.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b374901df34ee468167a58e2a49e468cb059868479cafebeb804f6b855423d" +dependencies = [ + "ecdsa 0.17.0-rc.7", + "elliptic-curve 0.14.0-rc.15", + "primefield", + "primeorder 0.14.0-pre.9", + "sha2 0.11.0-rc.2", ] [[package]] @@ -2835,10 +3896,24 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder 0.13.6", + "sha2 0.10.9", +] + +[[package]] +name = "p384" +version = "0.14.0-pre.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "701032b3730df6b882496d6cee8221de0ce4bc11ddc64e6d89784aa5b8a6de30" +dependencies = [ + "ecdsa 0.17.0-rc.7", + "elliptic-curve 0.14.0-rc.15", + "fiat-crypto 0.3.0", + "primefield", + "primeorder 0.14.0-pre.9", + "sha2 0.11.0-rc.2", ] [[package]] @@ -2847,12 +3922,27 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" dependencies = [ - "base16ct", - "ecdsa", - "elliptic-curve", - "primeorder", + "base16ct 0.2.0", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder 0.13.6", "rand_core 0.6.4", - "sha2", + "sha2 0.10.9", +] + +[[package]] +name = "p521" +version = "0.14.0-pre.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ba29c2906eb5c89a8c411c4f11243ee4e5517ee7d71d9a13fedc877a6057b1" +dependencies = [ + "base16ct 0.3.0", + "ecdsa 0.17.0-rc.7", + "elliptic-curve 0.14.0-rc.15", + "primefield", + "primeorder 0.14.0-pre.9", + "rand_core 0.9.5", + "sha2 0.11.0-rc.2", ] [[package]] @@ -2929,6 +4019,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pathdiff" version = "0.2.3" @@ -2941,8 +4037,19 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest", - "hmac", + "digest 0.10.7", + "hmac 0.12.1", +] + +[[package]] +name = "pbkdf2" +version = "0.13.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3fc18bb4460ac250ba6b75dfa7cf9d0b2273e3e623f660bd6ce2c3e902342e" +dependencies = [ + "digest 0.11.0-rc.3", + "hmac 0.13.0-rc.2", + "sha1 0.11.0-rc.2", ] [[package]] @@ -2954,6 +4061,15 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pem-rfc7468" +version = "1.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8e58fab693c712c0d4e88f8eb3087b6521d060bcaf76aeb20cb192d809115ba" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -3147,6 +4263,145 @@ dependencies = [ "siphasher 1.0.2", ] +[[package]] +name = "picky" +version = "7.0.0-rc.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cdc52be663aebd70d7006ae305c87eb32a2b836d6c2f26f7e384f845d80b621" +dependencies = [ + "aead 0.6.0-rc.2", + "aes 0.9.0-rc.1", + "aes-gcm 0.11.0-rc.1", + "aes-kw", + "base64 0.22.1", + "block-buffer 0.11.0-rc.5", + "block-padding 0.4.0-rc.4", + "cbc 0.2.0-rc.1", + "cipher 0.5.0-rc.1", + "crypto-bigint 0.7.0-rc.8", + "crypto-common 0.2.0-rc.4", + "crypto-primes", + "ctr 0.10.0-rc.1", + "curve25519-dalek 5.0.0-pre.1", + "der 0.8.0-rc.9", + "des 0.9.0-rc.1", + "digest 0.11.0-rc.3", + "ecdsa 0.17.0-rc.7", + "ed25519 3.0.0-rc.1", + "ed25519-dalek 3.0.0-pre.1", + "elliptic-curve 0.14.0-rc.15", + "ff 0.14.0-pre.0", + "ghash 0.6.0-rc.2", + "group 0.14.0-pre.0", + "hex", + "hkdf 0.13.0-rc.2", + "hmac 0.13.0-rc.2", + "http", + "inout 0.2.0-rc.6", + "keccak", + "md-5 0.11.0-rc.2", + "p256 0.14.0-pre.11", + "p384 0.14.0-pre.11", + "p521 0.14.0-pre.11", + "pbkdf2 0.13.0-rc.1", + "pem-rfc7468 1.0.0-rc.3", + "picky-asn1", + "picky-asn1-der", + "picky-asn1-x509", + "pkcs1 0.8.0-rc.4", + "pkcs8 0.11.0-rc.7", + "polyval 0.7.0-rc.2", + "primefield", + "primeorder 0.14.0-pre.9", + "rand 0.9.2", + "rand_core 0.9.5", + "rc2", + "rfc6979 0.5.0-rc.1", + "rsa 0.10.0-rc.9", + "sec1 0.8.0-rc.10", + "serde", + "serde_json", + "sha1 0.11.0-rc.2", + "sha2 0.11.0-rc.2", + "sha3", + "signature 3.0.0-rc.4", + "spki 0.8.0-rc.4", + "thiserror 2.0.18", + "universal-hash 0.6.0-rc.2", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "picky-asn1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ff038f9360b934342fb3c0a1d6e82c438a2624b51c3c6e3e6d7cf252b6f3ee3" +dependencies = [ + "oid", + "serde", + "serde_bytes", + "time", + "zeroize", +] + +[[package]] +name = "picky-asn1-der" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09561f7aa88cd6fae98edaf7dca3d8520da5b86a92839f2109a928af12a55c41" +dependencies = [ + "picky-asn1", + "serde", + "serde_bytes", +] + +[[package]] +name = "picky-asn1-x509" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c97cd14d567a17755910fa8718277baf39d08682a980b1b1a4b4da7d0bc61a04" +dependencies = [ + "base64 0.22.1", + "crypto-bigint 0.7.0-rc.8", + "oid", + "picky-asn1", + "picky-asn1-der", + "serde", + "widestring", + "zeroize", +] + +[[package]] +name = "picky-krb" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed61c8d7448649c031ecae02afb10c679524c7a9af5fb0fbee466b3cc0d6df1" +dependencies = [ + "aes 0.9.0-rc.1", + "block-buffer 0.11.0-rc.5", + "block-padding 0.4.0-rc.4", + "byteorder", + "cbc 0.2.0-rc.1", + "cipher 0.5.0-rc.1", + "crypto-bigint 0.7.0-rc.8", + "crypto-common 0.2.0-rc.4", + "des 0.9.0-rc.1", + "digest 0.11.0-rc.3", + "hmac 0.13.0-rc.2", + "inout 0.2.0-rc.6", + "oid", + "pbkdf2 0.13.0-rc.1", + "picky-asn1", + "picky-asn1-der", + "picky-asn1-x509", + "rand 0.9.2", + "serde", + "sha1 0.11.0-rc.2", + "thiserror 2.0.18", + "uuid", +] + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -3165,9 +4420,19 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der", - "pkcs8", - "spki", + "der 0.7.10", + "pkcs8 0.10.2", + "spki 0.7.3", +] + +[[package]] +name = "pkcs1" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986d2e952779af96ea048f160fd9194e1751b4faea78bcf3ceb456efe008088e" +dependencies = [ + "der 0.8.0-rc.9", + "spki 0.8.0-rc.4", ] [[package]] @@ -3176,13 +4441,13 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" dependencies = [ - "aes", - "cbc", - "der", - "pbkdf2", + "aes 0.8.4", + "cbc 0.1.2", + "der 0.7.10", + "pbkdf2 0.12.2", "scrypt", - "sha2", - "spki", + "sha2 0.10.9", + "spki 0.7.3", ] [[package]] @@ -3191,10 +4456,20 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", + "der 0.7.10", "pkcs5", "rand_core 0.6.4", - "spki", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.11.0-rc.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93eac55f10aceed84769df670ea4a32d2ffad7399400d41ee1c13b1cd8e1b478" +dependencies = [ + "der 0.8.0-rc.9", + "spki 0.8.0-rc.4", ] [[package]] @@ -3237,7 +4512,7 @@ checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", "opaque-debug", - "universal-hash", + "universal-hash 0.5.1", ] [[package]] @@ -3249,7 +4524,18 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug", - "universal-hash", + "universal-hash 0.5.1", +] + +[[package]] +name = "polyval" +version = "0.7.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffd40cc99d0fbb02b4b3771346b811df94194bc103983efa0203c8893755085" +dependencies = [ + "cfg-if", + "cpufeatures", + "universal-hash 0.6.0-rc.2", ] [[package]] @@ -3267,6 +4553,15 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "portpicker" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be97d76faf1bfab666e1375477b23fde79eccf0276e9b63b92a39d676a889ba9" +dependencies = [ + "rand 0.8.5", +] + [[package]] name = "potential_utf" version = "0.1.4" @@ -3307,13 +4602,35 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "primefield" +version = "0.14.0-pre.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7fcd4a163053332fd93f39b81c133e96a98567660981654579c90a99062fbf5" +dependencies = [ + "crypto-bigint 0.7.0-rc.8", + "ff 0.14.0-pre.0", + "rand_core 0.9.5", + "subtle", + "zeroize", +] + [[package]] name = "primeorder" version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.8", +] + +[[package]] +name = "primeorder" +version = "0.14.0-pre.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c36e8766fcd270fa9c665b9dc364f570695f5a59240949441b077a397f15b74" +dependencies = [ + "elliptic-curve 0.14.0-rc.15", ] [[package]] @@ -3393,6 +4710,61 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.6.3", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.3", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" version = "1.0.45" @@ -3414,6 +4786,12 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.7.3" @@ -3530,6 +4908,15 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "rc2" +version = "0.9.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03621ac292cc723def9e0fd0eb9573b1df8d6a9ee7ad637fe94dfc153705f3c" +dependencies = [ + "cipher 0.5.0-rc.1", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -3599,6 +4986,47 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + [[package]] name = "reqwest" version = "0.13.2" @@ -3633,33 +5061,83 @@ dependencies = [ "web-sys", ] +[[package]] +name = "resolv-conf" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" + [[package]] name = "rfc6979" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] +[[package]] +name = "rfc6979" +version = "0.5.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d369f9c4f79388704648e7bcb92749c0d6cf4397039293a9b747694fa4fb4bae" +dependencies = [ + "hmac 0.13.0-rc.2", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rsa" version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ - "const-oid", - "digest", + "const-oid 0.9.6", + "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", - "pkcs1", - "pkcs8", + "pkcs1 0.7.5", + "pkcs8 0.10.2", "rand_core 0.6.4", - "sha2", - "signature", - "spki", + "sha2 0.10.9", + "signature 2.2.0", + "spki 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "rsa" +version = "0.10.0-rc.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf8955ab399f6426998fde6b76ae27233cce950705e758a6c17afd2f6d0e5d52" +dependencies = [ + "const-oid 0.10.2", + "crypto-bigint 0.7.0-rc.8", + "crypto-primes", + "digest 0.11.0-rc.3", + "pkcs1 0.8.0-rc.4", + "pkcs8 0.11.0-rc.7", + "rand_core 0.9.5", + "sha1 0.11.0-rc.2", + "signature 3.0.0-rc.4", + "spki 0.8.0-rc.4", "subtle", "zeroize", ] @@ -3684,42 +5162,42 @@ version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c086efe0c429fa0b4e448c67147366d0319ed1c9a051d91b8f38e93fef25cc7" dependencies = [ - "aes", - "aes-gcm", + "aes 0.8.4", + "aes-gcm 0.10.3", "async-trait", "bitflags 2.11.0", "byteorder", "bytes", - "cbc", + "cbc 0.1.2", "chacha20", - "ctr", - "curve25519-dalek", + "ctr 0.9.2", + "curve25519-dalek 4.1.3", "delegate", - "des", - "digest", - "elliptic-curve", + "des 0.8.1", + "digest 0.10.7", + "elliptic-curve 0.13.8", "flate2", "futures", "generic-array", "hex-literal", - "hmac", + "hmac 0.12.1", "log", "num-bigint", "once_cell", - "p256", - "p384", - "p521", + "p256 0.13.2", + "p384 0.13.1", + "p521 0.13.3", "poly1305", "rand 0.8.5", "rand_core 0.6.4", - "rsa", + "rsa 0.9.10", "russh-cryptovec", "russh-keys", "russh-sftp", "russh-util", - "sha1", - "sha2", - "signature", + "sha1 0.10.6", + "sha2 0.10.9", + "signature 2.2.0", "ssh-encoding", "ssh-key", "subtle", @@ -3744,47 +5222,47 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed9bf3da16ad2892a44b840e40483010295bfc8fda8134650c381654cb1ef36" dependencies = [ - "aes", + "aes 0.8.4", "async-trait", "bcrypt-pbkdf", - "block-padding", + "block-padding 0.3.3", "byteorder", "bytes", - "cbc", - "ctr", + "cbc 0.1.2", + "ctr 0.9.2", "data-encoding", - "der", - "digest", - "ecdsa", - "ed25519-dalek", - "elliptic-curve", + "der 0.7.10", + "digest 0.10.7", + "ecdsa 0.16.9", + "ed25519-dalek 2.2.0", + "elliptic-curve 0.13.8", "futures", "getrandom 0.2.17", - "hmac", + "hmac 0.12.1", "home", - "inout", + "inout 0.1.4", "log", "md5", "num-integer", - "p256", - "p384", - "p521", + "p256 0.13.2", + "p384 0.13.1", + "p521 0.13.3", "pageant", - "pbkdf2", - "pkcs1", + "pbkdf2 0.12.2", + "pkcs1 0.7.5", "pkcs5", - "pkcs8", + "pkcs8 0.10.2", "rand 0.8.5", "rand_core 0.6.4", - "rsa", + "rsa 0.9.10", "russh-cryptovec", "russh-util", - "sec1", + "sec1 0.7.3", "serde", - "sha1", - "sha2", - "signature", - "spki", + "sha1 0.10.6", + "sha2 0.10.9", + "signature 2.2.0", + "spki 0.7.3", "ssh-encoding", "ssh-key", "thiserror 1.0.69", @@ -3838,19 +5316,84 @@ dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustls" +version = "0.23.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "salsa20" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" dependencies = [ - "cipher", + "cipher 0.4.4", ] [[package]] @@ -3862,6 +5405,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "schemars" version = "0.8.22" @@ -3925,9 +5477,9 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" dependencies = [ - "pbkdf2", + "pbkdf2 0.12.2", "salsa20", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -3936,14 +5488,59 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct", - "der", + "base16ct 0.2.0", + "der 0.7.10", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] +[[package]] +name = "sec1" +version = "0.8.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dff52f6118bc9f0ac974a54a639d499ac26a6cad7a6e39bc0990c19625e793b" +dependencies = [ + "base16ct 0.3.0", + "der 0.8.0-rc.9", + "hybrid-array", + "subtle", + "zeroize", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.11.0", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "seize" version = "0.3.3" @@ -4019,6 +5616,16 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -4092,6 +5699,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_with" version = "3.18.0" @@ -4123,6 +5742,16 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "serdect" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af4a3e75ebd5599b30d4de5768e00b5095d518a79fefc3ecbaf77e665d1ec06" +dependencies = [ + "base16ct 1.0.0", + "serde", +] + [[package]] name = "serialize-to-javascript" version = "0.1.2" @@ -4172,7 +5801,18 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.11.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e046edf639aa2e7afb285589e5405de2ef7e61d4b0ac1e30256e3eab911af9" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.0-rc.3", ] [[package]] @@ -4183,7 +5823,28 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1e3878ab0f98e35b2df35fe53201d088299b41a6bb63e3e34dada2ac4abd924" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.0-rc.3", +] + +[[package]] +name = "sha3" +version = "0.11.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2103ca0e6f4e9505eae906de5e5883e06fc3b2232fb5d6914890c7bbcb62f478" +dependencies = [ + "digest 0.11.0-rc.3", + "keccak", ] [[package]] @@ -4240,10 +5901,20 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "3.0.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc280a6ff65c79fbd6622f64d7127f32b85563bca8c53cd2e9141d6744a9056d" +dependencies = [ + "digest 0.11.0-rc.3", + "rand_core 0.9.5", +] + [[package]] name = "simd-adler32" version = "0.3.8" @@ -4274,6 +5945,16 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "socket2" version = "0.6.3" @@ -4337,6 +6018,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spki" @@ -4345,7 +6029,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.10", +] + +[[package]] +name = "spki" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" +dependencies = [ + "base64ct", + "der 0.8.0-rc.9", ] [[package]] @@ -4354,12 +6048,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" dependencies = [ - "aes", - "aes-gcm", - "cbc", + "aes 0.8.4", + "aes-gcm 0.10.3", + "cbc 0.1.2", "chacha20", - "cipher", - "ctr", + "cipher 0.4.4", + "ctr 0.9.2", "poly1305", "ssh-encoding", "subtle", @@ -4373,8 +6067,8 @@ checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" dependencies = [ "base64ct", "bytes", - "pem-rfc7468", - "sha2", + "pem-rfc7468 0.7.0", + "sha2 0.10.9", ] [[package]] @@ -4384,22 +6078,90 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b86f5297f0f04d08cabaa0f6bff7cb6aec4d9c3b49d87990d63da9d9156a8c3" dependencies = [ "bcrypt-pbkdf", - "ed25519-dalek", + "ed25519-dalek 2.2.0", "num-bigint-dig", - "p256", - "p384", - "p521", + "p256 0.13.2", + "p384 0.13.1", + "p521 0.13.3", "rand_core 0.6.4", - "rsa", - "sec1", - "sha2", - "signature", + "rsa 0.9.10", + "sec1 0.7.3", + "sha2 0.10.9", + "signature 2.2.0", "ssh-cipher", "ssh-encoding", "subtle", "zeroize", ] +[[package]] +name = "sspi" +version = "0.18.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2f4823ee743a4a0cc2153eb640e28ff95b55ca25c88085b559bae59fb6c317a" +dependencies = [ + "async-dnssd", + "async-recursion", + "bitflags 2.11.0", + "block-buffer 0.11.0-rc.5", + "byteorder", + "cfg-if", + "crypto-bigint 0.7.0-rc.8", + "crypto-common 0.2.0-rc.4", + "crypto-mac", + "crypto-primes", + "cryptoki", + "curve25519-dalek 5.0.0-pre.1", + "der 0.8.0-rc.9", + "digest 0.11.0-rc.3", + "ed25519-dalek 3.0.0-pre.1", + "ff 0.14.0-pre.0", + "futures", + "getrandom 0.3.4", + "group 0.14.0-pre.0", + "hickory-proto", + "hickory-resolver", + "hmac 0.13.0-rc.2", + "md-5 0.11.0-rc.2", + "md4", + "num-derive", + "num-traits", + "oid", + "p256 0.14.0-pre.11", + "p384 0.14.0-pre.11", + "p521 0.14.0-pre.11", + "pem-rfc7468 1.0.0-rc.3", + "picky", + "picky-asn1", + "picky-asn1-der", + "picky-asn1-x509", + "picky-krb", + "pkcs1 0.8.0-rc.4", + "pkcs8 0.11.0-rc.7", + "portpicker", + "primefield", + "primeorder 0.14.0-pre.9", + "rand 0.9.2", + "reqwest 0.12.28", + "rsa 0.10.0-rc.9", + "rustls", + "rustls-native-certs", + "serde", + "sha1 0.11.0-rc.2", + "sha2 0.11.0-rc.2", + "signature 3.0.0-rc.4", + "spki 0.8.0-rc.4", + "time", + "tokio", + "tracing", + "url", + "uuid", + "windows 0.62.2", + "windows-registry", + "winscard", + "zeroize", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -4520,6 +6282,27 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.11.0", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -4533,6 +6316,12 @@ dependencies = [ "version-compare", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tao" version = "0.34.6" @@ -4541,7 +6330,7 @@ checksum = "6e06d52c379e63da659a483a958110bbde891695a0ecb53e48cc7786d5eda7bb" dependencies = [ "bitflags 2.11.0", "block2", - "core-foundation", + "core-foundation 0.10.1", "core-graphics", "crossbeam-channel", "dispatch2", @@ -4582,6 +6371,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "target-lexicon" version = "0.12.16" @@ -4618,7 +6413,7 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest", + "reqwest 0.13.2", "serde", "serde_json", "serde_repr", @@ -4678,7 +6473,7 @@ dependencies = [ "semver", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "syn 2.0.117", "tauri-utils", "thiserror 2.0.18", @@ -4909,6 +6704,7 @@ checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", + "js-sys", "num-conv", "powerfmt", "serde_core", @@ -4951,6 +6747,42 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tls_codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de2e01245e2bb89d6f05801c564fa27624dbd7b1846859876c7dad82e90bf6b" +dependencies = [ + "tls_codec_derive", + "zeroize", +] + +[[package]] +name = "tls_codec_derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "tokio" version = "1.50.0" @@ -4963,7 +6795,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] @@ -4979,6 +6811,16 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.18" @@ -5160,10 +7002,23 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "tracing-core" version = "0.1.36" @@ -5278,10 +7133,26 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "universal-hash" +version = "0.6.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55be643b40a21558f44806b53ee9319595bc7ca6896372e4e08e5d7d83c9cd6" +dependencies = [ + "crypto-common 0.2.0-rc.4", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.8" @@ -5540,6 +7411,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "web_atoms" version = "0.2.3" @@ -5596,6 +7477,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webview2-com" version = "0.38.2" @@ -5632,6 +7522,12 @@ dependencies = [ "windows-core 0.61.2", ] +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + [[package]] name = "winapi" version = "0.3.9" @@ -5694,11 +7590,23 @@ version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-collections", + "windows-collections 0.2.0", "windows-core 0.61.2", - "windows-future", + "windows-future 0.2.1", "windows-link 0.1.3", - "windows-numerics", + "windows-numerics 0.2.0", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections 0.3.2", + "windows-core 0.62.2", + "windows-future 0.3.2", + "windows-numerics 0.3.1", ] [[package]] @@ -5710,6 +7618,15 @@ dependencies = [ "windows-core 0.61.2", ] +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + [[package]] name = "windows-core" version = "0.58.0" @@ -5757,7 +7674,18 @@ checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", "windows-link 0.1.3", - "windows-threading", + "windows-threading 0.1.0", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading 0.2.1", ] [[package]] @@ -5826,6 +7754,27 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + [[package]] name = "windows-result" version = "0.2.0" @@ -5890,6 +7839,24 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -5932,6 +7899,21 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -5974,6 +7956,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-version" version = "0.1.7" @@ -5989,6 +7980,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -6007,6 +8004,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -6025,6 +8028,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -6055,6 +8064,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -6073,6 +8088,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -6091,6 +8112,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -6109,6 +8136,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -6139,6 +8172,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winreg" version = "0.55.0" @@ -6149,6 +8192,29 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winscard" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b6ec4e6176df62589d1ac9950f6295be87ca06ee61a7c9a579a2bcc80efe34" +dependencies = [ + "bitflags 2.11.0", + "crypto-bigint 0.7.0-rc.8", + "flate2", + "iso7816", + "iso7816-tlv", + "num-derive", + "num-traits", + "picky", + "picky-asn1-x509", + "rand_core 0.9.5", + "rsa 0.10.0-rc.9", + "sha1 0.11.0-rc.2", + "time", + "tracing", + "uuid", +] + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -6241,13 +8307,16 @@ dependencies = [ name = "wraith" version = "0.1.0" dependencies = [ - "aes-gcm", + "aes-gcm 0.10.3", "argon2", "async-trait", "base64 0.22.1", "dashmap", "env_logger", "hex", + "ironrdp", + "ironrdp-tls", + "ironrdp-tokio", "log", "rand 0.9.2", "rusqlite", @@ -6256,12 +8325,15 @@ dependencies = [ "serde", "serde_json", "ssh-key", + "sspi", "tauri", "tauri-build", "tauri-plugin-shell", "thiserror 2.0.18", "tokio", + "tokio-rustls", "uuid", + "x509-cert", ] [[package]] @@ -6300,7 +8372,7 @@ dependencies = [ "once_cell", "percent-encoding", "raw-window-handle", - "sha2", + "sha2 0.10.9", "soup3", "tao-macros", "thiserror 2.0.18", @@ -6314,6 +8386,15 @@ dependencies = [ "x11-dl", ] +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x11" version = "2.21.0" @@ -6335,6 +8416,30 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x25519-dalek" +version = "3.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a45998121837fd8c92655d2334aa8f3e5ef0645cdfda5b321b13760c548fd55" +dependencies = [ + "curve25519-dalek 5.0.0-pre.1", + "rand_core 0.9.5", + "serde", + "zeroize", +] + +[[package]] +name = "x509-cert" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" +dependencies = [ + "const-oid 0.9.6", + "der 0.7.10", + "spki 0.7.3", + "tls_codec", +] + [[package]] name = "yoke" version = "0.8.1" @@ -6358,6 +8463,15 @@ dependencies = [ "synstructure", ] +[[package]] +name = "yuv" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a0036e8395a36727d814d90c490872c580e29d69edccf6f00d956d9bca985c" +dependencies = [ + "num-traits", +] + [[package]] name = "zerocopy" version = "0.8.42" @@ -6404,6 +8518,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] [[package]] name = "zerotrie" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 0c0d5a0..3bd3e53 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -31,3 +31,11 @@ thiserror = "2" russh = "0.48" russh-sftp = "2.1.1" ssh-key = { version = "0.6", features = ["ed25519", "rsa"] } + +# RDP (IronRDP) +ironrdp = { version = "0.14", features = ["connector", "session", "graphics", "input"] } +ironrdp-tokio = { version = "0.8", features = ["reqwest-rustls-ring"] } +ironrdp-tls = { version = "0.2", features = ["rustls"] } +tokio-rustls = "0.26" +x509-cert = { version = "0.2", default-features = false, features = ["std"] } +sspi = { version = "0.18", features = ["network_client"] } diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index ed3d902..b2582ee 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -4,3 +4,4 @@ pub mod connections; pub mod credentials; pub mod ssh_commands; pub mod sftp_commands; +pub mod rdp_commands; diff --git a/src-tauri/src/commands/rdp_commands.rs b/src-tauri/src/commands/rdp_commands.rs new file mode 100644 index 0000000..05abef7 --- /dev/null +++ b/src-tauri/src/commands/rdp_commands.rs @@ -0,0 +1,94 @@ +//! Tauri commands for RDP session management. +//! +//! Mirrors the pattern used by `ssh_commands.rs` — thin command wrappers that +//! delegate to the `RdpService` via `State`. + +use serde::Deserialize; +use tauri::State; + +use crate::rdp::{RdpConfig, RdpSessionInfo}; +use crate::AppState; + +/// Connect to an RDP server. +/// +/// Performs the full connection handshake (TCP -> TLS -> CredSSP -> RDP) and +/// starts streaming frame updates in the background. +/// +/// Returns the session UUID. +#[tauri::command] +pub fn connect_rdp( + config: RdpConfig, + state: State<'_, AppState>, +) -> Result { + state.rdp.connect(config) +} + +/// Get the current frame buffer as a base64-encoded RGBA string. +/// +/// The frontend decodes this and draws it onto a `` element. +/// Pixel format: RGBA, 4 bytes per pixel, row-major, top-left origin. +#[tauri::command] +pub async fn rdp_get_frame( + session_id: String, + state: State<'_, AppState>, +) -> Result { + state.rdp.get_frame(&session_id).await +} + +/// Send a mouse event to an RDP session. +/// +/// `flags` uses MS-RDPBCGR mouse event flags: +/// - 0x0800 = move +/// - 0x1000 = left button +/// - 0x2000 = right button +/// - 0x4000 = middle button +/// - 0x8000 = button pressed (absence = released) +/// - 0x0200 = vertical wheel +/// - 0x0100 = negative wheel direction +/// - 0x0400 = horizontal wheel +#[tauri::command] +pub async fn rdp_send_mouse( + session_id: String, + x: u16, + y: u16, + flags: u32, + state: State<'_, AppState>, +) -> Result<(), String> { + state.rdp.send_mouse(&session_id, x, y, flags) +} + +/// Send a keyboard event to an RDP session. +/// +/// `scancode` is the RDP hardware scancode (from the scancode map in +/// `rdp::input`). For extended keys (e.g. arrows, numpad enter), the high +/// byte is 0xE0. +/// +/// `pressed` is `true` for key-down, `false` for key-up. +#[tauri::command] +pub async fn rdp_send_key( + session_id: String, + scancode: u16, + pressed: bool, + state: State<'_, AppState>, +) -> Result<(), String> { + state.rdp.send_key(&session_id, scancode, pressed) +} + +/// Disconnect an RDP session. +/// +/// Sends a graceful shutdown to the RDP server and removes the session. +#[tauri::command] +pub async fn disconnect_rdp( + session_id: String, + state: State<'_, AppState>, +) -> Result<(), String> { + state.rdp.disconnect(&session_id) +} + +/// List all active RDP sessions (metadata only). +#[tauri::command] +pub async fn list_rdp_sessions( + state: State<'_, AppState>, +) -> Result, String> { + Ok(state.rdp.list_sessions()) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 2529743..9370621 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -5,6 +5,7 @@ pub mod connections; pub mod credentials; pub mod ssh; pub mod sftp; +pub mod rdp; pub mod commands; use std::path::PathBuf; @@ -17,6 +18,7 @@ use settings::SettingsService; use connections::ConnectionService; use sftp::SftpService; use ssh::session::SshService; +use rdp::RdpService; /// Application state shared across all Tauri commands via State. pub struct AppState { @@ -27,6 +29,7 @@ pub struct AppState { pub credentials: Mutex>, pub ssh: SshService, pub sftp: SftpService, + pub rdp: RdpService, } impl AppState { @@ -41,6 +44,7 @@ impl AppState { let connections = ConnectionService::new(database.clone()); let ssh = SshService::new(database.clone()); let sftp = SftpService::new(); + let rdp = RdpService::new(); Ok(Self { db: database, @@ -50,6 +54,7 @@ impl AppState { credentials: Mutex::new(None), ssh, sftp, + rdp, }) } @@ -125,6 +130,12 @@ pub fn run() { commands::sftp_commands::sftp_mkdir, commands::sftp_commands::sftp_delete, commands::sftp_commands::sftp_rename, + commands::rdp_commands::connect_rdp, + commands::rdp_commands::rdp_get_frame, + commands::rdp_commands::rdp_send_mouse, + commands::rdp_commands::rdp_send_key, + commands::rdp_commands::disconnect_rdp, + commands::rdp_commands::list_rdp_sessions, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/rdp/input.rs b/src-tauri/src/rdp/input.rs new file mode 100644 index 0000000..9dfcecd --- /dev/null +++ b/src-tauri/src/rdp/input.rs @@ -0,0 +1,192 @@ +//! Scancode mapping table — maps JavaScript `KeyboardEvent.code` strings to +//! RDP hardware scancodes (Set 1 / XT scan codes). +//! +//! Extended keys (those with a 0xE0 prefix on the wire) have the high byte set +//! to 0xE0. Use [`is_extended`] and [`scancode_value`] to decompose them. +//! +//! Ported from `wraith/internal/rdp/input.go`. + +use std::collections::HashMap; +use std::sync::LazyLock; + +/// RDP mouse event flags — these match the MS-RDPBCGR specification. +pub mod mouse_flags { + pub const MOVE: u32 = 0x0800; + pub const BUTTON1: u32 = 0x1000; // Left + pub const BUTTON2: u32 = 0x2000; // Right + pub const BUTTON3: u32 = 0x4000; // Middle + pub const DOWN: u32 = 0x8000; // Button pressed (absence = released) + pub const WHEEL: u32 = 0x0200; // Vertical wheel rotation + pub const WHEEL_NEG: u32 = 0x0100; // Negative wheel direction (scroll down) + pub const HWHEEL: u32 = 0x0400; // Horizontal wheel rotation +} + +/// Lazily-initialized map from JS `KeyboardEvent.code` to RDP hardware scancode. +pub static SCANCODE_MAP: LazyLock> = LazyLock::new(|| { + let mut m = HashMap::new(); + + // ── Row 0: Escape + Function keys ────────────────────────────── + m.insert("Escape", 0x0001u32); + m.insert("F1", 0x003B); + m.insert("F2", 0x003C); + m.insert("F3", 0x003D); + m.insert("F4", 0x003E); + m.insert("F5", 0x003F); + m.insert("F6", 0x0040); + m.insert("F7", 0x0041); + m.insert("F8", 0x0042); + m.insert("F9", 0x0043); + m.insert("F10", 0x0044); + m.insert("F11", 0x0057); + m.insert("F12", 0x0058); + + // ── Row 1: Number row ────────────────────────────────────────── + m.insert("Backquote", 0x0029); + m.insert("Digit1", 0x0002); + m.insert("Digit2", 0x0003); + m.insert("Digit3", 0x0004); + m.insert("Digit4", 0x0005); + m.insert("Digit5", 0x0006); + m.insert("Digit6", 0x0007); + m.insert("Digit7", 0x0008); + m.insert("Digit8", 0x0009); + m.insert("Digit9", 0x000A); + m.insert("Digit0", 0x000B); + m.insert("Minus", 0x000C); + m.insert("Equal", 0x000D); + m.insert("Backspace", 0x000E); + + // ── Row 2: QWERTY row ───────────────────────────────────────── + m.insert("Tab", 0x000F); + m.insert("KeyQ", 0x0010); + m.insert("KeyW", 0x0011); + m.insert("KeyE", 0x0012); + m.insert("KeyR", 0x0013); + m.insert("KeyT", 0x0014); + m.insert("KeyY", 0x0015); + m.insert("KeyU", 0x0016); + m.insert("KeyI", 0x0017); + m.insert("KeyO", 0x0018); + m.insert("KeyP", 0x0019); + m.insert("BracketLeft", 0x001A); + m.insert("BracketRight", 0x001B); + m.insert("Backslash", 0x002B); + + // ── Row 3: Home row ─────────────────────────────────────────── + m.insert("CapsLock", 0x003A); + m.insert("KeyA", 0x001E); + m.insert("KeyS", 0x001F); + m.insert("KeyD", 0x0020); + m.insert("KeyF", 0x0021); + m.insert("KeyG", 0x0022); + m.insert("KeyH", 0x0023); + m.insert("KeyJ", 0x0024); + m.insert("KeyK", 0x0025); + m.insert("KeyL", 0x0026); + m.insert("Semicolon", 0x0027); + m.insert("Quote", 0x0028); + m.insert("Enter", 0x001C); + + // ── Row 4: Bottom row ───────────────────────────────────────── + m.insert("ShiftLeft", 0x002A); + m.insert("KeyZ", 0x002C); + m.insert("KeyX", 0x002D); + m.insert("KeyC", 0x002E); + m.insert("KeyV", 0x002F); + m.insert("KeyB", 0x0030); + m.insert("KeyN", 0x0031); + m.insert("KeyM", 0x0032); + m.insert("Comma", 0x0033); + m.insert("Period", 0x0034); + m.insert("Slash", 0x0035); + m.insert("ShiftRight", 0x0036); + + // ── Row 5: Bottom modifiers + space ─────────────────────────── + m.insert("ControlLeft", 0x001D); + m.insert("MetaLeft", 0xE05B); + m.insert("AltLeft", 0x0038); + m.insert("Space", 0x0039); + m.insert("AltRight", 0xE038); + m.insert("MetaRight", 0xE05C); + m.insert("ContextMenu", 0xE05D); + m.insert("ControlRight", 0xE01D); + + // ── Navigation cluster ──────────────────────────────────────── + m.insert("PrintScreen", 0xE037); + m.insert("ScrollLock", 0x0046); + m.insert("Pause", 0x0045); + m.insert("Insert", 0xE052); + m.insert("Home", 0xE047); + m.insert("PageUp", 0xE049); + m.insert("Delete", 0xE053); + m.insert("End", 0xE04F); + m.insert("PageDown", 0xE051); + + // ── Arrow keys ──────────────────────────────────────────────── + m.insert("ArrowUp", 0xE048); + m.insert("ArrowLeft", 0xE04B); + m.insert("ArrowDown", 0xE050); + m.insert("ArrowRight", 0xE04D); + + // ── Numpad ──────────────────────────────────────────────────── + m.insert("NumLock", 0x0045); + m.insert("NumpadDivide", 0xE035); + m.insert("NumpadMultiply", 0x0037); + m.insert("NumpadSubtract", 0x004A); + m.insert("Numpad7", 0x0047); + m.insert("Numpad8", 0x0048); + m.insert("Numpad9", 0x0049); + m.insert("NumpadAdd", 0x004E); + m.insert("Numpad4", 0x004B); + m.insert("Numpad5", 0x004C); + m.insert("Numpad6", 0x004D); + m.insert("Numpad1", 0x004F); + m.insert("Numpad2", 0x0050); + m.insert("Numpad3", 0x0051); + m.insert("NumpadEnter", 0xE01C); + m.insert("Numpad0", 0x0052); + m.insert("NumpadDecimal", 0x0053); + + // ── Multimedia / browser keys ───────────────────────────────── + m.insert("BrowserBack", 0xE06A); + m.insert("BrowserForward", 0xE069); + m.insert("BrowserRefresh", 0xE067); + m.insert("BrowserStop", 0xE068); + m.insert("BrowserSearch", 0xE065); + m.insert("BrowserFavorites", 0xE066); + m.insert("BrowserHome", 0xE032); + m.insert("VolumeMute", 0xE020); + m.insert("VolumeDown", 0xE02E); + m.insert("VolumeUp", 0xE030); + m.insert("MediaTrackNext", 0xE019); + m.insert("MediaTrackPrevious", 0xE010); + m.insert("MediaStop", 0xE024); + m.insert("MediaPlayPause", 0xE022); + m.insert("LaunchMail", 0xE06C); + m.insert("LaunchApp1", 0xE06B); + m.insert("LaunchApp2", 0xE021); + + // ── International keys ──────────────────────────────────────── + m.insert("IntlBackslash", 0x0056); + m.insert("IntlYen", 0x007D); + m.insert("IntlRo", 0x0073); + + m +}); + +/// Look up the RDP hardware scancode for a JS `KeyboardEvent.code` string. +/// +/// Returns `None` for unmapped keys. +pub fn js_key_to_scancode(js_code: &str) -> Option { + SCANCODE_MAP.get(js_code).copied() +} + +/// Returns `true` if the scancode has the 0xE0 extended prefix. +pub fn is_extended(scancode: u32) -> bool { + (scancode & 0xFF00) == 0xE000 +} + +/// Returns the low byte of the scancode (the actual value without the prefix). +pub fn scancode_value(scancode: u32) -> u8 { + (scancode & 0xFF) as u8 +} diff --git a/src-tauri/src/rdp/mod.rs b/src-tauri/src/rdp/mod.rs new file mode 100644 index 0000000..6a467a2 --- /dev/null +++ b/src-tauri/src/rdp/mod.rs @@ -0,0 +1,619 @@ +//! RDP session manager — connects to Windows RDP servers via IronRDP, +//! maintains an RGBA frame buffer per session, and exposes input injection. +//! +//! Architecture: +//! - `RdpService` holds a `DashMap` of active sessions. +//! - Each session spawns a tokio task that runs the IronRDP active stage loop, +//! reading frames from the server and updating a shared `Vec` (RGBA). +//! - The frontend fetches frames via a Tauri command that reads the buffer. +//! - Mouse/keyboard input is sent to the session via an mpsc channel. + +pub mod input; + +use std::sync::Arc; + +use base64::Engine; +use dashmap::DashMap; +use log::{debug, error, info, warn}; +use serde::{Deserialize, Serialize}; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::net::TcpStream; +use tokio::sync::mpsc; +use tokio::sync::Mutex as TokioMutex; + +use ironrdp::connector::{self, ClientConnector, ConnectionResult, Credentials, DesktopSize}; +use ironrdp::graphics::image_processing::PixelFormat; +use ironrdp::input::{self as rdp_input, MouseButton, MousePosition, Operation, Scancode, WheelRotations}; +use ironrdp::pdu::gcc::KeyboardType; +use ironrdp::pdu::rdp::capability_sets::MajorPlatformType; +use ironrdp::pdu::rdp::client_info::{PerformanceFlags, TimezoneInfo}; +use ironrdp::session::image::DecodedImage; +use ironrdp::session::{ActiveStage, ActiveStageOutput}; +use ironrdp_tokio::reqwest::ReqwestNetworkClient; +use ironrdp_tokio::{split_tokio_framed, FramedWrite, TokioFramed}; + +use self::input::mouse_flags; + +// ── Public types ────────────────────────────────────────────────────────────── + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RdpConfig { + pub hostname: String, + pub port: u16, + pub username: String, + pub password: String, + pub domain: Option, + pub width: u16, + pub height: u16, +} + +#[derive(Debug, Serialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RdpSessionInfo { + pub id: String, + pub hostname: String, + pub width: u16, + pub height: u16, + pub connected: bool, +} + +/// Input events sent from the frontend to a session's background task. +enum InputEvent { + Mouse { + x: u16, + y: u16, + flags: u32, + }, + Key { + scancode: u16, + pressed: bool, + }, + Disconnect, +} + +// ── Session handle ──────────────────────────────────────────────────────────── + +/// A handle to a running RDP session. The actual IronRDP connection runs in a +/// background tokio task. This struct holds the shared frame buffer and an input +/// channel. +struct RdpSessionHandle { + id: String, + hostname: String, + width: u16, + height: u16, + /// RGBA pixel data — updated by the background task, read by the frontend. + frame_buffer: Arc>>, + /// Send input events to the background task. + input_tx: mpsc::UnboundedSender, +} + +// ── Service ─────────────────────────────────────────────────────────────────── + +pub struct RdpService { + sessions: DashMap>, +} + +impl RdpService { + pub fn new() -> Self { + Self { + sessions: DashMap::new(), + } + } + + /// Connect to an RDP server. Returns the session UUID on success. + /// + /// The entire RDP connection (handshake + active session loop) runs in a + /// dedicated thread with its own tokio runtime. This avoids Send/lifetime + /// issues with ironrdp's internal trait objects and tokio::spawn. + pub fn connect(&self, config: RdpConfig) -> Result { + let session_id = uuid::Uuid::new_v4().to_string(); + let width = config.width; + let height = config.height; + let hostname = config.hostname.clone(); + + // Create shared frame buffer — initialized to opaque black. + let buf_size = (width as usize) * (height as usize) * 4; + let mut initial_buf = vec![0u8; buf_size]; + for pixel in initial_buf.chunks_exact_mut(4) { + pixel[3] = 255; + } + let frame_buffer = Arc::new(TokioMutex::new(initial_buf)); + + // Create input channel. + let (input_tx, input_rx) = mpsc::unbounded_channel(); + + // Build session handle (accessible from main thread for frame reads + input sends). + let handle = Arc::new(RdpSessionHandle { + id: session_id.clone(), + hostname: hostname.clone(), + width, + height, + frame_buffer: frame_buffer.clone(), + input_tx, + }); + + self.sessions.insert(session_id.clone(), handle); + + // Spawn dedicated thread for the RDP connection + session loop. + let sid = session_id.clone(); + let sessions_ref = self.sessions.clone(); + let (ready_tx, ready_rx) = std::sync::mpsc::channel::>(); + + std::thread::spawn(move || { + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + rt.block_on(async move { + // Build connector config. + let connector_config = match build_connector_config(&config) { + Ok(c) => c, + Err(e) => { + let _ = ready_tx.send(Err(format!("Failed to build RDP config: {}", e))); + sessions_ref.remove(&sid); + return; + } + }; + + // Establish connection (TCP + TLS + CredSSP + RDP handshake). + let (connection_result, framed) = + match establish_connection(connector_config, &config.hostname, config.port).await { + Ok(r) => r, + Err(e) => { + let _ = ready_tx.send(Err(format!("RDP connection failed: {}", e))); + sessions_ref.remove(&sid); + return; + } + }; + + info!("RDP connection established to {}:{} (session {})", config.hostname, config.port, sid); + let _ = ready_tx.send(Ok(())); + + // Run active session loop until disconnect. + if let Err(e) = run_active_session( + connection_result, + framed, + frame_buffer, + input_rx, + width as u16, + height as u16, + ) + .await + { + error!("RDP session {} error: {}", sid, e); + } + info!("RDP session {} ended", sid); + sessions_ref.remove(&sid); + }); + }); + + // Wait for the connection to establish or fail. + match ready_rx.recv() { + Ok(Ok(())) => {} + Ok(Err(e)) => { + self.sessions.remove(&session_id); + return Err(e); + } + Err(_) => { + self.sessions.remove(&session_id); + return Err("RDP connection thread died unexpectedly".into()); + } + } + + Ok(session_id) + } + + /// Get the current frame buffer as base64-encoded RGBA data. + pub async fn get_frame(&self, session_id: &str) -> Result { + let handle = self + .sessions + .get(session_id) + .ok_or_else(|| format!("RDP session {} not found", session_id))?; + + let buf = handle.frame_buffer.lock().await; + let encoded = base64::engine::general_purpose::STANDARD.encode(&*buf); + Ok(encoded) + } + + /// Get the raw frame buffer bytes (for potential future optimization). + pub async fn get_frame_raw(&self, session_id: &str) -> Result, String> { + let handle = self + .sessions + .get(session_id) + .ok_or_else(|| format!("RDP session {} not found", session_id))?; + + let buf = handle.frame_buffer.lock().await; + Ok(buf.clone()) + } + + /// Send a mouse event to the RDP session. + /// + /// The `flags` parameter uses MS-RDPBCGR mouse event flags (see `input::mouse_flags`). + /// The frontend should construct these from DOM mouse events. + pub fn send_mouse(&self, session_id: &str, x: u16, y: u16, flags: u32) -> Result<(), String> { + let handle = self + .sessions + .get(session_id) + .ok_or_else(|| format!("RDP session {} not found", session_id))?; + + handle + .input_tx + .send(InputEvent::Mouse { x, y, flags }) + .map_err(|_| format!("RDP session {} input channel closed", session_id)) + } + + /// Send a keyboard event to the RDP session. + /// + /// `scancode` is the RDP hardware scancode (use `input::js_key_to_scancode` + /// on the frontend side or pass it through). `pressed` indicates key-down + /// vs key-up. + pub fn send_key(&self, session_id: &str, scancode: u16, pressed: bool) -> Result<(), String> { + let handle = self + .sessions + .get(session_id) + .ok_or_else(|| format!("RDP session {} not found", session_id))?; + + handle + .input_tx + .send(InputEvent::Key { scancode, pressed }) + .map_err(|_| format!("RDP session {} input channel closed", session_id)) + } + + /// Disconnect an RDP session. + pub fn disconnect(&self, session_id: &str) -> Result<(), String> { + let handle = self + .sessions + .get(session_id) + .ok_or_else(|| format!("RDP session {} not found", session_id))?; + + // Send disconnect signal — the background task will clean up. + let _ = handle.input_tx.send(InputEvent::Disconnect); + // Remove from map immediately so no new commands target it. + drop(handle); + self.sessions.remove(session_id); + + info!("RDP session {} disconnect requested", session_id); + Ok(()) + } + + /// List all active RDP sessions. + pub fn list_sessions(&self) -> Vec { + self.sessions + .iter() + .map(|entry| { + let h = entry.value(); + RdpSessionInfo { + id: h.id.clone(), + hostname: h.hostname.clone(), + width: h.width, + height: h.height, + connected: !h.input_tx.is_closed(), + } + }) + .collect() + } +} + +// Clone the DashMap reference for use in spawned tasks. +impl Clone for RdpService { + fn clone(&self) -> Self { + // This is intentionally a shallow clone — we want to share the same + // sessions map. But since DashMap doesn't implement Clone directly in + // a way we can use here, we use a different approach: the service + // itself is stored in AppState and accessed via State. + // The Clone here is only needed if we want to pass a reference to + // spawned tasks, which we handle via Arc internally. + unreachable!("RdpService should not be cloned — access via State"); + } +} + +// ── Connection establishment ────────────────────────────────────────────────── + +/// Build the IronRDP `connector::Config` from our simplified `RdpConfig`. +fn build_connector_config(config: &RdpConfig) -> Result { + Ok(connector::Config { + credentials: Credentials::UsernamePassword { + username: config.username.clone(), + password: config.password.clone(), + }, + domain: config.domain.clone(), + enable_tls: false, + enable_credssp: true, + keyboard_type: KeyboardType::IbmEnhanced, + keyboard_subtype: 0, + keyboard_layout: 0, + keyboard_functional_keys_count: 12, + ime_file_name: String::new(), + dig_product_id: String::new(), + desktop_size: DesktopSize { + width: config.width, + height: config.height, + }, + bitmap: None, + client_build: 0, + client_name: "Wraith Desktop".to_owned(), + client_dir: "C:\\Windows\\System32\\mstscax.dll".to_owned(), + + #[cfg(windows)] + platform: MajorPlatformType::WINDOWS, + #[cfg(target_os = "macos")] + platform: MajorPlatformType::MACINTOSH, + #[cfg(target_os = "linux")] + platform: MajorPlatformType::UNIX, + #[cfg(not(any(windows, target_os = "macos", target_os = "linux")))] + platform: MajorPlatformType::UNIX, + + enable_server_pointer: true, + pointer_software_rendering: true, + request_data: None, + autologon: false, + enable_audio_playback: false, + performance_flags: PerformanceFlags::default(), + desktop_scale_factor: 0, + hardware_id: None, + license_cache: None, + timezone_info: TimezoneInfo::default(), + }) +} + +/// Trait alias for types that implement both AsyncRead and AsyncWrite. +trait AsyncReadWrite: AsyncRead + AsyncWrite + 'static {} +impl AsyncReadWrite for T {} + +type UpgradedFramed = TokioFramed>; + +/// Perform the full RDP connection: TCP -> TLS upgrade -> CredSSP -> RDP handshake. +async fn establish_connection( + config: connector::Config, + hostname: &str, + port: u16, +) -> Result<(ConnectionResult, UpgradedFramed), String> { + // Resolve and connect TCP. + let addr = format!("{}:{}", hostname, port); + let stream = TcpStream::connect(&addr) + .await + .map_err(|e| format!("TCP connect to {} failed: {}", addr, e))?; + + let client_addr = stream + .local_addr() + .map_err(|e| format!("Failed to get local address: {}", e))?; + + let mut framed = TokioFramed::new(stream); + let mut connector = ClientConnector::new(config, client_addr); + + // Phase 1: Initial connection (pre-TLS). + let should_upgrade = ironrdp_tokio::connect_begin(&mut framed, &mut connector) + .await + .map_err(|e| format!("RDP connect_begin failed: {}", e))?; + + debug!("RDP TLS upgrade starting for {}", hostname); + + // Phase 2: TLS upgrade. + let (initial_stream, leftover_bytes) = framed.into_inner(); + + let (tls_stream, tls_cert) = ironrdp_tls::upgrade(initial_stream, hostname) + .await + .map_err(|e| format!("TLS upgrade failed: {}", e))?; + + let upgraded = ironrdp_tokio::mark_as_upgraded(should_upgrade, &mut connector); + + // Wrap the TLS stream in an erased box for the framed type. + let erased_stream: Box = Box::new(tls_stream); + let mut upgraded_framed = TokioFramed::new_with_leftover(erased_stream, leftover_bytes); + + // Phase 3: CredSSP + finalize. + let server_public_key = ironrdp_tls::extract_tls_server_public_key(&tls_cert) + .ok_or_else(|| "Failed to extract TLS server public key".to_string())? + .to_owned(); + + let connection_result = ironrdp_tokio::connect_finalize( + upgraded, + connector, + &mut upgraded_framed, + &mut ReqwestNetworkClient::new(), + hostname.into(), + server_public_key, + None, // No Kerberos config + ) + .await + .map_err(|e| format!("RDP connect_finalize failed: {}", e))?; + + debug!("RDP connection finalized for {}", hostname); + + Ok((connection_result, upgraded_framed)) +} + +// ── Active session loop ─────────────────────────────────────────────────────── + +/// Run the active RDP session loop — processes incoming frames and outgoing input. +async fn run_active_session( + connection_result: ConnectionResult, + framed: UpgradedFramed, + frame_buffer: Arc>>, + mut input_rx: mpsc::UnboundedReceiver, + width: u16, + height: u16, +) -> Result<(), String> { + let (mut reader, mut writer) = split_tokio_framed(framed); + + let mut image = DecodedImage::new(PixelFormat::RgbA32, width, height); + let mut active_stage = ActiveStage::new(connection_result); + let mut input_db = rdp_input::Database::new(); + + loop { + let outputs = tokio::select! { + // Read a PDU from the server. + frame = reader.read_pdu() => { + let (action, payload) = frame + .map_err(|e| format!("Failed to read RDP frame: {}", e))?; + + active_stage + .process(&mut image, action, &payload) + .map_err(|e| format!("Failed to process RDP frame: {}", e))? + } + // Receive input from the frontend. + input_event = input_rx.recv() => { + match input_event { + Some(InputEvent::Disconnect) | None => { + info!("RDP session disconnect signal received"); + // Attempt graceful shutdown. + match active_stage.graceful_shutdown() { + Ok(outputs) => { + for out in outputs { + if let ActiveStageOutput::ResponseFrame(frame) = out { + let _ = writer.write_all(&frame).await; + } + } + } + Err(e) => { + warn!("Graceful RDP shutdown failed: {}", e); + } + } + return Ok(()); + } + Some(InputEvent::Mouse { x, y, flags }) => { + let ops = translate_mouse_flags(x, y, flags); + let events = input_db.apply(ops); + active_stage + .process_fastpath_input(&mut image, &events) + .map_err(|e| format!("Failed to process mouse input: {}", e))? + } + Some(InputEvent::Key { scancode, pressed }) => { + let sc = Scancode::from_u16(scancode); + let op = if pressed { + Operation::KeyPressed(sc) + } else { + Operation::KeyReleased(sc) + }; + let events = input_db.apply([op]); + active_stage + .process_fastpath_input(&mut image, &events) + .map_err(|e| format!("Failed to process keyboard input: {}", e))? + } + } + } + }; + + // Process outputs from the active stage. + for out in outputs { + match out { + ActiveStageOutput::ResponseFrame(frame) => { + writer + .write_all(&frame) + .await + .map_err(|e| format!("Failed to write RDP response frame: {}", e))?; + } + ActiveStageOutput::GraphicsUpdate(_region) => { + // Copy the decoded image data into the shared frame buffer. + let mut buf = frame_buffer.lock().await; + let src = image.data(); + let dst_len = buf.len(); + if src.len() == dst_len { + buf.copy_from_slice(src); + } else { + // Desktop size may have changed — resize the buffer. + *buf = src.to_vec(); + } + } + ActiveStageOutput::Terminate(reason) => { + info!("RDP session terminated: {:?}", reason); + return Ok(()); + } + ActiveStageOutput::DeactivateAll(_connection_activation) => { + // The server requested deactivation-reactivation. For now, + // log and continue — a full implementation would re-run + // the connection activation sequence. + warn!("RDP server sent DeactivateAll — reconnection not yet implemented"); + return Ok(()); + } + // Pointer events — we could emit these to the frontend for + // custom cursor rendering, but for now we just log them. + ActiveStageOutput::PointerDefault => { + debug!("RDP pointer: default"); + } + ActiveStageOutput::PointerHidden => { + debug!("RDP pointer: hidden"); + } + ActiveStageOutput::PointerPosition { x, y } => { + debug!("RDP pointer position: ({}, {})", x, y); + } + ActiveStageOutput::PointerBitmap(_) => { + debug!("RDP pointer bitmap received"); + } + _ => { + // Future variants (MultitransportRequest, etc.) + } + } + } + } +} + +// ── Input translation ───────────────────────────────────────────────────────── + +/// Translate MS-RDPBCGR mouse flags into IronRDP `Operation` values. +/// +/// The frontend sends raw MS-RDPBCGR flags so this mapping is straightforward. +fn translate_mouse_flags(x: u16, y: u16, flags: u32) -> Vec { + let mut ops = Vec::new(); + let pos = MousePosition { x, y }; + + // Always include a move operation if the MOVE flag is set. + if flags & mouse_flags::MOVE != 0 { + ops.push(Operation::MouseMove(pos)); + } + + // Check for button press/release. + let is_down = flags & mouse_flags::DOWN != 0; + + if flags & mouse_flags::BUTTON1 != 0 { + if is_down { + ops.push(Operation::MouseButtonPressed(MouseButton::Left)); + } else { + ops.push(Operation::MouseButtonReleased(MouseButton::Left)); + } + } + + if flags & mouse_flags::BUTTON2 != 0 { + if is_down { + ops.push(Operation::MouseButtonPressed(MouseButton::Right)); + } else { + ops.push(Operation::MouseButtonReleased(MouseButton::Right)); + } + } + + if flags & mouse_flags::BUTTON3 != 0 { + if is_down { + ops.push(Operation::MouseButtonPressed(MouseButton::Middle)); + } else { + ops.push(Operation::MouseButtonReleased(MouseButton::Middle)); + } + } + + // Wheel events. + if flags & mouse_flags::WHEEL != 0 { + let negative = flags & mouse_flags::WHEEL_NEG != 0; + let units: i16 = if negative { -120 } else { 120 }; + ops.push(Operation::WheelRotations(WheelRotations { + is_vertical: true, + rotation_units: units, + })); + } + + if flags & mouse_flags::HWHEEL != 0 { + let negative = flags & mouse_flags::WHEEL_NEG != 0; + let units: i16 = if negative { -120 } else { 120 }; + ops.push(Operation::WheelRotations(WheelRotations { + is_vertical: false, + rotation_units: units, + })); + } + + // If no specific operation was generated but we have coordinates, treat + // it as a plain mouse move (some frontends send move without the flag). + if ops.is_empty() { + ops.push(Operation::MouseMove(pos)); + } + + ops +} diff --git a/src/components/rdp/RdpToolbar.vue b/src/components/rdp/RdpToolbar.vue new file mode 100644 index 0000000..7022d92 --- /dev/null +++ b/src/components/rdp/RdpToolbar.vue @@ -0,0 +1,168 @@ + + + + + diff --git a/src/components/rdp/RdpView.vue b/src/components/rdp/RdpView.vue new file mode 100644 index 0000000..98ab632 --- /dev/null +++ b/src/components/rdp/RdpView.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/src/components/session/SessionContainer.vue b/src/components/session/SessionContainer.vue index 34eeacd..39d3517 100644 --- a/src/components/session/SessionContainer.vue +++ b/src/components/session/SessionContainer.vue @@ -1,6 +1,6 @@