From 07a4f895b33388325266de8531cafdb92888d013 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Wed, 3 Sep 2025 10:43:37 +0200 Subject: [PATCH] treewide: Migrate to russh russh doesn't have the libsodium compilation issues on Windows that ssh2 - migrate to it. Signed-off-by: Konrad Dybcio --- Cargo.lock | 1925 ++++++++++++++++++++++++++++++++++++++------ cli/Cargo.toml | 16 +- cli/src/main.rs | 48 +- client/Cargo.toml | 16 +- client/src/main.rs | 59 +- proto/Cargo.toml | 19 +- proto/src/lib.rs | 28 +- proto/src/ssh.rs | 170 +++- 8 files changed, 1918 insertions(+), 363 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3cfe31d..2b822ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -17,6 +17,62 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.14" @@ -34,9 +90,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" @@ -72,6 +128,42 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "asynchronous-codec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" +dependencies = [ + "bytes", + "futures-sink", + "futures-util", + "memchr", + "pin-project-lite", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -88,16 +180,33 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.3", "object", "rustc-demangle", ] [[package]] -name = "bitflags" -version = "1.3.2" +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + +[[package]] +name = "bcrypt-pbkdf" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" +dependencies = [ + "blowfish", + "pbkdf2", + "sha2", +] [[package]] name = "bitflags" @@ -105,11 +214,69 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" -version = "1.6.0" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cbc" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] [[package]] name = "cc" @@ -123,11 +290,46 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" -version = "4.5.4" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" dependencies = [ "clap_builder", "clap_derive", @@ -135,9 +337,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" dependencies = [ "anstream", "anstyle", @@ -147,9 +349,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck", "proc-macro2", @@ -159,9 +361,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" @@ -171,25 +373,54 @@ checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "colored" -version = "2.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", ] [[package]] name = "crossterm" -version = "0.27.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.5.0", + "bitflags", "crossterm_winapi", - "libc", "mio", - "parking_lot 0.12.2", + "parking_lot", + "rustix", "signal-hook", "signal-hook-mio", "winapi", @@ -205,288 +436,1157 @@ dependencies = [ ] [[package]] -name = "gimli" -version = "0.28.1" +name = "crypto-bigint" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] [[package]] -name = "heck" -version = "0.5.0" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] [[package]] -name = "hermit-abi" -version = "0.3.9" +name = "ctr" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] [[package]] -name = "instant" -version = "0.1.13" +name = "curve25519-dalek" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.0" +name = "curve25519-dalek-derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "data-encoding" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] -name = "libc" -version = "0.2.155" +name = "delegate" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "6178a82cf56c836a3ba61a7935cdb1c49bfaa6fa4327cd5bf554a503087de26b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "libssh2-sys" -version = "0.3.0" +name = "der" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", + "const-oid", + "pem-rfc7468", + "zeroize", ] [[package]] -name = "libz-sys" -version = "1.1.16" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", + "block-buffer", + "const-oid", + "crypto-common", + "subtle", ] [[package]] -name = "lock_api" -version = "0.4.12" +name = "ecdsa" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "autocfg", - "scopeguard", + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", ] [[package]] -name = "log" -version = "0.4.21" +name = "ed25519" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] [[package]] -name = "memchr" -version = "2.7.2" +name = "ed25519-dalek" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core", + "serde", + "sha2", + "subtle", + "zeroize", +] [[package]] -name = "miniz_oxide" -version = "0.7.3" +name = "elliptic-curve" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "adler", + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", ] [[package]] -name = "mio" -version = "0.8.11" +name = "enum_dispatch" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", + "once_cell", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "num_cpus" -version = "1.16.0" +name = "errno" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ - "hermit-abi", "libc", + "windows-sys 0.52.0", ] [[package]] -name = "object" -version = "0.32.2" +name = "ff" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "memchr", + "rand_core", + "subtle", ] [[package]] -name = "openssl-sys" -version = "0.9.102" +name = "fiat-crypto" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] -name = "os_pipe" -version = "1.1.5" +name = "flate2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ - "libc", - "windows-sys 0.52.0", + "crc32fast", + "miniz_oxide 0.8.9", ] [[package]] -name = "parking_lot" -version = "0.11.2" +name = "futures" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "parking_lot" -version = "0.12.2" +name = "futures-channel" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ - "lock_api", - "parking_lot_core 0.9.10", + "futures-core", + "futures-sink", ] [[package]] -name = "parking_lot_core" -version = "0.8.6" +name = "futures-core" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "parking_lot_core" -version = "0.9.10" +name = "futures-io" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.1", - "smallvec", - "windows-targets 0.52.5", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "pin-project-lite" -version = "0.2.14" +name = "futures-sink" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] -name = "pkg-config" -version = "0.3.30" +name = "futures-task" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] -name = "proc-macro2" -version = "1.0.83" +name = "futures-util" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "unicode-ident", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "quote" -version = "1.0.36" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "proc-macro2", + "typenum", + "version_check", + "zeroize", ] [[package]] -name = "redox_syscall" +name = "getrandom" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ - "bitflags 1.3.2", + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", ] [[package]] -name = "redox_syscall" +name = "ghash" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ - "bitflags 2.5.0", + "opaque-debug", + "polyval", ] [[package]] -name = "rustc-demangle" -version = "0.1.24" +name = "gimli" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] -name = "scopeguard" -version = "1.2.0" +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.61.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "internal-russh-forked-ssh-key" +version = "0.6.9+upstream-0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5af01d366561582e9ea5f841837cc1d8e37e7142a32f33a43801e81863cba5" +dependencies = [ + "argon2", + "bcrypt-pbkdf", + "ecdsa", + "ed25519-dalek", + "hex", + "hmac", + "num-bigint-dig", + "p256", + "p384", + "p521", + "rand_core", + "rsa", + "sec1", + "sha1", + "sha2", + "signature", + "ssh-cipher", + "ssh-encoding", + "subtle", + "zeroize", +] + +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "miniz_oxide" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.59.0", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "rand", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "os_pipe" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p521" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +dependencies = [ + "base16ct", + "ecdsa", + "elliptic-curve", + "primeorder", + "rand_core", + "sha2", +] + +[[package]] +name = "pageant" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6f0e349ea8dea1b50aa17c082777d30df133d89898c7568a615354772d3731" +dependencies = [ + "bytes", + "delegate", + "futures", + "log", + "rand", + "thiserror", + "tokio", + "windows", +] + +[[package]] +name = "parking_lot" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs5" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +dependencies = [ + "aes", + "cbc", + "der", + "pbkdf2", + "scrypt", + "sha2", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "pkcs5", + "rand_core", + "spki", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rsa" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "sha2", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "russh" +version = "0.50.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d8075561703e70dab7b095b2c13597cde37f5be94af0849fa4e51c315020d0" +dependencies = [ + "aes", + "aes-gcm", + "bitflags", + "block-padding", + "byteorder", + "bytes", + "cbc", + "chacha20", + "ctr", + "curve25519-dalek", + "data-encoding", + "delegate", + "der", + "digest", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "enum_dispatch", + "flate2", + "futures", + "generic-array", + "getrandom", + "hex-literal", + "hmac", + "home", + "inout", + "internal-russh-forked-ssh-key", + "log", + "md5", + "num-bigint", + "once_cell", + "p256", + "p384", + "p521", + "pageant", + "pbkdf2", + "pkcs1", + "pkcs5", + "pkcs8", + "poly1305", + "rand", + "rand_core", + "rsa", + "russh-cryptovec", + "russh-util", + "sec1", + "sha1", + "sha2", + "signature", + "spki", + "ssh-encoding", + "subtle", + "thiserror", + "tokio", + "tokio-stream", + "typenum", + "zeroize", +] + +[[package]] +name = "russh-cryptovec" +version = "0.50.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fcb7c127135848b47715b5bcb13d8a27ccd86ce1de1c15eab5982df91fe279a" +dependencies = [ + "libc", + "log", + "ssh-encoding", + "winapi", +] + +[[package]] +name = "russh-util" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c698d702527b51a82e64de98d506e9c1e83a063035d41df4f2354499ec090b79" +dependencies = [ + "chrono", + "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scrypt" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +dependencies = [ + "pbkdf2", + "salsa20", + "sha2", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + [[package]] name = "serde" -version = "1.0.202" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "signal-hook" version = "0.3.17" @@ -499,9 +1599,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", "mio", @@ -517,6 +1617,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "sk8brd" version = "0.1.0" @@ -526,9 +1636,9 @@ dependencies = [ "colored", "crossterm", "os_pipe", + "russh", "serde", "sk8brd-proto", - "ssh2", "tokio", ] @@ -541,9 +1651,9 @@ dependencies = [ "colored", "crossterm", "os_pipe", + "russh", "serde", "sk8brd-proto", - "ssh2", "tokio", ] @@ -552,15 +1662,24 @@ name = "sk8brd-proto" version = "0.1.0" dependencies = [ "anyhow", + "async-trait", + "asynchronous-codec", "clap", "colored", "crossterm", "os_pipe", + "russh", "serde", - "ssh2", "tokio", + "use", ] +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + [[package]] name = "smallvec" version = "1.13.2" @@ -569,24 +1688,57 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.7" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] -name = "ssh2" -version = "0.9.4" +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7fe461910559f6d5604c3731d00d2aafc4a83d1665922e280f42f9a168d5455" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ - "bitflags 1.3.2", - "libc", - "libssh2-sys", - "parking_lot 0.11.2", + "base64ct", + "der", +] + +[[package]] +name = "ssh-cipher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" +dependencies = [ + "aes", + "aes-gcm", + "cbc", + "chacha20", + "cipher", + "ctr", + "poly1305", + "ssh-encoding", + "subtle", +] + +[[package]] +name = "ssh-encoding" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" +dependencies = [ + "base64ct", + "bytes", + "pem-rfc7468", + "sha2", ] [[package]] @@ -595,53 +1747,127 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" -version = "2.0.65" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio" -version = "1.37.0" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", - "num_cpus", - "parking_lot 0.12.2", + "parking_lot", "pin-project-lite", "signal-hook-registry", + "slab", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "use" +version = "0.0.1-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f916b8b6102de89f9999988ddc8e9bd0f119a8344e06bb19b0b03fb655769035" + [[package]] name = "utf8parse" version = "0.2.1" @@ -649,10 +1875,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] -name = "vcpkg" -version = "0.2.15" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" @@ -660,6 +1886,87 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -683,140 +1990,232 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-targets 0.48.5", + "windows-core 0.58.0", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "windows-core" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-targets 0.52.5", + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-core" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" 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", + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] -name = "windows-targets" -version = "0.52.5" +name = "windows-implement" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" +name = "windows-implement" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" +name = "windows-interface" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +name = "windows-interface" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" +name = "windows-link" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] -name = "windows_i686_gnu" -version = "0.48.5" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] [[package]] -name = "windows_i686_gnu" -version = "0.52.5" +name = "windows-result" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] [[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets", +] [[package]] -name = "windows_i686_msvc" -version = "0.48.5" +name = "windows-strings" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] [[package]] -name = "windows_i686_msvc" -version = "0.52.5" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] [[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] [[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] [[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index eaf0997..11a61d5 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -8,7 +8,7 @@ description = "Simple remote devboard control software (non-interactive CLI)" readme = "README.md" repository = "https://github.com/linux-msm/sk8brd" categories = ["command-line-utilities"] -publish = false # TODO +publish = false # TODO [badges] maintenance = { status = "actively-developed" } @@ -19,11 +19,11 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" -clap = { version = "4.5.4", features = ["derive"] } -colored = "2.1.0" -crossterm = "0.27.0" +clap = { version = "4.5.31", features = ["derive"] } +colored = "3.0.0" +crossterm = "0.28.1" sk8brd-proto = { path = "../proto/", features = ["ssh"] } -os_pipe = "1.1.5" -serde = { version = "^1.0.198", features = ["derive"] } -ssh2 = "^0.9.4" -tokio = { version = "^1.37.0", features = ["full"] } +os_pipe = "1.2.1" +russh = "0.50.4" +serde = { version = "1.0.218", features = ["derive"] } +tokio = { version = "1.43.0", features = ["full"] } diff --git a/cli/src/main.rs b/cli/src/main.rs index c7c7074..f938911 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,14 +1,17 @@ +use anyhow::Context; use clap::Parser; use colored::Colorize; -use sk8brd::ssh::{ssh_connect, ssh_disconnect, ssh_get_chan, SSH_BUFFER_SIZE}; +use russh::client::Msg; +use sk8brd::ssh::{ssh_connect, SSH_BUFFER_SIZE}; use sk8brd::{ console_print, parse_recv_msg, print_string_msg, select_brd, send_ack, send_image, todo, Sk8brdMsgs, CDBA_SERVER_BIN_NAME, MSG_HDR_SIZE, }; use std::fs; -use std::io::{stdout, Read, Write}; +use std::io::{stdout, Write}; use std::sync::Arc; use std::time::{Duration, SystemTime}; +use tokio::io::AsyncReadExt; use tokio::sync::Mutex; #[derive(Parser, Debug)] @@ -48,22 +51,30 @@ async fn main() -> anyhow::Result<()> { println!("sk8brd-cli {}", env!("CARGO_PKG_VERSION")); - let mut sess = ssh_connect(args.farm, args.port, args.user).await?; - sess.set_blocking(true); - let mut chan = ssh_get_chan(&mut sess, CDBA_SERVER_BIN_NAME).await?; + let chan = Arc::new(Mutex::new( + ssh_connect(&format!("{}:{}", args.farm, args.port), args.user).await?, + )); + (*chan.lock().await) + .exec(true, CDBA_SERVER_BIN_NAME) + .await + .with_context(|| format!("Couldn't execute {CDBA_SERVER_BIN_NAME} on remote server"))?; + + let mut server_stdin = Arc::new(Mutex::new((*chan.lock().await).make_writer())); + let (server_stdout, server_stderr) = sk8brd::ssh::into_streams::(chan).await; + let server_stdout = Arc::new(Mutex::new(server_stdout)); + let server_stderr = Arc::new(Mutex::new(server_stderr)); if args.board.is_empty() { - send_ack(&mut chan, Sk8brdMsgs::MsgListDevices).await?; + send_ack(&mut server_stdin, Sk8brdMsgs::MsgListDevices).await?; } else { - select_brd(&mut chan, &args.board).await?; + select_brd(&mut server_stdin, &args.board).await?; } // Msg handler // Read the message header first while time.elapsed()? < Duration::from_secs(args.timeout) { // Stream of "blue text" - status updates from the server - sess.set_blocking(false); - if let Ok(bytes_read) = (*chan.lock().await).stderr().read(&mut buf) { + if let Ok(bytes_read) = (*server_stderr.lock().await).read(&mut buf).await { let s = String::from_utf8_lossy(&buf[..bytes_read]); print!( "{}\r", @@ -71,19 +82,24 @@ async fn main() -> anyhow::Result<()> { ); stdout().flush()?; } - sess.set_blocking(true); - if (*chan.lock().await).read_exact(&mut hdr_buf).is_ok() { + if (*server_stdout.lock().await) + .read_exact(&mut hdr_buf) + .await + .is_ok() + { let msg = parse_recv_msg(&hdr_buf); let mut msgbuf = vec![0u8; msg.len as usize]; // Now read the actual data... - (*chan.lock().await).read_exact(&mut msgbuf)?; + (*server_stderr.lock().await) + .read_exact(&mut msgbuf) + .await?; // ..and process it match msg.r#type.try_into() { Ok(Sk8brdMsgs::MsgSelectBoard) => { - send_ack(&mut chan, Sk8brdMsgs::MsgPowerOn).await? + send_ack(&mut server_stdin, Sk8brdMsgs::MsgPowerOn).await? } Ok(Sk8brdMsgs::MsgConsole) => { if args.verbose { @@ -96,7 +112,7 @@ async fn main() -> anyhow::Result<()> { } Ok(Sk8brdMsgs::MsgFastbootPresent) => { if !msgbuf.is_empty() && msgbuf[0] != 0 { - send_image(&mut chan, &fastboot_image, &quit).await? + send_image(&mut server_stdin, &fastboot_image, &quit).await? } } Ok(Sk8brdMsgs::MsgFastbootDownload) => (), @@ -115,9 +131,9 @@ async fn main() -> anyhow::Result<()> { } // Power off the board on goodbye - send_ack(&mut chan, Sk8brdMsgs::MsgPowerOff).await?; + send_ack(&mut server_stdin, Sk8brdMsgs::MsgPowerOff).await?; - ssh_disconnect(&mut sess).await?; + // ssh_disconnect(&mut sess).await?; println!("\nGoodbye"); Ok(()) diff --git a/client/Cargo.toml b/client/Cargo.toml index 7a19c32..0953f7e 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -19,11 +19,11 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" -clap = { version = "4.5.4", features = ["derive"] } -colored = "2.1.0" -crossterm = "0.27.0" -sk8brd-proto = { version = "^0.1.0", path = "../proto", features = ["ssh"] } -os_pipe = "1.1.5" -serde = { version = "^1.0.198", features = ["derive"] } -ssh2 = "^0.9.4" -tokio = { version = "^1.37.0", features = ["full"] } +clap = { version = "4.5.31", features = ["derive"] } +colored = "3.0.0" +crossterm = "0.28.1" +sk8brd-proto = { path = "../proto", features = ["ssh"] } +os_pipe = "1.2.1" +serde = { version = "1.0.218", features = ["derive"] } +tokio = { version = "1.43.0", features = ["full"] } +russh = "0.50.4" diff --git a/client/src/main.rs b/client/src/main.rs index 76d7b44..b0bb1f7 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -1,6 +1,8 @@ +use anyhow::Context; use clap::Parser; use colored::Colorize; -use sk8brd::ssh::{ssh_connect, ssh_disconnect, ssh_get_chan, SSH_BUFFER_SIZE}; +use russh::client::Msg; +use sk8brd::ssh::{ssh_connect, SSH_BUFFER_SIZE}; use sk8brd::{ console_print, parse_recv_msg, print_string_msg, select_brd, send_ack, send_break, send_console, send_image, send_msg, todo, Sk8brdMsgs, CDBA_SERVER_BIN_NAME, MSG_HDR_SIZE, @@ -8,6 +10,7 @@ use sk8brd::{ use std::fs; use std::io::{stdout, Read, Write}; use std::sync::Arc; +use tokio::io::{AsyncReadExt, AsyncWrite}; use tokio::sync::Mutex; macro_rules! get_arc { @@ -42,7 +45,7 @@ async fn handle_keypress( c: char, quit: &mut Arc>, special: &mut bool, - message_sink: &mut Arc>, + message_sink: &mut Arc>, ) { if *special { *special = false; @@ -86,21 +89,31 @@ async fn main() -> anyhow::Result<()> { println!("sk8brd {}", env!("CARGO_PKG_VERSION")); - let mut sess = ssh_connect(args.farm, args.port, args.user).await?; - let mut chan = ssh_get_chan(&mut sess, CDBA_SERVER_BIN_NAME).await?; - sess.set_blocking(false); + let chan = Arc::new(Mutex::new( + ssh_connect(&format!("{}:{}", args.farm, args.port), args.user).await?, + )); + get_arc!(chan) + .exec(true, CDBA_SERVER_BIN_NAME) + .await + .with_context(|| format!("Couldn't execute {CDBA_SERVER_BIN_NAME} on remote server"))?; - send_ack(&mut chan, Sk8brdMsgs::MsgListDevices).await?; - select_brd(&mut chan, &args.board).await?; + let mut server_stdin = Arc::new(Mutex::new(get_arc!(chan).make_writer())); + + let (server_stdout, server_stderr) = sk8brd::ssh::into_streams::(chan).await; + let server_stdout = Arc::new(Mutex::new(server_stdout)); + let server_stderr = Arc::new(Mutex::new(server_stderr)); + + send_ack(&mut server_stdin, Sk8brdMsgs::MsgListDevices).await?; + select_brd(&mut server_stdin, &args.board).await?; if args.power_cycle { println!("Powering off the board first"); - send_ack(&mut chan, Sk8brdMsgs::MsgPowerOff).await?; + send_ack(&mut server_stdin, Sk8brdMsgs::MsgPowerOff).await?; } crossterm::terminal::enable_raw_mode()?; let mut quit2 = Arc::clone(&quit); - let mut chan2 = Arc::clone(&chan); + let mut server_stdin2 = Arc::clone(&server_stdin); let stdin_handler = tokio::spawn(async move { let mut stdin = os_pipe::dup_stdin().expect("Couldn't dup stdin"); let mut ctrl_a_pressed = false; @@ -108,7 +121,13 @@ async fn main() -> anyhow::Result<()> { while !*get_arc!(quit2) { if let Ok(len) = stdin.read(&mut key_buf) { for c in key_buf[0..len].iter() { - handle_keypress(*c as char, &mut quit2, &mut ctrl_a_pressed, &mut chan2).await; + handle_keypress( + *c as char, + &mut quit2, + &mut ctrl_a_pressed, + &mut server_stdin2, + ) + .await; } }; } @@ -116,7 +135,7 @@ async fn main() -> anyhow::Result<()> { while !*get_arc!(quit) { // Stream of "blue text" - status updates from the server - if let Ok(bytes_read) = (*get_arc!(chan)).stderr().read(&mut buf) { + if let Ok(bytes_read) = (*get_arc!(server_stderr)).read(&mut buf).await { let s = String::from_utf8_lossy(&buf[..bytes_read]); print!( "{}\r", @@ -127,18 +146,21 @@ async fn main() -> anyhow::Result<()> { // Msg handler // Read the message header first - if (*get_arc!(chan)).read_exact(&mut hdr_buf).is_ok() { - sess.set_blocking(true); + if (*get_arc!(server_stdout)) + .read_exact(&mut hdr_buf) + .await + .is_ok() + { let msg = parse_recv_msg(&hdr_buf); let mut msgbuf = vec![0u8; msg.len as usize]; // Now read the actual data... - (*get_arc!(chan)).read_exact(&mut msgbuf)?; + (*get_arc!(server_stdout)).read_exact(&mut msgbuf).await?; // ..and process it match msg.r#type.try_into() { Ok(Sk8brdMsgs::MsgSelectBoard) => { - send_msg(&mut chan, Sk8brdMsgs::MsgPowerOn, &[]).await? + send_msg(&mut server_stdin, Sk8brdMsgs::MsgPowerOn, &[]).await? } Ok(Sk8brdMsgs::MsgConsole) => console_print(&msgbuf).await, Ok(Sk8brdMsgs::MsgHardReset) => todo!("MsgHardReset is unused"), @@ -146,7 +168,7 @@ async fn main() -> anyhow::Result<()> { Ok(Sk8brdMsgs::MsgPowerOff) => (), Ok(Sk8brdMsgs::MsgFastbootPresent) => { if !msgbuf.is_empty() && msgbuf[0] != 0 { - send_image(&mut chan, &fastboot_image, &quit).await? + send_image(&mut server_stdin, &fastboot_image, &quit).await? } } Ok(Sk8brdMsgs::MsgFastbootDownload) => (), @@ -163,7 +185,6 @@ async fn main() -> anyhow::Result<()> { Ok(m) => todo!("{m:?} is unimplemented, skipping.."), Err(e) => todo!("Received unknown/invalid message: `{e}`"), }; - sess.set_blocking(false); } } @@ -174,9 +195,9 @@ async fn main() -> anyhow::Result<()> { crossterm::terminal::disable_raw_mode()?; // Power off the board on goodbye - send_ack(&mut chan, Sk8brdMsgs::MsgPowerOff).await?; + send_ack(&mut server_stdin, Sk8brdMsgs::MsgPowerOff).await?; - ssh_disconnect(&mut sess).await?; + // ssh_disconnect(&mut sess).await?; println!("\nGoodbye"); Ok(()) diff --git a/proto/Cargo.toml b/proto/Cargo.toml index 83f3431..d0b4378 100644 --- a/proto/Cargo.toml +++ b/proto/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sk8brd-proto" version = "0.1.0" -edition = "2021" +edition = "2024" authors = ["Konrad Dybcio "] license = "BSD-3-Clause" description = "Simple remote devboard control software" @@ -21,10 +21,13 @@ ssh = [] [dependencies] anyhow = "1.0" -clap = { version = "4.5.4", features = ["derive"] } -colored = "2.1.0" -crossterm = "0.27.0" -os_pipe = "1.1.5" -serde = { version = "^1.0.198", features = ["derive"] } -ssh2 = "^0.9.4" -tokio = { version = "^1.37.0", features = ["full"] } +async-trait = "0.1.87" +asynchronous-codec = "0.7.0" +clap = { version = "4.5.31", features = ["derive"] } +colored = "3.0.0" +crossterm = "0.28.1" +os_pipe = "1.2.1" +russh = "0.50.4" +serde = { version = "1.0.218", features = ["derive"] } +tokio = { version = "1.43.0", features = ["full"] } +use = "0.0.1-pre.0" diff --git a/proto/src/lib.rs b/proto/src/lib.rs index 8559ccd..0e448da 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -1,8 +1,9 @@ use colored::Colorize; use serde::{Deserialize, Serialize}; -use std::io::{stdout, Write}; +use std::io::{Write, stdout}; use std::mem::size_of; use std::sync::Arc; +use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio::sync::Mutex; #[cfg(feature = "ssh")] @@ -68,7 +69,7 @@ pub struct Sk8brdMsg { pub const MSG_HDR_SIZE: usize = size_of::(); pub async fn send_msg( - write_sink: &mut Arc>, + write_sink: &mut Arc>, r#type: Sk8brdMsgs, buf: &[u8], ) -> anyhow::Result<()> { @@ -78,13 +79,13 @@ pub async fn send_msg( let len = buf.len(); let hdr = [r#type as u8, (len & 0xff) as u8, ((len >> 8) & 0xff) as u8]; - write_sink.write_all(&hdr)?; - write_sink.write_all(buf)?; + write_sink.write_all(&hdr).await?; + write_sink.write_all(buf).await?; Ok(()) } pub async fn send_ack( - write_sink: &mut Arc>, + write_sink: &mut Arc>, r#type: Sk8brdMsgs, ) -> anyhow::Result<()> { send_msg(write_sink, r#type, &[]).await @@ -93,7 +94,7 @@ pub async fn send_ack( pub fn parse_recv_msg(buf: &[u8]) -> Sk8brdMsg { let msg: Sk8brdMsg = Sk8brdMsg { r#type: buf[0], - len: (buf[2] as u16) << 8 | buf[1] as u16, + len: ((buf[2] as u16) << 8) | buf[1] as u16, }; // println!("{:?}", msg); @@ -108,7 +109,7 @@ pub async fn console_print(buf: &[u8]) { #[allow(clippy::explicit_write)] pub async fn send_image( - write_sink: &mut Arc>, + write_sink: &mut Arc>, buf: &[u8], quit: &Arc>, ) -> anyhow::Result<()> { @@ -123,7 +124,7 @@ pub async fn send_image( } if percent_done != last_percent_done { - let s = format!("Sending image: {}%\r", percent_done); + let s = format!("Sending image: {percent_done}%\r"); print!("{}", s.green()); stdout().flush()?; } @@ -143,16 +144,21 @@ pub async fn send_image( send_ack(write_sink, Sk8brdMsgs::MsgFastbootDownload).await } -pub async fn select_brd(write_sink: &mut Arc>, name: &str) -> anyhow::Result<()> { +pub async fn select_brd( + write_sink: &mut Arc>, + name: &str, +) -> anyhow::Result<()> { send_msg(write_sink, Sk8brdMsgs::MsgSelectBoard, name.as_bytes()).await } -pub async fn send_break(write_sink: &mut Arc>) -> anyhow::Result<()> { +pub async fn send_break( + write_sink: &mut Arc>, +) -> anyhow::Result<()> { send_ack(write_sink, Sk8brdMsgs::MsgSendBreak).await } pub async fn send_console( - write_sink: &mut Arc>, + write_sink: &mut Arc>, buf: &[u8], ) -> anyhow::Result<()> { send_msg(write_sink, Sk8brdMsgs::MsgConsole, buf).await diff --git a/proto/src/ssh.rs b/proto/src/ssh.rs index 6bde9bf..94f8d3b 100644 --- a/proto/src/ssh.rs +++ b/proto/src/ssh.rs @@ -1,43 +1,153 @@ -use anyhow::Context as _; -use ssh2::{Channel, Session}; -use std::net::TcpStream; +use anyhow::{Context as _, bail}; +use asynchronous_codec::BytesMut; +use russh::Channel; +use russh::client::{self, Msg}; +use russh::keys::{HashAlg, ssh_key}; +use std::pin::Pin; use std::sync::Arc; -use tokio::sync::Mutex; +use std::task::{Context, Poll}; +use tokio::io::AsyncRead; +use tokio::sync::mpsc::Receiver; +use tokio::sync::{Mutex, mpsc}; pub const SSH_BUFFER_SIZE: usize = 2048; -pub async fn ssh_connect(farm: String, port: String, username: String) -> anyhow::Result { - // Connect to the local SSH server - let tcp = TcpStream::connect(format!("{}:{}", farm, port)) - .with_context(|| format!("Couldn't connect to {}:{}", farm, port))?; - let mut sess = Session::new()?; - sess.set_tcp_stream(tcp); - sess.handshake()?; +struct Client {} - // Try to authenticate with the first identity in the agent. - sess.userauth_agent(&username) - .with_context(|| format!("Couldn't authenticate as {username}"))?; +impl client::Handler for Client { + type Error = anyhow::Error; - Ok(sess) + async fn check_server_key( + &mut self, + _server_public_key: &ssh_key::PublicKey, + ) -> Result { + Ok(true) + } } -pub async fn ssh_get_chan( - sess: &mut Session, - server_bin_name: &str, -) -> anyhow::Result>> { - let chan = Arc::new(Mutex::new(sess.channel_session()?)); - (*chan.lock().await) - .exec(server_bin_name) - .with_context(|| format!("Couldn't execute {server_bin_name} on remote host"))?; +pub async fn ssh_connect(farm: &str, username: String) -> anyhow::Result> { + // Connect to the local SSH server + let config = client::Config::default(); + let client = Client {}; + #[cfg(unix)] + let agent = russh::keys::agent::client::AgentClient::connect_env().await; + #[cfg(windows)] + let agent = russh::keys::agent::client::AgentClient::connect_named_pipe( + "\\\\.\\\\pipe\\\\openssh-ssh-agent", + ) + .await; + + let mut agent = agent.expect("Couldn't authenticate with the ssh agent"); + + let mut sess = client::connect(Arc::new(config), farm, client) + .await + .with_context(|| format!("Couldn't connect to {farm}"))?; + + let keys = agent + .request_identities() + .await + .expect("Couldn't get identities from the ssh agent"); + while let Some(key) = keys.first() { + if sess + .authenticate_publickey_with( + &username, + key.to_owned(), + Some(HashAlg::Sha256), + &mut agent, + ) + .await + .is_ok() + { + break; + } + } + + if sess.is_closed() { + bail!("No key was accepted by the server"); + } + + let chan = sess + .channel_open_session() + .await + .expect("Couldn't open session"); Ok(chan) } -pub async fn ssh_disconnect(sess: &mut Session) -> anyhow::Result<()> { - sess.disconnect( - Option::Some(ssh2::DisconnectCode::ConnectionLost), - "bye", - Option::Some("C"), - ) - .context("Couldn't disconnect cleanly") +pub struct Wrap(Receiver>, BytesMut); + +impl Wrap { + fn new(rx: Receiver>) -> Self { + Self(rx, BytesMut::new()) + } +} + +/// Create streams for a channel's stdout and stderr, consuming the channel in the process +pub async fn into_streams(chan: Arc>>) -> (Wrap, Wrap) +where + S: From<(russh::ChannelId, russh::ChannelMsg)> + std::marker::Send + 'static + Sync, +{ + let (txo, rxo) = mpsc::channel::>(1000); + let (txe, rxe) = mpsc::channel::>(1000); + + tokio::spawn(async move { + loop { + match chan.lock().await.wait().await { + Some(russh::ChannelMsg::Data { data }) => { + txo.send(data[..].into()) + .await + .map_err(|_| russh::Error::SendError)?; + } + Some(russh::ChannelMsg::ExtendedData { data, ext: 1 }) => { + txe.send(data[..].into()) + .await + .map_err(|_| russh::Error::SendError)?; + } + Some(russh::ChannelMsg::ExtendedData { data: _, ext }) => { + println!("Received surprise data on stream {ext}"); + } + Some(russh::ChannelMsg::Eof) => { + // Send a 0-length chunk to indicate EOF. + txo.send(vec![]) + .await + .map_err(|_| russh::Error::SendError)?; + break; + } + None => break, + _ => (), + } + } + + chan.lock().await.close().await?; + Ok::<_, russh::Error>(()) + }); + + (Wrap::new(rxo), Wrap::new(rxe)) +} + +impl AsyncRead for Wrap { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut tokio::io::ReadBuf<'_>, + ) -> Poll> { + let cache_size = self.1.len(); + buf.put_slice(&self.1.split_to(usize::min(buf.remaining(), cache_size))); + + if buf.remaining() > 0 { + match self.0.poll_recv(cx) { + Poll::Ready(Some(msg)) => { + self.1 = BytesMut::from(&msg[..]); + let len = self.1.len(); + buf.put_slice(&self.1.split_to(usize::min(buf.remaining(), len))); + Poll::Ready(Ok(())) + } + + Poll::Ready(None) => Poll::Ready(Ok(())), + Poll::Pending => Poll::Pending, + } + } else { + Poll::Ready(Ok(())) + } + } }