diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..331a22f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +// { +// "rust-analyzer.cargo.target": "wasm32-unknown-unknown" +// } diff --git a/Cargo.lock b/Cargo.lock index 124934c..89c118c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,7 +24,7 @@ version = "0.6.0-rc.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b657e772794c6b04730ea897b66a058ccd866c16d1967da05eeeecec39043fe" dependencies = [ - "crypto-common 0.2.1", + "crypto-common 0.2.2", "inout 0.2.2", ] @@ -45,11 +45,25 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" dependencies = [ - "cipher 0.5.1", + "cipher 0.5.2", "cpubits", "cpufeatures 0.3.0", ] +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead 0.5.2", + "aes 0.8.4", + "cipher 0.4.4", + "ctr 0.9.2", + "ghash 0.5.1", + "subtle", +] + [[package]] name = "aes-gcm" version = "0.11.0-rc.3" @@ -58,9 +72,9 @@ checksum = "e22c0c90bbe8d4f77c3ca9ddabe41a1f8382d6fc1f7cea89459d0f320371f972" dependencies = [ "aead 0.6.0-rc.10", "aes 0.9.0", - "cipher 0.5.1", - "ctr", - "ghash", + "cipher 0.5.2", + "ctr 0.10.1", + "ghash 0.6.0", "subtle", ] @@ -150,18 +164,6 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" -[[package]] -name = "apple-bundles" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f40bb8f844cec39fa3aceae717808c2ac3d2b6c474a9dffbeba07a4a945d10" -dependencies = [ - "anyhow", - "plist", - "simple-file-manifest", - "walkdir", -] - [[package]] name = "arrayvec" version = "0.7.6" @@ -170,9 +172,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "asn1-rs" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" +checksum = "b7f43a50ac4fdca5df8e885c21b835997f0a1cdee65494a6847694a98652d9d8" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -253,6 +255,17 @@ dependencies = [ "syn", ] +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version", +] + [[package]] name = "async_zip" version = "0.0.18" @@ -268,15 +281,6 @@ dependencies = [ "tokio-util", ] -[[package]] -name = "atomic" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" -dependencies = [ - "bytemuck", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -289,29 +293,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "aws-lc-rs" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" -dependencies = [ - "aws-lc-sys", - "untrusted 0.7.1", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - [[package]] name = "base16ct" version = "0.2.0" @@ -352,6 +333,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "bit-vec" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "2.11.1" @@ -422,12 +412,6 @@ version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" -[[package]] -name = "bytemuck" -version = "1.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" - [[package]] name = "byteorder" version = "1.5.0" @@ -448,22 +432,11 @@ checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" [[package]] name = "bzip2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" dependencies = [ - "cc", - "pkg-config", + "libbz2-rs-sys", ] [[package]] @@ -477,18 +450,18 @@ dependencies = [ [[package]] name = "cbc" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98db6aeaef0eeef2c1e3ce9a27b739218825dae116076352ac3777076aa22225" +checksum = "ce2dc9ee5f88d11e0beb842c88b33c8a5cf0d1329c4b19494af42b07dbfe8896" dependencies = [ - "cipher 0.5.1", + "cipher 0.5.2", ] [[package]] name = "cc" -version = "1.2.61" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", @@ -496,24 +469,12 @@ dependencies = [ "shlex", ] -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - [[package]] name = "chacha20" version = "0.9.1" @@ -576,12 +537,12 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ "block-buffer 0.12.0", - "crypto-common 0.2.1", + "crypto-common 0.2.2", "inout 0.2.2", ] @@ -625,15 +586,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" -[[package]] -name = "cmake" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" -dependencies = [ - "cc", -] - [[package]] name = "cmov" version = "0.5.3" @@ -731,15 +683,6 @@ dependencies = [ "typewit", ] -[[package]] -name = "cookie-factory" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2" -dependencies = [ - "futures", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -766,23 +709,11 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "cpio-archive" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11d34b07689c21889fc89bd7cc885b3244b0157bbededf4a1c159832cd0df05" -dependencies = [ - "chrono", - "is_executable", - "simple-file-manifest", - "thiserror 1.0.69", -] - [[package]] name = "cpubits" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" @@ -876,9 +807,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "getrandom 0.4.2", "hybrid-array", @@ -898,11 +829,20 @@ dependencies = [ [[package]] name = "ctr" -version = "0.10.0" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher 0.4.4", +] + +[[package]] +name = "ctr" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17469f8eb9bdbfad10f71f4cfddfd38b01143520c0e717d8796ccb4d44d44e42" +checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21" dependencies = [ - "cipher 0.5.1", + "cipher 0.5.2", ] [[package]] @@ -1054,7 +994,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "916a94e407b54f9034d71dd748234cd1e516ced6284009906ae246f177eafe5a" dependencies = [ - "cipher 0.5.1", + "cipher 0.5.2", ] [[package]] @@ -1090,13 +1030,13 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", "const-oid 0.10.2", - "crypto-common 0.2.1", + "crypto-common 0.2.2", "ctutils", ] @@ -1132,12 +1072,6 @@ dependencies = [ "syn", ] -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - [[package]] name = "ecdsa" version = "0.16.9" @@ -1147,6 +1081,7 @@ dependencies = [ "der 0.7.10", "digest 0.10.7", "elliptic-curve", + "rfc6979", "signature 2.2.0", "spki 0.7.3", ] @@ -1178,9 +1113,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elliptic-curve" @@ -1194,6 +1129,8 @@ dependencies = [ "ff", "generic-array", "group", + "hkdf", + "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", "sec1", @@ -1277,29 +1214,14 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" -[[package]] -name = "figment" -version = "0.10.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" -dependencies = [ - "atomic", - "pear", - "serde", - "toml", - "uncased", - "version_check", -] - [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", ] [[package]] @@ -1361,12 +1283,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "funty" version = "2.0.0" @@ -1505,11 +1421,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] @@ -1528,13 +1442,23 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval 0.6.2", +] + [[package]] name = "ghash" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5" dependencies = [ - "polyval", + "polyval 0.7.1", ] [[package]] @@ -1567,9 +1491,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -1610,9 +1534,9 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -1650,7 +1574,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -1694,9 +1618,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hybrid-array" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" dependencies = [ "typenum", ] @@ -1905,6 +1829,8 @@ dependencies = [ "chrono", "ed25519-dalek", "futures", + "getrandom 0.2.17", + "getrandom 0.4.2", "hkdf", "hmac 0.12.1", "idevice-srp", @@ -1915,6 +1841,8 @@ dependencies = [ "rand 0.10.1", "rsa 0.9.10", "rustls", + "rustls-pki-types", + "rustls-rustcrypto", "serde", "serde_json", "sha1 0.10.6", @@ -1925,6 +1853,8 @@ dependencies = [ "tokio-rustls", "tracing", "uuid", + "wasm-bindgen-futures", + "wasmtimer", "x25519-dalek", ] @@ -1955,9 +1885,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1970,17 +1900,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] -[[package]] -name = "inlinable_string" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" - [[package]] name = "inout" version = "0.1.4" @@ -2007,16 +1931,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is_executable" version = "1.0.5" @@ -2034,20 +1948,25 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "isideload" -version = "0.2.22" +version = "0.3.10" dependencies = [ "aes 0.9.0", - "aes-gcm", + "aes-gcm 0.11.0-rc.3", "async-trait", "base64 0.22.1", - "cbc 0.2.0", + "cbc 0.2.1", + "futures", "futures-util", + "getrandom 0.2.17", + "getrandom 0.4.2", "hex", "hmac 0.13.0", + "http", "idevice", "isideload-apple-codesign", "isideload-p12-keystore", - "isideload-x509-certificate 0.26.0", + "isideload-vfs", + "isideload-x509-certificate", "keyring", "pbkdf2 0.13.0", "plist", @@ -2055,8 +1974,11 @@ dependencies = [ "rand 0.10.1", "rcgen", "reqwest", + "reqwest-middleware", + "ring", "rootcause", - "rsa 0.10.0-rc.17", + "rsa 0.10.0-rc.18", + "rustls", "serde", "serde_json", "sha1 0.11.0", @@ -2066,19 +1988,33 @@ dependencies = [ "tokio", "tokio-tungstenite", "tracing", + "urlencoding", "uuid", + "web-time", + "ws_stream_wasm", "zip", ] +[[package]] +name = "isideload-apple-bundles" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "285e2bb63164fdcbc79472037acf78adb7e6d7675733f1b3851ff9cfeb82fa47" +dependencies = [ + "anyhow", + "isideload-simple-file-manifest", + "isideload-vfs", + "isideload-walkdir", + "plist", +] + [[package]] name = "isideload-apple-codesign" -version = "0.29.4" +version = "0.29.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51fa9e2b18c4408d79afc72d21b581ffe2fe95d1fb457a997dc3a091a7a3b2dd" +checksum = "aad04d98b94687253eebe7f7dd25e05e229eee8ccf2b0dcf256149db172e27ef" dependencies = [ "anyhow", - "apple-bundles", - "aws-lc-rs", "base64 0.22.1", "bcder", "bitflags", @@ -2092,15 +2028,20 @@ dependencies = [ "dirs", "elliptic-curve", "env_logger", - "figment", "filetime", + "getrandom 0.2.17", + "getrandom 0.4.2", "glob", "goblin", "hex", + "isideload-apple-bundles", "isideload-apple-flat-package", "isideload-apple-xar", "isideload-cryptographic-message-syntax", - "isideload-x509-certificate 0.25.0", + "isideload-simple-file-manifest", + "isideload-vfs", + "isideload-walkdir", + "isideload-x509-certificate", "log", "md-5", "num-traits", @@ -2118,6 +2059,7 @@ dependencies = [ "rasn", "rayon", "regex", + "ring", "rsa 0.9.10", "scroll", "security-framework 2.11.1", @@ -2128,19 +2070,16 @@ dependencies = [ "serde_yaml", "sha2 0.10.9", "signature 2.2.0", - "simple-file-manifest", "spki 0.7.3", "subtle", "tempfile", "thiserror 2.0.18", "tokio", "uuid", - "walkdir", "widestring", "windows-sys 0.59.0", - "x509", "xml-rs", - "yasna", + "yasna 0.5.2", "zeroize", "zip", "zip_structs", @@ -2148,13 +2087,13 @@ dependencies = [ [[package]] name = "isideload-apple-flat-package" -version = "0.20.2" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f3978cc1914a7a50335bcadcf0153ecca6d0197b78a351a2fe5ee6d2459e14" +checksum = "435ff123ac777fe7695d69fecd3739755d8dca97c0bd55ea0889b9870f7bac1c" dependencies = [ - "cpio-archive", "flate2", "isideload-apple-xar", + "isideload-cpio-archive", "scroll", "serde", "serde-xml-rs", @@ -2163,9 +2102,9 @@ dependencies = [ [[package]] name = "isideload-apple-xar" -version = "0.20.2" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad30993dda492d8ec75641d93569f22644a2c7304d8a67199149035f0f5789f4" +checksum = "d7500d73280fe3c7e55b7050f21d0bc252179e70599e1ec3c773837cd76b2e89" dependencies = [ "base64 0.22.1", "bcder", @@ -2173,8 +2112,12 @@ dependencies = [ "chrono", "digest 0.10.7", "flate2", + "getrandom 0.2.17", + "getrandom 0.4.2", "isideload-cryptographic-message-syntax", - "isideload-x509-certificate 0.25.0", + "isideload-vfs", + "isideload-x509-certificate", + "liblzma", "log", "md-5", "rand 0.8.6", @@ -2186,22 +2129,36 @@ dependencies = [ "signature 2.2.0", "thiserror 2.0.18", "xml-rs", - "xz2", +] + +[[package]] +name = "isideload-cpio-archive" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09393e5b7801a99cb7843fe6d092a473a5bc21c4e37cea60d11567d9a90bb09b" +dependencies = [ + "chrono", + "is_executable", + "isideload-simple-file-manifest", + "isideload-vfs", + "thiserror 2.0.18", ] [[package]] name = "isideload-cryptographic-message-syntax" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adacd3764e74e0041ac53c0dbb4e5a2d6833834afdbd58caaff272cd703f82f" +checksum = "934440f53a9cf7347b250b47255d93cd59fb00d0f5c18d290416d9d42ea40c6f" dependencies = [ - "aws-lc-rs", "bcder", "bytes", "chrono", + "getrandom 0.2.17", + "getrandom 0.4.2", "hex", - "isideload-x509-certificate 0.25.0", + "isideload-x509-certificate", "pem", + "ring", "signature 2.2.0", ] @@ -2211,7 +2168,7 @@ version = "0.3.0-rc4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "169d9344eb672235ee5e1f311809d7dec0b3a0448ce5138d53d0f19c2924d6f9" dependencies = [ - "cbc 0.2.0", + "cbc 0.2.1", "cms 0.3.0-pre.1", "der 0.8.0", "des 0.9.0", @@ -2219,7 +2176,7 @@ dependencies = [ "hmac 0.13.0", "pkcs12 0.2.0-pre.0", "pkcs5 0.8.0", - "pkcs8 0.11.0-rc.11", + "pkcs8 0.11.0", "rand 0.10.1", "rc2 0.9.0", "sha1 0.11.0", @@ -2229,29 +2186,36 @@ dependencies = [ ] [[package]] -name = "isideload-x509-certificate" -version = "0.25.0" +name = "isideload-simple-file-manifest" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8f6640892423dd86bac32808e94d586595b3e09a8e3b99ca101dc570d084bc" +checksum = "57a3e0a8090d8f14e38c7d08b68ca4b9200d87c72b6909131800c6db36a683c5" dependencies = [ - "aws-lc-rs", - "bcder", - "bytes", - "chrono", - "der 0.7.10", - "hex", - "pem", - "signature 2.2.0", - "spki 0.7.3", - "thiserror 2.0.18", - "zeroize", + "isideload-vfs", +] + +[[package]] +name = "isideload-vfs" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1133e156a6beed9d5e14a2b9618d52f8c2c6786326f4efbd73c7aecfcabab4c" + +[[package]] +name = "isideload-walkdir" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ad4075baa7089e82acee9dac0356db0a1c08a03d69b38c70c5a1ce790f9b6e8" +dependencies = [ + "isideload-vfs", + "same-file", + "winapi-util", ] [[package]] name = "isideload-x509-certificate" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f85f3d655536bce5bf609cd70283f851e221371eb5724aaa03783a9e804a2f" +checksum = "c4b4f85267f67c7b282782b65a9602b55d0f1680f6c2170ffb1e8dc9994202fa" dependencies = [ "bcder", "bytes", @@ -2309,27 +2273,32 @@ dependencies = [ [[package]] name = "jni" -version = "0.21.1" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" dependencies = [ - "cesu8", "cfg-if", "combine", - "jni-sys 0.3.1", + "jni-macros", + "jni-sys", "log", - "thiserror 1.0.69", + "simd_cesu8", + "thiserror 2.0.18", "walkdir", - "windows-sys 0.45.0", + "windows-link", ] [[package]] -name = "jni-sys" -version = "0.3.1" +name = "jni-macros" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" dependencies = [ - "jni-sys 0.4.1", + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn", ] [[package]] @@ -2363,9 +2332,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if", "futures-util", @@ -2424,6 +2393,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +[[package]] +name = "libbz2-rs-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c" + [[package]] name = "libc" version = "0.2.186" @@ -2439,6 +2414,26 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "liblzma" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6033b77c21d1f56deeae8014eb9fbe7bdf1765185a6c508b5ca82eeaed7f899" +dependencies = [ + "liblzma-sys", +] + +[[package]] +name = "liblzma-sys" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a60851d15cd8c5346eca4ab8babff585be2ae4bc8097c067291d3ffe2add3b6" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "libm" version = "0.2.16" @@ -2451,10 +2446,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags", "libc", - "plain", - "redox_syscall", ] [[package]] @@ -2479,29 +2471,21 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "lzma-sys" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "md-5" version = "0.10.6" @@ -2532,6 +2516,7 @@ dependencies = [ "isideload", "plist", "plist-macro", + "rustls", "tokio", "tracing", "tracing-subscriber", @@ -2628,9 +2613,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -2705,15 +2690,14 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.78" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -2737,9 +2721,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.114" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -2767,7 +2751,7 @@ dependencies = [ "lazy_static", "rc2 0.8.1", "sha1 0.10.6", - "yasna", + "yasna 0.5.2", ] [[package]] @@ -2802,6 +2786,19 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", + "sha2 0.10.9", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.9", ] [[package]] @@ -2811,46 +2808,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] -name = "pbkdf2" -version = "0.12.2" +name = "parking_lot" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ - "digest 0.10.7", - "hmac 0.12.1", + "lock_api", + "parking_lot_core", ] [[package]] -name = "pbkdf2" -version = "0.13.0" +name = "parking_lot_core" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112d82ceb8c5bf524d9af484d4e4970c9fd5a0cc15ba14ad93dccd28873b0629" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ - "digest 0.11.2", - "hmac 0.13.0", + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", ] [[package]] -name = "pear" -version = "0.2.9" +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "inlinable_string", - "pear_codegen", - "yansi", + "digest 0.10.7", + "hmac 0.12.1", ] [[package]] -name = "pear_codegen" -version = "0.2.9" +name = "pbkdf2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" +checksum = "112d82ceb8c5bf524d9af484d4e4970c9fd5a0cc15ba14ad93dccd28873b0629" dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn", + "digest 0.11.3", + "hmac 0.13.0", ] [[package]] @@ -2887,20 +2890,30 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", +] + [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -2913,6 +2926,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkcs1" version = "0.7.5" @@ -2958,7 +2977,7 @@ dependencies = [ "cms 0.3.0-pre.1", "const-oid 0.10.2", "der 0.8.0", - "digest 0.11.2", + "digest 0.11.3", "spki 0.8.0", "x509-cert 0.3.0-rc.4", "zeroize", @@ -2986,7 +3005,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279a91971a1d8eb1260a30938eae3be9cb67b472dffecb222fbbbe2fd2dc1453" dependencies = [ "aes 0.9.0", - "cbc 0.2.0", + "cbc 0.2.1", "der 0.8.0", "pbkdf2 0.13.0", "scrypt 0.12.0", @@ -3001,14 +3020,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.10", + "pkcs5 0.7.1", "spki 0.7.3", ] [[package]] name = "pkcs8" -version = "0.11.0-rc.11" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der 0.8.0", "spki 0.8.0", @@ -3059,6 +3079,18 @@ dependencies = [ "universal-hash 0.5.1", ] +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "opaque-debug", + "universal-hash 0.5.1", +] + [[package]] name = "polyval" version = "0.7.1" @@ -3137,84 +3169,15 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "version_check", - "yansi", -] - [[package]] name = "quick-xml" -version = "0.39.2" +version = "0.39.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" +checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" dependencies = [ "memchr", ] -[[package]] -name = "quinn" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror 2.0.18", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" -dependencies = [ - "aws-lc-rs", - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.4", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.18", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", -] - [[package]] name = "quote" version = "1.0.45" @@ -3392,28 +3355,28 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ceda21af1ae61033b63175653a1af86cae399d79cd03ca80ba347eb3a6c4a7fe" dependencies = [ - "cipher 0.5.1", + "cipher 0.5.2", ] [[package]] name = "rcgen" -version = "0.14.7" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b99e0098aa4082912d4c649628623db6aba77335e4f4569ff5083a6448b32e" +checksum = "57f6d249aad744e274e682777a50283a225a32705394ee6d5fcc01efa25e4055" dependencies = [ - "aws-lc-rs", "pem", + "ring", "rustls-pki-types", "time", "x509-parser", - "yasna", + "yasna 0.6.0", ] [[package]] name = "redox_syscall" -version = "0.7.4" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] @@ -3460,9 +3423,9 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ "base64 0.22.1", "bytes", @@ -3482,7 +3445,6 @@ dependencies = [ "native-tls", "percent-encoding", "pin-project-lite", - "quinn", "rustls", "rustls-pki-types", "rustls-platform-verifier", @@ -3501,6 +3463,30 @@ dependencies = [ "web-sys", ] +[[package]] +name = "reqwest-middleware" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc3f1384cffa4f274dad2d4ddd73aed32fed8f786d96c6be8aa4e5fd3c3b58" +dependencies = [ + "anyhow", + "async-trait", + "http", + "reqwest", + "thiserror 2.0.18", + "tower-service", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + [[package]] name = "ring" version = "0.17.14" @@ -3511,7 +3497,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.17", "libc", - "untrusted 0.9.0", + "untrusted", "windows-sys 0.52.0", ] @@ -3560,18 +3546,18 @@ dependencies = [ [[package]] name = "rsa" -version = "0.10.0-rc.17" +version = "0.10.0-rc.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ed3e93fc7e473e464b9726f4759659e72bc8665e4b8ea227547024f416d905" +checksum = "30b2aa4ba0d89f73d1e332df05be0eeab8840351c36ca5654341dfdb57bb3caf" dependencies = [ "const-oid 0.10.2", "crypto-bigint 0.7.3", "crypto-primes", - "digest 0.11.2", + "digest 0.11.3", "pkcs1 0.8.0-rc.4", - "pkcs8 0.11.0-rc.11", + "pkcs8 0.11.0", "rand_core 0.10.1", - "signature 3.0.0-rc.10", + "signature 3.0.0", "spki 0.8.0", "zeroize", ] @@ -3615,14 +3601,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.39" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ - "aws-lc-rs", "once_cell", + "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.13", "subtle", "zeroize", ] @@ -3651,9 +3637,9 @@ dependencies = [ [[package]] name = "rustls-platform-verifier" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", @@ -3663,7 +3649,7 @@ dependencies = [ "rustls", "rustls-native-certs", "rustls-platform-verifier-android", - "rustls-webpki", + "rustls-webpki 0.103.13", "security-framework 3.7.0", "security-framework-sys", "webpki-root-certs", @@ -3676,16 +3662,56 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" +[[package]] +name = "rustls-rustcrypto" +version = "0.0.2-alpha" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12052947763ab8515f753315357599e9b0b4dab3b8ba15f30f725fe6d025557" +dependencies = [ + "aead 0.5.2", + "aes-gcm 0.10.3", + "chacha20poly1305", + "crypto-common 0.1.7", + "der 0.7.10", + "digest 0.10.7", + "ecdsa", + "ed25519-dalek", + "hmac 0.12.1", + "p256", + "p384", + "paste", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "rsa 0.9.10", + "rustls", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "sec1", + "sha2 0.10.9", + "signature 2.2.0", + "x25519-dalek", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ - "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted 0.9.0", + "untrusted", ] [[package]] @@ -3725,7 +3751,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f874456e72520ff1375a06c588eaf074b0f01f9e9e1aada45bd9b7954a6e42c" dependencies = [ "cfg-if", - "cipher 0.5.1", + "cipher 0.5.2", ] [[package]] @@ -3746,6 +3772,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "scroll" version = "0.12.0" @@ -3845,6 +3877,12 @@ version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + [[package]] name = "serde" version = "1.0.228" @@ -3900,15 +3938,6 @@ dependencies = [ "zmij", ] -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -3924,9 +3953,9 @@ dependencies = [ [[package]] name = "serdect" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af4a3e75ebd5599b30d4de5768e00b5095d518a79fefc3ecbaf77e665d1ec06" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" dependencies = [ "base16ct 1.0.0", "serde", @@ -3951,7 +3980,7 @@ checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -3973,7 +4002,7 @@ checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -4009,11 +4038,11 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.10" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ - "digest 0.11.2", + "digest 0.11.3", "rand_core 0.10.1", ] @@ -4024,10 +4053,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] -name = "simple-file-manifest" -version = "0.11.0" +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd19be0257552dd56d1bb6946f89f193c6e5b9f13cc9327c4bc84a357507c74" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "siphasher" @@ -4111,8 +4150,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b5f622c2d21b826b3501f4c620ccc4696e4a09a6b51727fcb21036dec87c101" dependencies = [ "crypto-bigint 0.7.3", - "crypto-common 0.2.1", - "digest 0.11.2", + "crypto-common 0.2.2", + "digest 0.11.3", "subtle", ] @@ -4301,26 +4340,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -4392,47 +4416,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "tower" version = "0.5.3" @@ -4450,9 +4433,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "async-compression", "bitflags", @@ -4462,13 +4445,13 @@ dependencies = [ "http", "http-body", "http-body-util", - "iri-string", "pin-project-lite", "tokio", "tokio-util", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -4607,15 +4590,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" -[[package]] -name = "uncased" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-ident" version = "1.0.24" @@ -4650,7 +4624,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ - "crypto-common 0.2.1", + "crypto-common 0.2.2", "ctutils", ] @@ -4660,12 +4634,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -4684,6 +4652,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -4772,9 +4746,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -4785,9 +4759,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", @@ -4795,9 +4769,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4805,9 +4779,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -4818,9 +4792,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] @@ -4859,11 +4833,24 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmtimer" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "wasm-bindgen", +] + [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -4991,15 +4978,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -5045,21 +5023,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -5108,12 +5071,6 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5132,12 +5089,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -5156,12 +5107,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -5192,12 +5137,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -5216,12 +5155,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -5240,12 +5173,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -5264,12 +5191,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -5288,15 +5209,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] - [[package]] name = "wit-bindgen" version = "0.51.0" @@ -5397,6 +5309,25 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +[[package]] +name = "ws_stream_wasm" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c173014acad22e83f16403ee360115b38846fe754e735c5d9d3803fe70c6abc" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper", + "thiserror 2.0.18", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wyz" version = "0.5.1" @@ -5418,16 +5349,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "x509" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3cec94c3999f31341553f358ef55f65fc031291a022cd42ec0ce7219560c76" -dependencies = [ - "chrono", - "cookie-factory", -] - [[package]] name = "x509-cert" version = "0.2.5" @@ -5457,12 +5378,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" dependencies = [ "asn1-rs", - "aws-lc-rs", "data-encoding", "der-parser", "lazy_static", "nom", "oid-registry", + "ring", "rusticata-macros", "thiserror 2.0.18", "time", @@ -5475,26 +5396,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" [[package]] -name = "xz2" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" -dependencies = [ - "lzma-sys", -] - -[[package]] -name = "yansi" -version = "1.0.1" +name = "yasna" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" [[package]] name = "yasna" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +checksum = "b5f6765e852b9b4dc8e2a76843e4d64d1cea8e79bcde0b6901aea8e7c7f08282" dependencies = [ + "bit-vec", "time", ] @@ -5543,9 +5456,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] diff --git a/examples/minimal/Cargo.toml b/examples/minimal/Cargo.toml index abf29a2..28bc722 100644 --- a/examples/minimal/Cargo.toml +++ b/examples/minimal/Cargo.toml @@ -7,7 +7,8 @@ edition = "2024" isideload = { path = "../../isideload" } plist = "1.8.0" plist-macro = "0.1.3" -tokio = { version = "1.49.0", features = ["rt-multi-thread", "macros"] } +tokio = { version = "1.40.0", features = ["rt-multi-thread", "macros"] } tracing = "0.1.44" tracing-subscriber = "0.3.22" -idevice = { version = "0.1.54", features = ["usbmuxd"] } \ No newline at end of file +idevice = { version = "0.1.61", default-features = false, features = ["usbmuxd", "ring"] } +rustls = { version = "0.23", default-features = false, features = ["ring"] } \ No newline at end of file diff --git a/examples/minimal/src/main.rs b/examples/minimal/src/main.rs index d24ccf7..135d97f 100644 --- a/examples/minimal/src/main.rs +++ b/examples/minimal/src/main.rs @@ -17,6 +17,9 @@ use tracing_subscriber::FmtSubscriber; #[tokio::main] async fn main() { + rustls::crypto::ring::default_provider() + .install_default() + .expect("Failed to install rustls crypto provider"); isideload::init().expect("Failed to initialize error reporting"); let subscriber = FmtSubscriber::builder() .with_max_level(Level::INFO) @@ -34,7 +37,7 @@ async fn main() { .expect("Please provide the path to the app to install"), ); - let get_2fa_code = || { + let get_2fa_code = async || { let mut code = String::new(); println!("Enter 2FA code:"); std::io::stdin().read_line(&mut code).unwrap(); diff --git a/isideload/Cargo.toml b/isideload/Cargo.toml index d4bc598..e69c8e2 100644 --- a/isideload/Cargo.toml +++ b/isideload/Cargo.toml @@ -3,7 +3,7 @@ name = "isideload" description = "Sideload iOS/iPadOS applications" license = "MIT" authors = ["Nicholas Sharp "] -version = "0.2.22" +version = "0.3.10" edition = "2024" repository = "https://github.com/nab138/isideload" documentation = "https://docs.rs/isideload" @@ -11,26 +11,29 @@ keywords = ["ios", "sideload"] readme = "../README.md" [features] -default = ["install", "keyring-storage"] +default = ["install", "keyring-storage", "tokio-mt"] +# default = ["wasm"] +tokio-mt = ["tokio/rt-multi-thread", "dep:tokio-tungstenite"] install = ["dep:idevice"] keyring-storage = ["dep:keyring"] +wasm = ["idevice/wasm", "dep:getrandom_02", "dep:getrandom_04", "uuid/js", "dep:ws_stream_wasm"] fs-storage = [] # Unfortunately, dependencies are kinda a mess rn, since this requires a beta version of the srp crate. # Once that becomes stable, hopefuly duplicate dependencies should clean up.\ # Until then, I will wince in pain every time I see how long the output of cargo tree -d is. [dependencies] -idevice = { version = "0.1.61", optional = true, features = ["afc", "installation_proxy", "remote_pairing", "rsd"]} +idevice = { version = "0.1.61", optional = true, default-features = false, features = ["ring", "afc", "installation_proxy", "remote_pairing", "rsd"]} plist = "1.8" plist-macro = "0.1.4" -reqwest = { version = "0.13.2", features = ["json", "gzip"] } +reqwest = { version = "0.13.2", default-features = false, features = ["json", "gzip", "rustls-no-provider", "http2", "charset", "system-proxy"] } thiserror = "2.0.17" async-trait = "0.1.89" serde = "1.0.228" rand = "0.10.0" uuid = {version = "1.20.0", features = ["v4"] } tracing = "0.1.44" -tokio-tungstenite = { version = "0.29.0", features = ["rustls-tls-webpki-roots"] } +tokio-tungstenite = { version = "0.29.0", features = ["rustls-tls-webpki-roots"], optional = true } rootcause = "0.12.0" futures-util = "0.3.31" serde_json = "1.0.149" @@ -44,17 +47,35 @@ cbc = { version = "0.2.0", features = ["alloc"] } aes = "0.9.0" aes-gcm = "0.11.0-rc.3" rsa = { version = "0.10.0-rc.17" } -tokio = { version = "1.49.0", features = ["fs", "rt-multi-thread"] } +tokio = { version = "1.49" } keyring = { version = "3.6.3", features = ["apple-native", "linux-native-sync-persistent", "windows-native"], optional = true } -x509-certificate = { version = "0.26.0", package = "isideload-x509-certificate" } -rcgen = { version = "0.14.7", default-features = false, features = ["aws_lc_rs", "pem"] } +x509-certificate = { version = "0.26.1", package = "isideload-x509-certificate" } #, path = "../../cryptography-rs/x509-certificate" } +rcgen = { version = "0.14.7", default-features = false, features = ["ring", "pem"] } p12-keystore = { version = "0.3.0-rc4", package = "isideload-p12-keystore" } zip = { version = "8.3", default-features = false, features = ["deflate"] } -apple-codesign = { version = "0.29.4", package = "isideload-apple-codesign" } +apple-codesign = { version = "0.29.11", package = "isideload-apple-codesign" }#, path = "../../isideload-apple-platform-rs/apple-codesign"} +isideload-vfs = { version = "0.0.1" } #, path = "../../isideload-apple-platform-rs/isideload-vfs" } sha1 = "0.11.0" +rustls = { version = "0.23", default-features = false, features = ["ring", "tls12", "std"] } +reqwest-middleware = "0.5.1" +http = "1.4.0" +urlencoding = { version = "2.1.3" } +futures = "0.3.32" +ws_stream_wasm = { version = "0.7.5", optional = true} +web-time = "1" + # There is a bug in rustls-platform-verifier that causes an invalid certificate error with apple's root cert. # It has been fixed already but I am waiting for a new release before I can update the dependency. # Using native-tls avoids the issue. [target.'cfg(windows)'.dependencies] -reqwest = { version = "0.13.2", features = ["json", "gzip", "native-tls"] } +reqwest = { version = "0.13.2", default-features = false, features = ["json", "gzip", "native-tls", "http2", "charset", "system-proxy"] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +getrandom_02 = { package = "getrandom", version = "0.2", default-features = false, features = [ + "js", +], optional = true } +getrandom_04 = { package = "getrandom", version = "0.4", default-features = false, features = [ + "wasm_js", +], optional = true } +ring = { version = "0.17.14", features = ["wasm32_unknown_unknown_js"] } diff --git a/isideload/src/anisette/mod.rs b/isideload/src/anisette/mod.rs index bd3701a..5c83983 100644 --- a/isideload/src/anisette/mod.rs +++ b/isideload/src/anisette/mod.rs @@ -6,9 +6,10 @@ use plist_macro::plist; use reqwest::header::HeaderMap; use rootcause::prelude::*; use serde::Deserialize; -use std::{collections::HashMap, sync::Arc, time::SystemTime}; +use std::{collections::HashMap, sync::Arc}; use tokio::sync::RwLock; use tracing::warn; +use web_time::SystemTime; #[derive(Deserialize, Debug, Clone)] pub struct AnisetteClientInfo { @@ -100,7 +101,8 @@ impl AnisetteData { } } -#[async_trait::async_trait] +#[cfg_attr(feature = "wasm", async_trait::async_trait(?Send))] +#[cfg_attr(not(feature = "wasm"), async_trait::async_trait)] pub trait AnisetteProvider { async fn get_anisette_data(&self) -> Result; diff --git a/isideload/src/anisette/remote_v3/mod.rs b/isideload/src/anisette/remote_v3/mod.rs index 7c26d75..31b559d 100644 --- a/isideload/src/anisette/remote_v3/mod.rs +++ b/isideload/src/anisette/remote_v3/mod.rs @@ -1,25 +1,27 @@ mod state; +mod websocket; use std::sync::Arc; -use std::time::SystemTime; +use web_time::SystemTime; use base64::prelude::*; use plist_macro::plist; -use reqwest::header::{CONTENT_TYPE, HeaderMap, HeaderValue}; +use reqwest::{ + ClientBuilder, + header::{CONTENT_TYPE, HeaderMap, HeaderValue}, +}; +use reqwest_middleware::ClientBuilder as MwClientBuilder; use rootcause::option_ext::OptionExt; use rootcause::prelude::*; use serde::Deserialize; -use tokio::time::{Duration, timeout}; -use tokio_tungstenite::tungstenite::Message; use tracing::{debug, info, warn}; -use crate::SideloadError; -use crate::anisette::remote_v3::state::AnisetteState; +use crate::anisette::remote_v3::{state::AnisetteState, websocket::WsMessage}; use crate::anisette::{AnisetteClientInfo, AnisetteData, AnisetteProvider}; use crate::auth::grandslam::GrandSlam; use crate::util::plist::PlistDataExtract; use crate::util::storage::{SideloadingStorage, new_storage}; -use futures_util::{SinkExt, StreamExt}; +use crate::{SideloadError, anisette::remote_v3::websocket::AppWebSocket}; pub const DEFAULT_ANISETTE_V3_URL: &str = "https://ani.stikstore.app"; @@ -29,7 +31,8 @@ pub struct RemoteV3AnisetteProvider { storage: Box, serial_number: String, client_info: Option, - client: reqwest::Client, + client: reqwest_middleware::ClientWithMiddleware, + websocket_proxy: Option, } impl RemoteV3AnisetteProvider { @@ -50,12 +53,35 @@ impl RemoteV3AnisetteProvider { storage, serial_number, client_info: None, - client: reqwest::ClientBuilder::new() - .build() - .context("Failed to build HTTP client")?, + client: Self::build_reqwest_client(None)?, + websocket_proxy: None, }) } + pub fn set_websocket_proxy(mut self, websocket_proxy: Option) -> Result { + self.websocket_proxy = websocket_proxy; + self.client = Self::build_reqwest_client(self.websocket_proxy.clone())?; + Ok(self) + } + + fn build_reqwest_client( + websocket_proxy: Option, + ) -> Result { + if let Some(websocket_proxy) = websocket_proxy { + use crate::auth::middleware::WasmProxyMiddleware; + + let client = ClientBuilder::new().build()?; + + Ok(MwClientBuilder::new(client) + .with(WasmProxyMiddleware::new(websocket_proxy)) + .build()) + } else { + let client = ClientBuilder::new().build()?; + + Ok(MwClientBuilder::new(client).build()) + } + } + pub fn default() -> Result { Self::new( DEFAULT_ANISETTE_V3_URL, @@ -80,7 +106,8 @@ impl RemoteV3AnisetteProvider { } } -#[async_trait::async_trait] +#[cfg_attr(feature = "wasm", async_trait::async_trait(?Send))] +#[cfg_attr(not(feature = "wasm"), async_trait::async_trait)] impl AnisetteProvider for RemoteV3AnisetteProvider { async fn get_anisette_data(&self) -> Result { let state = self @@ -191,7 +218,7 @@ impl RemoteV3AnisetteProvider { let state = self.state.as_mut().ok_or_report()?; if !state.is_provisioned() { info!("Provisioning required..."); - Self::provision(state, gs, &self.url) + Self::provision(state, gs, &self.url, self.websocket_proxy.as_deref()) .await .context("Failed to provision")?; } @@ -233,6 +260,7 @@ impl RemoteV3AnisetteProvider { state: &mut AnisetteState, gs: Arc, url: &str, + proxy_url: Option<&str>, ) -> Result<(), Report> { let start_provisioning = gs.get_url("midStartProvisioning")?; let end_provisioning = gs.get_url("midFinishProvisioning")?; @@ -242,47 +270,46 @@ impl RemoteV3AnisetteProvider { .replace("http://", "ws://"); debug!("Starting provisioning at {}", websocket_url); - let (mut ws_stream, _) = timeout( - Duration::from_secs(30), - tokio_tungstenite::connect_async(&websocket_url), - ) - .await - .map_err(|_| { - report!("Timed out connecting to provisioning socket. Try a different anisette server.") - }) - .context("Failed to connect to provisioning socket")? - .context("Failed to connect to provisioning socket")?; + // let (mut ws_stream, _) = timeout( + // Duration::from_secs(30), + // tokio_tungstenite::connect_async(&websocket_url), + // ) + // .await + // .map_err(|_| { + // report!("Timed out connecting to provisioning socket. Try a different anisette server.") + // }) + // .context("Failed to connect to provisioning socket")? + // .context("Failed to connect to provisioning socket")?; + + let mut ws = AppWebSocket::connect(&websocket_url, proxy_url.as_deref()) + .await + .context("Failed to connect to provisioning socket")?; debug!("Connected to provisioning socket"); loop { - let Some(msg) = ws_stream.next().await else { - continue; + let Some(msg) = ws.next().await else { continue }; + let msg = msg?; + + let text = match msg { + WsMessage::Close => bail!("Provisioning socket closed unexpectedly"), + WsMessage::Text(t) => t, }; - let msg = msg.context("Failed to read anisette provisioning socket message")?; - if msg.is_close() { - bail!("Anisette provisioning socket closed unexpectedly"); - } - let msg = msg - .into_text() - .context("Failed to parse provisioning message")?; - debug!("Received provisioning message: {}", msg); - let provision_msg: ProvisioningMessage = - serde_json::from_str(&msg).context("Unknown provisioning message")?; + debug!("Received provisioning message: {}", text); + let provision_msg: ProvisioningMessage = serde_json::from_str(&text)?; match provision_msg { ProvisioningMessage::GiveIdentifier => { - ws_stream - .send(Message::Text( - serde_json::json!({ - "identifier": BASE64_STANDARD.encode(state.keychain_identifier), - }) - .to_string() - .into(), - )) - .await - .context("Failed to send identifier")?; + ws.send_text( + serde_json::json!({ + "identifier": BASE64_STANDARD.encode(state.keychain_identifier), + }) + .to_string() + .into(), + ) + .await + .context("Failed to send identifier")?; } ProvisioningMessage::GiveStartProvisioningData => { let body = plist!(dict { @@ -303,16 +330,15 @@ impl RemoteV3AnisetteProvider { .get_str("spim") .context("Start provisioning response missing spim")?; - ws_stream - .send(Message::Text( - serde_json::json!({ - "spim": spim, - }) - .to_string() - .into(), - )) - .await - .context("Failed to send start provisioning data")?; + ws.send_text( + serde_json::json!({ + "spim": spim, + }) + .to_string() + .into(), + ) + .await + .context("Failed to send start provisioning data")?; } ProvisioningMessage::GiveEndProvisioningData { cpim } => { let body = plist!(dict { @@ -331,25 +357,24 @@ impl RemoteV3AnisetteProvider { .await .context("Failed to send end provisioning request")?; - ws_stream - .send(Message::Text( - serde_json::json!({ - "ptm": response - .get_str("ptm") - .context("End provisioning response missing ptm")?, - "tk": response - .get_str("tk") - .context("End provisioning response missing tk")?, - }) - .to_string() - .into(), - )) - .await - .context("Failed to send start provisioning data")?; + ws.send_text( + serde_json::json!({ + "ptm": response + .get_str("ptm") + .context("End provisioning response missing ptm")?, + "tk": response + .get_str("tk") + .context("End provisioning response missing tk")?, + }) + .to_string() + .into(), + ) + .await + .context("Failed to send start provisioning data")?; } ProvisioningMessage::ProvisioningSuccess { adi_pb } => { state.adi_pb = Some(BASE64_STANDARD.decode(adi_pb)?); - ws_stream.close(None).await?; + ws.close().await?; info!("Provisioning successful"); break; } diff --git a/isideload/src/anisette/remote_v3/websocket.rs b/isideload/src/anisette/remote_v3/websocket.rs new file mode 100644 index 0000000..2d1cded --- /dev/null +++ b/isideload/src/anisette/remote_v3/websocket.rs @@ -0,0 +1,103 @@ +use futures::{SinkExt, StreamExt}; +use rootcause::prelude::*; + +pub enum WsMessage { + Text(String), + Close, +} + +pub struct AppWebSocket { + #[cfg(not(feature = "wasm"))] + inner: tokio_tungstenite::WebSocketStream< + tokio_tungstenite::MaybeTlsStream, + >, + #[cfg(feature = "wasm")] + inner: ws_stream_wasm::WsStream, + #[cfg(feature = "wasm")] + meta: ws_stream_wasm::WsMeta, +} + +impl AppWebSocket { + pub async fn connect(url: &str, proxy_url: Option<&str>) -> Result { + let target_url = if proxy_url.is_some() { + let proxied = format!( + "{}{}", + proxy_url.unwrap(), + urlencoding::encode(url) + ) + .replace("https://", "wss://"); + proxied + } else { + url.to_string() + }; + + #[cfg(not(feature = "wasm"))] + { + use tokio::time::{Duration, timeout}; + + let (stream, _) = timeout( + Duration::from_secs(30), + tokio_tungstenite::connect_async(&target_url), + ) + .await? + .context( + "Timed out connecting to provisioning socket. Try a different anisette server.", + )?; + Ok(Self { inner: stream }) + } + #[cfg(feature = "wasm")] + { + let (meta, stream) = ws_stream_wasm::WsMeta::connect(&target_url, None) + .await + .map_err(|e| report!("WS connect failed: {e:?}"))?; + Ok(Self { + meta, + inner: stream, + }) + } + } + + pub async fn send_text(&mut self, text: String) -> Result<(), Report> { + #[cfg(not(feature = "wasm"))] + self.inner + .send(tokio_tungstenite::tungstenite::Message::Text(text.into())) + .await?; + #[cfg(feature = "wasm")] + self.inner + .send(ws_stream_wasm::WsMessage::Text(text)) + .await + .map_err(|e| report!("WS send failed: {e:?}"))?; + Ok(()) + } + + pub async fn next(&mut self) -> Option> { + #[cfg(not(feature = "wasm"))] + { + let msg = self.inner.next().await?; + Some(msg.map_err(Into::into).map(|m| match m { + tokio_tungstenite::tungstenite::Message::Text(t) => WsMessage::Text(t.to_string()), + tokio_tungstenite::tungstenite::Message::Close(_) => WsMessage::Close, + _ => WsMessage::Close, + })) + } + #[cfg(feature = "wasm")] + { + let msg = self.inner.next().await?; + Some(Ok(match msg { + ws_stream_wasm::WsMessage::Text(t) => WsMessage::Text(t), + ws_stream_wasm::WsMessage::Binary(_) => WsMessage::Close, + })) + } + } + + pub async fn close(&mut self) -> Result<(), Report> { + #[cfg(not(feature = "wasm"))] + self.inner.close(None).await?; + #[cfg(feature = "wasm")] + self.meta + .close() + .await + .map_err(|e| report!("WS close failed: {e:?}"))?; + Ok(()) + } +} diff --git a/isideload/src/auth/apple_account.rs b/isideload/src/auth/apple_account.rs index 137d594..4115b85 100644 --- a/isideload/src/auth/apple_account.rs +++ b/isideload/src/auth/apple_account.rs @@ -62,6 +62,7 @@ impl AppleAccount { email: &str, anisette_generator: AnisetteDataGenerator, debug: bool, + proxy_url: Option, ) -> Result { if debug { warn!("Debug mode enabled: this is a security risk!"); @@ -72,7 +73,7 @@ impl AppleAccount { .await .context("Failed to get anisette client info")?; - let grandslam_client = GrandSlam::new(client_info, debug).await?; + let grandslam_client = GrandSlam::new(client_info, debug, proxy_url.clone()).await?; Ok(AppleAccount { email: email.to_string(), @@ -90,11 +91,15 @@ impl AppleAccount { /// - `two_factor_callback`: A callback function that returns the two-factor authentication code /// # Errors /// Returns an error if the login fails - pub async fn login( + pub async fn login( &mut self, password: &str, - two_factor_callback: impl Fn() -> Option, - ) -> Result<(), Report> { + two_factor_callback: F, + ) -> Result<(), Report> + where + F: Fn() -> Fut, + Fut: Future>, + { info!("Logging in to Apple ID: {}", censor_email(&self.email)); if self.debug { warn!("Debug mode enabled: this is a security risk!"); @@ -179,10 +184,11 @@ impl AppleAccount { Ok(pet) } - async fn trusted_device_2fa( - &mut self, - two_factor_callback: impl Fn() -> Option, - ) -> Result<(), Report> { + async fn trusted_device_2fa(&mut self, two_factor_callback: F) -> Result<(), Report> + where + F: Fn() -> Fut, + Fut: Future>, + { debug!("Trusted device 2FA required"); let anisette_data = self @@ -208,8 +214,9 @@ impl AppleAccount { info!("Trusted device 2FA request sent"); - let code = - two_factor_callback().ok_or_else(|| report!("No 2FA code provided, aborting"))?; + let code = two_factor_callback() + .await + .ok_or_else(|| report!("No 2FA code provided, aborting"))?; let res = self .grandslam_client @@ -235,10 +242,11 @@ impl AppleAccount { Ok(()) } - async fn sms_2fa( - &mut self, - two_factor_callback: impl Fn() -> Option, - ) -> Result<(), Report> { + async fn sms_2fa(&mut self, two_factor_callback: F) -> Result<(), Report> + where + F: Fn() -> Fut, + Fut: Future>, + { debug!("SMS 2FA required"); let anisette_data = self @@ -260,8 +268,9 @@ impl AppleAccount { info!("SMS 2FA request sent"); - let code = - two_factor_callback().ok_or_else(|| report!("No 2FA code provided, aborting"))?; + let code = two_factor_callback() + .await + .ok_or_else(|| report!("No 2FA code provided, aborting"))?; let body = serde_json::json!({ "securityCode": { diff --git a/isideload/src/auth/builder.rs b/isideload/src/auth/builder.rs index 0962335..17311a1 100644 --- a/isideload/src/auth/builder.rs +++ b/isideload/src/auth/builder.rs @@ -12,6 +12,7 @@ pub struct AppleAccountBuilder { email: String, debug: Option, anisette_generator: Option, + proxy_url: Option, } impl AppleAccountBuilder { @@ -24,6 +25,7 @@ impl AppleAccountBuilder { email: email.to_string(), debug: None, anisette_generator: None, + proxy_url: None, } } @@ -36,6 +38,11 @@ impl AppleAccountBuilder { self } + pub fn proxy_url(mut self, proxy_url: String) -> Self { + self.proxy_url = Some(proxy_url); + self + } + pub fn anisette_provider( mut self, anisette_provider: impl AnisetteProvider + Send + Sync + 'static, @@ -60,7 +67,7 @@ impl AppleAccountBuilder { } }; - AppleAccount::new(&self.email, anisette_generator, debug).await + AppleAccount::new(&self.email, anisette_generator, debug, self.proxy_url).await } /// Build the AppleAccount and log in @@ -70,13 +77,14 @@ impl AppleAccountBuilder { /// - `two_factor_callback`: A callback function that returns the two-factor authentication code /// # Errors /// Returns an error if the reqwest client cannot be built - pub async fn login( + pub async fn login( self, password: &str, two_factor_callback: F, ) -> Result where - F: Fn() -> Option, + F: Fn() -> Fut, + Fut: Future>, { let mut account = self.build().await?; account.login(password, two_factor_callback).await?; diff --git a/isideload/src/auth/grandslam.rs b/isideload/src/auth/grandslam.rs index 1876812..e58e4dd 100644 --- a/isideload/src/auth/grandslam.rs +++ b/isideload/src/auth/grandslam.rs @@ -1,20 +1,25 @@ +use super::middleware::WasmProxyMiddleware; use plist::Dictionary; use plist_macro::plist_to_xml_string; use plist_macro::pretty_print_dictionary; +#[cfg(not(feature = "wasm"))] +use reqwest::Certificate; use reqwest::{ - Certificate, ClientBuilder, + ClientBuilder, header::{HeaderMap, HeaderValue}, }; +use reqwest_middleware::ClientBuilder as MwClientBuilder; use rootcause::prelude::*; use tracing::debug; use crate::{SideloadError, anisette::AnisetteClientInfo, util::plist::PlistDataExtract}; +#[cfg(not(feature = "wasm"))] const APPLE_ROOT: &[u8] = include_bytes!("./apple_root.der"); const URL_BAG: &str = "https://gsa.apple.com/grandslam/GsService2/lookup"; pub struct GrandSlam { - pub client: reqwest::Client, + pub client: reqwest_middleware::ClientWithMiddleware, pub client_info: AnisetteClientInfo, url_bag: Dictionary, } @@ -24,8 +29,13 @@ impl GrandSlam { /// /// # Arguments /// - `client`: The reqwest client to use for requests - pub async fn new(client_info: AnisetteClientInfo, debug: bool) -> Result { - let client = Self::build_reqwest_client(debug).context("Failed to build HTTP client")?; + pub async fn new( + client_info: AnisetteClientInfo, + debug: bool, + proxy_url: Option, + ) -> Result { + let client = + Self::build_reqwest_client(debug, proxy_url).context("Failed to build HTTP client")?; let base_headers = Self::base_headers(&client_info, false)?; let url_bag = Self::fetch_url_bag(&client, base_headers).await?; Ok(Self { @@ -37,7 +47,7 @@ impl GrandSlam { /// Fetch the URL bag from GrandSlam and cache it pub async fn fetch_url_bag( - client: &reqwest::Client, + client: &reqwest_middleware::ClientWithMiddleware, base_headers: HeaderMap, ) -> Result { debug!("Fetching URL bag from GrandSlam"); @@ -70,7 +80,7 @@ impl GrandSlam { Ok(url) } - pub fn get(&self, url: &str) -> Result { + pub fn get(&self, url: &str) -> Result { let builder = self .client .get(url) @@ -79,7 +89,7 @@ impl GrandSlam { Ok(builder) } - pub fn get_sms(&self, url: &str) -> Result { + pub fn get_sms(&self, url: &str) -> Result { let builder = self .client .get(url) @@ -88,7 +98,7 @@ impl GrandSlam { Ok(builder) } - pub fn post(&self, url: &str) -> Result { + pub fn post(&self, url: &str) -> Result { let builder = self .client .post(url) @@ -97,7 +107,7 @@ impl GrandSlam { Ok(builder) } - pub fn patch(&self, url: &str) -> Result { + pub fn patch(&self, url: &str) -> Result { let builder = self .client .patch(url) @@ -173,16 +183,29 @@ impl GrandSlam { /// - `debug`: DANGER, If true, accept invalid certificates and enable verbose connection logging /// # Errors /// Returns an error if the reqwest client cannot be built - pub fn build_reqwest_client(debug: bool) -> Result { + pub fn build_reqwest_client( + debug: bool, + proxy_url: Option, + ) -> Result { + #[cfg(not(feature = "wasm"))] let cert = Certificate::from_der(APPLE_ROOT)?; + #[cfg(not(feature = "wasm"))] let client = ClientBuilder::new() .add_root_certificate(cert) .http1_title_case_headers() .danger_accept_invalid_certs(debug) .connection_verbose(debug) .build()?; - - Ok(client) + #[cfg(feature = "wasm")] + let client = ClientBuilder::new().build()?; + + let builder = MwClientBuilder::new(client); + let builder = if let Some(proxy_url) = proxy_url { + builder.with(WasmProxyMiddleware::new(proxy_url)) + } else { + builder + }; + Ok(builder.build()) } } diff --git a/isideload/src/auth/middleware.rs b/isideload/src/auth/middleware.rs new file mode 100644 index 0000000..e98d31f --- /dev/null +++ b/isideload/src/auth/middleware.rs @@ -0,0 +1,35 @@ +use reqwest_middleware::{Middleware, Next}; + +pub struct WasmProxyMiddleware { + proxy_url: String, +} + +impl WasmProxyMiddleware { + pub fn new(proxy_url: String) -> Self { + Self { proxy_url } + } +} + +// You might be wondering, why does this cfg_attr check the target_arch AND the feature when all the others just check the feature? +// For some reason, I could not get rust analyzer to output errors when the arch was set to wasm32-unknown-unknown +// In an effort to make my life not miserable, I wanted isideload to compile as x86 even with the wasm feature enabled +// This one trait however didn't agree with that, so I added the additional check +// The arch check caused problems in other places, so everywhere else just gets the feature check +#[cfg_attr(all(target_arch = "wasm32", feature = "wasm"), async_trait::async_trait(?Send))] +#[cfg_attr( + not(all(target_arch = "wasm32", feature = "wasm")), + async_trait::async_trait +)] +impl Middleware for WasmProxyMiddleware { + async fn handle( + &self, + mut req: reqwest::Request, + extensions: &mut http::Extensions, + next: Next<'_>, + ) -> reqwest_middleware::Result { + let original = req.url().to_string(); + let proxied = format!("{}{}", self.proxy_url, urlencoding::encode(&original)); + *req.url_mut() = proxied.parse().unwrap(); + next.run(req, extensions).await + } +} diff --git a/isideload/src/auth/mod.rs b/isideload/src/auth/mod.rs index 8ef46dc..8b7f2c6 100644 --- a/isideload/src/auth/mod.rs +++ b/isideload/src/auth/mod.rs @@ -1,3 +1,4 @@ pub mod apple_account; pub mod builder; pub mod grandslam; +pub mod middleware; diff --git a/isideload/src/dev/app_groups.rs b/isideload/src/dev/app_groups.rs index c17d2a9..dee44c2 100644 --- a/isideload/src/dev/app_groups.rs +++ b/isideload/src/dev/app_groups.rs @@ -17,7 +17,8 @@ pub struct AppGroup { pub application_group: String, } -#[async_trait::async_trait] +#[cfg_attr(feature = "wasm", async_trait::async_trait(?Send))] +#[cfg_attr(not(feature = "wasm"), async_trait::async_trait)] pub trait AppGroupsApi { fn developer_session(&mut self) -> &mut DeveloperSession; diff --git a/isideload/src/dev/app_ids.rs b/isideload/src/dev/app_ids.rs index 099d336..51277c1 100644 --- a/isideload/src/dev/app_ids.rs +++ b/isideload/src/dev/app_ids.rs @@ -51,7 +51,8 @@ pub struct Profile { pub is_free_provisioning_profile: Option, } -#[async_trait::async_trait] +#[cfg_attr(feature = "wasm", async_trait::async_trait(?Send))] +#[cfg_attr(not(feature = "wasm"), async_trait::async_trait)] pub trait AppIdsApi { fn developer_session(&mut self) -> &mut DeveloperSession; diff --git a/isideload/src/dev/certificates.rs b/isideload/src/dev/certificates.rs index cd485a7..a0ba1c6 100644 --- a/isideload/src/dev/certificates.rs +++ b/isideload/src/dev/certificates.rs @@ -71,7 +71,8 @@ impl std::fmt::Debug for DevelopmentCertificate { } } -#[async_trait::async_trait] +#[cfg_attr(feature = "wasm", async_trait::async_trait(?Send))] +#[cfg_attr(not(feature = "wasm"), async_trait::async_trait)] pub trait CertificatesApi { fn developer_session(&mut self) -> &mut DeveloperSession; diff --git a/isideload/src/dev/devices.rs b/isideload/src/dev/devices.rs index aa77a02..8fb5208 100644 --- a/isideload/src/dev/devices.rs +++ b/isideload/src/dev/devices.rs @@ -20,7 +20,8 @@ pub struct DeveloperDevice { pub status: Option, } -#[async_trait::async_trait] +#[cfg_attr(feature = "wasm", async_trait::async_trait(?Send))] +#[cfg_attr(not(feature = "wasm"), async_trait::async_trait)] pub trait DevicesApi { fn developer_session(&mut self) -> &mut DeveloperSession; diff --git a/isideload/src/dev/teams.rs b/isideload/src/dev/teams.rs index 1a4cb66..4c14774 100644 --- a/isideload/src/dev/teams.rs +++ b/isideload/src/dev/teams.rs @@ -14,7 +14,8 @@ pub struct DeveloperTeam { pub status: Option, } -#[async_trait::async_trait] +#[cfg_attr(feature = "wasm", async_trait::async_trait(?Send))] +#[cfg_attr(not(feature = "wasm"), async_trait::async_trait)] pub trait TeamsApi { fn developer_session(&mut self) -> &mut DeveloperSession; diff --git a/isideload/src/lib.rs b/isideload/src/lib.rs index 2cc5e74..1712801 100644 --- a/isideload/src/lib.rs +++ b/isideload/src/lib.rs @@ -55,5 +55,6 @@ pub fn init() -> Result<(), Report> { .context_formatter::(ReqwestErrorFormatter) .install() .context("Failed to install error reporting hooks")?; + Ok(()) } diff --git a/isideload/src/sideload/application.rs b/isideload/src/sideload/application.rs index 7c65883..ccfd181 100644 --- a/isideload/src/sideload/application.rs +++ b/isideload/src/sideload/application.rs @@ -7,11 +7,11 @@ use crate::dev::developer_session::DeveloperSession; use crate::dev::teams::DeveloperTeam; use crate::sideload::bundle::Bundle; use crate::sideload::cert_identity::CertificateIdentity; +use isideload_vfs::fs::File; use rootcause::option_ext::OptionExt; use rootcause::prelude::*; -use std::fs::File; +use std::io::Write; use std::path::PathBuf; -use tokio::io::AsyncWriteExt; use tracing::info; use zip::ZipArchive; @@ -22,7 +22,7 @@ pub struct Application { impl Application { pub fn new(path: PathBuf) -> Result { - if !path.exists() { + if !isideload_vfs::fs::metadata(&path).is_ok() { bail!(SideloadError::InvalidBundle( "Application path does not exist".to_string(), )); @@ -31,8 +31,8 @@ impl Application { let mut bundle_path = path.clone(); //let mut temp_path = PathBuf::new(); - if path.is_file() { - let temp_dir = std::env::temp_dir(); + if isideload_vfs::fs::metadata(&bundle_path)?.is_file() { + let temp_dir = isideload_vfs::fs::temp_dir(); let temp_path = temp_dir.join( path.file_name() .ok_or_report()? @@ -40,22 +40,24 @@ impl Application { .to_string() + "_extracted", ); - if temp_path.exists() { - std::fs::remove_dir_all(&temp_path) + if isideload_vfs::fs::metadata(&temp_path).is_ok() { + isideload_vfs::fs::remove_dir_all(&temp_path) .context("Failed to remove existing temporary directory")?; } - std::fs::create_dir_all(&temp_path).context("Failed to create temporary directory")?; + isideload_vfs::fs::create_dir_all(&temp_path) + .context("Failed to create temporary directory")?; let file = File::open(&path).context("Failed to open application archive")?; let mut archive = ZipArchive::new(file).context("Failed to open application archive")?; + archive .extract(&temp_path) .context("Failed to extract application archive")?; let payload_folder = temp_path.join("Payload"); - if payload_folder.exists() && payload_folder.is_dir() { - let app_dirs: Vec<_> = std::fs::read_dir(&payload_folder) + if isideload_vfs::fs::metadata(&payload_folder).is_ok() && payload_folder.is_dir() { + let app_dirs: Vec<_> = isideload_vfs::fs::read_dir(&payload_folder) .context("Failed to read Payload directory")? .filter_map(Result::ok) .filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) @@ -73,9 +75,22 @@ impl Application { )); } } else { - bail!(SideloadError::InvalidBundle( - "No Payload directory found in the application archive".to_string(), - )); + // gather the directory contents as a string for debugging + let mut contents = String::new(); + if isideload_vfs::fs::metadata(&temp_path).is_ok() && temp_path.is_dir() { + let entries = isideload_vfs::fs::read_dir(&temp_path) + .context("Failed to read temporary directory for error reporting")?; + for entry in entries { + if let Ok(entry) = entry { + contents + .push_str(&format!("{}\n", entry.file_name().to_string_lossy())); + } + } + } + bail!(SideloadError::InvalidBundle(format!( + "No Payload directory found in the application archive, instead: {}", + contents + ),)); } } let bundle = Bundle::new(bundle_path)?; @@ -271,11 +286,9 @@ impl Application { .context("Failed to encode cert as p12")?; let alt_cert_path = target_bundle.bundle_dir.join(cert_file_name); - let mut file = tokio::fs::File::create(&alt_cert_path) - .await + let mut file = isideload_vfs::fs::File::create(&alt_cert_path) .context(format!("Failed to create {}", cert_file_name))?; file.write_all(&p12_bytes) - .await .context(format!("Failed to write {}", cert_file_name))?; } } diff --git a/isideload/src/sideload/bundle.rs b/isideload/src/sideload/bundle.rs index fdee936..67a947d 100644 --- a/isideload/src/sideload/bundle.rs +++ b/isideload/src/sideload/bundle.rs @@ -1,10 +1,11 @@ // This file was made using https://github.com/Dadoum/Sideloader as a reference. // I'm planning on redoing this later to better handle entitlements, extensions, etc, but it will do for now -use plist::{Dictionary, Value}; +use isideload_vfs::fs::File; +use plist::{Dictionary, Value, to_writer_binary}; use rootcause::prelude::*; use std::{ - fs, + io::BufWriter, path::{Path, PathBuf}, }; @@ -32,13 +33,13 @@ impl Bundle { let info_plist_path = bundle_path.join("Info.plist"); assert_bundle( - info_plist_path.exists(), + isideload_vfs::fs::metadata(&info_plist_path).is_ok(), &format!("No Info.plist here: {}", info_plist_path.display()), )?; - let plist_data = fs::read(&info_plist_path).context(SideloadError::InvalidBundle( - "Failed to read Info.plist".to_string(), - ))?; + let plist_data = isideload_vfs::fs::read(&info_plist_path).context( + SideloadError::InvalidBundle("Failed to read Info.plist".to_string()), + )?; let app_info = plist::from_bytes(&plist_data).context(SideloadError::InvalidBundle( "Failed to parse Info.plist".to_string(), @@ -46,15 +47,15 @@ impl Bundle { // Load app extensions from PlugIns directory let plug_ins_dir = bundle_path.join("PlugIns"); - let app_extensions = if plug_ins_dir.exists() { - fs::read_dir(&plug_ins_dir) + let app_extensions = if isideload_vfs::fs::metadata(&plug_ins_dir).is_ok() { + isideload_vfs::fs::read_dir(&plug_ins_dir) .context(SideloadError::InvalidBundle( "Failed to read PlugIns directory".to_string(), ))? .filter_map(|entry| entry.ok()) .filter(|entry| { entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) - && entry.path().join("Info.plist").exists() + && isideload_vfs::fs::metadata(&entry.path().join("Info.plist")).is_ok() }) .filter_map(|entry| Bundle::new(entry.path()).ok()) .collect() @@ -64,15 +65,15 @@ impl Bundle { // Load frameworks from Frameworks directory let frameworks_dir = bundle_path.join("Frameworks"); - let frameworks = if frameworks_dir.exists() { - fs::read_dir(&frameworks_dir) + let frameworks = if isideload_vfs::fs::metadata(&frameworks_dir).is_ok() { + isideload_vfs::fs::read_dir(&frameworks_dir) .context(SideloadError::InvalidBundle( "Failed to read Frameworks directory".to_string(), ))? .filter_map(|entry| entry.ok()) .filter(|entry| { entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) - && entry.path().join("Info.plist").exists() + && isideload_vfs::fs::metadata(&entry.path().join("Info.plist")).is_ok() }) .filter_map(|entry| Bundle::new(entry.path()).ok()) .collect() @@ -129,9 +130,19 @@ impl Bundle { pub fn write_info(&self) -> Result<(), Report> { let info_plist_path = self.bundle_dir.join("Info.plist"); - plist::to_file_binary(&info_plist_path, &self.app_info).context( - SideloadError::InvalidBundle("Failed to write Info.plist".to_string()), + // plist::to_file_binary(&info_plist_path, &self.app_info).context( + // SideloadError::InvalidBundle("Failed to write Info.plist".to_string()), + // )?; + let mut file = File::create(&info_plist_path).context(SideloadError::InvalidBundle( + "Failed to write Info.plist".to_string(), + ))?; + to_writer_binary(BufWriter::new(&mut file), &self.app_info).context( + SideloadError::InvalidBundle("Failed to create Info.plist writer".to_string()), )?; + + file.sync_all().context(SideloadError::InvalidBundle( + "Failed to sync Info.plist".to_string(), + ))?; Ok(()) } @@ -196,10 +207,9 @@ fn find_dylibs(dir: &Path, bundle_root: &Path) -> Result, Report> { bundle_root: &Path, libraries: &mut Vec, ) -> Result<(), Report> { - let entries = fs::read_dir(dir).context(SideloadError::InvalidBundle(format!( - "Failed to read directory {}", - dir.display() - )))?; + let entries = isideload_vfs::fs::read_dir(dir).context(SideloadError::InvalidBundle( + format!("Failed to read directory {}", dir.display()), + ))?; for entry in entries { let entry = entry.context(SideloadError::InvalidBundle( @@ -207,9 +217,11 @@ fn find_dylibs(dir: &Path, bundle_root: &Path) -> Result, Report> { ))?; let path = entry.path(); - let file_type = entry.file_type().context(SideloadError::InvalidBundle( - "Failed to get file type".to_string(), - ))?; + let file_type = isideload_vfs::fs::metadata(&path) + .map(|m| m.file_type()) + .context(SideloadError::InvalidBundle( + "Failed to get file type".to_string(), + ))?; if file_type.is_file() { if let Some(name) = path.file_name().and_then(|n| n.to_str()) diff --git a/isideload/src/sideload/install.rs b/isideload/src/sideload/install.rs index 8937322..d505a11 100644 --- a/isideload/src/sideload/install.rs +++ b/isideload/src/sideload/install.rs @@ -18,7 +18,7 @@ use std::{future::Future, path::Path}; pub async fn install_app( provider: &impl IdeviceProvider, app_path: &Path, - progress_callback: impl Fn(u64), + progress_callback: impl Fn(u64) + Send + Sync, ) -> Result<(), Report> { let mut afc_client = AfcClient::connect(provider) .await @@ -28,7 +28,20 @@ pub async fn install_app( "PublicStaging/{}", app_path.file_name().ok_or_report()?.to_string_lossy() ); - afc_upload_dir(&mut afc_client, app_path, &dir).await?; + let total_size = get_dir_size(app_path).unwrap_or(1) as f64; + let mut uploaded = 0; + let cb = |progress: f64| { + progress_callback((progress * 70.0) as u64); + }; + afc_upload_dir( + &mut afc_client, + app_path, + &dir, + &cb, + &mut uploaded, + total_size, + ) + .await?; let mut instproxy_client = InstallationProxyClient::connect(provider) .await @@ -43,7 +56,7 @@ pub async fn install_app( dir, Some(plist::Value::Dictionary(options)), async |(percentage, _)| { - progress_callback(percentage); + progress_callback((70.0 + 0.3 * percentage as f64) as u64); }, (), ) @@ -59,7 +72,7 @@ pub async fn install_app_rsd( provider: &mut impl RsdProvider, handshake: &mut RsdHandshake, app_path: &Path, - progress_callback: impl Fn(u64), + progress_callback: impl Fn(u64) + Send + Sync, ) -> Result<(), Report> { let mut afc_client = AfcClient::connect_rsd(provider, handshake) .await @@ -69,7 +82,20 @@ pub async fn install_app_rsd( "PublicStaging/{}", app_path.file_name().ok_or_report()?.to_string_lossy() ); - afc_upload_dir(&mut afc_client, app_path, &dir).await?; + let total_size = get_dir_size(app_path).unwrap_or(1) as f64; + let mut uploaded = 0; + let cb = |pct: f64| { + progress_callback((pct * 70.0) as u64); + }; + afc_upload_dir( + &mut afc_client, + app_path, + &dir, + &cb, + &mut uploaded, + total_size, + ) + .await?; let mut instproxy_client = InstallationProxyClient::connect_rsd(provider, handshake) .await @@ -84,7 +110,7 @@ pub async fn install_app_rsd( dir, Some(plist::Value::Dictionary(options)), async |(percentage, _)| { - progress_callback(percentage); + progress_callback((70.0 + 0.3 * percentage as f64) as u64); }, (), ) @@ -94,27 +120,46 @@ pub async fn install_app_rsd( Ok(()) } +fn get_dir_size(path: &Path) -> Result { + let mut size = 0; + for entry in isideload_vfs::fs::read_dir(path)? { + let entry = entry?; + let path = entry.path(); + let meta = isideload_vfs::fs::metadata(&path)?; + if meta.is_dir() { + size += get_dir_size(&path)?; + } else { + size += meta.len(); + } + } + Ok(size) +} + fn afc_upload_dir<'a>( afc_client: &'a mut AfcClient, path: &'a Path, afc_path: &'a str, + cb: &'a (dyn Fn(f64) + Send + Sync), + uploaded: &'a mut u64, + total: f64, ) -> Pin> + Send + 'a>> { Box::pin(async move { - let entries = std::fs::read_dir(path)?; + let entries = isideload_vfs::fs::read_dir(path)?; afc_client .mk_dir(afc_path) .await .map_err(Error::IdeviceError)?; + for entry in entries { let entry = entry?; let path = entry.path(); - if path.is_dir() { + if isideload_vfs::fs::metadata(&path)?.is_dir() { let new_afc_path = format!( "{}/{}", afc_path, path.file_name().ok_or_report()?.to_string_lossy() ); - afc_upload_dir(afc_client, &path, &new_afc_path).await?; + afc_upload_dir(afc_client, &path, &new_afc_path, cb, uploaded, total).await?; } else { let mut file_handle = afc_client .open( @@ -127,11 +172,16 @@ fn afc_upload_dir<'a>( ) .await .map_err(Error::IdeviceError)?; - let bytes = std::fs::read(&path)?; - file_handle - .write_entire(&bytes) - .await - .map_err(Error::IdeviceError)?; + + let bytes = isideload_vfs::fs::read(&path)?; + for chunk in bytes.chunks(8 * 1024) { + file_handle + .write_entire(chunk) + .await + .map_err(Error::IdeviceError)?; + *uploaded += chunk.len() as u64; + cb(*uploaded as f64 / total); + } file_handle.close().await.map_err(Error::IdeviceError)?; } } diff --git a/isideload/src/sideload/sideloader.rs b/isideload/src/sideload/sideloader.rs index a1ed42f..28accfe 100644 --- a/isideload/src/sideload/sideloader.rs +++ b/isideload/src/sideload/sideloader.rs @@ -62,13 +62,18 @@ impl Sideloader { } /// Sign the app at the provided path and return the path to the signed app bundle (in a temp dir). To sign and install, see [`Self::install_app`]. - pub async fn sign_app( + pub async fn sign_app( &mut self, app_path: PathBuf, team: Option, // this will be replaced with proper entitlement handling later increased_memory_limit: bool, - ) -> Result<(PathBuf, Option), Report> { + progress_callback: Option, + ) -> Result<(PathBuf, Option), Report> + where + F: Fn(f32) -> Fut, + Fut: Future, + { let team = match team { Some(t) => t, None => self.get_team().await?, @@ -84,6 +89,10 @@ impl Sideloader { .await .context("Failed to retrieve certificate identity")?; + if let Some(callback) = &progress_callback { + callback(0.1).await; + } + let mut app = Application::new(app_path)?; let special = app.get_special_app(); @@ -141,6 +150,10 @@ impl Sideloader { } } + if let Some(callback) = &progress_callback { + callback(0.15).await; + } + info!("App IDs configured"); app.apply_special_app_behavior(&special, &group_identifier, &cert_identity) @@ -152,6 +165,10 @@ impl Sideloader { .download_team_provisioning_profile(&team, &main_app_id, None) .await?; + if let Some(callback) = &progress_callback { + callback(0.2).await; + } + info!("Acquired provisioning profile"); app.bundle.write_info()?; @@ -162,11 +179,14 @@ impl Sideloader { ext.write_info()?; } - tokio::fs::write( + isideload_vfs::fs::write( app.bundle.bundle_dir.join("embedded.mobileprovision"), provisioning_profile.encoded_profile.as_ref(), - ) - .await?; + )?; + + if let Some(callback) = &progress_callback { + callback(0.3).await; + } sign::sign( &mut app, @@ -174,7 +194,9 @@ impl Sideloader { &provisioning_profile, &special, &team, + progress_callback, ) + .await .context("Failed to sign app")?; info!("App signed!"); @@ -184,13 +206,18 @@ impl Sideloader { #[cfg(feature = "install")] /// Sign and install an app to a device. - pub async fn install_app( + pub async fn install_app( &mut self, device_provider: &impl IdeviceProvider, app_path: PathBuf, // this is gross but will be replaced with proper entitlement handling later increased_memory_limit: bool, - ) -> Result, Report> { + progress_callback: Option, + ) -> Result, Report> + where + F: Fn(f32) -> Fut, + Fut: Future, + { let device_info = IdeviceInfo::from_device(device_provider).await?; let team = self.get_team().await?; @@ -199,7 +226,12 @@ impl Sideloader { .await?; let (signed_app_path, special_app) = self - .sign_app(app_path, Some(team), increased_memory_limit) + .sign_app( + app_path, + Some(team), + increased_memory_limit, + progress_callback, + ) .await?; info!("Transferring App..."); @@ -211,7 +243,7 @@ impl Sideloader { .context("Failed to install app on device")?; if self.delete_app_after_install - && let Err(e) = tokio::fs::remove_dir_all(signed_app_path).await + && let Err(e) = isideload_vfs::fs::remove_dir_all(signed_app_path) { tracing::warn!("Failed to remove temporary signed app file: {}", e); } diff --git a/isideload/src/sideload/sign.rs b/isideload/src/sideload/sign.rs index 3468405..c3062b7 100644 --- a/isideload/src/sideload/sign.rs +++ b/isideload/src/sideload/sign.rs @@ -13,19 +13,21 @@ use crate::{ util::plist::PlistDataExtract, }; -pub fn sign( +pub async fn sign( app: &mut Application, cert_identity: &CertificateIdentity, provisioning_profile: &Profile, special: &Option, team: &DeveloperTeam, -) -> Result<(), Report> { + progress_callback: Option, +) -> Result<(), Report> +where + F: Fn(f32) -> Fut, + Fut: Future, +{ let mut settings = signing_settings(cert_identity)?; - let entitlements: Dictionary = entitlements_from_prov( - provisioning_profile.encoded_profile.as_ref(), - special, - team, - )?; + let entitlements: Dictionary = + entitlements_from_prov(provisioning_profile.encoded_profile.as_ref(), special, team)?; settings .set_entitlements_xml( @@ -35,7 +37,12 @@ pub fn sign( .context("Failed to set entitlements XML")?; let signer = UnifiedSigner::new(settings); - for bundle in app.bundle.collect_bundles_sorted() { + let sorted_bundles = app.bundle.collect_bundles_sorted(); + + for (index, bundle) in sorted_bundles.iter().enumerate() { + if let Some(callback) = &progress_callback { + callback(0.3 + 0.7 * (index as f32 / sorted_bundles.len() as f32)).await; + } info!( "Signing {}", bundle @@ -44,6 +51,7 @@ pub fn sign( .unwrap_or(bundle.bundle_dir.as_os_str()) .to_string_lossy() ); + signer .sign_path_in_place(&bundle.bundle_dir) .context(format!( diff --git a/isideload/src/util/fs_storage.rs b/isideload/src/util/fs_storage.rs index 4ccb959..4fada20 100644 --- a/isideload/src/util/fs_storage.rs +++ b/isideload/src/util/fs_storage.rs @@ -24,15 +24,15 @@ impl SideloadingStorage for FsStorage { fn store_data(&self, key: &str, data: &[u8]) -> Result<(), Report> { let path = self.path.join(key); let parent = path.parent().unwrap_or(Path::new(".")); - std::fs::create_dir_all(parent).context("Failed to create storage directory")?; - std::fs::write(&path, data).context("Failed to write data to file")?; + isideload_vfs::fs::create_dir_all(parent).context("Failed to create storage directory")?; + isideload_vfs::fs::write(&path, data).context("Failed to write data to file")?; Ok(()) } fn retrieve_data(&self, key: &str) -> Result>, Report> { let path = self.path.join(key); - match std::fs::read(&path) { + match isideload_vfs::fs::read(&path) { Ok(data) => Ok(Some(data)), Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None), Err(e) => Err(report!(e).context("Failed to read data from file").into()),