mirror of
https://github.com/nab138/isideload.git
synced 2026-03-02 14:36:16 +01:00
Improve error handling and fix issues
This commit is contained in:
354
Cargo.lock
generated
354
Cargo.lock
generated
@@ -180,7 +180,7 @@ version = "0.30.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff"
|
checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen 0.69.5",
|
||||||
"cc",
|
"cc",
|
||||||
"cmake",
|
"cmake",
|
||||||
"dunce",
|
"dunce",
|
||||||
@@ -202,12 +202,6 @@ dependencies = [
|
|||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64"
|
|
||||||
version = "0.13.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.7"
|
version = "0.21.7"
|
||||||
@@ -235,7 +229,7 @@ dependencies = [
|
|||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"cexpr",
|
"cexpr",
|
||||||
"clang-sys",
|
"clang-sys",
|
||||||
"itertools",
|
"itertools 0.12.1",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lazycell",
|
"lazycell",
|
||||||
"log",
|
"log",
|
||||||
@@ -243,12 +237,32 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash 1.1.0",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
"which",
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bindgen"
|
||||||
|
version = "0.72.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f72209734318d0b619a5e0f5129918b848c416e122a3c4ce054e03cb87b726f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
|
"cexpr",
|
||||||
|
"clang-sys",
|
||||||
|
"itertools 0.13.0",
|
||||||
|
"log",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash 2.1.1",
|
||||||
|
"shlex",
|
||||||
|
"syn 2.0.104",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@@ -273,7 +287,7 @@ version = "0.10.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array 0.14.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -282,31 +296,32 @@ version = "0.3.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
|
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array 0.14.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "botan"
|
name = "botan"
|
||||||
version = "0.11.1"
|
version = "0.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24d4c7647d67c53194fa0740404c6c508880aef2bfe99a9868dbb4b86f090377"
|
checksum = "f23e39f9dbdfec8b4b6ba8509c8202a573b5d52fe213349c385d86656c89d7b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"botan-sys",
|
"botan-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "botan-src"
|
name = "botan-src"
|
||||||
version = "0.30701.2"
|
version = "0.30900.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c4e1c7910f3b4712aed10e4259eca77e79ed84c1b023098c8eac596b993fc44"
|
checksum = "9bc24a437ed9a438eaace54677eead87931fcdf5cb9fef85567be2f82d8c5d92"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "botan-sys"
|
name = "botan-sys"
|
||||||
version = "0.11.1"
|
version = "1.20250506.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04285fa0c094cc9961fe435b1b279183db9394844ad82ce483aa6196c0e6da38"
|
checksum = "9a68b2bca80766adc60e9d88e99d958bba278a99ed616bf92b9d266c89dd2a9e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"botan-src",
|
"botan-src",
|
||||||
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -315,12 +330,6 @@ version = "3.19.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "byteorder"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
@@ -347,9 +356,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.31"
|
version = "1.2.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2"
|
checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -381,7 +390,6 @@ dependencies = [
|
|||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
@@ -424,9 +432,9 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-oid"
|
name = "const-oid"
|
||||||
version = "0.7.1"
|
version = "0.9.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3"
|
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "constant_time_eq"
|
name = "constant_time_eq"
|
||||||
@@ -474,7 +482,7 @@ version = "0.1.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array 0.14.7",
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -492,11 +500,25 @@ checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.5.1"
|
version = "0.7.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c"
|
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
|
"der_derive",
|
||||||
|
"flagset",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "der_derive"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -630,6 +652,12 @@ version = "2.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flagset"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
@@ -776,6 +804,15 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8c8444bc9d71b935156cc0ccab7f622180808af7867b1daae6547d773591703"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@@ -822,7 +859,7 @@ dependencies = [
|
|||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http 0.2.12",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -832,9 +869,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.4"
|
version = "0.15.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hex"
|
name = "hex"
|
||||||
@@ -871,6 +908,17 @@ dependencies = [
|
|||||||
"itoa",
|
"itoa",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http-body"
|
name = "http-body"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -878,7 +926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
|
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http 0.2.12",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -905,7 +953,7 @@ dependencies = [
|
|||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2",
|
||||||
"http",
|
"http 0.2.12",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
"httpdate",
|
"httpdate",
|
||||||
@@ -925,7 +973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
|
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http 0.2.12",
|
||||||
"hyper",
|
"hyper",
|
||||||
"rustls 0.21.12",
|
"rustls 0.21.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -974,25 +1022,24 @@ name = "icloud_auth"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"base64 0.13.1",
|
"base64 0.22.1",
|
||||||
"botan",
|
"botan",
|
||||||
"cbc",
|
"cbc",
|
||||||
"chrono",
|
|
||||||
"hmac",
|
"hmac",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"omnisette",
|
"omnisette",
|
||||||
"pbkdf2 0.11.0",
|
"pbkdf2 0.11.0",
|
||||||
"pkcs7",
|
"pkcs7",
|
||||||
"plist",
|
"plist",
|
||||||
"rand 0.8.5",
|
"rand 0.9.2",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rustls 0.20.9",
|
"rustls 0.23.31",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile 2.2.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"srp",
|
"srp",
|
||||||
"thiserror 1.0.69",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1095,7 +1142,7 @@ dependencies = [
|
|||||||
"plist",
|
"plist",
|
||||||
"rustls 0.23.31",
|
"rustls 0.23.31",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.12",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls 0.26.2",
|
"tokio-rustls 0.26.2",
|
||||||
]
|
]
|
||||||
@@ -1138,7 +1185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
|
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-padding",
|
"block-padding",
|
||||||
"generic-array",
|
"generic-array 0.14.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1176,8 +1223,10 @@ dependencies = [
|
|||||||
"plist",
|
"plist",
|
||||||
"serde",
|
"serde",
|
||||||
"sha1",
|
"sha1",
|
||||||
|
"thiserror",
|
||||||
"uuid",
|
"uuid",
|
||||||
"zip",
|
"zip",
|
||||||
|
"zsign-rust",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1189,6 +1238,15 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
@@ -1497,7 +1555,7 @@ dependencies = [
|
|||||||
"android-loader",
|
"android-loader",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.21.7",
|
"base64 0.22.1",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dlopen2",
|
"dlopen2",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@@ -1507,13 +1565,13 @@ dependencies = [
|
|||||||
"objc",
|
"objc",
|
||||||
"objc-foundation",
|
"objc-foundation",
|
||||||
"plist",
|
"plist",
|
||||||
"rand 0.8.5",
|
"rand 0.9.2",
|
||||||
"remove-async-await",
|
"remove-async-await",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"thiserror 1.0.69",
|
"thiserror",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
@@ -1564,9 +1622,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-src"
|
name = "openssl-src"
|
||||||
version = "300.5.1+3.5.1"
|
version = "300.5.2+3.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "735230c832b28c000e3bc117119e6466a663ec73506bc0a9907ea4187508e42a"
|
checksum = "d270b79e2926f5150189d475bc7e9d2c69f9c4697b185fa917d5a32b792d21b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
@@ -1637,12 +1695,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkcs7"
|
name = "pkcs7"
|
||||||
version = "0.3.0"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f7364e6d0e236473de91e042395d71e0e64715f99a60620b014a4a4c7d1619b"
|
checksum = "d79178be066405e0602bf3035946edef6b11b3f9dde46dfe5f8bfd7dea4b77e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"der",
|
"der",
|
||||||
"spki",
|
"spki",
|
||||||
|
"x509-cert",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1875,7 +1934,7 @@ dependencies = [
|
|||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2",
|
||||||
"http",
|
"http 0.2.12",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-rustls",
|
"hyper-rustls",
|
||||||
@@ -1889,7 +1948,7 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls 0.21.12",
|
"rustls 0.21.12",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile 1.0.4",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
@@ -1904,25 +1963,10 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"webpki-roots",
|
"webpki-roots 0.25.4",
|
||||||
"winreg",
|
"winreg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ring"
|
|
||||||
version = "0.16.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"spin",
|
|
||||||
"untrusted 0.7.1",
|
|
||||||
"web-sys",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.14"
|
version = "0.17.14"
|
||||||
@@ -1933,7 +1977,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"getrandom 0.2.16",
|
"getrandom 0.2.16",
|
||||||
"libc",
|
"libc",
|
||||||
"untrusted 0.9.0",
|
"untrusted",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1949,6 +1993,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "2.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.44"
|
version = "0.38.44"
|
||||||
@@ -1975,18 +2025,6 @@ dependencies = [
|
|||||||
"windows-sys 0.60.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls"
|
|
||||||
version = "0.20.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99"
|
|
||||||
dependencies = [
|
|
||||||
"log",
|
|
||||||
"ring 0.16.20",
|
|
||||||
"sct",
|
|
||||||
"webpki",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.21.12"
|
version = "0.21.12"
|
||||||
@@ -1994,7 +2032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
|
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring 0.17.14",
|
"ring",
|
||||||
"rustls-webpki 0.101.7",
|
"rustls-webpki 0.101.7",
|
||||||
"sct",
|
"sct",
|
||||||
]
|
]
|
||||||
@@ -2023,6 +2061,15 @@ dependencies = [
|
|||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pki-types"
|
name = "rustls-pki-types"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
@@ -2038,8 +2085,8 @@ version = "0.101.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
|
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring 0.17.14",
|
"ring",
|
||||||
"untrusted 0.9.0",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2049,16 +2096,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc"
|
checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aws-lc-rs",
|
"aws-lc-rs",
|
||||||
"ring 0.17.14",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"untrusted 0.9.0",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.21"
|
version = "1.0.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
@@ -2081,8 +2128,8 @@ version = "0.7.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
|
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring 0.17.14",
|
"ring",
|
||||||
"untrusted 0.9.0",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2188,9 +2235,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.10"
|
version = "0.4.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
|
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
@@ -2218,18 +2265,13 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "spin"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spki"
|
name = "spki"
|
||||||
version = "0.5.4"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27"
|
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
"der",
|
"der",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2237,9 +2279,9 @@ dependencies = [
|
|||||||
name = "srp"
|
name = "srp"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.22.1",
|
||||||
"digest",
|
"digest",
|
||||||
"generic-array",
|
"generic-array 1.2.0",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"subtle",
|
"subtle",
|
||||||
@@ -2335,33 +2377,13 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "1.0.69"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl 1.0.69",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.12"
|
version = "2.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl 2.0.12",
|
"thiserror-impl",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "1.0.69"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.104",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2465,17 +2487,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-tungstenite"
|
name = "tokio-tungstenite"
|
||||||
version = "0.20.1"
|
version = "0.27.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
|
checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
"rustls 0.21.12",
|
"rustls 0.23.31",
|
||||||
|
"rustls-pki-types",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls 0.24.1",
|
"tokio-rustls 0.26.2",
|
||||||
"tungstenite",
|
"tungstenite",
|
||||||
"webpki-roots",
|
"webpki-roots 0.26.11",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2524,21 +2547,20 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tungstenite"
|
name = "tungstenite"
|
||||||
version = "0.20.1"
|
version = "0.27.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9"
|
checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
|
||||||
"bytes",
|
"bytes",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"http",
|
"http 1.3.1",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.8.5",
|
"rand 0.9.2",
|
||||||
"rustls 0.21.12",
|
"rustls 0.23.31",
|
||||||
|
"rustls-pki-types",
|
||||||
"sha1",
|
"sha1",
|
||||||
"thiserror 1.0.69",
|
"thiserror",
|
||||||
"url",
|
|
||||||
"utf-8",
|
"utf-8",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2554,12 +2576,6 @@ version = "1.0.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "untrusted"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@@ -2736,22 +2752,30 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "webpki"
|
|
||||||
version = "0.22.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53"
|
|
||||||
dependencies = [
|
|
||||||
"ring 0.17.14",
|
|
||||||
"untrusted 0.9.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.25.4"
|
version = "0.25.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
|
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "0.26.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
|
||||||
|
dependencies = [
|
||||||
|
"webpki-roots 1.0.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "which"
|
name = "which"
|
||||||
version = "4.4.2"
|
version = "4.4.2"
|
||||||
@@ -3092,6 +3116,17 @@ version = "0.6.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x509-cert"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94"
|
||||||
|
dependencies = [
|
||||||
|
"const-oid",
|
||||||
|
"der",
|
||||||
|
"spki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xmas-elf"
|
name = "xmas-elf"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
@@ -3270,6 +3305,17 @@ dependencies = [
|
|||||||
"simd-adler32",
|
"simd-adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zsign-rust"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9190123f81d18e157f6f3aab47f19b786538b158417f06ee9348c63163b23fca"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen 0.72.0",
|
||||||
|
"cc",
|
||||||
|
"openssl-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd"
|
name = "zstd"
|
||||||
version = "0.13.3"
|
version = "0.13.3"
|
||||||
|
|||||||
@@ -9,13 +9,15 @@ vendored-openssl = ["openssl/vendored"]
|
|||||||
vendored-botan = ["icloud_auth/vendored-botan"]
|
vendored-botan = ["icloud_auth/vendored-botan"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
plist = { version = "1.7.2" }
|
plist = { version = "1.7.2" }
|
||||||
icloud_auth = {path = "./apple-private-apis/icloud-auth" }
|
icloud_auth = {path = "./apple-private-apis/icloud-auth" }
|
||||||
uuid = "1.17.0"
|
uuid = "1.17.0"
|
||||||
zip = "4.3.0"
|
zip = "4.3.0"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
sha1 = "0.10.6"
|
sha1 = "0.10"
|
||||||
idevice = { version = "0.1.37", features = ["afc", "usbmuxd", "installation_proxy"] }
|
idevice = { version = "0.1.37", features = ["afc", "usbmuxd", "installation_proxy"] }
|
||||||
openssl = "0.10.73"
|
openssl = "0.10.73"
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
|
zsign-rust = "0.1"
|
||||||
|
thiserror = "2.0.12"
|
||||||
|
|||||||
@@ -8,27 +8,26 @@ default = []
|
|||||||
vendored-botan = ["botan/vendored"]
|
vendored-botan = ["botan/vendored"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = { version = "1.0.142" }
|
serde_json = { version = "1" }
|
||||||
base64 = "0.13.1"
|
base64 = "0.22"
|
||||||
srp = { version = "0.6.0", path = "./rustcrypto-srp" }
|
srp = { version = "0.6.0", path = "./rustcrypto-srp" }
|
||||||
pbkdf2 = { version = "0.11.0" }
|
pbkdf2 = "0.11"
|
||||||
sha2 = { version = "0.10.6" }
|
sha2 = "0.10"
|
||||||
rand = { version = "0.8.5" }
|
rand = "0.9"
|
||||||
rustls = { version = "0.20.7" }
|
rustls = "0.23"
|
||||||
rustls-pemfile = { version = "1.0.1" }
|
rustls-pemfile = "2.2"
|
||||||
plist = { version = "1.7.2" }
|
plist = "1.7.2"
|
||||||
hmac = "0.12.1"
|
hmac = "0.12.1"
|
||||||
num-bigint = "0.4.3"
|
num-bigint = "0.4.3"
|
||||||
cbc = { version = "0.1.2", features = ["std"] }
|
cbc = { version = "0.1.2", features = ["std"] }
|
||||||
aes = "0.8.2"
|
aes = "0.8.2"
|
||||||
pkcs7 = "0.3.0"
|
pkcs7 = "0.4.1"
|
||||||
reqwest = { version = "0.11.14", features = ["blocking", "json", "default-tls"] }
|
reqwest = { version = "0.11.14", features = ["blocking", "json", "default-tls"] }
|
||||||
omnisette = {path = "../omnisette", features = ["remote-anisette-v3"]}
|
omnisette = {path = "../omnisette", features = ["remote-anisette-v3"]}
|
||||||
thiserror = "1.0.58"
|
thiserror = "2"
|
||||||
tokio = "1"
|
tokio = "1"
|
||||||
botan = { version = "0.11.1" }
|
botan = "0.12.0"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1", features = ["rt", "macros"] }
|
tokio = { version = "1", features = ["rt", "macros"] }
|
||||||
|
|||||||
@@ -14,15 +14,15 @@ rust-version = "1.56"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num-bigint = "0.4"
|
num-bigint = "0.4"
|
||||||
generic-array = "0.14"
|
generic-array = "1"
|
||||||
digest = "0.10"
|
digest = "0.10"
|
||||||
lazy_static = "1.2"
|
lazy_static = "1.2"
|
||||||
subtle = "2.4"
|
subtle = "2.4"
|
||||||
base64 = "0.21.0"
|
base64 = "0.22"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex-literal = "0.3"
|
hex-literal = "1"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
rand = "0.8"
|
rand = "0.9"
|
||||||
sha1 = "0.10.6"
|
sha1 = "0.10"
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10"
|
||||||
|
|||||||
@@ -15,11 +15,7 @@ impl AnisetteData {
|
|||||||
let mut b = AnisetteHeaders::get_anisette_headers_provider(config.clone())?;
|
let mut b = AnisetteHeaders::get_anisette_headers_provider(config.clone())?;
|
||||||
let base_headers = b.provider.get_authentication_headers().await?;
|
let base_headers = b.provider.get_authentication_headers().await?;
|
||||||
|
|
||||||
Ok(AnisetteData {
|
Ok(AnisetteData { base_headers, generated_at: SystemTime::now(), config })
|
||||||
base_headers,
|
|
||||||
generated_at: SystemTime::now(),
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn needs_refresh(&self) -> bool {
|
pub fn needs_refresh(&self) -> bool {
|
||||||
@@ -69,7 +65,7 @@ impl AnisetteData {
|
|||||||
"X-Apple-App-Info".to_owned(),
|
"X-Apple-App-Info".to_owned(),
|
||||||
"com.apple.gs.xcode.auth".to_owned(),
|
"com.apple.gs.xcode.auth".to_owned(),
|
||||||
);
|
);
|
||||||
headers.insert("X-Xcode-Version".to_owned(), "14.2 (14C18)".to_owned());
|
headers.insert("X-Xcode-Version".to_owned(), "11.2 (11B41)".to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
if cpd {
|
if cpd {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::{anisette::AnisetteData, Error};
|
use crate::{anisette::AnisetteData, Error};
|
||||||
use aes::cipher::block_padding::Pkcs7;
|
use aes::cipher::block_padding::Pkcs7;
|
||||||
|
use base64::{engine::general_purpose, Engine};
|
||||||
use botan::Cipher;
|
use botan::Cipher;
|
||||||
use cbc::cipher::{BlockDecryptMut, KeyIvInit};
|
use cbc::cipher::{BlockDecryptMut, KeyIvInit};
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
@@ -269,7 +270,6 @@ impl AppleAccount {
|
|||||||
return Err(err_check.err().unwrap());
|
return Err(err_check.err().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- D code logic starts here ---
|
|
||||||
let encrypted_token = res
|
let encrypted_token = res
|
||||||
.get("et")
|
.get("et")
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse)?
|
||||||
@@ -286,7 +286,7 @@ impl AppleAccount {
|
|||||||
"Encrypted token is in an unknown format.".to_string(),
|
"Encrypted token is in an unknown format.".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let iv = &encrypted_token[3..19]; // 16 bytes
|
let iv = &encrypted_token[3..19];
|
||||||
let ciphertext_and_tag = &encrypted_token[19..];
|
let ciphertext_and_tag = &encrypted_token[19..];
|
||||||
|
|
||||||
if sk.len() != 32 {
|
if sk.len() != 32 {
|
||||||
@@ -296,8 +296,6 @@ impl AppleAccount {
|
|||||||
return Err(Error::Parse);
|
return Err(Error::Parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Botan AES-256/GCM decryption with 16-byte IV and 3-byte AAD
|
|
||||||
// true = encrypt, false = decrypt
|
|
||||||
let mut cipher = Cipher::new("AES-256/GCM", botan::CipherDirection::Decrypt)
|
let mut cipher = Cipher::new("AES-256/GCM", botan::CipherDirection::Decrypt)
|
||||||
.map_err(|_| Error::Parse)?;
|
.map_err(|_| Error::Parse)?;
|
||||||
cipher.set_key(sk).map_err(|_| Error::Parse)?;
|
cipher.set_key(sk).map_err(|_| Error::Parse)?;
|
||||||
@@ -357,14 +355,17 @@ impl AppleAccount {
|
|||||||
///
|
///
|
||||||
/// let anisette = AnisetteData::new();
|
/// let anisette = AnisetteData::new();
|
||||||
/// let account = AppleAccount::login(
|
/// let account = AppleAccount::login(
|
||||||
/// || ("test@waffle.me", "password")
|
/// || Ok(("test@waffle.me", "password"))
|
||||||
/// || "123123",
|
/// || Ok("123123"),
|
||||||
/// anisette
|
/// anisette
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
/// Note: You would not provide the 2FA code like this, you would have to actually ask input for it.
|
/// Note: You would not provide the 2FA code like this, you would have to actually ask input for it.
|
||||||
//TODO: add login_with_anisette and login, where login autodetcts anisette
|
//TODO: add login_with_anisette and login, where login autodetcts anisette
|
||||||
pub async fn login_with_anisette<F: Fn() -> Result<(String, String), String>, G: Fn() -> Result<String, String>>(
|
pub async fn login_with_anisette<
|
||||||
|
F: Fn() -> Result<(String, String), String>,
|
||||||
|
G: Fn() -> Result<String, String>,
|
||||||
|
>(
|
||||||
appleid_closure: F,
|
appleid_closure: F,
|
||||||
tfa_closure: G,
|
tfa_closure: G,
|
||||||
anisette: AnisetteData,
|
anisette: AnisetteData,
|
||||||
@@ -378,15 +379,25 @@ impl AppleAccount {
|
|||||||
match response {
|
match response {
|
||||||
LoginState::NeedsDevice2FA => response = _self.send_2fa_to_devices().await?,
|
LoginState::NeedsDevice2FA => response = _self.send_2fa_to_devices().await?,
|
||||||
LoginState::Needs2FAVerification => {
|
LoginState::Needs2FAVerification => {
|
||||||
response = _self.verify_2fa(tfa_closure().map_err(|e| {
|
response = _self
|
||||||
|
.verify_2fa(tfa_closure().map_err(|e| {
|
||||||
Error::AuthSrpWithMessage(0, format!("Failed to get 2FA code: {}", e))
|
Error::AuthSrpWithMessage(0, format!("Failed to get 2FA code: {}", e))
|
||||||
})?).await?
|
})?)
|
||||||
|
.await?
|
||||||
}
|
}
|
||||||
LoginState::NeedsSMS2FA => response = _self.send_sms_2fa_to_devices(1).await?,
|
LoginState::NeedsSMS2FA => response = _self.send_sms_2fa_to_devices(1).await?,
|
||||||
LoginState::NeedsSMS2FAVerification(body) => {
|
LoginState::NeedsSMS2FAVerification(body) => {
|
||||||
response = _self.verify_sms_2fa(tfa_closure().map_err(|e| {
|
response = _self
|
||||||
Error::AuthSrpWithMessage(0, format!("Failed to get SMS 2FA code: {}", e))
|
.verify_sms_2fa(
|
||||||
})?, body).await?
|
tfa_closure().map_err(|e| {
|
||||||
|
Error::AuthSrpWithMessage(
|
||||||
|
0,
|
||||||
|
format!("Failed to get SMS 2FA code: {}", e),
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
body,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
}
|
}
|
||||||
LoginState::NeedsLogin => {
|
LoginState::NeedsLogin => {
|
||||||
response = _self.login_email_pass(&username, &password).await?
|
response = _self.login_email_pass(&username, &password).await?
|
||||||
@@ -735,7 +746,7 @@ impl AppleAccount {
|
|||||||
let dsid = spd.get("adsid").unwrap().as_string().unwrap();
|
let dsid = spd.get("adsid").unwrap().as_string().unwrap();
|
||||||
let token = spd.get("GsIdmsToken").unwrap().as_string().unwrap();
|
let token = spd.get("GsIdmsToken").unwrap().as_string().unwrap();
|
||||||
|
|
||||||
let identity_token = base64::encode(format!("{}:{}", dsid, token));
|
let identity_token = general_purpose::STANDARD.encode(format!("{}:{}", dsid, token));
|
||||||
|
|
||||||
let valid_anisette = self.get_anisette().await;
|
let valid_anisette = self.get_anisette().await;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
// use icloud_auth::ani
|
use base64::engine::{general_purpose, Engine};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use srp::{
|
use srp::{
|
||||||
client::{SrpClient, SrpClientVerifier},
|
client::{SrpClient, SrpClientVerifier},
|
||||||
@@ -11,15 +8,18 @@ use srp::{
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn auth_debug() {
|
fn auth_debug() {
|
||||||
// not a real account
|
// not a real account
|
||||||
let bytes_a = base64::decode("XChHXELsQ+ljxTFbvRMUsGJxiDIlOh9f8e+JzoegmVcOdAXXtPNzkHpAbAgSjyA+vXrTA93+BUu8EJ9+4xZu9g==").unwrap();
|
let bytes_a = general_purpose::STANDARD.decode("XChHXELsQ+ljxTFbvRMUsGJxiDIlOh9f8e+JzoegmVcOdAXXtPNzkHpAbAgSjyA+vXrTA93+BUu8EJ9+4xZu9g==").unwrap();
|
||||||
let username = "apple3@f1sh.me";
|
let username = "apple3@f1sh.me";
|
||||||
let password = "WaffleTest123";
|
let password = "WaffleTest123";
|
||||||
let salt = base64::decode("6fK6ailLUcp2kJswJVrKjQ==").unwrap();
|
let salt = general_purpose::STANDARD
|
||||||
|
.decode("6fK6ailLUcp2kJswJVrKjQ==")
|
||||||
|
.unwrap();
|
||||||
let iters = 20832;
|
let iters = 20832;
|
||||||
|
|
||||||
let mut password_hasher = sha2::Sha256::new();
|
let mut password_hasher = sha2::Sha256::new();
|
||||||
@@ -41,7 +41,9 @@ mod tests {
|
|||||||
|
|
||||||
// apub: N2XHuh/4P1urPoBvDocF0RCRIl2pliZYqg9p6wGH0nnJdckJPn3M00jEqoM4teqH03HjG1murdcZiNHb5YayufW//+asW01XB7nYIIVvGiUFLRypYITEKYWBQ6h2q02GaZspYJKy98V8Fwcvr0ri+al7zJo1X1aoRKINyjV5TywhhwmTleI1qJkf+JBRYKKqO1XFtOTpQsysWD3ZJdK3K78kSgT3q0kXE3oDRMiHPAO77GFJZErYTuvI6QPRbOgcrn+RKV6AsjR5tUQAoSGRdtibdZTAQijJg788qVg+OFVCNZoY9GYVxa+Ze1bPGdkkgCYicTE8iNFG9KlJ+QpKgQ==
|
// apub: N2XHuh/4P1urPoBvDocF0RCRIl2pliZYqg9p6wGH0nnJdckJPn3M00jEqoM4teqH03HjG1murdcZiNHb5YayufW//+asW01XB7nYIIVvGiUFLRypYITEKYWBQ6h2q02GaZspYJKy98V8Fwcvr0ri+al7zJo1X1aoRKINyjV5TywhhwmTleI1qJkf+JBRYKKqO1XFtOTpQsysWD3ZJdK3K78kSgT3q0kXE3oDRMiHPAO77GFJZErYTuvI6QPRbOgcrn+RKV6AsjR5tUQAoSGRdtibdZTAQijJg788qVg+OFVCNZoY9GYVxa+Ze1bPGdkkgCYicTE8iNFG9KlJ+QpKgQ==
|
||||||
|
|
||||||
let a_random = base64::decode("ywN1O32vmBogb5Fyt9M7Tn8bbzLtDDbcYgPFpSy8n9E=").unwrap();
|
let a_random = general_purpose::STANDARD
|
||||||
|
.decode("ywN1O32vmBogb5Fyt9M7Tn8bbzLtDDbcYgPFpSy8n9E=")
|
||||||
|
.unwrap();
|
||||||
let client = SrpClient::<Sha256>::new(&G_2048);
|
let client = SrpClient::<Sha256>::new(&G_2048);
|
||||||
|
|
||||||
let a_pub_compute =
|
let a_pub_compute =
|
||||||
@@ -49,14 +51,21 @@ mod tests {
|
|||||||
// expect it to be same to a_pub
|
// expect it to be same to a_pub
|
||||||
println!(
|
println!(
|
||||||
"compute a_pub: {:?}",
|
"compute a_pub: {:?}",
|
||||||
base64::encode(&a_pub_compute.to_bytes_be())
|
general_purpose::STANDARD.encode(&a_pub_compute.to_bytes_be())
|
||||||
);
|
);
|
||||||
|
|
||||||
let b_pub = base64::decode("HlWxsRmNi/9DCGxYCoqCTfdSvpbx3mrgFLQfOsgf3Rojn7MQQN/g63PwlBghUcVVB4//yAaRRnz/VIByl8thA9AKuVZl8k52PAHKSh4e7TuXSeYCFr0+GYu8/hFdMDl42219uzSuOXuaKGVKq6hxEAf3n3uXXgQRkXWtLFJ5nn1wq/emf46hYAHzc/pYyvckAdh9WDCw95IXbzKD8LcPw/0ZQoydMuXgW2ZKZ52fiyEs94IZ7L5RLL7jY1nVdwtsp2fxeqiZ3DNmVZ2GdNrbJGT//160tyd2evtUtehr8ygXNzjWdjV0cc4+1F38ywSPFyieVzVTYzDywRllgo3A5A==").unwrap();
|
let b_pub = general_purpose::STANDARD.decode("HlWxsRmNi/9DCGxYCoqCTfdSvpbx3mrgFLQfOsgf3Rojn7MQQN/g63PwlBghUcVVB4//yAaRRnz/VIByl8thA9AKuVZl8k52PAHKSh4e7TuXSeYCFr0+GYu8/hFdMDl42219uzSuOXuaKGVKq6hxEAf3n3uXXgQRkXWtLFJ5nn1wq/emf46hYAHzc/pYyvckAdh9WDCw95IXbzKD8LcPw/0ZQoydMuXgW2ZKZ52fiyEs94IZ7L5RLL7jY1nVdwtsp2fxeqiZ3DNmVZ2GdNrbJGT//160tyd2evtUtehr8ygXNzjWdjV0cc4+1F38ywSPFyieVzVTYzDywRllgo3A5A==").unwrap();
|
||||||
println!("fixed b_pub: {:?}", base64::encode(&b_pub));
|
println!(
|
||||||
|
"fixed b_pub: {:?}",
|
||||||
|
general_purpose::STANDARD.encode(&b_pub)
|
||||||
|
);
|
||||||
println!("");
|
println!("");
|
||||||
|
|
||||||
println!("salt: {:?} iterations: {:?}", base64::encode(&salt), iters);
|
println!(
|
||||||
|
"salt: {:?} iterations: {:?}",
|
||||||
|
general_purpose::STANDARD.encode(&salt),
|
||||||
|
iters
|
||||||
|
);
|
||||||
|
|
||||||
let verifier: SrpClientVerifier<Sha256> = SrpClient::<Sha256>::process_reply(
|
let verifier: SrpClientVerifier<Sha256> = SrpClient::<Sha256>::process_reply(
|
||||||
&client,
|
&client,
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ default = ["remote-anisette", "dep:remove-async-await"]
|
|||||||
remote-anisette-v3 = ["async", "dep:serde", "dep:serde_json", "dep:tokio-tungstenite", "dep:futures-util", "dep:chrono"]
|
remote-anisette-v3 = ["async", "dep:serde", "dep:serde_json", "dep:tokio-tungstenite", "dep:futures-util", "dep:chrono"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.21"
|
base64 = "0.22"
|
||||||
hex = "0.4.3"
|
hex = "0.4"
|
||||||
plist = "1.4"
|
plist = "1.4"
|
||||||
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls", "gzip"] }
|
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls", "gzip"] }
|
||||||
rand = "0.8"
|
rand = "0.9"
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10"
|
||||||
uuid = { version = "1.3", features = [ "v4", "fast-rng", "macro-diagnostics" ] }
|
uuid = { version = "1.3", features = [ "v4", "fast-rng", "macro-diagnostics" ] }
|
||||||
android-loader = { git = "https://github.com/Dadoum/android-loader", branch = "bigger_pages" }
|
android-loader = { git = "https://github.com/Dadoum/android-loader", branch = "bigger_pages" }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
@@ -23,11 +23,11 @@ log = "0.4"
|
|||||||
async-trait = { version = "0.1", optional = true }
|
async-trait = { version = "0.1", optional = true }
|
||||||
remove-async-await = { version = "1.0", optional = true }
|
remove-async-await = { version = "1.0", optional = true }
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||||
serde_json = { version = "1.0.142", optional = true }
|
serde_json = { version = "1.0.115", optional = true }
|
||||||
tokio-tungstenite = { version = "0.20.1", optional = true, features = ["rustls-tls-webpki-roots"] }
|
tokio-tungstenite = { version = "0.27.0", optional = true, features = ["rustls-tls-webpki-roots"] }
|
||||||
futures-util = { version = "0.3.28", optional = true }
|
futures-util = { version = "0.3.28", optional = true }
|
||||||
chrono = { version = "0.4.37", optional = true }
|
chrono = { version = "0.4.37", optional = true }
|
||||||
thiserror = "1.0.58"
|
thiserror = "2"
|
||||||
anyhow = "1.0.81"
|
anyhow = "1.0.81"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub enum ADIError {
|
|||||||
ReqwestError(#[from] reqwest::Error),
|
ReqwestError(#[from] reqwest::Error),
|
||||||
Base64Error(#[from] base64::DecodeError),
|
Base64Error(#[from] base64::DecodeError),
|
||||||
InvalidHeaderValue(#[from] InvalidHeaderValue),
|
InvalidHeaderValue(#[from] InvalidHeaderValue),
|
||||||
IOError(#[from] io::Error)
|
IOError(#[from] io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ADIError {
|
impl ADIError {
|
||||||
@@ -291,7 +291,9 @@ pub struct ADIProxyAnisetteProvider<ProxyType: ADIProxy + 'static> {
|
|||||||
|
|
||||||
impl<ProxyType: ADIProxy + 'static> ADIProxyAnisetteProvider<ProxyType> {
|
impl<ProxyType: ADIProxy + 'static> ADIProxyAnisetteProvider<ProxyType> {
|
||||||
/// If you use this method, you are expected to set the identifier yourself.
|
/// If you use this method, you are expected to set the identifier yourself.
|
||||||
pub fn without_identifier(adi_proxy: ProxyType) -> Result<ADIProxyAnisetteProvider<ProxyType>, ADIError> {
|
pub fn without_identifier(
|
||||||
|
adi_proxy: ProxyType,
|
||||||
|
) -> Result<ADIProxyAnisetteProvider<ProxyType>, ADIError> {
|
||||||
Ok(ADIProxyAnisetteProvider { adi_proxy })
|
Ok(ADIProxyAnisetteProvider { adi_proxy })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +311,7 @@ impl<ProxyType: ADIProxy + 'static> ADIProxyAnisetteProvider<ProxyType> {
|
|||||||
if identifier_file.metadata()?.len() == IDENTIFIER_LENGTH as u64 {
|
if identifier_file.metadata()?.len() == IDENTIFIER_LENGTH as u64 {
|
||||||
identifier_file.read_exact(&mut identifier)?;
|
identifier_file.read_exact(&mut identifier)?;
|
||||||
} else {
|
} else {
|
||||||
rand::thread_rng().fill_bytes(&mut identifier);
|
rand::rng().fill_bytes(&mut identifier);
|
||||||
identifier_file.write_all(&identifier)?;
|
identifier_file.write_all(&identifier)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
use crate::adi_proxy::{ADIProxyAnisetteProvider, ConfigurableADIProxy};
|
use crate::adi_proxy::{ADIProxyAnisetteProvider, ConfigurableADIProxy};
|
||||||
use crate::anisette_headers_provider::AnisetteHeadersProvider;
|
use crate::anisette_headers_provider::AnisetteHeadersProvider;
|
||||||
use adi_proxy::ADIError;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use adi_proxy::ADIError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub mod adi_proxy;
|
pub mod adi_proxy;
|
||||||
@@ -58,7 +58,7 @@ pub enum AnisetteError {
|
|||||||
#[error("Missing Libraries")]
|
#[error("Missing Libraries")]
|
||||||
MissingLibraries,
|
MissingLibraries,
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Anyhow(#[from] anyhow::Error),
|
Anyhow(#[from] anyhow::Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULT_ANISETTE_URL: &str = "https://ani.f1sh.me/";
|
pub const DEFAULT_ANISETTE_URL: &str = "https://ani.f1sh.me/";
|
||||||
@@ -85,7 +85,7 @@ impl AnisetteConfiguration {
|
|||||||
anisette_url: DEFAULT_ANISETTE_URL.to_string(),
|
anisette_url: DEFAULT_ANISETTE_URL.to_string(),
|
||||||
anisette_url_v3: DEFAULT_ANISETTE_URL_V3.to_string(),
|
anisette_url_v3: DEFAULT_ANISETTE_URL_V3.to_string(),
|
||||||
configuration_path: PathBuf::new(),
|
configuration_path: PathBuf::new(),
|
||||||
macos_serial: "0".to_string(),
|
macos_serial: "0".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,15 +157,10 @@ impl AnisetteHeaders {
|
|||||||
|
|
||||||
#[cfg(feature = "remote-anisette-v3")]
|
#[cfg(feature = "remote-anisette-v3")]
|
||||||
return Ok(AnisetteHeadersProviderRes::remote(Box::new(
|
return Ok(AnisetteHeadersProviderRes::remote(Box::new(
|
||||||
remote_anisette_v3::RemoteAnisetteProviderV3::new(
|
remote_anisette_v3::RemoteAnisetteProviderV3::new(configuration.anisette_url_v3, configuration.configuration_path.clone(), configuration.macos_serial.clone()),
|
||||||
configuration.anisette_url_v3,
|
|
||||||
configuration.configuration_path.clone(),
|
|
||||||
configuration.macos_serial.clone(),
|
|
||||||
),
|
|
||||||
)));
|
)));
|
||||||
|
|
||||||
#[cfg(feature = "remote-anisette")]
|
#[cfg(feature = "remote-anisette")]
|
||||||
#[allow(unreachable_code)]
|
|
||||||
return Ok(AnisetteHeadersProviderRes::remote(Box::new(
|
return Ok(AnisetteHeadersProviderRes::remote(Box::new(
|
||||||
remote_anisette::RemoteAnisetteProvider::new(configuration.anisette_url),
|
remote_anisette::RemoteAnisetteProvider::new(configuration.anisette_url),
|
||||||
)));
|
)));
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ pub struct AnisetteState {
|
|||||||
impl Default for AnisetteState {
|
impl Default for AnisetteState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
AnisetteState {
|
AnisetteState {
|
||||||
keychain_identifier: rand::thread_rng().gen::<[u8; 16]>(),
|
keychain_identifier: rand::rng().random::<[u8; 16]>(),
|
||||||
adi_pb: None,
|
adi_pb: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ impl AnisetteClient {
|
|||||||
.header("X-Apple-I-MD-LU", encode_hex(&state.md_lu()))
|
.header("X-Apple-I-MD-LU", encode_hex(&state.md_lu()))
|
||||||
.header("X-Mme-Device-Id", state.device_id())
|
.header("X-Mme-Device-Id", state.device_id())
|
||||||
.header("X-Apple-I-Client-Time", dt.format("%+").to_string())
|
.header("X-Apple-I-Client-Time", dt.format("%+").to_string())
|
||||||
.header("X-Apple-I-TimeZone", "EDT")
|
.header("X-Apple-I-TimeZone", "UTC")
|
||||||
.header("X-Apple-Locale", "en_US")
|
.header("X-Apple-Locale", "en_US")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +352,7 @@ impl AnisetteClient {
|
|||||||
identifier: base64_encode(&state.keychain_identifier),
|
identifier: base64_encode(&state.keychain_identifier),
|
||||||
};
|
};
|
||||||
connection
|
connection
|
||||||
.send(Message::Text(serde_json::to_string(&identifier)?))
|
.send(Message::Text(serde_json::to_string(&identifier)?.into()))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
ProvisionInput::GiveStartProvisioningData => {
|
ProvisionInput::GiveStartProvisioningData => {
|
||||||
@@ -390,7 +390,7 @@ impl AnisetteClient {
|
|||||||
spim: spim.to_string(),
|
spim: spim.to_string(),
|
||||||
};
|
};
|
||||||
connection
|
connection
|
||||||
.send(Message::Text(serde_json::to_string(&spim)?))
|
.send(Message::Text(serde_json::to_string(&spim)?.into()))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
ProvisionInput::GiveEndProvisioningData { cpim } => {
|
ProvisionInput::GiveEndProvisioningData { cpim } => {
|
||||||
@@ -427,7 +427,9 @@ impl AnisetteClient {
|
|||||||
tk: response.get("tk").unwrap().as_string().unwrap(),
|
tk: response.get("tk").unwrap().as_string().unwrap(),
|
||||||
};
|
};
|
||||||
connection
|
connection
|
||||||
.send(Message::Text(serde_json::to_string(&end_provisioning)?))
|
.send(Message::Text(
|
||||||
|
serde_json::to_string(&end_provisioning)?.into(),
|
||||||
|
))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
ProvisionInput::ProvisioningSuccess { adi_pb } => {
|
ProvisionInput::ProvisioningSuccess { adi_pb } => {
|
||||||
|
|||||||
@@ -66,11 +66,16 @@ pub struct StoreServicesCoreADIProxy<'lt> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StoreServicesCoreADIProxy<'_> {
|
impl StoreServicesCoreADIProxy<'_> {
|
||||||
pub fn new<'lt>(library_path: &PathBuf) -> Result<StoreServicesCoreADIProxy<'lt>, AnisetteError> {
|
pub fn new<'lt>(
|
||||||
|
library_path: &PathBuf,
|
||||||
|
) -> Result<StoreServicesCoreADIProxy<'lt>, AnisetteError> {
|
||||||
Self::with_custom_provisioning_path(library_path, library_path)
|
Self::with_custom_provisioning_path(library_path, library_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_custom_provisioning_path<'lt>(library_path: &PathBuf, provisioning_path: &PathBuf) -> Result<StoreServicesCoreADIProxy<'lt>, AnisetteError> {
|
pub fn with_custom_provisioning_path<'lt>(
|
||||||
|
library_path: &PathBuf,
|
||||||
|
provisioning_path: &PathBuf,
|
||||||
|
) -> Result<StoreServicesCoreADIProxy<'lt>, AnisetteError> {
|
||||||
// Should be safe if the library is correct.
|
// Should be safe if the library is correct.
|
||||||
unsafe {
|
unsafe {
|
||||||
LoaderHelpers::setup_hooks();
|
LoaderHelpers::setup_hooks();
|
||||||
@@ -104,12 +109,8 @@ impl StoreServicesCoreADIProxy<'_> {
|
|||||||
.ok_or(AnisetteError::InvalidLibraryFormat)?,
|
.ok_or(AnisetteError::InvalidLibraryFormat)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
let path = CString::new(
|
let path =
|
||||||
native_library_path
|
CString::new(native_library_path.to_str().ok_or(AnisetteError::Misc)?).unwrap();
|
||||||
.to_str()
|
|
||||||
.ok_or(AnisetteError::Misc)?,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!((adi_load_library_with_path)(path.as_ptr() as *const u8), 0);
|
assert_eq!((adi_load_library_with_path)(path.as_ptr() as *const u8), 0);
|
||||||
|
|
||||||
let adi_set_android_id = store_services_core
|
let adi_set_android_id = store_services_core
|
||||||
@@ -163,9 +164,7 @@ impl StoreServicesCoreADIProxy<'_> {
|
|||||||
adi_otp_request: std::mem::transmute(adi_otp_request),
|
adi_otp_request: std::mem::transmute(adi_otp_request),
|
||||||
};
|
};
|
||||||
|
|
||||||
proxy.set_provisioning_path(
|
proxy.set_provisioning_path(provisioning_path.to_str().ok_or(AnisetteError::Misc)?)?;
|
||||||
provisioning_path.to_str().ok_or(AnisetteError::Misc)?,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(proxy)
|
Ok(proxy)
|
||||||
}
|
}
|
||||||
@@ -370,7 +369,7 @@ unsafe fn __errno_location() -> *mut i32 {
|
|||||||
|
|
||||||
#[sysv64]
|
#[sysv64]
|
||||||
fn arc4random() -> u32 {
|
fn arc4random() -> u32 {
|
||||||
rand::thread_rng().gen()
|
rand::rng().random()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[sysv64]
|
#[sysv64]
|
||||||
@@ -412,10 +411,10 @@ impl LoaderHelpers {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::AnisetteError;
|
||||||
use crate::{AnisetteConfiguration, AnisetteHeaders};
|
use crate::{AnisetteConfiguration, AnisetteHeaders};
|
||||||
use log::info;
|
use log::info;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use crate::AnisetteError;
|
|
||||||
|
|
||||||
#[cfg(not(feature = "async"))]
|
#[cfg(not(feature = "async"))]
|
||||||
#[test]
|
#[test]
|
||||||
@@ -436,7 +435,6 @@ mod tests {
|
|||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn fetch_anisette_ssc_async() -> Result<(), AnisetteError> {
|
async fn fetch_anisette_ssc_async() -> Result<(), AnisetteError> {
|
||||||
|
|
||||||
crate::tests::init_logger();
|
crate::tests::init_logger();
|
||||||
|
|
||||||
let mut provider = AnisetteHeaders::get_ssc_anisette_headers_provider(
|
let mut provider = AnisetteHeaders::get_ssc_anisette_headers_provider(
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ impl CertificateIdentity {
|
|||||||
let hash_string = hex::encode(hasher.finalize()).to_lowercase();
|
let hash_string = hex::encode(hasher.finalize()).to_lowercase();
|
||||||
let key_path = configuration_path.join("keys").join(hash_string);
|
let key_path = configuration_path.join("keys").join(hash_string);
|
||||||
fs::create_dir_all(&key_path)
|
fs::create_dir_all(&key_path)
|
||||||
.map_err(|e| Error::Certificate(format!("Failed to create key directory: {}", e)))?;
|
.map_err(|e| Error::Filesystem(format!("Failed to create key directory: {}", e)))?;
|
||||||
|
|
||||||
let key_file = key_path.join("key.pem");
|
let key_file = key_path.join("key.pem");
|
||||||
let cert_file = key_path.join("cert.pem");
|
let cert_file = key_path.join("cert.pem");
|
||||||
@@ -54,7 +54,7 @@ impl CertificateIdentity {
|
|||||||
.private_key_to_pem_pkcs8()
|
.private_key_to_pem_pkcs8()
|
||||||
.map_err(|e| Error::Certificate(format!("Failed to encode private key: {}", e)))?;
|
.map_err(|e| Error::Certificate(format!("Failed to encode private key: {}", e)))?;
|
||||||
fs::write(&key_file, pem_data)
|
fs::write(&key_file, pem_data)
|
||||||
.map_err(|e| Error::Certificate(format!("Failed to save key file: {}", e)))?;
|
.map_err(|e| Error::Filesystem(format!("Failed to save key file: {}", e)))?;
|
||||||
key
|
key
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ impl CertificateIdentity {
|
|||||||
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
|
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
|
||||||
})?;
|
})?;
|
||||||
fs::write(&cert_identity.cert_file, cert_pem).map_err(|e| {
|
fs::write(&cert_identity.cert_file, cert_pem).map_err(|e| {
|
||||||
Error::Certificate(format!("Failed to save certificate file: {}", e))
|
Error::Filesystem(format!("Failed to save certificate file: {}", e))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
return Ok(cert_identity);
|
return Ok(cert_identity);
|
||||||
@@ -200,7 +200,7 @@ impl CertificateIdentity {
|
|||||||
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
|
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
|
||||||
})?;
|
})?;
|
||||||
fs::write(&self.cert_file, cert_pem)
|
fs::write(&self.cert_file, cert_pem)
|
||||||
.map_err(|e| Error::Certificate(format!("Failed to save certificate file: {}", e)))?;
|
.map_err(|e| Error::Filesystem(format!("Failed to save certificate file: {}", e)))?;
|
||||||
|
|
||||||
self.certificate = Some(certificate);
|
self.certificate = Some(certificate);
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ impl DeveloperSession {
|
|||||||
if let ICloudError::AuthSrpWithMessage(code, message) = e {
|
if let ICloudError::AuthSrpWithMessage(code, message) = e {
|
||||||
Error::DeveloperSession(code, format!("Developer request failed: {}", message))
|
Error::DeveloperSession(code, format!("Developer request failed: {}", message))
|
||||||
} else {
|
} else {
|
||||||
Error::Generic
|
Error::Generic("Failed to send developer request".to_string())
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -85,20 +85,22 @@ impl DeveloperSession {
|
|||||||
let teams = response
|
let teams = response
|
||||||
.get("teams")
|
.get("teams")
|
||||||
.and_then(|v| v.as_array())
|
.and_then(|v| v.as_array())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("teams".to_string()))?;
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for team in teams {
|
for team in teams {
|
||||||
let dict = team.as_dictionary().ok_or(Error::Parse)?;
|
let dict = team
|
||||||
|
.as_dictionary()
|
||||||
|
.ok_or(Error::Parse("team".to_string()))?;
|
||||||
let name = dict
|
let name = dict
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("name".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let team_id = dict
|
let team_id = dict
|
||||||
.get("teamId")
|
.get("teamId")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("teamId".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
result.push(DeveloperTeam {
|
result.push(DeveloperTeam {
|
||||||
_name: name,
|
_name: name,
|
||||||
@@ -140,25 +142,27 @@ impl DeveloperSession {
|
|||||||
let devices = response
|
let devices = response
|
||||||
.get("devices")
|
.get("devices")
|
||||||
.and_then(|v| v.as_array())
|
.and_then(|v| v.as_array())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("devices".to_string()))?;
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for device in devices {
|
for device in devices {
|
||||||
let dict = device.as_dictionary().ok_or(Error::Parse)?;
|
let dict = device
|
||||||
|
.as_dictionary()
|
||||||
|
.ok_or(Error::Parse("device".to_string()))?;
|
||||||
let device_id = dict
|
let device_id = dict
|
||||||
.get("deviceId")
|
.get("deviceId")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("deviceId".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let name = dict
|
let name = dict
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("name".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let device_number = dict
|
let device_number = dict
|
||||||
.get("deviceNumber")
|
.get("deviceNumber")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("deviceNumber".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
result.push(DeveloperDevice {
|
result.push(DeveloperDevice {
|
||||||
_device_id: device_id,
|
_device_id: device_id,
|
||||||
@@ -187,22 +191,22 @@ impl DeveloperSession {
|
|||||||
let device_dict = response
|
let device_dict = response
|
||||||
.get("device")
|
.get("device")
|
||||||
.and_then(|v| v.as_dictionary())
|
.and_then(|v| v.as_dictionary())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("device".to_string()))?;
|
||||||
|
|
||||||
let device_id = device_dict
|
let device_id = device_dict
|
||||||
.get("deviceId")
|
.get("deviceId")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("deviceId".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let name = device_dict
|
let name = device_dict
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("name".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let device_number = device_dict
|
let device_number = device_dict
|
||||||
.get("deviceNumber")
|
.get("deviceNumber")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("deviceNumber".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
Ok(DeveloperDevice {
|
Ok(DeveloperDevice {
|
||||||
@@ -226,25 +230,27 @@ impl DeveloperSession {
|
|||||||
let certs = response
|
let certs = response
|
||||||
.get("certificates")
|
.get("certificates")
|
||||||
.and_then(|v| v.as_array())
|
.and_then(|v| v.as_array())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("certificates".to_string()))?;
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for cert in certs {
|
for cert in certs {
|
||||||
let dict = cert.as_dictionary().ok_or(Error::Parse)?;
|
let dict = cert
|
||||||
|
.as_dictionary()
|
||||||
|
.ok_or(Error::Parse("certificate".to_string()))?;
|
||||||
let name = dict
|
let name = dict
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("name".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let certificate_id = dict
|
let certificate_id = dict
|
||||||
.get("certificateId")
|
.get("certificateId")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("certificateId".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let serial_number = dict
|
let serial_number = dict
|
||||||
.get("serialNumber")
|
.get("serialNumber")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("serialNumber".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let machine_name = dict
|
let machine_name = dict
|
||||||
.get("machineName")
|
.get("machineName")
|
||||||
@@ -254,7 +260,7 @@ impl DeveloperSession {
|
|||||||
let cert_content = dict
|
let cert_content = dict
|
||||||
.get("certContent")
|
.get("certContent")
|
||||||
.and_then(|v| v.as_data())
|
.and_then(|v| v.as_data())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("certContent".to_string()))?
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
result.push(DevelopmentCertificate {
|
result.push(DevelopmentCertificate {
|
||||||
@@ -309,11 +315,11 @@ impl DeveloperSession {
|
|||||||
let cert_dict = response
|
let cert_dict = response
|
||||||
.get("certRequest")
|
.get("certRequest")
|
||||||
.and_then(|v| v.as_dictionary())
|
.and_then(|v| v.as_dictionary())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("certRequest".to_string()))?;
|
||||||
let id = cert_dict
|
let id = cert_dict
|
||||||
.get("certRequestId")
|
.get("certRequestId")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("certRequestId".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
@@ -333,35 +339,37 @@ impl DeveloperSession {
|
|||||||
let app_ids = response
|
let app_ids = response
|
||||||
.get("appIds")
|
.get("appIds")
|
||||||
.and_then(|v| v.as_array())
|
.and_then(|v| v.as_array())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("appIds".to_string()))?;
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for app_id in app_ids {
|
for app_id in app_ids {
|
||||||
let dict = app_id.as_dictionary().ok_or(Error::Parse)?;
|
let dict = app_id
|
||||||
|
.as_dictionary()
|
||||||
|
.ok_or(Error::Parse("appId".to_string()))?;
|
||||||
let name = dict
|
let name = dict
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("name".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let app_id_id = dict
|
let app_id_id = dict
|
||||||
.get("appIdId")
|
.get("appIdId")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("appIdId".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let identifier = dict
|
let identifier = dict
|
||||||
.get("identifier")
|
.get("identifier")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("identifier".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let features = dict
|
let features = dict
|
||||||
.get("features")
|
.get("features")
|
||||||
.and_then(|v| v.as_dictionary())
|
.and_then(|v| v.as_dictionary())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("features".to_string()))?;
|
||||||
let expiration_date = if dict.contains_key("expirationDate") {
|
let expiration_date = if dict.contains_key("expirationDate") {
|
||||||
Some(
|
Some(
|
||||||
dict.get("expirationDate")
|
dict.get("expirationDate")
|
||||||
.and_then(|v| v.as_date())
|
.and_then(|v| v.as_date())
|
||||||
.ok_or(Error::Parse)?,
|
.ok_or(Error::Parse("expirationDate".to_string()))?,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -379,11 +387,11 @@ impl DeveloperSession {
|
|||||||
let max_quantity = response
|
let max_quantity = response
|
||||||
.get("maxQuantity")
|
.get("maxQuantity")
|
||||||
.and_then(|v| v.as_unsigned_integer())
|
.and_then(|v| v.as_unsigned_integer())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("maxQuantity".to_string()))?;
|
||||||
let available_quantity = response
|
let available_quantity = response
|
||||||
.get("availableQuantity")
|
.get("availableQuantity")
|
||||||
.and_then(|v| v.as_unsigned_integer())
|
.and_then(|v| v.as_unsigned_integer())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("availableQuantity".to_string()))?;
|
||||||
|
|
||||||
Ok(ListAppIdsResponse {
|
Ok(ListAppIdsResponse {
|
||||||
app_ids: result,
|
app_ids: result,
|
||||||
@@ -436,11 +444,11 @@ impl DeveloperSession {
|
|||||||
let cert_dict = response
|
let cert_dict = response
|
||||||
.get("appId")
|
.get("appId")
|
||||||
.and_then(|v| v.as_dictionary())
|
.and_then(|v| v.as_dictionary())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("appId".to_string()))?;
|
||||||
let feats = cert_dict
|
let feats = cert_dict
|
||||||
.get("features")
|
.get("features")
|
||||||
.and_then(|v| v.as_dictionary())
|
.and_then(|v| v.as_dictionary())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("features".to_string()))?;
|
||||||
|
|
||||||
Ok(feats.clone())
|
Ok(feats.clone())
|
||||||
}
|
}
|
||||||
@@ -475,25 +483,27 @@ impl DeveloperSession {
|
|||||||
let app_groups = response
|
let app_groups = response
|
||||||
.get("applicationGroupList")
|
.get("applicationGroupList")
|
||||||
.and_then(|v| v.as_array())
|
.and_then(|v| v.as_array())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("applicationGroupList".to_string()))?;
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for app_group in app_groups {
|
for app_group in app_groups {
|
||||||
let dict = app_group.as_dictionary().ok_or(Error::Parse)?;
|
let dict = app_group
|
||||||
|
.as_dictionary()
|
||||||
|
.ok_or(Error::Parse("applicationGroup".to_string()))?;
|
||||||
let application_group = dict
|
let application_group = dict
|
||||||
.get("applicationGroup")
|
.get("applicationGroup")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("applicationGroup".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let name = dict
|
let name = dict
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("name".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let identifier = dict
|
let identifier = dict
|
||||||
.get("identifier")
|
.get("identifier")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("identifier".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
result.push(ApplicationGroup {
|
result.push(ApplicationGroup {
|
||||||
@@ -526,21 +536,21 @@ impl DeveloperSession {
|
|||||||
let app_group_dict = response
|
let app_group_dict = response
|
||||||
.get("applicationGroup")
|
.get("applicationGroup")
|
||||||
.and_then(|v| v.as_dictionary())
|
.and_then(|v| v.as_dictionary())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("applicationGroup".to_string()))?;
|
||||||
let application_group = app_group_dict
|
let application_group = app_group_dict
|
||||||
.get("applicationGroup")
|
.get("applicationGroup")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("applicationGroup".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let name = app_group_dict
|
let name = app_group_dict
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("name".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let identifier = app_group_dict
|
let identifier = app_group_dict
|
||||||
.get("identifier")
|
.get("identifier")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("identifier".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
Ok(ApplicationGroup {
|
Ok(ApplicationGroup {
|
||||||
@@ -593,21 +603,21 @@ impl DeveloperSession {
|
|||||||
let profile = response
|
let profile = response
|
||||||
.get("provisioningProfile")
|
.get("provisioningProfile")
|
||||||
.and_then(|v| v.as_dictionary())
|
.and_then(|v| v.as_dictionary())
|
||||||
.ok_or(Error::Parse)?;
|
.ok_or(Error::Parse("provisioningProfile".to_string()))?;
|
||||||
let name = profile
|
let name = profile
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("name".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let provisioning_profile_id = profile
|
let provisioning_profile_id = profile
|
||||||
.get("provisioningProfileId")
|
.get("provisioningProfileId")
|
||||||
.and_then(|v| v.as_string())
|
.and_then(|v| v.as_string())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("provisioningProfileId".to_string()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let encoded_profile = profile
|
let encoded_profile = profile
|
||||||
.get("encodedProfile")
|
.get("encodedProfile")
|
||||||
.and_then(|v| v.as_data())
|
.and_then(|v| v.as_data())
|
||||||
.ok_or(Error::Parse)?
|
.ok_or(Error::Parse("encodedProfile".to_string()))?
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
Ok(ProvisioningProfile {
|
Ok(ProvisioningProfile {
|
||||||
|
|||||||
33
src/lib.rs
33
src/lib.rs
@@ -10,12 +10,39 @@ pub use developer_session::{
|
|||||||
DevelopmentCertificate, ListAppIdsResponse, ProvisioningProfile,
|
DevelopmentCertificate, ListAppIdsResponse, ProvisioningProfile,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, ThisError)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("Authentication error {0}: {1}")]
|
||||||
Auth(i64, String),
|
Auth(i64, String),
|
||||||
|
#[error("Developer session error {0}: {1}")]
|
||||||
DeveloperSession(i64, String),
|
DeveloperSession(i64, String),
|
||||||
Generic,
|
#[error("Error: {0}")]
|
||||||
Parse,
|
Generic(String),
|
||||||
|
#[error("Failed to parse: {0}")]
|
||||||
|
Parse(String),
|
||||||
|
#[error("Invalid bundle: {0}")]
|
||||||
InvalidBundle(String),
|
InvalidBundle(String),
|
||||||
|
#[error("Certificate error: {0}")]
|
||||||
Certificate(String),
|
Certificate(String),
|
||||||
|
#[error("Failed to use files: {0}")]
|
||||||
|
Filesystem(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SideloadLogger {
|
||||||
|
async fn log(&self, message: &str);
|
||||||
|
async fn error(&self, error: &Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DefaultLogger;
|
||||||
|
|
||||||
|
impl SideloadLogger for DefaultLogger {
|
||||||
|
async fn log(&self, message: &str) {
|
||||||
|
println!("{message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn error(&self, error: &Error) {
|
||||||
|
eprintln!("Error: {}", error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
209
src/sideload.rs
209
src/sideload.rs
@@ -1,85 +1,81 @@
|
|||||||
// This file was made using https://github.com/Dadoum/Sideloader as a reference.
|
// This file was made using https://github.com/Dadoum/Sideloader as a reference.
|
||||||
|
|
||||||
use crate::Error;
|
use zsign_rust::ZSignOptions;
|
||||||
|
|
||||||
|
use crate::application::Application;
|
||||||
|
use crate::{Error, SideloadLogger};
|
||||||
use crate::{
|
use crate::{
|
||||||
certificate::CertificateIdentity,
|
certificate::CertificateIdentity,
|
||||||
developer_session::DeveloperDeviceType,
|
developer_session::{DeveloperDeviceType, DeveloperSession},
|
||||||
device::{DeviceInfo, install_app},
|
device::{DeviceInfo, install_app},
|
||||||
};
|
};
|
||||||
use std::{io::Write, path::PathBuf};
|
use std::{io::Write, path::PathBuf};
|
||||||
|
|
||||||
|
fn error_and_return(logger: &impl SideloadLogger, error: Error) -> Result<(), Error> {
|
||||||
|
logger.error(&error);
|
||||||
|
Err(error)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn sideload_app(
|
pub async fn sideload_app(
|
||||||
handle: &tauri::AppHandle,
|
logger: impl SideloadLogger,
|
||||||
window: &tauri::Window,
|
dev_session: &DeveloperSession,
|
||||||
anisette_server: String,
|
device: &DeviceInfo,
|
||||||
device: DeviceInfo,
|
|
||||||
app_path: PathBuf,
|
app_path: PathBuf,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if device.uuid.is_empty() {
|
if device.uuid.is_empty() {
|
||||||
return emit_error_and_return(window, "No device selected");
|
return error_and_return(&logger, Error::Generic("No device selected".to_string()));
|
||||||
}
|
}
|
||||||
let dev_session = match crate::sideloader::apple::get_developer_session(
|
|
||||||
&handle,
|
|
||||||
window,
|
|
||||||
anisette_server.clone(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(acc) => acc,
|
|
||||||
Err(e) => {
|
|
||||||
return emit_error_and_return(
|
|
||||||
window,
|
|
||||||
&format!("Failed to login to Apple account: {:?}", e),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let team = match dev_session.get_team().await {
|
let team = match dev_session.get_team().await {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return emit_error_and_return(window, &format!("Failed to get team: {:?}", e));
|
return error_and_return(&logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window
|
|
||||||
.emit("build-output", "Successfully retrieved team".to_string())
|
logger.log("Successfully retrieved team");
|
||||||
.ok();
|
|
||||||
ensure_device_registered(&dev_session, window, &team, &device).await?;
|
ensure_device_registered(&dev_session, window, &team, &device).await?;
|
||||||
|
|
||||||
let config_dir = handle.path().app_config_dir().map_err(|e| e.to_string())?;
|
let config_dir = handle.path().app_config_dir().map_err(|e| e.to_string())?;
|
||||||
let cert = match CertificateIdentity::new(config_dir, &dev_session, get_apple_email()).await {
|
let cert = match CertificateIdentity::new(config_dir, &dev_session, get_apple_email()).await {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return emit_error_and_return(window, &format!("Failed to get certificate: {:?}", e));
|
return error_and_return(&logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window
|
|
||||||
.emit(
|
logger.log("Successfully acquired certificate");
|
||||||
"build-output",
|
|
||||||
"Certificate acquired succesfully".to_string(),
|
|
||||||
)
|
|
||||||
.ok();
|
|
||||||
let mut list_app_id_response = match dev_session
|
let mut list_app_id_response = match dev_session
|
||||||
.list_app_ids(DeveloperDeviceType::Ios, &team)
|
.list_app_ids(DeveloperDeviceType::Ios, &team)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(ids) => ids,
|
Ok(ids) => ids,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return emit_error_and_return(window, &format!("Failed to list app IDs: {:?}", e));
|
return error_and_return(&logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut app = crate::sideloader::application::Application::new(app_path);
|
let mut app = Application::new(app_path);
|
||||||
let is_sidestore = app.bundle.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore";
|
let is_sidestore = app.bundle.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore";
|
||||||
let main_app_bundle_id = match app.bundle.bundle_identifier() {
|
let main_app_bundle_id = match app.bundle.bundle_identifier() {
|
||||||
Some(id) => id.to_string(),
|
Some(id) => id.to_string(),
|
||||||
None => {
|
None => {
|
||||||
return emit_error_and_return(window, "No bundle identifier found in IPA");
|
return error_and_return(
|
||||||
|
&logger,
|
||||||
|
Error::InvalidBundle("No bundle identifier found in IPA".to_string()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let main_app_id_str = format!("{}.{}", main_app_bundle_id, team.team_id);
|
let main_app_id_str = format!("{}.{}", main_app_bundle_id, team.team_id);
|
||||||
let main_app_name = match app.bundle.bundle_name() {
|
let main_app_name = match app.bundle.bundle_name() {
|
||||||
Some(name) => name.to_string(),
|
Some(name) => name.to_string(),
|
||||||
None => {
|
None => {
|
||||||
return emit_error_and_return(window, "No bundle name found in IPA");
|
return error_and_return(
|
||||||
|
&logger,
|
||||||
|
Error::InvalidBundle("No bundle name found in IPA".to_string()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,13 +84,13 @@ pub async fn sideload_app(
|
|||||||
for ext in extensions.iter_mut() {
|
for ext in extensions.iter_mut() {
|
||||||
if let Some(id) = ext.bundle_identifier() {
|
if let Some(id) = ext.bundle_identifier() {
|
||||||
if !(id.starts_with(&main_app_bundle_id) && id.len() > main_app_bundle_id.len()) {
|
if !(id.starts_with(&main_app_bundle_id) && id.len() > main_app_bundle_id.len()) {
|
||||||
return emit_error_and_return(
|
return error_and_return(
|
||||||
window,
|
&logger,
|
||||||
&format!(
|
Error::InvalidBundle(format!(
|
||||||
"Extension {} is not part of the main app bundle identifier: {}",
|
"Extension {} is not part of the main app bundle identifier: {}",
|
||||||
ext.bundle_name().unwrap_or("Unknown"),
|
ext.bundle_name().unwrap_or("Unknown"),
|
||||||
id
|
id
|
||||||
),
|
)),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
ext.set_bundle_identifier(&format!(
|
ext.set_bundle_identifier(&format!(
|
||||||
@@ -123,13 +119,13 @@ pub async fn sideload_app(
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if app_ids_to_register.len() > list_app_id_response.available_quantity.try_into().unwrap() {
|
if app_ids_to_register.len() > list_app_id_response.available_quantity.try_into().unwrap() {
|
||||||
return emit_error_and_return(
|
return error_and_return(
|
||||||
window,
|
&logger,
|
||||||
&format!(
|
Error::InvalidBundle(format!(
|
||||||
"This app requires {} app ids, but you only have {} available",
|
"This app requires {} app ids, but you only have {} available",
|
||||||
app_ids_to_register.len(),
|
app_ids_to_register.len(),
|
||||||
list_app_id_response.available_quantity
|
list_app_id_response.available_quantity
|
||||||
),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +136,7 @@ pub async fn sideload_app(
|
|||||||
.add_app_id(DeveloperDeviceType::Ios, &team, &name, &id)
|
.add_app_id(DeveloperDeviceType::Ios, &team, &name, &id)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
return emit_error_and_return(window, &format!("Failed to register app ID: {:?}", e));
|
return error_and_return(&logger, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_app_id_response = match dev_session
|
list_app_id_response = match dev_session
|
||||||
@@ -149,7 +145,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(ids) => ids,
|
Ok(ids) => ids,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return emit_error_and_return(window, &format!("Failed to list app IDs: {:?}", e));
|
return error_and_return(&logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -169,19 +165,17 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => {
|
None => {
|
||||||
return emit_error_and_return(
|
return error_and_return(
|
||||||
window,
|
&logger,
|
||||||
&format!(
|
Error::Generic(format!(
|
||||||
"Main app ID {} not found in registered app IDs",
|
"Main app ID {} not found in registered app IDs",
|
||||||
main_app_id_str
|
main_app_id_str
|
||||||
),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window
|
logger.log("Successfully registered app IDs");
|
||||||
.emit("build-output", "Registered app IDs".to_string())
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
for app_id in app_ids.iter_mut() {
|
for app_id in app_ids.iter_mut() {
|
||||||
let app_group_feature_enabled = app_id
|
let app_group_feature_enabled = app_id
|
||||||
@@ -190,7 +184,9 @@ pub async fn sideload_app(
|
|||||||
"APG3427HIY", /* Gotta love apple and their magic strings! */
|
"APG3427HIY", /* Gotta love apple and their magic strings! */
|
||||||
)
|
)
|
||||||
.and_then(|v| v.as_boolean())
|
.and_then(|v| v.as_boolean())
|
||||||
.ok_or("App group feature not found in app id")?;
|
.ok_or(Error::Generic(
|
||||||
|
"App group feature not found in app id".to_string(),
|
||||||
|
))?;
|
||||||
if !app_group_feature_enabled {
|
if !app_group_feature_enabled {
|
||||||
let mut body = plist::Dictionary::new();
|
let mut body = plist::Dictionary::new();
|
||||||
body.insert("APG3427HIY".to_string(), plist::Value::Boolean(true));
|
body.insert("APG3427HIY".to_string(), plist::Value::Boolean(true));
|
||||||
@@ -200,10 +196,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(new_feats) => new_feats,
|
Ok(new_feats) => new_feats,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return emit_error_and_return(
|
return error_and_return(&logger, e);
|
||||||
window,
|
|
||||||
&format!("Failed to update app ID features: {:?}", e),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
app_id.features = new_features;
|
app_id.features = new_features;
|
||||||
@@ -225,7 +218,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(groups) => groups,
|
Ok(groups) => groups,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return emit_error_and_return(window, &format!("Failed to list app groups: {:?}", e));
|
return error_and_return(&logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -246,10 +239,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(group) => group,
|
Ok(group) => group,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return emit_error_and_return(
|
return error_and_return(&logger, e);
|
||||||
window,
|
|
||||||
&format!("Failed to register app group: {:?}", e),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -267,13 +257,7 @@ pub async fn sideload_app(
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
if assign_res.is_err() {
|
if assign_res.is_err() {
|
||||||
return emit_error_and_return(
|
return error_and_return(&logger, assign_res.err().unwrap());
|
||||||
window,
|
|
||||||
&format!(
|
|
||||||
"Failed to assign app group to app ID: {:?}",
|
|
||||||
assign_res.err()
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// let provisioning_profile = match account
|
// let provisioning_profile = match account
|
||||||
// // This doesn't seem right to me, but it's what Sideloader does... Shouldn't it be downloading the provisioning profile for this app ID, not the main?
|
// // This doesn't seem right to me, but it's what Sideloader does... Shouldn't it be downloading the provisioning profile for this app ID, not the main?
|
||||||
@@ -291,9 +275,7 @@ pub async fn sideload_app(
|
|||||||
// provisioning_profiles.insert(app_id.identifier.clone(), provisioning_profile);
|
// provisioning_profiles.insert(app_id.identifier.clone(), provisioning_profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
window
|
logger.log("Successfully registered app groups");
|
||||||
.emit("build-output", "Registered app groups".to_string())
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
let provisioning_profile = match dev_session
|
let provisioning_profile = match dev_session
|
||||||
.download_team_provisioning_profile(DeveloperDeviceType::Ios, &team, &main_app_id)
|
.download_team_provisioning_profile(DeveloperDeviceType::Ios, &team, &main_app_id)
|
||||||
@@ -301,10 +283,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(pp /* tee hee */) => pp,
|
Ok(pp /* tee hee */) => pp,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return emit_error_and_return(
|
return error_and_return(&logger, e);
|
||||||
window,
|
|
||||||
&format!("Failed to download provisioning profile: {:?}", e),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -318,9 +297,10 @@ pub async fn sideload_app(
|
|||||||
std::fs::remove_file(&profile_path).map_err(|e| e.to_string())?;
|
std::fs::remove_file(&profile_path).map_err(|e| e.to_string())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut file = std::fs::File::create(&profile_path).map_err(|e| e.to_string())?;
|
let mut file =
|
||||||
|
std::fs::File::create(&profile_path).map_err(|e| Error::Filesystem(e.to_string()))?;
|
||||||
file.write_all(&provisioning_profile.encoded_profile)
|
file.write_all(&provisioning_profile.encoded_profile)
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| Error::Filesystem(e.to_string()))?;
|
||||||
|
|
||||||
// Without this, zsign complains it can't find the provision file
|
// Without this, zsign complains it can't find the provision file
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@@ -332,67 +312,28 @@ pub async fn sideload_app(
|
|||||||
// TODO: Recursive for sub-bundles?
|
// TODO: Recursive for sub-bundles?
|
||||||
app.bundle.write_info().map_err(|e| e.to_string())?;
|
app.bundle.write_info().map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
window
|
match ZSignOptions::new(app.bundle.bundle_dir.to_str().unwrap())
|
||||||
.emit("build-output", "Signining app...".to_string())
|
.with_cert_file(cert.get_certificate_file_path().to_str().unwrap())
|
||||||
.ok();
|
.with_pkey_file(cert.get_private_key_file_path().to_str().unwrap())
|
||||||
|
.with_prov_file(profile_path.to_str().unwrap())
|
||||||
let zsign_command = handle.shell().sidecar("zsign").unwrap().args([
|
.sign()
|
||||||
"-k",
|
{
|
||||||
cert.get_private_key_file_path().to_str().unwrap(),
|
Ok(_) => {}
|
||||||
"-c",
|
Err(e) => {
|
||||||
cert.get_certificate_file_path().to_str().unwrap(),
|
return error_and_return(&logger, &format!("Failed to sign app: {:?}", e));
|
||||||
"-m",
|
|
||||||
profile_path.to_str().unwrap(),
|
|
||||||
app.bundle.bundle_dir.to_str().unwrap(),
|
|
||||||
]);
|
|
||||||
let (mut rx, mut _child) = zsign_command.spawn().expect("Failed to spawn zsign");
|
|
||||||
|
|
||||||
let mut signing_failed = false;
|
|
||||||
while let Some(event) = rx.recv().await {
|
|
||||||
match event {
|
|
||||||
CommandEvent::Stdout(line_bytes) | CommandEvent::Stderr(line_bytes) => {
|
|
||||||
let line = String::from_utf8_lossy(&line_bytes);
|
|
||||||
window
|
|
||||||
.emit("build-output", Some(line))
|
|
||||||
.expect("failed to emit event");
|
|
||||||
}
|
}
|
||||||
CommandEvent::Terminated(result) => {
|
};
|
||||||
if result.code != Some(0) {
|
|
||||||
window
|
|
||||||
.emit("build-output", "App signing failed!".to_string())
|
|
||||||
.ok();
|
|
||||||
signing_failed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
window.emit("build-output", "App signed!").ok();
|
|
||||||
|
|
||||||
window
|
logger.log("App signed!");
|
||||||
.emit(
|
|
||||||
"build-output",
|
logger.log("Installing app (Transfer)... 0%");
|
||||||
"Installing app (Transfer)... 0%".to_string(),
|
|
||||||
)
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
let res = install_app(&device, &app.bundle.bundle_dir, |percentage| {
|
let res = install_app(&device, &app.bundle.bundle_dir, |percentage| {
|
||||||
window
|
logger.log(format!("Installing app... {}%", percentage));
|
||||||
.emit("build-output", format!("Installing app... {}%", percentage))
|
|
||||||
.expect("failed to emit event");
|
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
window
|
return error_and_return(&logger, &format!("Failed to install app: {:?}", e));
|
||||||
.emit("build-output", format!("Failed to install app: {:?}", e))
|
|
||||||
.ok();
|
|
||||||
signing_failed = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if signing_failed {
|
|
||||||
return Err("Signing or installation failed".to_string());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user