From 947636579a65cb7ee5483e656678c8ca71a76376 Mon Sep 17 00:00:00 2001 From: Eric Rodrigues Pires Date: Sat, 30 Aug 2025 11:58:21 -0300 Subject: [PATCH] Update dependencies, bump MSRV, and make further changes to logs --- .github/workflows/validate.yml | 2 +- CHANGELOG.md | 1 + Cargo.lock | 563 +++++++++------------ Cargo.toml | 28 +- Dockerfile | 2 +- docker-compose-example/client/Dockerfile | 2 +- src/addressing.rs | 25 +- src/admin/interface.rs | 19 +- src/connections.rs | 24 +- src/ssh/forwarding.rs | 613 ++++++++++++----------- src/ssh/mod.rs | 12 +- src/tcp.rs | 77 ++- tests/admin_missing_pty.rs | 2 +- 13 files changed, 644 insertions(+), 726 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index fdc80b5..bd09f72 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -9,7 +9,7 @@ permissions: contents: read env: - RUST_MSRV: 1.85.0 + RUST_MSRV: 1.88.0 CARGO_INCREMENTAL: 0 CARGO_PROFILE_TEST_DEBUG: 0 diff --git a/CHANGELOG.md b/CHANGELOG.md index d87676a..8bcefa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Changed - Improve SSH log messages. +- Update dependencies. ## 0.8.1 diff --git a/Cargo.lock b/Cargo.lock index 375414f..8bdca90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" dependencies = [ "anstyle", "anstyle-parse", @@ -146,29 +146,29 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "argon2" @@ -229,9 +229,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ "concurrent-queue", "event-listener-strategy", @@ -254,9 +254,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1237c0ae75a0f3765f58910ff9cdd0a12eeb39ab2f4c7de23262f337f0aacbb3" +checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca" dependencies = [ "async-lock", "cfg-if", @@ -265,17 +265,16 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 1.0.7", + "rustix 1.0.8", "slab", - "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "async-lock" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ "event-listener", "event-listener-strategy", @@ -314,9 +313,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", @@ -496,7 +495,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "cexpr", "clang-sys", "itertools 0.12.1", @@ -521,9 +520,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" [[package]] name = "blake2" @@ -565,9 +564,9 @@ dependencies = [ [[package]] name = "blocking" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ "async-channel", "async-task", @@ -588,9 +587,9 @@ dependencies = [ [[package]] name = "bon" -version = "3.6.5" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d9ef19ae5263a138da9a86871eca537478ab0332a7770bac7e3f08b801f89f" +checksum = "537c317ddf588aab15c695bf92cf55dec159b93221c074180ca3e0e5a94da415" dependencies = [ "bon-macros", "rustversion", @@ -598,11 +597,11 @@ dependencies = [ [[package]] name = "bon-macros" -version = "3.6.5" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577ae008f2ca11ca7641bd44601002ee5ab49ef0af64846ce1ab6057218a5cc1" +checksum = "ca5abbf2d4a4c6896197c9de13d6d7cb7eff438c63dacde1dde980569cb00248" dependencies = [ - "darling 0.21.0", + "darling 0.21.3", "ident_case", "prettyplease", "proc-macro2", @@ -613,9 +612,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.18.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -643,9 +642,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "castaway" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" dependencies = [ "rustversion", ] @@ -661,9 +660,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.27" +version = "1.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" dependencies = [ "jobserver", "libc", @@ -681,9 +680,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "cfg_aliases" @@ -739,9 +738,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.42" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" +checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" dependencies = [ "clap_builder", "clap_derive", @@ -749,9 +748,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.42" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" +checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" dependencies = [ "anstream", "anstyle", @@ -761,9 +760,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" dependencies = [ "heck", "proc-macro2", @@ -897,9 +896,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -950,7 +949,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "crossterm_winapi", "mio", "parking_lot", @@ -966,10 +965,10 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "document-features", "parking_lot", - "rustix 1.0.7", + "rustix 1.0.8", ] [[package]] @@ -1051,12 +1050,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.21.0" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a79c4acb1fd5fa3d9304be4c76e031c54d2e92d172a393e24b19a14fe8532fe9" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core 0.21.0", - "darling_macro 0.21.0", + "darling_core 0.21.3", + "darling_macro 0.21.3", ] [[package]] @@ -1075,9 +1074,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.21.0" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74875de90daf30eb59609910b84d4d368103aaec4c924824c6799b28f77d6a1d" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", @@ -1100,11 +1099,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.21.0" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79f8e61677d5df9167cd85265f8e5f64b215cdea3fb55eebc3e622e44c7a146" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "darling_core 0.21.0", + "darling_core 0.21.3", "quote", "syn", ] @@ -1131,9 +1130,9 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "delegate" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b6483c2bbed26f97861cf57651d4f2b731964a28cd2257f934a4b452480d21" +checksum = "6178a82cf56c836a3ba61a7935cdb1c49bfaa6fa4327cd5bf554a503087de26b" dependencies = [ "proc-macro2", "quote", @@ -1250,9 +1249,9 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek", "ed25519", @@ -1388,9 +1387,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -1493,9 +1492,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -1571,9 +1570,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ "fastrand", "futures-core", @@ -1642,9 +1641,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" +checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" dependencies = [ "cc", "cfg-if", @@ -1688,7 +1687,7 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.3+wasi-0.2.4", "wasm-bindgen", ] @@ -1710,9 +1709,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "group" @@ -1727,9 +1726,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", @@ -1752,9 +1751,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", @@ -1785,30 +1784,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" -[[package]] -name = "hickory-proto" -version = "0.24.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna", - "ipnet", - "once_cell", - "rand 0.8.5", - "thiserror 1.0.69", - "tinyvec", - "tokio", - "tracing", - "url", -] - [[package]] name = "hickory-proto" version = "0.25.2" @@ -1827,34 +1802,13 @@ dependencies = [ "once_cell", "rand 0.9.2", "ring", - "thiserror 2.0.12", + "thiserror 2.0.16", "tinyvec", "tokio", "tracing", "url", ] -[[package]] -name = "hickory-resolver" -version = "0.24.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" -dependencies = [ - "cfg-if", - "futures-util", - "hickory-proto 0.24.4", - "ipconfig", - "lru-cache", - "once_cell", - "parking_lot", - "rand 0.8.5", - "resolv-conf", - "smallvec", - "thiserror 1.0.69", - "tokio", - "tracing", -] - [[package]] name = "hickory-resolver" version = "0.25.2" @@ -1863,7 +1817,7 @@ checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" dependencies = [ "cfg-if", "futures-util", - "hickory-proto 0.25.2", + "hickory-proto", "ipconfig", "moka", "once_cell", @@ -1871,7 +1825,7 @@ dependencies = [ "rand 0.9.2", "resolv-conf", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -1957,13 +1911,14 @@ checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "hyper" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "h2", "http", "http-body", @@ -1971,6 +1926,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -2137,9 +2093,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -2158,18 +2114,18 @@ dependencies = [ [[package]] name = "indenter" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" dependencies = [ "equivalent", - "hashbrown 0.15.4", + "hashbrown 0.15.5", ] [[package]] @@ -2184,7 +2140,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "inotify-sys", "libc", ] @@ -2222,9 +2178,9 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d" +checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" dependencies = [ "darling 0.20.11", "indoc", @@ -2263,11 +2219,11 @@ dependencies = [ [[package]] name = "io-uring" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "cfg-if", "libc", ] @@ -2360,9 +2316,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom 0.3.3", "libc", @@ -2415,9 +2371,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libloading" @@ -2426,7 +2382,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.2", + "windows-targets 0.53.3", ] [[package]] @@ -2435,12 +2391,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -2461,9 +2411,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "litrs" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock_api" @@ -2509,16 +2459,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.4", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", + "hashbrown 0.15.5", ] [[package]] @@ -2529,11 +2470,11 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -2580,7 +2521,7 @@ dependencies = [ "metrics", "metrics-util", "quanta", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -2593,7 +2534,7 @@ checksum = "fe8db7a05415d0f919ffb905afa37784f71901c9a773188876984b4f769ab986" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.4", + "hashbrown 0.15.5", "metrics", "quanta", "rand 0.9.2", @@ -2685,7 +2626,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "cfg-if", "cfg_aliases", "libc", @@ -2697,7 +2638,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "cfg-if", "cfg_aliases", "libc", @@ -2715,11 +2656,11 @@ dependencies = [ [[package]] name = "notify" -version = "8.1.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3163f59cd3fa0e9ef8c32f242966a7b9994fd7378366099593e0e73077cd8c97" +checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "fsevent-sys", "inotify", "kqueue", @@ -2748,12 +2689,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2826,7 +2766,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", ] [[package]] @@ -2885,7 +2825,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "cfg-if", "foreign-types", "libc", @@ -2913,9 +2853,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.5.0+3.5.0" +version = "300.5.2+3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ce546f549326b0e6052b649198487d91320875da901e7bd11a06d1ee3f9c2f" +checksum = "d270b79e2926f5150189d475bc7e9d2c69f9c4697b185fa917d5a32b792d21b4" dependencies = [ "cc", ] @@ -2933,17 +2873,11 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "owo-colors" -version = "4.2.1" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26995317201fa17f3656c36716aed4a7c81743a9634ac4c99c0eeda495db0cec" +checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" [[package]] name = "p256" @@ -3076,9 +3010,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project-lite" @@ -3149,17 +3083,16 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "polling" -version = "3.8.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53a684391ad002dd6a596ceb6c74fd004fdce75f4be2e3f615068abbea5fd50" +checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.0.7", - "tracing", - "windows-sys 0.59.0", + "rustix 1.0.8", + "windows-sys 0.60.2", ] [[package]] @@ -3193,9 +3126,9 @@ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -3259,9 +3192,9 @@ checksum = "d8868e7264af614b3634ff0abbe37b178e61000611b8a75221aea40221924aba" [[package]] name = "prettyplease" -version = "0.2.35" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn", @@ -3278,9 +3211,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -3302,9 +3235,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", "cfg_aliases", @@ -3313,8 +3246,8 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.5.10", - "thiserror 2.0.12", + "socket2 0.6.0", + "thiserror 2.0.16", "tokio", "tracing", "web-time", @@ -3322,9 +3255,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", "getrandom 0.3.3", @@ -3335,7 +3268,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror 2.0.16", "tinyvec", "tracing", "web-time", @@ -3343,16 +3276,16 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.0", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -3462,7 +3395,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "cassowary", "compact_str", "crossterm 0.28.1", @@ -3483,14 +3416,14 @@ version = "11.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", ] [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -3498,9 +3431,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3521,69 +3454,54 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.13" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "reqwest" -version = "0.12.22" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "base64", "bytes", "encoding_rs", "futures-core", "h2", - "hickory-resolver 0.24.4", + "hickory-resolver", "http", "http-body", "http-body-util", @@ -3667,14 +3585,14 @@ dependencies = [ [[package]] name = "russh" -version = "0.54.1" +version = "0.54.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de956421c15e2068e207578852cf1af4f24b32ede68ab3ae60d8489444ff31df" +checksum = "00897b69ab623d39b396af89f1acbb775fb5a730f0db91833da297d5a6cd3f8d" dependencies = [ "aes", "aws-lc-rs", "base64ct", - "bitflags 2.9.1", + "bitflags 2.9.3", "block-padding", "byteorder", "bytes", @@ -3755,9 +3673,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -3795,7 +3713,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3804,15 +3722,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -3852,10 +3770,10 @@ dependencies = [ "rcgen", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-util", - "webpki-roots 1.0.1", + "webpki-roots 1.0.2", "x509-parser", ] @@ -3895,9 +3813,9 @@ dependencies = [ [[package]] name = "rustrict" -version = "0.7.35" +version = "0.7.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dfe349049fa49baa564f8483d40e7561ff19ccaa308ab4f844bb59d2c5d8d34" +checksum = "d93719b9aa6a53f9beae62fe36f34ed88226be314aea6829031ed0f878ca493d" dependencies = [ "arrayvec", "bitflags 1.3.2", @@ -3912,9 +3830,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -3960,7 +3878,7 @@ dependencies = [ "dashmap", "enumflags2", "futures-util", - "hickory-resolver 0.25.2", + "hickory-resolver", "http", "http-body-util", "humantime", @@ -3993,7 +3911,7 @@ dependencies = [ "serde_json", "sysinfo", "test-log", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-rustls", "tokio-stream", @@ -4005,7 +3923,7 @@ dependencies = [ "tracing-subscriber", "trie-rs", "vt100-ctt", - "webpki-roots 1.0.1", + "webpki-roots 1.0.2", ] [[package]] @@ -4056,11 +3974,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -4105,9 +4023,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" dependencies = [ "itoa", "memchr", @@ -4197,9 +4115,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -4228,9 +4146,9 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "slab" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" @@ -4357,9 +4275,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.104" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -4388,9 +4306,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.36.1" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d" +checksum = "07cec4dc2d2e357ca1e610cfb07de2fa7a10fc3e9fe89f72545f3d244ea87753" dependencies = [ "libc", "memchr", @@ -4406,7 +4324,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -4466,11 +4384,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.16", ] [[package]] @@ -4486,9 +4404,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" dependencies = [ "proc-macro2", "quote", @@ -4547,9 +4465,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -4638,9 +4556,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.15" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", @@ -4672,7 +4590,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.3", "bytes", "futures-util", "http", @@ -4752,15 +4670,15 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "chrono", "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", @@ -4797,7 +4715,7 @@ dependencies = [ "log", "rand 0.9.2", "sha1", - "thiserror 2.0.12", + "thiserror 2.0.16", "utf-8", ] @@ -4814,7 +4732,7 @@ dependencies = [ "log", "rand 0.9.2", "sha1", - "thiserror 2.0.12", + "thiserror 2.0.16", "utf-8", ] @@ -4892,13 +4810,14 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -4921,9 +4840,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -5008,11 +4927,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.3+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] @@ -5112,14 +5031,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.1", + "webpki-roots 1.0.2", ] [[package]] name = "webpki-roots" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" dependencies = [ "rustls-pki-types", ] @@ -5160,11 +5079,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -5383,7 +5302,7 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.2", + "windows-targets 0.53.3", ] [[package]] @@ -5419,10 +5338,11 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.2" +version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ + "windows-link", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -5591,13 +5511,10 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] +checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" [[package]] name = "writeable" @@ -5715,9 +5632,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", diff --git a/Cargo.toml b/Cargo.toml index 1794f2c..6d31565 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "sandhole" version = "0.8.1" edition = "2024" -rust-version = "1.85.0" +rust-version = "1.88.0" description = "Expose HTTP/SSH/TCP services through SSH port forwarding." repository = "https://github.com/EpicEric/sandhole" homepage = "https://sandhole.com.br/" @@ -26,11 +26,11 @@ async-speed-limit = { version = "0.4.2", features = ["tokio"] } aws-lc-rs = "1.13.3" axum = { version = "0.8.4", default-features = false } block-id = "0.2.1" -bon = "3.6.5" +bon = "3.7.1" bytes = "1.10.1" bytesize = "2.0.1" chrono = "0.4.41" -clap = { version = "4.5.42", features = ["derive", "string"] } +clap = { version = "4.5.46", features = ["derive", "string"] } color-eyre = "0.6.5" crossterm = { version = "0.29.0", default-features = false } dashmap = "6.1.0" @@ -39,14 +39,14 @@ hickory-resolver = "0.25.2" http = "1.3.1" http-body-util = "0.1.3" humantime = "2.2.0" -hyper = { version = "1.6.0", features = ["full"] } +hyper = { version = "1.7.0", features = ["full"] } hyper-util = { version = "0.1.16", features = ["full"] } ipnet = "2.11.0" ipnet-trie = "0.3.0" itertools = "0.14.0" metrics = "0.24.2" metrics-exporter-prometheus = { version = "0.17.2", optional = true } -notify = "8.1.0" +notify = "8.2.0" openssl = { version = "0.10.73", features = ["vendored"] } pretty-duration = "0.1.1" rand = { version = "0.9.2", default-features = false, features = [ @@ -60,14 +60,14 @@ rand_seeder = "0.4.0" ratatui = { version = "0.29.0", default-features = false, features = [ "crossterm", ] } -reqwest = { version = "0.12.22", optional = true, default-features = false, features = [ +reqwest = { version = "0.12.23", optional = true, default-features = false, features = [ "charset", "http2", "hickory-dns", "json", "rustls-tls-manual-roots", ] } -russh = "0.54.1" +russh = "0.54.3" rustls = "0.23.31" rustls-acme = { version = "0.14.0", optional = true, default-features = false, features = [ "tokio", @@ -77,20 +77,20 @@ rustls-acme = { version = "0.14.0", optional = true, default-features = false, f ] } rustls-pki-types = "1.12.0" rustls-webpki = "0.103.4" -rustrict = { version = "0.7.35", optional = true, features = ["customize"] } +rustrict = { version = "0.7.36", optional = true, features = ["customize"] } serde = { version = "1.0.219", default-features = false, features = [ "serde_derive", ] } -serde_json = "1.0.142" -sysinfo = "0.36.1" -thiserror = "2.0.12" +serde_json = "1.0.143" +sysinfo = "0.37.0" +thiserror = "2.0.16" tokio = { version = "1.47.1", features = ["full"] } tokio-rustls = "0.26.2" tokio-stream = "0.1.17" -tokio-util = "0.7.15" +tokio-util = "0.7.16" tracing = "0.1.41" tracing-error = "0.2.1" -tracing-subscriber = { version = "0.3.19", features = [ +tracing-subscriber = { version = "0.3.20", features = [ "env-filter", "fmt", "chrono", @@ -106,7 +106,7 @@ futures-util = { version = "0.3.31", default-features = false, features = [ insta = { version = "1.43.1", features = ["yaml"] } mockall = "0.13.1" nix = "0.30.1" -regex = "1.11.1" +regex = "1.11.2" test-log = { version = "0.2.18", features = ["trace", "color"] } tokio-tungstenite = "0.27.0" tower = "0.5.2" diff --git a/Dockerfile b/Dockerfile index a531af7..07a41d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Compile application with the official Rust image -FROM --platform=$BUILDPLATFORM rust:1.88.0-alpine3.22 AS builder +FROM --platform=$BUILDPLATFORM rust:1.89.0-alpine3.22 AS builder ENV PKGCONFIG_SYSROOTDIR=/ # Add build dependencies and targets RUN apk add --no-cache musl-dev libressl-dev perl build-base zig diff --git a/docker-compose-example/client/Dockerfile b/docker-compose-example/client/Dockerfile index 054f754..379b2e2 100644 --- a/docker-compose-example/client/Dockerfile +++ b/docker-compose-example/client/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.21.3 +FROM alpine:3.22.1 RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \ && apk add --update --no-cache openssh-client autossh diff --git a/src/addressing.rs b/src/addressing.rs index 9785741..47011af 100644 --- a/src/addressing.rs +++ b/src/addressing.rs @@ -208,20 +208,17 @@ impl AddressDelegator { if matches!( self.bind_hostnames, BindHostnames::Cname | BindHostnames::Txt - ) { - if let Some(fingerprint) = fingerprint { - if self - .resolver - .has_txt_record_for_fingerprint( - &self.txt_record_prefix, - requested_address, - fingerprint, - ) - .await - { - return requested_address.to_string(); - } - } + ) && let Some(fingerprint) = fingerprint + && self + .resolver + .has_txt_record_for_fingerprint( + &self.txt_record_prefix, + requested_address, + fingerprint, + ) + .await + { + return requested_address.to_string(); } // If subdomains aren't random, check if user provided a valid one if !self.force_random_subdomains { diff --git a/src/admin/interface.rs b/src/admin/interface.rs index 039dddc..c230e7b 100644 --- a/src/admin/interface.rs +++ b/src/admin/interface.rs @@ -212,7 +212,11 @@ impl AdminState { " Error ".black().on_red().bold(), r#"PTY not detected! Make sure to connect with "ssh -t" instead."#.into(), ]), - Line::from(" = hint: press Ctrl-C to close this connection".dim()), + Line::from(vec![ + " = hint: press ".dim(), + " Ctrl-C ".dim().reversed(), + " to close this connection".dim(), + ]), ]); let widget = Paragraph::new(text).left_aligned(); widget.render(area, buf); @@ -818,19 +822,18 @@ impl AdminInterface { cancellation_token.cancel(); }); } - } else if let TokenHolderUser::Username(username) = user { - if let Some((_, sessions)) = interface + } else if let TokenHolderUser::Username(username) = user + && let Some((_, sessions)) = interface .state .server .sessions_password .lock() .unwrap() .remove(&username) - { - sessions.values().for_each(|cancellation_token| { - cancellation_token.cancel(); - }); - } + { + sessions.values().for_each(|cancellation_token| { + cancellation_token.cancel(); + }); } interface.state.prompt = Some(AdminPrompt::Infobox(text)); true diff --git a/src/connections.rs b/src/connections.rs index a02626a..f518b93 100644 --- a/src/connections.rs +++ b/src/connections.rs @@ -134,10 +134,10 @@ where } } // If the entry count increased, notify the reactor. - if self.map.len() > len { - if let Some(reactor) = self.reactor.read().unwrap().as_ref() { - reactor.call(self.map.iter().map(|entry| entry.key().clone()).collect()) - } + if self.map.len() > len + && let Some(reactor) = self.reactor.read().unwrap().as_ref() + { + reactor.call(self.map.iter().map(|entry| entry.key().clone()).collect()) } Ok(()) } @@ -194,10 +194,10 @@ where value.is_empty() }); // If the entry was removed, notify the reactor. - if self.map.len() < len { - if let Some(reactor) = self.reactor.read().unwrap().as_ref() { - reactor.call(self.map.iter().map(|entry| entry.key().clone()).collect()) - } + if self.map.len() < len + && let Some(reactor) = self.reactor.read().unwrap().as_ref() + { + reactor.call(self.map.iter().map(|entry| entry.key().clone()).collect()) } element } @@ -221,10 +221,10 @@ where !value.is_empty() }); // If one or more entries were removed, notify the reactor. - if self.map.len() < len { - if let Some(reactor) = self.reactor.read().unwrap().as_ref() { - reactor.call(self.map.iter().map(|entry| entry.key().clone()).collect()) - } + if self.map.len() < len + && let Some(reactor) = self.reactor.read().unwrap().as_ref() + { + reactor.call(self.map.iter().map(|entry| entry.key().clone()).collect()) } elements } diff --git a/src/ssh/forwarding.rs b/src/ssh/forwarding.rs index c56fd8e..32e6fdb 100644 --- a/src/ssh/forwarding.rs +++ b/src/ssh/forwarding.rs @@ -292,7 +292,7 @@ impl ForwardingHandlerStrategy for SshForwardingHandler { tracing::info!(peer = %context.peer, alias = %address, "Serving SSH connection..."); let _ = context.tx.send( format!( - "{}{}{} {}{:>14}{} forwarding on {}:{}\r\n{} = hint: connect with {}{}{}\r\n", + "{}{}{} {}{:>14}{} forwarding on {}:{}\r\n{} = hint: connect with {} {} {}\r\n", ansi!(dim), Utc::now().to_rfc3339(), ansi!(reset), @@ -302,7 +302,7 @@ impl ForwardingHandlerStrategy for SshForwardingHandler { address, context.server.ssh_port, ansi!(dim), - ansi!(bold), + ansi!(bold invert), if context.server.ssh_port == 22 { format!("ssh -J {} {}", context.server.domain, address) } else { @@ -374,110 +374,109 @@ impl ForwardingHandlerStrategy for SshForwardingHandler { channel: Channel, ) -> Result { let ip = context.peer.ip().to_canonical(); - if let Some(handler) = context.server.ssh.get(address, ip) { - if let Ok(mut io) = handler + if let Some(handler) = context.server.ssh.get(address, ip) + && let Ok(mut io) = handler .aliasing_channel( context.peer.ip(), context.peer.port(), context.key_fingerprint.as_ref(), ) .await - { - let gauge = gauge!(TELEMETRY_GAUGE_SSH_CONNECTIONS_CURRENT, TELEMETRY_KEY_ALIAS => address.to_string()); - gauge.increment(1); - counter!(TELEMETRY_COUNTER_SSH_CONNECTIONS_TOTAL, TELEMETRY_KEY_ALIAS => address.to_string()) + { + let gauge = gauge!(TELEMETRY_GAUGE_SSH_CONNECTIONS_CURRENT, TELEMETRY_KEY_ALIAS => address.to_string()); + gauge.increment(1); + counter!(TELEMETRY_COUNTER_SSH_CONNECTIONS_TOTAL, TELEMETRY_KEY_ALIAS => address.to_string()) .increment(1); - let _ = handler.log_channel().send( - format!( - "{}{}{} {}{:>14}{} - {}:{} => {}:{}\r\n", - ansi!(dim), - Utc::now().to_rfc3339(), - ansi!(reset), - ansi!(blue bold), - "Proxying SSH", - ansi!(reset), - originator_address, - originator_port, - address, - port, - ) - .into_bytes(), - ); - match context.auth_data { - // Serve SSH for unauthed user, then add disconnection timeout if this is the last proxy connection - AuthenticatedData::None { proxy_data } => { - let guard = proxy_data.clone(); - let tcp_connection_timeout = context.server.tcp_connection_timeout; - let buffer_size = context.server.buffer_size; - tokio::spawn(async move { - let mut stream = channel.into_stream(); - match tcp_connection_timeout { - Some(duration) => { - let _ = timeout(duration, async { - copy_bidirectional_with_sizes( - &mut stream, - &mut io, - buffer_size, - buffer_size, - ) - .await - }) - .await; - } - None => { - let _ = copy_bidirectional_with_sizes( + let _ = handler.log_channel().send( + format!( + "{}{}{} {}{:>14}{} - {}:{} => {}:{}\r\n", + ansi!(dim), + Utc::now().to_rfc3339(), + ansi!(reset), + ansi!(blue bold), + "Proxying SSH", + ansi!(reset), + originator_address, + originator_port, + address, + port, + ) + .into_bytes(), + ); + match context.auth_data { + // Serve SSH for unauthed user, then add disconnection timeout if this is the last proxy connection + AuthenticatedData::None { proxy_data } => { + let guard = proxy_data.clone(); + let tcp_connection_timeout = context.server.tcp_connection_timeout; + let buffer_size = context.server.buffer_size; + tokio::spawn(async move { + let mut stream = channel.into_stream(); + match tcp_connection_timeout { + Some(duration) => { + let _ = timeout(duration, async { + copy_bidirectional_with_sizes( &mut stream, &mut io, buffer_size, buffer_size, ) - .await; - } + .await + }) + .await; } - drop(guard); - gauge.decrement(1); - }); - } - // Serve SSH normally for authed user - _ => { - let tcp_connection_timeout = context.server.tcp_connection_timeout; - let buffer_size = context.server.buffer_size; - tokio::spawn(async move { - let mut stream = channel.into_stream(); - match tcp_connection_timeout { - Some(duration) => { - let _ = timeout(duration, async { - copy_bidirectional_with_sizes( - &mut stream, - &mut io, - buffer_size, - buffer_size, - ) - .await - }) - .await; - } - None => { - let _ = copy_bidirectional_with_sizes( + None => { + let _ = copy_bidirectional_with_sizes( + &mut stream, + &mut io, + buffer_size, + buffer_size, + ) + .await; + } + } + drop(guard); + gauge.decrement(1); + }); + } + // Serve SSH normally for authed user + _ => { + let tcp_connection_timeout = context.server.tcp_connection_timeout; + let buffer_size = context.server.buffer_size; + tokio::spawn(async move { + let mut stream = channel.into_stream(); + match tcp_connection_timeout { + Some(duration) => { + let _ = timeout(duration, async { + copy_bidirectional_with_sizes( &mut stream, &mut io, buffer_size, buffer_size, ) - .await; - } + .await + }) + .await; } - gauge.decrement(1); - }); - } + None => { + let _ = copy_bidirectional_with_sizes( + &mut stream, + &mut io, + buffer_size, + buffer_size, + ) + .await; + } + } + gauge.decrement(1); + }); } - #[cfg(not(coverage_nightly))] - tracing::debug!( - peer = %context.peer, remote = %handler.peer, alias = %address, - "Accepted SSH connection.", - ); - return Ok(true); } + #[cfg(not(coverage_nightly))] + tracing::debug!( + peer = %context.peer, remote = %handler.peer, alias = %address, + "Accepted SSH connection.", + ); + return Ok(true); } let _ = context.tx.send( format!( @@ -651,17 +650,19 @@ impl ForwardingHandlerStrategy for HttpForwardingHandler { tracing::info!(peer = %context.peer, host = %address, "Serving SNI proxy...",); let _ = context.tx.send( format!( - "{}{}{} {}{:>14}{} proxy for https://{}\r\n", + "{}{}{} {}{:>14}{} proxy for {}https://{}{}\r\n", ansi!(dim), Utc::now().to_rfc3339(), ansi!(reset), ansi!(green bold), "Starting SNI", ansi!(reset), + ansi!(underline), match context.server.https_port { 443 => address.to_string(), port => format!("{address}:{port}"), - } + }, + ansi!(reset), ) .into_bytes(), ); @@ -751,21 +752,23 @@ impl ForwardingHandlerStrategy for HttpForwardingHandler { tracing::info!(peer = %context.peer, host = %assigned_host, "Serving HTTP..."); let _ = context.tx.send( format!( - "{}{}{} {}{:>14}{} on http://{} for {}\r\n", + "{}{}{} {}{:>14}{} on {}http://{}{} for {}\r\n", ansi!(dim), Utc::now().to_rfc3339(), ansi!(reset), ansi!(green bold), "Starting HTTP", ansi!(reset), + ansi!(underline), match context.server.http_port { 80 => assigned_host.clone(), port => format!("{assigned_host}:{port}"), }, + ansi!(reset), if address.is_empty() { - "unspecified address" + "unspecified address".into() } else { - address + format!("address {address}") }, ) .into_bytes(), @@ -773,21 +776,23 @@ impl ForwardingHandlerStrategy for HttpForwardingHandler { if !context.server.disable_https { let _ = context.tx.send( format!( - "{}{}{} {}{:>14}{} on https://{} for {}\r\n", + "{}{}{} {}{:>14}{} on {}https://{}{} for {}\r\n", ansi!(dim), Utc::now().to_rfc3339(), ansi!(reset), ansi!(green bold), "Starting HTTPS", ansi!(reset), + ansi!(underline), match context.server.http_port { 80 => assigned_host.clone(), port => format!("{assigned_host}:{port}"), }, + ansi!(reset), if address.is_empty() { - "unspecified address" + "unspecified address".into() } else { - address + format!("address {address}") }, ) .into_bytes(), @@ -979,57 +984,56 @@ impl ForwardingHandlerStrategy for HttpForwardingHandler { .aliasing_proxy_data .conn_manager() .get_by_http_host(address, ip) + && handler.can_alias(ip, context.peer.port(), context.key_fingerprint.as_ref()) { - if handler.can_alias(ip, context.peer.port(), context.key_fingerprint.as_ref()) { - let peer = *context.peer; - let fingerprint = *context.key_fingerprint; - let proxy_data = Arc::clone(&context.server.aliasing_proxy_data); - let address = address.to_string(); - let service = service_fn(move |mut req: Request| { - // Set HTTP host via header - req.headers_mut() - .insert("host", address.clone().try_into().unwrap()); - proxy_handler(req, peer, fingerprint, Arc::clone(&proxy_data)) - }); - let io = TokioIo::new(channel.into_stream()); - let tcp_connection_timeout = context.server.tcp_connection_timeout; - match context.auth_data { - // Serve HTTP for unauthed user, then add disconnection timeout if this is the last proxy connection - AuthenticatedData::None { proxy_data } => { - let guard = proxy_data.clone(); - tokio::spawn(async move { - let server = auto::Builder::new(TokioExecutor::new()); - let conn = server.serve_connection_with_upgrades(io, service); - match tcp_connection_timeout { - Some(duration) => { - let _ = timeout(duration, conn).await; - } - None => { - let _ = conn.await; - } + let peer = *context.peer; + let fingerprint = *context.key_fingerprint; + let proxy_data = Arc::clone(&context.server.aliasing_proxy_data); + let address = address.to_string(); + let service = service_fn(move |mut req: Request| { + // Set HTTP host via header + req.headers_mut() + .insert("host", address.clone().try_into().unwrap()); + proxy_handler(req, peer, fingerprint, Arc::clone(&proxy_data)) + }); + let io = TokioIo::new(channel.into_stream()); + let tcp_connection_timeout = context.server.tcp_connection_timeout; + match context.auth_data { + // Serve HTTP for unauthed user, then add disconnection timeout if this is the last proxy connection + AuthenticatedData::None { proxy_data } => { + let guard = proxy_data.clone(); + tokio::spawn(async move { + let server = auto::Builder::new(TokioExecutor::new()); + let conn = server.serve_connection_with_upgrades(io, service); + match tcp_connection_timeout { + Some(duration) => { + let _ = timeout(duration, conn).await; } - drop(guard); - }); - } - // Serve HTTP normally for authed user - _ => { - tokio::spawn(async move { - let server = auto::Builder::new(TokioExecutor::new()); - let conn = server.serve_connection_with_upgrades(io, service); - match tcp_connection_timeout { - Some(duration) => { - let _ = timeout(duration, conn).await; - } - None => { - let _ = conn.await; - } + None => { + let _ = conn.await; } - }); - } + } + drop(guard); + }); + } + // Serve HTTP normally for authed user + _ => { + tokio::spawn(async move { + let server = auto::Builder::new(TokioExecutor::new()); + let conn = server.serve_connection_with_upgrades(io, service); + match tcp_connection_timeout { + Some(duration) => { + let _ = timeout(duration, conn).await; + } + None => { + let _ = conn.await; + } + } + }); } - - return Ok(true); } + + return Ok(true); } let _ = context.tx.send( format!( @@ -1303,107 +1307,105 @@ impl ForwardingHandlerStrategy for AliasForwardingHandler { .server .alias .get(&BorrowedTcpAlias(address, &port) as &dyn TcpAliasKey, ip) - { - if let Ok(mut io) = handler + && let Ok(mut io) = handler .aliasing_channel(ip, context.peer.port(), context.key_fingerprint.as_ref()) .await - { - let alias = TcpAlias(address.into(), port); - let gauge = gauge!(TELEMETRY_GAUGE_ALIAS_CONNECTIONS_CURRENT, TELEMETRY_KEY_ALIAS => alias.to_string()); - gauge.increment(1); - counter!(TELEMETRY_COUNTER_ALIAS_CONNECTIONS_TOTAL, TELEMETRY_KEY_ALIAS => alias.to_string()) + { + let alias = TcpAlias(address.into(), port); + let gauge = gauge!(TELEMETRY_GAUGE_ALIAS_CONNECTIONS_CURRENT, TELEMETRY_KEY_ALIAS => alias.to_string()); + gauge.increment(1); + counter!(TELEMETRY_COUNTER_ALIAS_CONNECTIONS_TOTAL, TELEMETRY_KEY_ALIAS => alias.to_string()) .increment(1); - let _ = handler.log_channel().send( - format!( - "{}{}{} {}{:>14}{} - {}:{} => {}:{}\r\n", - ansi!(dim), - Utc::now().to_rfc3339(), - ansi!(reset), - ansi!(blue bold), - "Proxying alias", - ansi!(reset), - originator_address, - originator_port, - address, - port, - ) - .into_bytes(), - ); - match context.auth_data { - // Serve TCP for unauthed user, then add disconnection timeout if this is the last proxy connection - AuthenticatedData::None { proxy_data } => { - let guard = proxy_data.clone(); - let tcp_connection_timeout = context.server.tcp_connection_timeout; - let buffer_size = context.server.buffer_size; - tokio::spawn(async move { - let mut stream = channel.into_stream(); - match tcp_connection_timeout { - Some(duration) => { - let _ = timeout(duration, async { - copy_bidirectional_with_sizes( - &mut stream, - &mut io, - buffer_size, - buffer_size, - ) - .await - }) - .await; - } - None => { - let _ = copy_bidirectional_with_sizes( + let _ = handler.log_channel().send( + format!( + "{}{}{} {}{:>14}{} - {}:{} => {}:{}\r\n", + ansi!(dim), + Utc::now().to_rfc3339(), + ansi!(reset), + ansi!(blue bold), + "Proxying alias", + ansi!(reset), + originator_address, + originator_port, + address, + port, + ) + .into_bytes(), + ); + match context.auth_data { + // Serve TCP for unauthed user, then add disconnection timeout if this is the last proxy connection + AuthenticatedData::None { proxy_data } => { + let guard = proxy_data.clone(); + let tcp_connection_timeout = context.server.tcp_connection_timeout; + let buffer_size = context.server.buffer_size; + tokio::spawn(async move { + let mut stream = channel.into_stream(); + match tcp_connection_timeout { + Some(duration) => { + let _ = timeout(duration, async { + copy_bidirectional_with_sizes( &mut stream, &mut io, buffer_size, buffer_size, ) - .await; - } + .await + }) + .await; } - drop(guard); - gauge.decrement(1); - }); - } - // Serve alias normally for authed user - _ => { - let tcp_connection_timeout = context.server.tcp_connection_timeout; - let buffer_size = context.server.buffer_size; - tokio::spawn(async move { - let mut stream = channel.into_stream(); - match tcp_connection_timeout { - Some(duration) => { - let _ = timeout(duration, async { - copy_bidirectional_with_sizes( - &mut stream, - &mut io, - buffer_size, - buffer_size, - ) - .await - }) - .await; - } - None => { - let _ = copy_bidirectional_with_sizes( + None => { + let _ = copy_bidirectional_with_sizes( + &mut stream, + &mut io, + buffer_size, + buffer_size, + ) + .await; + } + } + drop(guard); + gauge.decrement(1); + }); + } + // Serve alias normally for authed user + _ => { + let tcp_connection_timeout = context.server.tcp_connection_timeout; + let buffer_size = context.server.buffer_size; + tokio::spawn(async move { + let mut stream = channel.into_stream(); + match tcp_connection_timeout { + Some(duration) => { + let _ = timeout(duration, async { + copy_bidirectional_with_sizes( &mut stream, &mut io, buffer_size, buffer_size, ) - .await; - } + .await + }) + .await; } - gauge.decrement(1); - }); - } + None => { + let _ = copy_bidirectional_with_sizes( + &mut stream, + &mut io, + buffer_size, + buffer_size, + ) + .await; + } + } + gauge.decrement(1); + }); } - #[cfg(not(coverage_nightly))] - tracing::debug!( - peer = %context.peer, remote = %handler.peer, alias = %address, port = %port, - "Accepted alias connection.", - ); - return Ok(true); } + #[cfg(not(coverage_nightly))] + tracing::debug!( + peer = %context.peer, remote = %handler.peer, alias = %address, port = %port, + "Accepted alias connection.", + ); + return Ok(true); } let _ = context.tx.send( format!( @@ -1712,106 +1714,105 @@ impl ForwardingHandlerStrategy for TcpForwardingHandler { channel: Channel, ) -> Result { let ip = context.peer.ip().to_canonical(); - if let Some(handler) = context.server.tcp.get(&port, ip) { - if let Ok(mut io) = handler + if let Some(handler) = context.server.tcp.get(&port, ip) + && let Ok(mut io) = handler .aliasing_channel(ip, context.peer.port(), context.key_fingerprint.as_ref()) .await - { - let gauge = gauge!(TELEMETRY_GAUGE_TCP_CONNECTIONS_CURRENT, TELEMETRY_KEY_PORT => port.to_string()); - gauge.increment(1); - counter!(TELEMETRY_COUNTER_TCP_CONNECTIONS_TOTAL, TELEMETRY_KEY_PORT => port.to_string()) + { + let gauge = gauge!(TELEMETRY_GAUGE_TCP_CONNECTIONS_CURRENT, TELEMETRY_KEY_PORT => port.to_string()); + gauge.increment(1); + counter!(TELEMETRY_COUNTER_TCP_CONNECTIONS_TOTAL, TELEMETRY_KEY_PORT => port.to_string()) .increment(1); - let _ = handler.log_channel().send( - format!( - "{}{}{} {}{:>14}{} - {}:{} => {}:{}\r\n", - ansi!(dim), - Utc::now().to_rfc3339(), - ansi!(reset), - ansi!(blue bold), - "Proxying TCP", - ansi!(reset), - originator_address, - originator_port, - address, - port, - ) - .into_bytes(), - ); - match context.auth_data { - // Serve TCP for unauthed user, then add disconnection timeout if this is the last proxy connection - AuthenticatedData::None { proxy_data } => { - let guard = proxy_data.clone(); - let tcp_connection_timeout = context.server.tcp_connection_timeout; - let buffer_size = context.server.buffer_size; - tokio::spawn(async move { - let mut stream = channel.into_stream(); - match tcp_connection_timeout { - Some(duration) => { - let _ = timeout(duration, async { - copy_bidirectional_with_sizes( - &mut stream, - &mut io, - buffer_size, - buffer_size, - ) - .await - }) - .await; - } - None => { - let _ = copy_bidirectional_with_sizes( + let _ = handler.log_channel().send( + format!( + "{}{}{} {}{:>14}{} - {}:{} => {}:{}\r\n", + ansi!(dim), + Utc::now().to_rfc3339(), + ansi!(reset), + ansi!(blue bold), + "Proxying TCP", + ansi!(reset), + originator_address, + originator_port, + address, + port, + ) + .into_bytes(), + ); + match context.auth_data { + // Serve TCP for unauthed user, then add disconnection timeout if this is the last proxy connection + AuthenticatedData::None { proxy_data } => { + let guard = proxy_data.clone(); + let tcp_connection_timeout = context.server.tcp_connection_timeout; + let buffer_size = context.server.buffer_size; + tokio::spawn(async move { + let mut stream = channel.into_stream(); + match tcp_connection_timeout { + Some(duration) => { + let _ = timeout(duration, async { + copy_bidirectional_with_sizes( &mut stream, &mut io, buffer_size, buffer_size, ) - .await; - } + .await + }) + .await; } - drop(guard); - gauge.decrement(1); - }); - } - // Serve TCP normally for authed user - _ => { - let tcp_connection_timeout = context.server.tcp_connection_timeout; - let buffer_size = context.server.buffer_size; - tokio::spawn(async move { - let mut stream = channel.into_stream(); - match tcp_connection_timeout { - Some(duration) => { - let _ = timeout(duration, async { - copy_bidirectional_with_sizes( - &mut stream, - &mut io, - buffer_size, - buffer_size, - ) - .await - }) - .await; - } - None => { - let _ = copy_bidirectional_with_sizes( + None => { + let _ = copy_bidirectional_with_sizes( + &mut stream, + &mut io, + buffer_size, + buffer_size, + ) + .await; + } + } + drop(guard); + gauge.decrement(1); + }); + } + // Serve TCP normally for authed user + _ => { + let tcp_connection_timeout = context.server.tcp_connection_timeout; + let buffer_size = context.server.buffer_size; + tokio::spawn(async move { + let mut stream = channel.into_stream(); + match tcp_connection_timeout { + Some(duration) => { + let _ = timeout(duration, async { + copy_bidirectional_with_sizes( &mut stream, &mut io, buffer_size, buffer_size, ) - .await; - } + .await + }) + .await; } - gauge.decrement(1); - }); - } + None => { + let _ = copy_bidirectional_with_sizes( + &mut stream, + &mut io, + buffer_size, + buffer_size, + ) + .await; + } + } + gauge.decrement(1); + }); } - #[cfg(not(coverage_nightly))] - tracing::debug!( - peer = %context.peer, remote = %handler.peer, port = %port, - "Accepted TCP connection.", - ); - return Ok(true); } + #[cfg(not(coverage_nightly))] + tracing::debug!( + peer = %context.peer, remote = %handler.peer, port = %port, + "Accepted TCP connection.", + ); + return Ok(true); } let _ = context.tx.send( format!( diff --git a/src/ssh/mod.rs b/src/ssh/mod.rs index d42d46d..aef3388 100644 --- a/src/ssh/mod.rs +++ b/src/ssh/mod.rs @@ -741,12 +741,12 @@ impl Handler for ServerHandler { admin_data.col_width = Some(col_width); admin_data.row_height = Some(row_height); // Dynamically update the TUI if present. - if let Some(ref mut admin_interface) = admin_data.admin_interface { - if let Err(error) = admin_interface.resize(col_width as u16, row_height as u16) { - #[cfg(not(coverage_nightly))] - tracing::warn!(peer = %self.peer, %error, "Failed to resize terminal."); - return session.channel_failure(channel); - } + if let Some(ref mut admin_interface) = admin_data.admin_interface + && let Err(error) = admin_interface.resize(col_width as u16, row_height as u16) + { + #[cfg(not(coverage_nightly))] + tracing::warn!(peer = %self.peer, %error, "Failed to resize terminal."); + return session.channel_failure(channel); } } diff --git a/src/tcp.rs b/src/tcp.rs index 05ff3f3..d563ce6 100644 --- a/src/tcp.rs +++ b/src/tcp.rs @@ -72,52 +72,51 @@ impl PortHandler for Arc { } // Get the handler for this port let ip = address.ip().to_canonical(); - if let Some(handler) = clone.conn_manager.get(&port, ip) { - if let Ok(mut channel) = + if let Some(handler) = clone.conn_manager.get(&port, ip) + && let Ok(mut channel) = handler.tunneling_channel(ip, address.port()).await - { - counter!(TELEMETRY_COUNTER_TCP_CONNECTIONS_TOTAL, TELEMETRY_KEY_PORT => port.to_string()) + { + counter!(TELEMETRY_COUNTER_TCP_CONNECTIONS_TOTAL, TELEMETRY_KEY_PORT => port.to_string()) .increment(1); - // Log new connection to SSH handler - if !clone.disable_tcp_logs { - let _ = handler.log_channel().send( - format!( - "New connection from {}:{} to TCP port {}\r\n", - address.ip().to_canonical(), - address.port(), - port - ) - .into_bytes(), - ); - } - // Copy data between the TCP stream and the reverse forwarding channel, with optional timeout - let buffer_size = clone.buffer_size; - match clone.tcp_connection_timeout { - Some(duration) => { - tokio::spawn(async move { - let _ = timeout(duration, async { - copy_bidirectional_with_sizes( - &mut stream, - &mut channel, - buffer_size, - buffer_size, - ) - .await - }) - .await; - }); - } - None => { - tokio::spawn(async move { - let _ = copy_bidirectional_with_sizes( + // Log new connection to SSH handler + if !clone.disable_tcp_logs { + let _ = handler.log_channel().send( + format!( + "New connection from {}:{} to TCP port {}\r\n", + address.ip().to_canonical(), + address.port(), + port + ) + .into_bytes(), + ); + } + // Copy data between the TCP stream and the reverse forwarding channel, with optional timeout + let buffer_size = clone.buffer_size; + match clone.tcp_connection_timeout { + Some(duration) => { + tokio::spawn(async move { + let _ = timeout(duration, async { + copy_bidirectional_with_sizes( &mut stream, &mut channel, buffer_size, buffer_size, ) - .await; - }); - } + .await + }) + .await; + }); + } + None => { + tokio::spawn(async move { + let _ = copy_bidirectional_with_sizes( + &mut stream, + &mut channel, + buffer_size, + buffer_size, + ) + .await; + }); } } } diff --git a/tests/admin_missing_pty.rs b/tests/admin_missing_pty.rs index 5a0bcef..2cd3733 100644 --- a/tests/admin_missing_pty.rs +++ b/tests/admin_missing_pty.rs @@ -160,7 +160,7 @@ async fn admin_missing_pty() { let search_strings: Vec = [ "Error", r#"PTY not detected! Make sure to connect with "ssh -t" instead\."#, - r"= hint: press Ctrl-C to close this connection", + r"= hint: press Ctrl-C to close this connection", ] .into_iter() .map(|re| Regex::new(re).expect("Invalid regex")) -- 2.51.2