Dadoum commited on 2026-01-06 02:58:02
Showing 17 changed files, with 744 additions and 275 deletions.
| ... | ... |
@@ -188,6 +188,7 @@ dependencies = [ |
| 188 | 188 |
"sha2", |
| 189 | 189 |
"srp", |
| 190 | 190 |
"sys-locale", |
| 191 |
+ "thiserror 2.0.17", |
|
| 191 | 192 |
] |
| 192 | 193 |
|
| 193 | 194 |
[[package]] |
| ... | ... |
@@ -282,6 +283,28 @@ dependencies = [ |
| 282 | 283 |
"thiserror 1.0.69", |
| 283 | 284 |
] |
| 284 | 285 |
|
| 286 |
+[[package]] |
|
| 287 |
+name = "aws-lc-rs" |
|
| 288 |
+version = "1.15.2" |
|
| 289 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 290 |
+checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288" |
|
| 291 |
+dependencies = [ |
|
| 292 |
+ "aws-lc-sys", |
|
| 293 |
+ "zeroize", |
|
| 294 |
+] |
|
| 295 |
+ |
|
| 296 |
+[[package]] |
|
| 297 |
+name = "aws-lc-sys" |
|
| 298 |
+version = "0.35.0" |
|
| 299 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 300 |
+checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1" |
|
| 301 |
+dependencies = [ |
|
| 302 |
+ "cc", |
|
| 303 |
+ "cmake", |
|
| 304 |
+ "dunce", |
|
| 305 |
+ "fs_extra", |
|
| 306 |
+] |
|
| 307 |
+ |
|
| 285 | 308 |
[[package]] |
| 286 | 309 |
name = "backtrace" |
| 287 | 310 |
version = "0.3.76" |
| ... | ... |
@@ -417,14 +440,22 @@ dependencies = [ |
| 417 | 440 |
|
| 418 | 441 |
[[package]] |
| 419 | 442 |
name = "cc" |
| 420 |
-version = "1.2.41" |
|
| 443 |
+version = "1.2.51" |
|
| 421 | 444 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 422 |
-checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" |
|
| 445 |
+checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" |
|
| 423 | 446 |
dependencies = [ |
| 424 | 447 |
"find-msvc-tools", |
| 448 |
+ "jobserver", |
|
| 449 |
+ "libc", |
|
| 425 | 450 |
"shlex 1.3.0", |
| 426 | 451 |
] |
| 427 | 452 |
|
| 453 |
+[[package]] |
|
| 454 |
+name = "cesu8" |
|
| 455 |
+version = "1.1.0" |
|
| 456 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 457 |
+checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" |
|
| 458 |
+ |
|
| 428 | 459 |
[[package]] |
| 429 | 460 |
name = "cexpr" |
| 430 | 461 |
version = "0.4.0" |
| ... | ... |
@@ -467,9 +498,9 @@ dependencies = [ |
| 467 | 498 |
|
| 468 | 499 |
[[package]] |
| 469 | 500 |
name = "cipher" |
| 470 |
-version = "0.5.0-rc.2" |
|
| 501 |
+version = "0.5.0-rc.3" |
|
| 471 | 502 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 472 |
-checksum = "155e4a260750fa4f7754649f049748aacc31db238a358d85fd721002f230f92f" |
|
| 503 |
+checksum = "98d708bac5451350d56398433b19a7889022fa9187df1a769c0edbc3b2c03167" |
|
| 473 | 504 |
dependencies = [ |
| 474 | 505 |
"block-buffer", |
| 475 | 506 |
"crypto-common", |
| ... | ... |
@@ -502,12 +533,31 @@ dependencies = [ |
| 502 | 533 |
"vec_map", |
| 503 | 534 |
] |
| 504 | 535 |
|
| 536 |
+[[package]] |
|
| 537 |
+name = "cmake" |
|
| 538 |
+version = "0.1.57" |
|
| 539 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 540 |
+checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" |
|
| 541 |
+dependencies = [ |
|
| 542 |
+ "cc", |
|
| 543 |
+] |
|
| 544 |
+ |
|
| 505 | 545 |
[[package]] |
| 506 | 546 |
name = "colorchoice" |
| 507 | 547 |
version = "1.0.4" |
| 508 | 548 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 509 | 549 |
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" |
| 510 | 550 |
|
| 551 |
+[[package]] |
|
| 552 |
+name = "combine" |
|
| 553 |
+version = "4.6.7" |
|
| 554 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 555 |
+checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" |
|
| 556 |
+dependencies = [ |
|
| 557 |
+ "bytes", |
|
| 558 |
+ "memchr", |
|
| 559 |
+] |
|
| 560 |
+ |
|
| 511 | 561 |
[[package]] |
| 512 | 562 |
name = "const-oid" |
| 513 | 563 |
version = "0.10.1" |
| ... | ... |
@@ -524,6 +574,16 @@ dependencies = [ |
| 524 | 574 |
"libc", |
| 525 | 575 |
] |
| 526 | 576 |
|
| 577 |
+[[package]] |
|
| 578 |
+name = "core-foundation" |
|
| 579 |
+version = "0.10.1" |
|
| 580 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 581 |
+checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" |
|
| 582 |
+dependencies = [ |
|
| 583 |
+ "core-foundation-sys", |
|
| 584 |
+ "libc", |
|
| 585 |
+] |
|
| 586 |
+ |
|
| 527 | 587 |
[[package]] |
| 528 | 588 |
name = "core-foundation-sys" |
| 529 | 589 |
version = "0.8.7" |
| ... | ... |
@@ -614,9 +674,9 @@ dependencies = [ |
| 614 | 674 |
|
| 615 | 675 |
[[package]] |
| 616 | 676 |
name = "digest" |
| 617 |
-version = "0.11.0-rc.4" |
|
| 677 |
+version = "0.11.0-rc.5" |
|
| 618 | 678 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 619 |
-checksum = "ea390c940e465846d64775e55e3115d5dc934acb953de6f6e6360bc232fe2bf7" |
|
| 679 |
+checksum = "ebf9423bafb058e4142194330c52273c343f8a5beb7176d052f0e73b17dd35b9" |
|
| 620 | 680 |
dependencies = [ |
| 621 | 681 |
"block-buffer", |
| 622 | 682 |
"const-oid", |
| ... | ... |
@@ -635,6 +695,35 @@ dependencies = [ |
| 635 | 695 |
"syn 2.0.107", |
| 636 | 696 |
] |
| 637 | 697 |
|
| 698 |
+[[package]] |
|
| 699 |
+name = "dlopen2" |
|
| 700 |
+version = "0.8.2" |
|
| 701 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 702 |
+checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" |
|
| 703 |
+dependencies = [ |
|
| 704 |
+ "dlopen2_derive", |
|
| 705 |
+ "libc", |
|
| 706 |
+ "once_cell", |
|
| 707 |
+ "winapi", |
|
| 708 |
+] |
|
| 709 |
+ |
|
| 710 |
+[[package]] |
|
| 711 |
+name = "dlopen2_derive" |
|
| 712 |
+version = "0.4.3" |
|
| 713 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 714 |
+checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" |
|
| 715 |
+dependencies = [ |
|
| 716 |
+ "proc-macro2", |
|
| 717 |
+ "quote", |
|
| 718 |
+ "syn 2.0.107", |
|
| 719 |
+] |
|
| 720 |
+ |
|
| 721 |
+[[package]] |
|
| 722 |
+name = "dunce" |
|
| 723 |
+version = "1.0.5" |
|
| 724 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 725 |
+checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" |
|
| 726 |
+ |
|
| 638 | 727 |
[[package]] |
| 639 | 728 |
name = "either" |
| 640 | 729 |
version = "1.15.0" |
| ... | ... |
@@ -721,9 +810,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" |
| 721 | 810 |
|
| 722 | 811 |
[[package]] |
| 723 | 812 |
name = "find-msvc-tools" |
| 724 |
-version = "0.1.4" |
|
| 813 |
+version = "0.1.6" |
|
| 725 | 814 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 726 |
-checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" |
|
| 815 |
+checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" |
|
| 727 | 816 |
|
| 728 | 817 |
[[package]] |
| 729 | 818 |
name = "flate2" |
| ... | ... |
@@ -765,6 +854,20 @@ dependencies = [ |
| 765 | 854 |
"percent-encoding", |
| 766 | 855 |
] |
| 767 | 856 |
|
| 857 |
+[[package]] |
|
| 858 |
+name = "fpsd-proxy" |
|
| 859 |
+version = "0.1.0" |
|
| 860 |
+dependencies = [ |
|
| 861 |
+ "dlopen2", |
|
| 862 |
+ "objc2", |
|
| 863 |
+] |
|
| 864 |
+ |
|
| 865 |
+[[package]] |
|
| 866 |
+name = "fs_extra" |
|
| 867 |
+version = "1.3.0" |
|
| 868 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 869 |
+checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" |
|
| 870 |
+ |
|
| 768 | 871 |
[[package]] |
| 769 | 872 |
name = "futures" |
| 770 | 873 |
version = "0.3.31" |
| ... | ... |
@@ -1391,9 +1494,9 @@ dependencies = [ |
| 1391 | 1494 |
|
| 1392 | 1495 |
[[package]] |
| 1393 | 1496 |
name = "inout" |
| 1394 |
-version = "0.2.1" |
|
| 1497 |
+version = "0.2.2" |
|
| 1395 | 1498 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1396 |
-checksum = "c7357b6e7aa75618c7864ebd0634b115a7218b0615f4cb1df33ac3eca23943d4" |
|
| 1499 |
+checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" |
|
| 1397 | 1500 |
dependencies = [ |
| 1398 | 1501 |
"block-padding", |
| 1399 | 1502 |
"hybrid-array", |
| ... | ... |
@@ -1486,6 +1589,38 @@ dependencies = [ |
| 1486 | 1589 |
"syn 2.0.107", |
| 1487 | 1590 |
] |
| 1488 | 1591 |
|
| 1592 |
+[[package]] |
|
| 1593 |
+name = "jni" |
|
| 1594 |
+version = "0.21.1" |
|
| 1595 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1596 |
+checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" |
|
| 1597 |
+dependencies = [ |
|
| 1598 |
+ "cesu8", |
|
| 1599 |
+ "cfg-if 1.0.4", |
|
| 1600 |
+ "combine", |
|
| 1601 |
+ "jni-sys", |
|
| 1602 |
+ "log", |
|
| 1603 |
+ "thiserror 1.0.69", |
|
| 1604 |
+ "walkdir", |
|
| 1605 |
+ "windows-sys 0.45.0", |
|
| 1606 |
+] |
|
| 1607 |
+ |
|
| 1608 |
+[[package]] |
|
| 1609 |
+name = "jni-sys" |
|
| 1610 |
+version = "0.3.0" |
|
| 1611 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1612 |
+checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" |
|
| 1613 |
+ |
|
| 1614 |
+[[package]] |
|
| 1615 |
+name = "jobserver" |
|
| 1616 |
+version = "0.1.34" |
|
| 1617 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1618 |
+checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" |
|
| 1619 |
+dependencies = [ |
|
| 1620 |
+ "getrandom 0.3.4", |
|
| 1621 |
+ "libc", |
|
| 1622 |
+] |
|
| 1623 |
+ |
|
| 1489 | 1624 |
[[package]] |
| 1490 | 1625 |
name = "js-sys" |
| 1491 | 1626 |
version = "0.3.81" |
| ... | ... |
@@ -1698,10 +1833,10 @@ dependencies = [ |
| 1698 | 1833 |
"libc", |
| 1699 | 1834 |
"log", |
| 1700 | 1835 |
"openssl", |
| 1701 |
- "openssl-probe", |
|
| 1836 |
+ "openssl-probe 0.1.6", |
|
| 1702 | 1837 |
"openssl-sys", |
| 1703 | 1838 |
"schannel", |
| 1704 |
- "security-framework", |
|
| 1839 |
+ "security-framework 2.11.1", |
|
| 1705 | 1840 |
"security-framework-sys", |
| 1706 | 1841 |
"tempfile", |
| 1707 | 1842 |
] |
| ... | ... |
@@ -1761,6 +1896,21 @@ dependencies = [ |
| 1761 | 1896 |
"autocfg", |
| 1762 | 1897 |
] |
| 1763 | 1898 |
|
| 1899 |
+[[package]] |
|
| 1900 |
+name = "objc2" |
|
| 1901 |
+version = "0.6.3" |
|
| 1902 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1903 |
+checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" |
|
| 1904 |
+dependencies = [ |
|
| 1905 |
+ "objc2-encode", |
|
| 1906 |
+] |
|
| 1907 |
+ |
|
| 1908 |
+[[package]] |
|
| 1909 |
+name = "objc2-encode" |
|
| 1910 |
+version = "4.1.0" |
|
| 1911 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1912 |
+checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" |
|
| 1913 |
+ |
|
| 1764 | 1914 |
[[package]] |
| 1765 | 1915 |
name = "object" |
| 1766 | 1916 |
version = "0.37.3" |
| ... | ... |
@@ -1814,6 +1964,12 @@ version = "0.1.6" |
| 1814 | 1964 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1815 | 1965 |
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" |
| 1816 | 1966 |
|
| 1967 |
+[[package]] |
|
| 1968 |
+name = "openssl-probe" |
|
| 1969 |
+version = "0.2.0" |
|
| 1970 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 1971 |
+checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" |
|
| 1972 |
+ |
|
| 1817 | 1973 |
[[package]] |
| 1818 | 1974 |
name = "openssl-sys" |
| 1819 | 1975 |
version = "0.9.111" |
| ... | ... |
@@ -2068,6 +2224,7 @@ version = "0.11.13" |
| 2068 | 2224 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2069 | 2225 |
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" |
| 2070 | 2226 |
dependencies = [ |
| 2227 |
+ "aws-lc-rs", |
|
| 2071 | 2228 |
"bytes", |
| 2072 | 2229 |
"getrandom 0.3.4", |
| 2073 | 2230 |
"lru-slab", |
| ... | ... |
@@ -2273,6 +2430,44 @@ dependencies = [ |
| 2273 | 2430 |
"webpki-roots 1.0.4", |
| 2274 | 2431 |
] |
| 2275 | 2432 |
|
| 2433 |
+[[package]] |
|
| 2434 |
+name = "reqwest" |
|
| 2435 |
+version = "0.13.1" |
|
| 2436 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 2437 |
+checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" |
|
| 2438 |
+dependencies = [ |
|
| 2439 |
+ "base64 0.22.1", |
|
| 2440 |
+ "bytes", |
|
| 2441 |
+ "encoding_rs", |
|
| 2442 |
+ "futures-core", |
|
| 2443 |
+ "h2 0.4.12", |
|
| 2444 |
+ "http 1.3.1", |
|
| 2445 |
+ "http-body 1.0.1", |
|
| 2446 |
+ "http-body-util", |
|
| 2447 |
+ "hyper 1.7.0", |
|
| 2448 |
+ "hyper-rustls 0.27.7", |
|
| 2449 |
+ "hyper-util", |
|
| 2450 |
+ "js-sys", |
|
| 2451 |
+ "log", |
|
| 2452 |
+ "mime", |
|
| 2453 |
+ "percent-encoding", |
|
| 2454 |
+ "pin-project-lite", |
|
| 2455 |
+ "quinn", |
|
| 2456 |
+ "rustls 0.23.33", |
|
| 2457 |
+ "rustls-pki-types", |
|
| 2458 |
+ "rustls-platform-verifier", |
|
| 2459 |
+ "sync_wrapper 1.0.2", |
|
| 2460 |
+ "tokio", |
|
| 2461 |
+ "tokio-rustls 0.26.4", |
|
| 2462 |
+ "tower", |
|
| 2463 |
+ "tower-http", |
|
| 2464 |
+ "tower-service", |
|
| 2465 |
+ "url", |
|
| 2466 |
+ "wasm-bindgen", |
|
| 2467 |
+ "wasm-bindgen-futures", |
|
| 2468 |
+ "web-sys", |
|
| 2469 |
+] |
|
| 2470 |
+ |
|
| 2276 | 2471 |
[[package]] |
| 2277 | 2472 |
name = "ring" |
| 2278 | 2473 |
version = "0.17.14" |
| ... | ... |
@@ -2336,6 +2531,7 @@ version = "0.23.33" |
| 2336 | 2531 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2337 | 2532 |
checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c" |
| 2338 | 2533 |
dependencies = [ |
| 2534 |
+ "aws-lc-rs", |
|
| 2339 | 2535 |
"once_cell", |
| 2340 | 2536 |
"ring", |
| 2341 | 2537 |
"rustls-pki-types", |
| ... | ... |
@@ -2344,6 +2540,18 @@ dependencies = [ |
| 2344 | 2540 |
"zeroize", |
| 2345 | 2541 |
] |
| 2346 | 2542 |
|
| 2543 |
+[[package]] |
|
| 2544 |
+name = "rustls-native-certs" |
|
| 2545 |
+version = "0.8.3" |
|
| 2546 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 2547 |
+checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" |
|
| 2548 |
+dependencies = [ |
|
| 2549 |
+ "openssl-probe 0.2.0", |
|
| 2550 |
+ "rustls-pki-types", |
|
| 2551 |
+ "schannel", |
|
| 2552 |
+ "security-framework 3.5.1", |
|
| 2553 |
+] |
|
| 2554 |
+ |
|
| 2347 | 2555 |
[[package]] |
| 2348 | 2556 |
name = "rustls-pemfile" |
| 2349 | 2557 |
version = "1.0.4" |
| ... | ... |
@@ -2363,6 +2571,33 @@ dependencies = [ |
| 2363 | 2571 |
"zeroize", |
| 2364 | 2572 |
] |
| 2365 | 2573 |
|
| 2574 |
+[[package]] |
|
| 2575 |
+name = "rustls-platform-verifier" |
|
| 2576 |
+version = "0.6.2" |
|
| 2577 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 2578 |
+checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" |
|
| 2579 |
+dependencies = [ |
|
| 2580 |
+ "core-foundation 0.10.1", |
|
| 2581 |
+ "core-foundation-sys", |
|
| 2582 |
+ "jni", |
|
| 2583 |
+ "log", |
|
| 2584 |
+ "once_cell", |
|
| 2585 |
+ "rustls 0.23.33", |
|
| 2586 |
+ "rustls-native-certs", |
|
| 2587 |
+ "rustls-platform-verifier-android", |
|
| 2588 |
+ "rustls-webpki 0.103.7", |
|
| 2589 |
+ "security-framework 3.5.1", |
|
| 2590 |
+ "security-framework-sys", |
|
| 2591 |
+ "webpki-root-certs", |
|
| 2592 |
+ "windows-sys 0.61.2", |
|
| 2593 |
+] |
|
| 2594 |
+ |
|
| 2595 |
+[[package]] |
|
| 2596 |
+name = "rustls-platform-verifier-android" |
|
| 2597 |
+version = "0.1.1" |
|
| 2598 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 2599 |
+checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" |
|
| 2600 |
+ |
|
| 2366 | 2601 |
[[package]] |
| 2367 | 2602 |
name = "rustls-webpki" |
| 2368 | 2603 |
version = "0.101.7" |
| ... | ... |
@@ -2379,6 +2614,7 @@ version = "0.103.7" |
| 2379 | 2614 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2380 | 2615 |
checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" |
| 2381 | 2616 |
dependencies = [ |
| 2617 |
+ "aws-lc-rs", |
|
| 2382 | 2618 |
"ring", |
| 2383 | 2619 |
"rustls-pki-types", |
| 2384 | 2620 |
"untrusted", |
| ... | ... |
@@ -2396,6 +2632,15 @@ version = "1.0.20" |
| 2396 | 2632 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2397 | 2633 |
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" |
| 2398 | 2634 |
|
| 2635 |
+[[package]] |
|
| 2636 |
+name = "same-file" |
|
| 2637 |
+version = "1.0.6" |
|
| 2638 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 2639 |
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" |
|
| 2640 |
+dependencies = [ |
|
| 2641 |
+ "winapi-util", |
|
| 2642 |
+] |
|
| 2643 |
+ |
|
| 2399 | 2644 |
[[package]] |
| 2400 | 2645 |
name = "schannel" |
| 2401 | 2646 |
version = "0.1.28" |
| ... | ... |
@@ -2442,7 +2687,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2442 | 2687 |
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" |
| 2443 | 2688 |
dependencies = [ |
| 2444 | 2689 |
"bitflags 2.10.0", |
| 2445 |
- "core-foundation", |
|
| 2690 |
+ "core-foundation 0.9.4", |
|
| 2691 |
+ "core-foundation-sys", |
|
| 2692 |
+ "libc", |
|
| 2693 |
+ "security-framework-sys", |
|
| 2694 |
+] |
|
| 2695 |
+ |
|
| 2696 |
+[[package]] |
|
| 2697 |
+name = "security-framework" |
|
| 2698 |
+version = "3.5.1" |
|
| 2699 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 2700 |
+checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" |
|
| 2701 |
+dependencies = [ |
|
| 2702 |
+ "bitflags 2.10.0", |
|
| 2703 |
+ "core-foundation 0.10.1", |
|
| 2446 | 2704 |
"core-foundation-sys", |
| 2447 | 2705 |
"libc", |
| 2448 | 2706 |
"security-framework-sys", |
| ... | ... |
@@ -2600,7 +2858,7 @@ dependencies = [ |
| 2600 | 2858 |
[[package]] |
| 2601 | 2859 |
name = "srp" |
| 2602 | 2860 |
version = "0.7.0-pre.0" |
| 2603 |
-source = "git+https://github.com/RustCrypto/PAKEs#5e629b72caf484a3cb4c2292594a0fde8aa32df7" |
|
| 2861 |
+source = "git+https://github.com/RustCrypto/PAKEs#ce6ac89ba36ed72becdd62146ac5f52882ff9f12" |
|
| 2604 | 2862 |
dependencies = [ |
| 2605 | 2863 |
"digest", |
| 2606 | 2864 |
"lazy_static", |
| ... | ... |
@@ -2640,10 +2898,13 @@ dependencies = [ |
| 2640 | 2898 |
"adid-proxy", |
| 2641 | 2899 |
"android-coreadi", |
| 2642 | 2900 |
"apple-account", |
| 2901 |
+ "base64 0.22.1", |
|
| 2643 | 2902 |
"elf-loader", |
| 2644 | 2903 |
"env_logger 0.11.8", |
| 2645 | 2904 |
"libc", |
| 2905 |
+ "reqwest 0.13.1", |
|
| 2646 | 2906 |
"tokio", |
| 2907 |
+ "xcode", |
|
| 2647 | 2908 |
] |
| 2648 | 2909 |
|
| 2649 | 2910 |
[[package]] |
| ... | ... |
@@ -2738,7 +2999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2738 | 2999 |
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" |
| 2739 | 3000 |
dependencies = [ |
| 2740 | 3001 |
"bitflags 1.3.2", |
| 2741 |
- "core-foundation", |
|
| 3002 |
+ "core-foundation 0.9.4", |
|
| 2742 | 3003 |
"system-configuration-sys 0.5.0", |
| 2743 | 3004 |
] |
| 2744 | 3005 |
|
| ... | ... |
@@ -2749,7 +3010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2749 | 3010 |
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" |
| 2750 | 3011 |
dependencies = [ |
| 2751 | 3012 |
"bitflags 2.10.0", |
| 2752 |
- "core-foundation", |
|
| 3013 |
+ "core-foundation 0.9.4", |
|
| 2753 | 3014 |
"system-configuration-sys 0.6.0", |
| 2754 | 3015 |
] |
| 2755 | 3016 |
|
| ... | ... |
@@ -3157,6 +3418,16 @@ version = "0.9.5" |
| 3157 | 3418 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3158 | 3419 |
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" |
| 3159 | 3420 |
|
| 3421 |
+[[package]] |
|
| 3422 |
+name = "walkdir" |
|
| 3423 |
+version = "2.5.0" |
|
| 3424 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3425 |
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" |
|
| 3426 |
+dependencies = [ |
|
| 3427 |
+ "same-file", |
|
| 3428 |
+ "winapi-util", |
|
| 3429 |
+] |
|
| 3430 |
+ |
|
| 3160 | 3431 |
[[package]] |
| 3161 | 3432 |
name = "want" |
| 3162 | 3433 |
version = "0.3.1" |
| ... | ... |
@@ -3273,6 +3544,15 @@ dependencies = [ |
| 3273 | 3544 |
"wasm-bindgen", |
| 3274 | 3545 |
] |
| 3275 | 3546 |
|
| 3547 |
+[[package]] |
|
| 3548 |
+name = "webpki-root-certs" |
|
| 3549 |
+version = "1.0.4" |
|
| 3550 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3551 |
+checksum = "ee3e3b5f5e80bc89f30ce8d0343bf4e5f12341c51f3e26cbeecbc7c85443e85b" |
|
| 3552 |
+dependencies = [ |
|
| 3553 |
+ "rustls-pki-types", |
|
| 3554 |
+] |
|
| 3555 |
+ |
|
| 3276 | 3556 |
[[package]] |
| 3277 | 3557 |
name = "webpki-roots" |
| 3278 | 3558 |
version = "0.25.4" |
| ... | ... |
@@ -3404,6 +3684,15 @@ dependencies = [ |
| 3404 | 3684 |
"windows-link 0.1.3", |
| 3405 | 3685 |
] |
| 3406 | 3686 |
|
| 3687 |
+[[package]] |
|
| 3688 |
+name = "windows-sys" |
|
| 3689 |
+version = "0.45.0" |
|
| 3690 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3691 |
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" |
|
| 3692 |
+dependencies = [ |
|
| 3693 |
+ "windows-targets 0.42.2", |
|
| 3694 |
+] |
|
| 3695 |
+ |
|
| 3407 | 3696 |
[[package]] |
| 3408 | 3697 |
name = "windows-sys" |
| 3409 | 3698 |
version = "0.48.0" |
| ... | ... |
@@ -3440,6 +3729,21 @@ dependencies = [ |
| 3440 | 3729 |
"windows-link 0.2.1", |
| 3441 | 3730 |
] |
| 3442 | 3731 |
|
| 3732 |
+[[package]] |
|
| 3733 |
+name = "windows-targets" |
|
| 3734 |
+version = "0.42.2" |
|
| 3735 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3736 |
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" |
|
| 3737 |
+dependencies = [ |
|
| 3738 |
+ "windows_aarch64_gnullvm 0.42.2", |
|
| 3739 |
+ "windows_aarch64_msvc 0.42.2", |
|
| 3740 |
+ "windows_i686_gnu 0.42.2", |
|
| 3741 |
+ "windows_i686_msvc 0.42.2", |
|
| 3742 |
+ "windows_x86_64_gnu 0.42.2", |
|
| 3743 |
+ "windows_x86_64_gnullvm 0.42.2", |
|
| 3744 |
+ "windows_x86_64_msvc 0.42.2", |
|
| 3745 |
+] |
|
| 3746 |
+ |
|
| 3443 | 3747 |
[[package]] |
| 3444 | 3748 |
name = "windows-targets" |
| 3445 | 3749 |
version = "0.48.5" |
| ... | ... |
@@ -3488,6 +3792,12 @@ dependencies = [ |
| 3488 | 3792 |
"windows_x86_64_msvc 0.53.1", |
| 3489 | 3793 |
] |
| 3490 | 3794 |
|
| 3795 |
+[[package]] |
|
| 3796 |
+name = "windows_aarch64_gnullvm" |
|
| 3797 |
+version = "0.42.2" |
|
| 3798 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3799 |
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" |
|
| 3800 |
+ |
|
| 3491 | 3801 |
[[package]] |
| 3492 | 3802 |
name = "windows_aarch64_gnullvm" |
| 3493 | 3803 |
version = "0.48.5" |
| ... | ... |
@@ -3506,6 +3816,12 @@ version = "0.53.1" |
| 3506 | 3816 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3507 | 3817 |
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" |
| 3508 | 3818 |
|
| 3819 |
+[[package]] |
|
| 3820 |
+name = "windows_aarch64_msvc" |
|
| 3821 |
+version = "0.42.2" |
|
| 3822 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3823 |
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" |
|
| 3824 |
+ |
|
| 3509 | 3825 |
[[package]] |
| 3510 | 3826 |
name = "windows_aarch64_msvc" |
| 3511 | 3827 |
version = "0.48.5" |
| ... | ... |
@@ -3524,6 +3840,12 @@ version = "0.53.1" |
| 3524 | 3840 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3525 | 3841 |
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" |
| 3526 | 3842 |
|
| 3843 |
+[[package]] |
|
| 3844 |
+name = "windows_i686_gnu" |
|
| 3845 |
+version = "0.42.2" |
|
| 3846 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3847 |
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" |
|
| 3848 |
+ |
|
| 3527 | 3849 |
[[package]] |
| 3528 | 3850 |
name = "windows_i686_gnu" |
| 3529 | 3851 |
version = "0.48.5" |
| ... | ... |
@@ -3554,6 +3876,12 @@ version = "0.53.1" |
| 3554 | 3876 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3555 | 3877 |
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" |
| 3556 | 3878 |
|
| 3879 |
+[[package]] |
|
| 3880 |
+name = "windows_i686_msvc" |
|
| 3881 |
+version = "0.42.2" |
|
| 3882 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3883 |
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" |
|
| 3884 |
+ |
|
| 3557 | 3885 |
[[package]] |
| 3558 | 3886 |
name = "windows_i686_msvc" |
| 3559 | 3887 |
version = "0.48.5" |
| ... | ... |
@@ -3572,6 +3900,12 @@ version = "0.53.1" |
| 3572 | 3900 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3573 | 3901 |
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" |
| 3574 | 3902 |
|
| 3903 |
+[[package]] |
|
| 3904 |
+name = "windows_x86_64_gnu" |
|
| 3905 |
+version = "0.42.2" |
|
| 3906 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3907 |
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" |
|
| 3908 |
+ |
|
| 3575 | 3909 |
[[package]] |
| 3576 | 3910 |
name = "windows_x86_64_gnu" |
| 3577 | 3911 |
version = "0.48.5" |
| ... | ... |
@@ -3590,6 +3924,12 @@ version = "0.53.1" |
| 3590 | 3924 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3591 | 3925 |
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" |
| 3592 | 3926 |
|
| 3927 |
+[[package]] |
|
| 3928 |
+name = "windows_x86_64_gnullvm" |
|
| 3929 |
+version = "0.42.2" |
|
| 3930 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3931 |
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" |
|
| 3932 |
+ |
|
| 3593 | 3933 |
[[package]] |
| 3594 | 3934 |
name = "windows_x86_64_gnullvm" |
| 3595 | 3935 |
version = "0.48.5" |
| ... | ... |
@@ -3608,6 +3948,12 @@ version = "0.53.1" |
| 3608 | 3948 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3609 | 3949 |
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" |
| 3610 | 3950 |
|
| 3951 |
+[[package]] |
|
| 3952 |
+name = "windows_x86_64_msvc" |
|
| 3953 |
+version = "0.42.2" |
|
| 3954 |
+source = "registry+https://github.com/rust-lang/crates.io-index" |
|
| 3955 |
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" |
|
| 3956 |
+ |
|
| 3611 | 3957 |
[[package]] |
| 3612 | 3958 |
name = "windows_x86_64_msvc" |
| 3613 | 3959 |
version = "0.48.5" |
| ... | ... |
@@ -3648,6 +3994,17 @@ version = "0.6.1" |
| 3648 | 3994 |
source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3649 | 3995 |
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" |
| 3650 | 3996 |
|
| 3997 |
+[[package]] |
|
| 3998 |
+name = "xcode" |
|
| 3999 |
+version = "0.1.0" |
|
| 4000 |
+dependencies = [ |
|
| 4001 |
+ "adi", |
|
| 4002 |
+ "apple-account", |
|
| 4003 |
+ "plist", |
|
| 4004 |
+ "plist-macros", |
|
| 4005 |
+ "reqwest 0.12.27", |
|
| 4006 |
+] |
|
| 4007 |
+ |
|
| 3651 | 4008 |
[[package]] |
| 3652 | 4009 |
name = "xpc-connection-sys" |
| 3653 | 4010 |
version = "0.1.1" |
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
[workspace] |
| 2 | 2 |
resolver = "2" |
| 3 |
-members = ["adi", "adid-proxy", "android-coreadi", "apple-account", "apple-codesign-quick", "elf-loader", "plist-macros", "purple-builder", "super-sideloader"] |
|
| 3 |
+members = ["adi", "adid-proxy", "android-coreadi", "apple-account", "apple-codesign-quick", "elf-loader", "fpsd-proxy", "plist-macros", "purple-builder", "super-sideloader", "xcode"] |
|
| 4 | 4 |
|
| 5 | 5 |
[workspace.dependencies] |
| 6 | 6 |
adi = { path = "adi" }
|
| ... | ... |
@@ -9,9 +9,11 @@ android-coreadi = { path = "android-coreadi" }
|
| 9 | 9 |
apple-account = { path = "apple-account" }
|
| 10 | 10 |
elf-loader = { path = "elf-loader" }
|
| 11 | 11 |
plist-macros = { path = "plist-macros" }
|
| 12 |
+xcode = { path = "xcode" }
|
|
| 12 | 13 |
|
| 13 | 14 |
plist = "1" |
| 14 | 15 |
reqwest = { version = "0.12", features = ["rustls-tls"] }
|
| 16 |
+thiserror = "2" |
|
| 15 | 17 |
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
|
| 16 | 18 |
|
| 17 | 19 |
aes = "0.9.0-rc.2" |
| ... | ... |
@@ -1,4 +1,5 @@ |
| 1 |
-pub struct BundleInformation<'lt> { // Maybe simplify to 'static?
|
|
| 1 |
+pub struct BundleInformation<'lt> {
|
|
| 2 |
+ // Maybe simplify to 'static? |
|
| 2 | 3 |
pub bundle_name: &'lt str, |
| 3 | 4 |
pub bundle_identifier: &'lt str, |
| 4 | 5 |
pub bundle_version: &'lt str, |
| ... | ... |
@@ -11,13 +12,6 @@ pub const AUTH_KIT_BUNDLE_INFORMATION: BundleInformation = BundleInformation {
|
| 11 | 12 |
bundle_version: "1", |
| 12 | 13 |
}; |
| 13 | 14 |
|
| 14 |
-/// Xcode 16.4 |
|
| 15 |
-pub const XCODE_BUNDLE_INFORMATION: BundleInformation = BundleInformation {
|
|
| 16 |
- bundle_name: "Xcode", |
|
| 17 |
- bundle_identifier: "com.apple.dt.Xcode", |
|
| 18 |
- bundle_version: "23792", |
|
| 19 |
-}; |
|
| 20 |
- |
|
| 21 | 15 |
/// Apple TV 1.5.6 (macOS Sequoia 15.7.3) |
| 22 | 16 |
pub const APPLE_TV_BUNDLE_INFORMATION: BundleInformation = BundleInformation {
|
| 23 | 17 |
bundle_name: "TV", |
| ... | ... |
@@ -1,10 +1,9 @@ |
| 1 | 1 |
mod anisette; |
| 2 |
+mod authenticated_session; |
|
| 2 | 3 |
mod post_data; |
| 3 | 4 |
mod secondary_actions; |
| 4 | 5 |
mod url_switch; |
| 5 |
-mod authenticated_session; |
|
| 6 | 6 |
|
| 7 |
-pub use authenticated_session::*; |
|
| 8 | 7 |
use crate::bundle_information::BundleInformation; |
| 9 | 8 |
use crate::device::Device; |
| 10 | 9 |
use crate::grandslam::AuthOutcome::AnisetteResyncRequired; |
| ... | ... |
@@ -12,31 +11,29 @@ use crate::http_session::{
|
| 12 | 11 |
AnisetteHTTPSession, AppleError, BasicHTTPSession, HTTPSession, HTTPSessionCreationError, |
| 13 | 12 |
URLBagError, parse_status, |
| 14 | 13 |
}; |
| 14 |
+use crate::plist_request::dict_to_body; |
|
| 15 | 15 |
use adi::proxy::{ADIError, ADIResult};
|
| 16 |
-use aes::Aes256; |
|
| 17 | 16 |
use aes::cipher::block_padding; |
| 18 | 17 |
use aes::cipher::block_padding::Pkcs7; |
| 19 |
-use aes_gcm::AesGcm; |
|
| 20 |
-use aes_gcm::aead::consts::U16; |
|
| 21 |
-use aes_gcm::aead::{Aead, Payload};
|
|
| 22 | 18 |
pub use anisette::*; |
| 19 |
+pub use authenticated_session::*; |
|
| 23 | 20 |
use base64::Engine; |
| 24 | 21 |
use base64::prelude::BASE64_STANDARD; |
| 25 | 22 |
use bytes::Bytes; |
| 26 | 23 |
use cbc::cipher::{BlockModeDecrypt, KeyIvInit};
|
| 27 | 24 |
use chrono::{Local, SecondsFormat};
|
| 28 | 25 |
use hmac::{Hmac, KeyInit, Mac};
|
| 29 |
-use log::{trace, warn};
|
|
| 26 |
+use log::trace; |
|
| 30 | 27 |
use plist::{Dictionary, Value};
|
| 31 | 28 |
use plist_macros::{array, dict};
|
| 32 | 29 |
pub use post_data::*; |
| 33 | 30 |
use reqwest::{Certificate, Method, RequestBuilder};
|
| 34 |
-use serde::Deserialize; |
|
| 35 | 31 |
use sha2::{Digest, Sha256};
|
| 36 | 32 |
use srp::client::SrpClient; |
| 37 | 33 |
use srp::groups::G_2048; |
| 38 | 34 |
use srp::types::SrpAuthError; |
| 39 | 35 |
use std::fmt::{Display, Formatter};
|
| 36 |
+use thiserror::Error; |
|
| 40 | 37 |
pub use url_switch::*; |
| 41 | 38 |
|
| 42 | 39 |
const ROOT_CA: &[u8] = include_bytes!("grandslam/root-ca.pem");
|
| ... | ... |
@@ -184,89 +181,35 @@ impl<'lt, 'lt2, 'adi> Token<'lt, 'lt2, 'adi> {
|
| 184 | 181 |
#[derive(Debug)] |
| 185 | 182 |
pub enum AuthOutcome {
|
| 186 | 183 |
Success(Dictionary), |
| 187 |
- SecondaryActionRequired(Dictionary, String), |
|
| 184 |
+ SecondaryActionRequired(Option<Dictionary>, String), |
|
| 188 | 185 |
AnisetteResyncRequired(Vec<u8>), |
| 189 | 186 |
AnisetteReprovisionRequired, |
| 190 | 187 |
UrlSwitchingRequired(String), |
| 191 | 188 |
} |
| 192 | 189 |
|
| 193 |
-#[derive(Debug)] |
|
| 190 |
+#[derive(Error, Debug)] |
|
| 194 | 191 |
pub enum AuthError {
|
| 192 |
+ #[error("Could not log-in to Apple servers: {0}")]
|
|
| 193 |
+ Apple(#[from] AppleError), |
|
| 194 |
+ #[error("Cannot generate device authentication data: {0}")]
|
|
| 195 |
+ Anisette(#[from] ADIError), |
|
| 196 |
+ #[error("Network error: {0}")]
|
|
| 197 |
+ Network(#[from] reqwest::Error), |
|
| 198 |
+ // vvv Internal errors vvv |
|
| 199 |
+ #[error("Invalid URL bag")]
|
|
| 195 | 200 |
InvalidURLBag, |
| 196 |
- Apple(AppleError), |
|
| 197 |
- Anisette(ADIError), |
|
| 198 |
- Network(reqwest::Error), |
|
| 199 |
- Parsing(u8, plist::Error), |
|
| 201 |
+ #[error("Cannot parse server response from step {auth_step}: {error}")]
|
|
| 202 |
+ Parsing { auth_step: u8, error: plist::Error },
|
|
| 203 |
+ #[error("Invalid server response structure (censor private data before reporting): {0:?}")]
|
|
| 200 | 204 |
Structure(Dictionary), |
| 201 |
- SRP(SrpAuthError), |
|
| 205 |
+ #[error("Authentication protocol failure: {0}")]
|
|
| 206 |
+ SRP(#[from] SrpAuthError), |
|
| 207 |
+ #[error("Unknown server protocol: {0}")]
|
|
| 202 | 208 |
UnknownProtocol(String), |
| 203 |
- Decryption(block_padding::Error), |
|
| 204 |
-} |
|
| 205 |
- |
|
| 206 |
-/* |
|
| 207 |
-impl From<SrpAuthError> for AuthError {
|
|
| 208 |
- fn from(error: SrpAuthError) -> Self {
|
|
| 209 |
- AuthError::SRP(error) |
|
| 210 |
- } |
|
| 211 |
-} |
|
| 212 |
- |
|
| 213 |
-impl From<reqwest::Error> for AuthError {
|
|
| 214 |
- fn from(error: reqwest::Error) -> Self {
|
|
| 215 |
- Self::Network(error) |
|
| 216 |
- } |
|
| 209 |
+ #[error("Decryption error: {0}")]
|
|
| 210 |
+ Decryption(#[from] block_padding::Error), |
|
| 217 | 211 |
} |
| 218 | 212 |
|
| 219 |
-impl From<ADIError> for AuthError {
|
|
| 220 |
- fn from(err: ADIError) -> AuthError {
|
|
| 221 |
- AuthError::Anisette(err) |
|
| 222 |
- } |
|
| 223 |
-} |
|
| 224 |
- |
|
| 225 |
-impl From<AppleError> for AuthError {
|
|
| 226 |
- fn from(err: AppleError) -> AuthError {
|
|
| 227 |
- AuthError::Apple(err) |
|
| 228 |
- } |
|
| 229 |
-} // */ |
|
| 230 |
- |
|
| 231 |
-impl Display for AuthError {
|
|
| 232 |
- fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
|
| 233 |
- match self {
|
|
| 234 |
- AuthError::InvalidURLBag => {
|
|
| 235 |
- write!(f, "Invalid URL bag") |
|
| 236 |
- } |
|
| 237 |
- AuthError::Apple(err) => {
|
|
| 238 |
- write!(f, "Could not log-in to Apple servers: {err}")
|
|
| 239 |
- } |
|
| 240 |
- AuthError::Anisette(err) => {
|
|
| 241 |
- write!(f, "Cannot generate device authentication data: {err}")
|
|
| 242 |
- } |
|
| 243 |
- AuthError::Network(err) => {
|
|
| 244 |
- write!(f, "Network error: {err}")
|
|
| 245 |
- } |
|
| 246 |
- AuthError::Parsing(step, err) => {
|
|
| 247 |
- write!(f, "Cannot parse server response from step {step}: {err}")
|
|
| 248 |
- } |
|
| 249 |
- AuthError::Structure(dict) => {
|
|
| 250 |
- write!( |
|
| 251 |
- f, |
|
| 252 |
- "Invalid server response structure (censor private data before reporting): {dict:?}"
|
|
| 253 |
- ) |
|
| 254 |
- } |
|
| 255 |
- AuthError::SRP(error) => {
|
|
| 256 |
- write!(f, "Authentication protocol failure: {error}")
|
|
| 257 |
- } |
|
| 258 |
- AuthError::UnknownProtocol(protocol) => {
|
|
| 259 |
- write!(f, "Unknown server protocol: {protocol}")
|
|
| 260 |
- } |
|
| 261 |
- AuthError::Decryption(block_padding) => {
|
|
| 262 |
- write!(f, "Decryption error: {block_padding}")
|
|
| 263 |
- } |
|
| 264 |
- } |
|
| 265 |
- } |
|
| 266 |
-} |
|
| 267 |
- |
|
| 268 |
-impl std::error::Error for AuthError {}
|
|
| 269 |
- |
|
| 270 | 213 |
pub type AuthResult = Result<AuthOutcome, AuthError>; |
| 271 | 214 |
|
| 272 | 215 |
pub fn build_client_provided_data( |
| ... | ... |
@@ -357,8 +300,9 @@ pub async fn login( |
| 357 | 300 |
.and_then(Value::as_string) |
| 358 | 301 |
.ok_or(AuthError::InvalidURLBag)?; |
| 359 | 302 |
|
| 360 |
- let cpd = build_client_provided_data(http_session).map_err(AuthError::Anisette)?; |
|
| 303 |
+ let cpd = build_client_provided_data(http_session)?; |
|
| 361 | 304 |
|
| 305 |
+ // TODO: implement s4k, if some day someone needs that. |
|
| 362 | 306 |
let srp_client = SrpClient::<Sha256>::new_with_options(&G_2048, true); |
| 363 | 307 |
let a: [u8; 256] = rand::random(); |
| 364 | 308 |
let a_pub = srp_client.compute_public_ephemeral(&a); |
| ... | ... |
@@ -379,23 +323,19 @@ pub async fn login( |
| 379 | 323 |
} |
| 380 | 324 |
}; |
| 381 | 325 |
|
| 382 |
- // TODO: make a function to easily send plist. |
|
| 383 |
- let mut request_body = Vec::new(); |
|
| 384 |
- plist::to_writer_xml(&mut request_body, &request_plist).unwrap(); |
|
| 385 |
- |
|
| 386 | 326 |
let response = http_session |
| 387 |
- .anisette_request_builder(GRANDSLAM_DSID, Method::POST, gs_service_url) |
|
| 388 |
- .map_err(AuthError::Anisette)? |
|
| 389 |
- .body(request_body) |
|
| 327 |
+ .anisette_request_builder(GRANDSLAM_DSID, Method::POST, gs_service_url)? |
|
| 328 |
+ .body(dict_to_body(request_plist)) |
|
| 390 | 329 |
.send() |
| 391 |
- .await |
|
| 392 |
- .map_err(AuthError::Network)? |
|
| 330 |
+ .await? |
|
| 393 | 331 |
.bytes() |
| 394 |
- .await |
|
| 395 |
- .map_err(AuthError::Network)?; |
|
| 332 |
+ .await?; |
|
| 396 | 333 |
|
| 397 | 334 |
let response_plist: Dictionary = |
| 398 |
- plist::from_bytes(&response).map_err(|err| AuthError::Parsing(1, err))?; |
|
| 335 |
+ plist::from_bytes(&response).map_err(|error| AuthError::Parsing {
|
|
| 336 |
+ auth_step: 0, |
|
| 337 |
+ error, |
|
| 338 |
+ })?; |
|
| 399 | 339 |
|
| 400 | 340 |
let response_dict = response_plist |
| 401 | 341 |
.get("Response")
|
| ... | ... |
@@ -435,7 +375,9 @@ pub async fn login( |
| 435 | 375 |
.ok_or(AuthError::Structure(response_plist.clone()))?; |
| 436 | 376 |
|
| 437 | 377 |
let hashed_password: Vec<u8> = match selected_protocol {
|
| 438 |
- "s2k" => Sha256::digest(password.as_bytes()).to_vec(), |
|
| 378 |
+ // SRP with a 2048/4096-bit long A. |
|
| 379 |
+ "s2k" | "s4k" => Sha256::digest(password.as_bytes()).to_vec(), |
|
| 380 |
+ // SRP with a 2048-bit long A + fo? |
|
| 439 | 381 |
"s2k_fo" => hex::encode(Sha256::digest(password.as_bytes())).into_bytes(), |
| 440 | 382 |
_ => {
|
| 441 | 383 |
return Err(AuthError::UnknownProtocol(selected_protocol.into())); |
| ... | ... |
@@ -449,11 +391,10 @@ pub async fn login( |
| 449 | 391 |
buf |
| 450 | 392 |
}; |
| 451 | 393 |
|
| 452 |
- let verifier = srp_client |
|
| 453 |
- .process_reply_rfc5054(&a, apple_id.as_bytes(), &processed_password, salt, b) |
|
| 454 |
- .map_err(AuthError::SRP)?; |
|
| 394 |
+ let verifier = |
|
| 395 |
+ srp_client.process_reply_rfc5054(&a, apple_id.as_bytes(), &processed_password, salt, b)?; |
|
| 455 | 396 |
|
| 456 |
- let cpd = build_client_provided_data(http_session).map_err(AuthError::Anisette)?; |
|
| 397 |
+ let cpd = build_client_provided_data(http_session)?; |
|
| 457 | 398 |
|
| 458 | 399 |
let request_plist = dict! {
|
| 459 | 400 |
"Header": dict!{
|
| ... | ... |
@@ -468,22 +409,19 @@ pub async fn login( |
| 468 | 409 |
} |
| 469 | 410 |
}; |
| 470 | 411 |
|
| 471 |
- let mut request_body = Vec::new(); |
|
| 472 |
- plist::to_writer_xml(&mut request_body, &request_plist).unwrap(); |
|
| 473 |
- |
|
| 474 | 412 |
let response = http_session |
| 475 |
- .anisette_request_builder(GRANDSLAM_DSID, Method::POST, gs_service_url) |
|
| 476 |
- .map_err(AuthError::Anisette)? |
|
| 477 |
- .body(request_body) |
|
| 413 |
+ .anisette_request_builder(GRANDSLAM_DSID, Method::POST, gs_service_url)? |
|
| 414 |
+ .body(dict_to_body(request_plist)) |
|
| 478 | 415 |
.send() |
| 479 |
- .await |
|
| 480 |
- .map_err(AuthError::Network)? |
|
| 416 |
+ .await? |
|
| 481 | 417 |
.bytes() |
| 482 |
- .await |
|
| 483 |
- .map_err(AuthError::Network)?; |
|
| 418 |
+ .await?; |
|
| 484 | 419 |
|
| 485 | 420 |
let response_plist: Dictionary = |
| 486 |
- plist::from_bytes(&response).map_err(|err| AuthError::Parsing(2, err))?; |
|
| 421 |
+ plist::from_bytes(&response).map_err(|error| AuthError::Parsing {
|
|
| 422 |
+ auth_step: 1, |
|
| 423 |
+ error, |
|
| 424 |
+ })?; |
|
| 487 | 425 |
|
| 488 | 426 |
trace!("Received: {:#?}", response_plist);
|
| 489 | 427 |
|
| ... | ... |
@@ -499,7 +437,7 @@ pub async fn login( |
| 499 | 437 |
.and_then(|status| status.as_dictionary()) |
| 500 | 438 |
.ok_or(AuthError::Structure(response_plist.clone()))?; |
| 501 | 439 |
|
| 502 |
- parse_status(status).map_err(AuthError::Apple)?; |
|
| 440 |
+ parse_status(status)?; |
|
| 503 | 441 |
|
| 504 | 442 |
let status_code: StatusCode = status |
| 505 | 443 |
.get("hsc")
|
| ... | ... |
@@ -511,7 +449,7 @@ pub async fn login( |
| 511 | 449 |
let server_provided_data = response_dict |
| 512 | 450 |
.get("spd")
|
| 513 | 451 |
.and_then(|server_provided_data| server_provided_data.as_data()) |
| 514 |
- .map(|server_provided_data| {
|
|
| 452 |
+ .map::<Result<_, AuthError>, _>(|server_provided_data| {
|
|
| 515 | 453 |
let server_reply = response_dict |
| 516 | 454 |
.get("M2")
|
| 517 | 455 |
.and_then(|server_reply| server_reply.as_data()) |
| ... | ... |
@@ -546,7 +484,10 @@ pub async fn login( |
| 546 | 484 |
.map_err(AuthError::Decryption)?; |
| 547 | 485 |
|
| 548 | 486 |
let server_provided_data: Dictionary = plist::from_bytes(&server_provided_data) |
| 549 |
- .map_err(|err| AuthError::Parsing(2, err))?; |
|
| 487 |
+ .map_err(|error| AuthError::Parsing {
|
|
| 488 |
+ auth_step: 3, |
|
| 489 |
+ error, |
|
| 490 |
+ })?; |
|
| 550 | 491 |
|
| 551 | 492 |
trace!("Parsed server provided data: {:#?}", server_provided_data);
|
| 552 | 493 |
|
| ... | ... |
@@ -556,7 +497,8 @@ pub async fn login( |
| 556 | 497 |
|
| 557 | 498 |
match status_code {
|
| 558 | 499 |
StatusCode::Success => {
|
| 559 |
- let server_provided_data = server_provided_data.unwrap_or_default(); |
|
| 500 |
+ let server_provided_data = |
|
| 501 |
+ server_provided_data.expect("No server data has been provided??");
|
|
| 560 | 502 |
Ok(AuthOutcome::Success(server_provided_data)) |
| 561 | 503 |
} |
| 562 | 504 |
StatusCode::SecondaryActionRequired => {
|
| ... | ... |
@@ -566,8 +508,6 @@ pub async fn login( |
| 566 | 508 |
.map(|action_url| action_url.to_string()) |
| 567 | 509 |
.ok_or(AuthError::Structure(response_plist))?; |
| 568 | 510 |
|
| 569 |
- let server_provided_data = server_provided_data.unwrap_or_default(); |
|
| 570 |
- |
|
| 571 | 511 |
Ok(AuthOutcome::SecondaryActionRequired( |
| 572 | 512 |
server_provided_data, |
| 573 | 513 |
action_url, |
| ... | ... |
@@ -11,14 +11,14 @@ use std::fmt::{Display, Formatter};
|
| 11 | 11 |
#[derive(Debug)] |
| 12 | 12 |
pub enum ProvisioningError {
|
| 13 | 13 |
ADIError(ADIError), |
| 14 |
+ AppleError(AppleError), |
|
| 15 |
+ URLNotFound(String), |
|
| 14 | 16 |
StartProvisioningRequest(reqwest::Error), |
| 15 | 17 |
StartProvisioningRequestPlist(plist::Error), |
| 16 | 18 |
StartProvisioningRequestStructure(Dictionary), |
| 17 |
- AppleError(AppleError), |
|
| 18 | 19 |
FinishProvisioningRequest(reqwest::Error), |
| 19 | 20 |
FinishProvisioningRequestPlist(plist::Error), |
| 20 | 21 |
FinishProvisioningRequestStructure(Dictionary), |
| 21 |
- URLNotFound(String), |
|
| 22 | 22 |
} |
| 23 | 23 |
|
| 24 | 24 |
impl Display for ProvisioningError {
|
| ... | ... |
@@ -1,3 +1,6 @@ |
| 1 |
+use crate::grandslam::{GRANDSLAM_DSID, build_client_provided_data};
|
|
| 2 |
+use crate::http_session::{AnisetteHTTPSession, AppleError, URLBag, parse_status};
|
|
| 3 |
+use adi::proxy::{ADIError, ADIResult};
|
|
| 1 | 4 |
use aes::Aes256; |
| 2 | 5 |
use aes::cipher::consts::U16; |
| 3 | 6 |
use aes_gcm::aead::{Aead, Payload};
|
| ... | ... |
@@ -7,16 +10,14 @@ use base64::prelude::BASE64_STANDARD; |
| 7 | 10 |
use hmac::{Hmac, Mac};
|
| 8 | 11 |
use log::{trace, warn};
|
| 9 | 12 |
use plist::{Dictionary, Value};
|
| 13 |
+use plist_macros::{array, dict};
|
|
| 10 | 14 |
use reqwest::{Method, RequestBuilder};
|
| 11 | 15 |
use serde::Deserialize; |
| 12 | 16 |
use sha2::Sha256; |
| 13 |
-use adi::proxy::{ADIError, ADIResult};
|
|
| 14 |
-use plist_macros::{array, dict};
|
|
| 15 |
-use crate::grandslam::{build_client_provided_data, GRANDSLAM_DSID};
|
|
| 16 |
-use crate::http_session::{parse_status, AnisetteHTTPSession, AppleError, URLBag};
|
|
| 17 |
+use thiserror::Error; |
|
| 17 | 18 |
|
| 18 |
-#[derive(Debug, Deserialize)] |
|
| 19 |
-pub struct GSToken {
|
|
| 19 |
+#[derive(Debug, Deserialize, Clone)] |
|
| 20 |
+pub struct Token {
|
|
| 20 | 21 |
pub duration: u64, |
| 21 | 22 |
// #[serde(rename = "cts")] |
| 22 | 23 |
// pub start_epoch_millis: u64, |
| ... | ... |
@@ -49,7 +50,7 @@ impl AuthToken {
|
| 49 | 50 |
|
| 50 | 51 |
pub fn parse_tokens_from_server_provided_data( |
| 51 | 52 |
server_provided_data: &Dictionary, |
| 52 |
-) -> Option<(AuthToken, Vec<(String, GSToken)>)> {
|
|
| 53 |
+) -> Option<(AuthToken, Vec<(String, Token)>)> {
|
|
| 53 | 54 |
let alt_dsid = server_provided_data |
| 54 | 55 |
.get("adsid")
|
| 55 | 56 |
.and_then(|alt_dsid| alt_dsid.as_string()) |
| ... | ... |
@@ -86,85 +87,116 @@ pub fn parse_tokens_from_server_provided_data( |
| 86 | 87 |
|
| 87 | 88 |
match (alt_dsid, idms_token, session_key, cookie) {
|
| 88 | 89 |
(Some(alt_dsid), Some(idms_token), Some(session_key), Some(cookie)) => Some(( |
| 89 |
- AuthToken::new( |
|
| 90 |
- alt_dsid, |
|
| 91 |
- idms_token, |
|
| 92 |
- session_key, |
|
| 93 |
- cookie, |
|
| 94 |
- ), |
|
| 90 |
+ AuthToken::new(alt_dsid, idms_token, session_key, cookie), |
|
| 95 | 91 |
tokens.unwrap_or_default(), |
| 96 | 92 |
)), |
| 97 | 93 |
_ => None, |
| 98 | 94 |
} |
| 99 | 95 |
} |
| 100 | 96 |
|
| 101 |
-#[derive(Debug)] |
|
| 97 |
+#[derive(Debug, Error)] |
|
| 102 | 98 |
pub enum AppTokenRequestError {
|
| 103 |
- InvalidURLBag, |
|
| 104 |
- Anisette(ADIError), |
|
| 99 |
+ #[error("Cannot proceed: {0}")]
|
|
| 100 |
+ Apple(#[from] AppleError), |
|
| 101 |
+ #[error("Cannot generate device authentication data: {0}")]
|
|
| 102 |
+ Anisette(#[from] ADIError), |
|
| 103 |
+ #[error("The provided authentication token is not valid")]
|
|
| 105 | 104 |
InvalidAuthToken, |
| 106 |
- Network(reqwest::Error), |
|
| 107 |
- Parsing(plist::Error), |
|
| 105 |
+ // vvvv Internal errors vvvv |
|
| 106 |
+ #[error("Invalid URL bag")]
|
|
| 107 |
+ InvalidURLBag, |
|
| 108 |
+ #[error("Network error: {0}")]
|
|
| 109 |
+ Network(#[from] reqwest::Error), |
|
| 110 |
+ #[error("Failed to parse the app token request response: {0}")]
|
|
| 111 |
+ Parsing(#[from] plist::Error), |
|
| 112 |
+ #[error("Failed to parse the app token request response")]
|
|
| 108 | 113 |
Structure(Dictionary), |
| 109 |
- Apple(AppleError), |
|
| 114 |
+ #[error("Invalid token returned by the server")]
|
|
| 110 | 115 |
InvalidResponse, |
| 111 | 116 |
} |
| 112 | 117 |
|
| 113 |
-impl std::fmt::Display for AppTokenRequestError {
|
|
| 114 |
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
| 115 |
- match self {
|
|
| 116 |
- AppTokenRequestError::InvalidURLBag => write!(f, "Invalid URL bag"), |
|
| 117 |
- AppTokenRequestError::Anisette(err) => {
|
|
| 118 |
- write!(f, "Cannot generate device authentication data: {err}")
|
|
| 119 |
- } |
|
| 120 |
- AppTokenRequestError::InvalidAuthToken => {
|
|
| 121 |
- write!(f, "The provided authentication token is not valid") |
|
| 122 |
- } |
|
| 123 |
- AppTokenRequestError::Network(err) => write!(f, "Network error: {err}"),
|
|
| 124 |
- AppTokenRequestError::Parsing(err) => {
|
|
| 125 |
- write!(f, "Failed to parse the app token request response: {err}")
|
|
| 126 |
- } |
|
| 127 |
- AppTokenRequestError::Structure(_) => {
|
|
| 128 |
- write!(f, "Failed to parse the app token request response") |
|
| 129 |
- } |
|
| 130 |
- AppTokenRequestError::Apple(err) => write!(f, "Cannot proceed: {err}"),
|
|
| 131 |
- AppTokenRequestError::InvalidResponse => {
|
|
| 132 |
- write!(f, "Invalid token returned by the server") |
|
| 133 |
- } |
|
| 134 |
- } |
|
| 135 |
- } |
|
| 118 |
+pub struct AppTokenIdentifier<'lt>(pub &'lt str); |
|
| 119 |
+ |
|
| 120 |
+#[derive(Debug, Error)] |
|
| 121 |
+pub enum AuthenticatedRequestError {
|
|
| 122 |
+ #[error("Server returned: {0}")]
|
|
| 123 |
+ Apple(#[from] AppleError), |
|
| 124 |
+ #[error("Cannot generate Anisette headers: {0}")]
|
|
| 125 |
+ Anisette(#[from] ADIError), |
|
| 126 |
+ #[error("Invalid URL bag")]
|
|
| 127 |
+ InvalidURLBag, |
|
| 128 |
+ #[error("Network error: {0}")]
|
|
| 129 |
+ Network(#[from] reqwest::Error), |
|
| 130 |
+ #[error("Invalid server response")]
|
|
| 131 |
+ InvalidResponse(plist::Error), |
|
| 136 | 132 |
} |
| 137 | 133 |
|
| 138 |
-impl std::error::Error for AppTokenRequestError {}
|
|
| 134 |
+pub type AuthenticatedRequestResult<T> = Result<T, AuthenticatedRequestError>; |
|
| 139 | 135 |
|
| 140 | 136 |
pub struct AuthenticatedHTTPSession<'lt, 'adi> {
|
| 141 | 137 |
pub http_session: AnisetteHTTPSession<'lt, 'adi>, |
| 142 | 138 |
pub auth_token: AuthToken, |
| 139 |
+ pub hb_token: String, |
|
| 143 | 140 |
} |
| 144 | 141 |
|
| 145 | 142 |
impl<'a, 'b> AuthenticatedHTTPSession<'a, 'b> {
|
| 146 |
- pub fn new(http_session: AnisetteHTTPSession<'a, 'b>, auth_token: AuthToken) -> Self {
|
|
| 143 |
+ pub fn new( |
|
| 144 |
+ http_session: AnisetteHTTPSession<'a, 'b>, |
|
| 145 |
+ auth_token: AuthToken, |
|
| 146 |
+ heartbeat_token: Token, |
|
| 147 |
+ ) -> Self {
|
|
| 148 |
+ let hb_token = |
|
| 149 |
+ BASE64_STANDARD.encode(format!("{}:{}", auth_token.alt_dsid, heartbeat_token.token));
|
|
| 150 |
+ |
|
| 147 | 151 |
Self {
|
| 148 | 152 |
http_session, |
| 149 | 153 |
auth_token, |
| 154 |
+ hb_token, |
|
| 150 | 155 |
} |
| 151 | 156 |
} |
| 152 | 157 |
|
| 153 |
- pub fn url_bag(&self) -> &URLBag { self.http_session.url_bag() }
|
|
| 154 |
- pub fn simple_request_builder(&self, method: Method, url: &str) -> RequestBuilder { self.http_session.simple_request_builder(method, url) }
|
|
| 155 |
- pub fn anisette_request_builder(&self, method: Method, url: &str) -> ADIResult<RequestBuilder> { self.http_session.anisette_request_builder(GRANDSLAM_DSID, method, url) }
|
|
| 156 |
- pub fn authenticated_request_builder(&self, method: Method, url: &str) -> ADIResult<RequestBuilder> {
|
|
| 157 |
- Ok( |
|
| 158 |
- self.anisette_request_builder(method, url)? |
|
| 159 |
- .header("X-Apple-Identity-Token", self.auth_token.identity_token.as_str())
|
|
| 160 |
- ) |
|
| 158 |
+ pub fn url_bag(&self) -> &URLBag {
|
|
| 159 |
+ self.http_session.url_bag() |
|
| 160 |
+ } |
|
| 161 |
+ |
|
| 162 |
+ pub fn simple_request_builder(&self, method: Method, url: &str) -> RequestBuilder {
|
|
| 163 |
+ self.http_session.simple_request_builder(method, url) |
|
| 164 |
+ } |
|
| 165 |
+ |
|
| 166 |
+ pub fn anisette_request_builder(&self, method: Method, url: &str) -> ADIResult<RequestBuilder> {
|
|
| 167 |
+ self.http_session |
|
| 168 |
+ .anisette_request_builder(GRANDSLAM_DSID, method, url) |
|
| 169 |
+ } |
|
| 170 |
+ |
|
| 171 |
+ pub fn authenticated_request_builder( |
|
| 172 |
+ &self, |
|
| 173 |
+ method: Method, |
|
| 174 |
+ url: &str, |
|
| 175 |
+ ) -> ADIResult<RequestBuilder> {
|
|
| 176 |
+ self.anisette_request_builder(method, url).map(|builder| {
|
|
| 177 |
+ builder |
|
| 178 |
+ // .header( |
|
| 179 |
+ // "X-Apple-Identity-Token", |
|
| 180 |
+ // self.auth_token.identity_token.as_str(), |
|
| 181 |
+ // ) |
|
| 182 |
+ // .header("X-Apple-I-Identity-Id", self.auth_token.alt_dsid.as_str())
|
|
| 183 |
+ // .header("X-Apple-DSID", self.auth_token.alt_dsid.as_str())
|
|
| 184 |
+ // .header("X-Apple-GS-Token", self.auth_token.idms_token.as_str())
|
|
| 185 |
+ // .header("X-Apple-I-CK-Presence", "false")
|
|
| 186 |
+ .header("X-Apple-HB-Token", self.hb_token.as_str())
|
|
| 187 |
+ }) |
|
| 161 | 188 |
} |
| 162 | 189 |
|
| 163 | 190 |
pub async fn get_app_token( |
| 164 | 191 |
&self, |
| 165 |
- app_token_identifier: &str, // TODO: maybe create some type for app tokens identifier? |
|
| 166 |
- ) -> Result<GSToken, AppTokenRequestError> {
|
|
| 167 |
- let AuthenticatedHTTPSession { http_session, auth_token } = self;
|
|
| 192 |
+ app_token_identifier: AppTokenIdentifier<'_>, |
|
| 193 |
+ ) -> Result<Token, AppTokenRequestError> {
|
|
| 194 |
+ let app_token_identifier = app_token_identifier.0; |
|
| 195 |
+ let AuthenticatedHTTPSession {
|
|
| 196 |
+ http_session, |
|
| 197 |
+ auth_token, |
|
| 198 |
+ .. |
|
| 199 |
+ } = self; |
|
| 168 | 200 |
|
| 169 | 201 |
let gs_service_url = http_session |
| 170 | 202 |
.url_bag() |
| ... | ... |
@@ -172,7 +204,8 @@ impl<'a, 'b> AuthenticatedHTTPSession<'a, 'b> {
|
| 172 | 204 |
.and_then(Value::as_string) |
| 173 | 205 |
.ok_or(AppTokenRequestError::InvalidURLBag)?; |
| 174 | 206 |
|
| 175 |
- let cpd = build_client_provided_data(&http_session).map_err(AppTokenRequestError::Anisette)?; |
|
| 207 |
+ let cpd = |
|
| 208 |
+ build_client_provided_data(&http_session).map_err(AppTokenRequestError::Anisette)?; |
|
| 176 | 209 |
|
| 177 | 210 |
let checksum = Hmac::<Sha256>::new_from_slice(&auth_token.session_key) |
| 178 | 211 |
.map_err(|_| AppTokenRequestError::InvalidAuthToken)? |
| ... | ... |
@@ -229,7 +262,7 @@ impl<'a, 'b> AuthenticatedHTTPSession<'a, 'b> {
|
| 229 | 262 |
.and_then(|status| status.as_dictionary()) |
| 230 | 263 |
.ok_or(AppTokenRequestError::Structure(response_plist.clone()))?; |
| 231 | 264 |
|
| 232 |
- parse_status(status).map_err(AppTokenRequestError::Apple)?; |
|
| 265 |
+ parse_status(status)?; |
|
| 233 | 266 |
|
| 234 | 267 |
let encrypted_tokens = response_dict |
| 235 | 268 |
.get("et")
|
| ... | ... |
@@ -270,16 +303,37 @@ impl<'a, 'b> AuthenticatedHTTPSession<'a, 'b> {
|
| 270 | 303 |
.ok_or(AppTokenRequestError::InvalidResponse) |
| 271 | 304 |
} |
| 272 | 305 |
|
| 273 |
- pub async fn validate_code(&self, validation_code: &str) -> Result<(), AppTokenRequestError> { // TODO: change that error type.
|
|
| 306 |
+ pub async fn fetch_user_info(&self) -> AuthenticatedRequestResult<Dictionary> {
|
|
| 307 |
+ let url = self |
|
| 308 |
+ .http_session |
|
| 309 |
+ .url_bag() |
|
| 310 |
+ .get("fetchUserInfo")
|
|
| 311 |
+ .and_then(Value::as_string) |
|
| 312 |
+ .ok_or(AuthenticatedRequestError::InvalidURLBag)?; |
|
| 313 |
+ |
|
| 314 |
+ let response = self |
|
| 315 |
+ .authenticated_request_builder(Method::GET, url)? |
|
| 316 |
+ .send() |
|
| 317 |
+ .await? |
|
| 318 |
+ .bytes() |
|
| 319 |
+ .await?; |
|
| 320 |
+ |
|
| 321 |
+ Ok(plist::from_bytes(&response).map_err(AuthenticatedRequestError::InvalidResponse)?) |
|
| 322 |
+ } |
|
| 323 |
+ |
|
| 324 |
+ pub async fn validate_code( |
|
| 325 |
+ &self, |
|
| 326 |
+ validation_code: &str, |
|
| 327 |
+ ) -> Result<(), Box<dyn std::error::Error>> {
|
|
| 328 |
+ // TODO: change that error type. |
|
| 274 | 329 |
let validate_code_url = self |
| 275 | 330 |
.url_bag() |
| 276 | 331 |
.get("validateCode")
|
| 277 | 332 |
.and_then(Value::as_string) |
| 278 | 333 |
.ok_or(AppTokenRequestError::InvalidURLBag)?; |
| 279 | 334 |
|
| 280 |
- let _ = |
|
| 281 |
- self.authenticated_request_builder(Method::POST, validate_code_url) |
|
| 282 |
- .map_err(AppTokenRequestError::Anisette)? |
|
| 335 |
+ let _ = self |
|
| 336 |
+ .authenticated_request_builder(Method::POST, validate_code_url)? |
|
| 283 | 337 |
.header("security-code", validation_code);
|
| 284 | 338 |
|
| 285 | 339 |
todo!() |
| ... | ... |
@@ -116,8 +116,10 @@ impl<'lt> BasicHTTPSession<'lt> {
|
| 116 | 116 |
let mut headers = HeaderMap::new(); |
| 117 | 117 |
headers.insert( |
| 118 | 118 |
"User-Agent", |
| 119 |
- client_bundle_info |
|
| 120 |
- .bundle_name |
|
| 119 |
+ format!( |
|
| 120 |
+ "{}/{}",
|
|
| 121 |
+ client_bundle_info.bundle_name, client_bundle_info.bundle_version |
|
| 122 |
+ ) |
|
| 121 | 123 |
.parse() |
| 122 | 124 |
.map_err(HTTPSessionCreationError::InvalidHeader)?, |
| 123 | 125 |
); |
| ... | ... |
@@ -5,11 +5,13 @@ use crate::http_session::{
|
| 5 | 5 |
URLBagError, |
| 6 | 6 |
}; |
| 7 | 7 |
use adi::proxy::ADIError; |
| 8 |
+use base64::Engine; |
|
| 9 |
+use base64::prelude::BASE64_STANDARD; |
|
| 8 | 10 |
use bytes::Bytes; |
| 9 | 11 |
use plist::{Dictionary, Value};
|
| 10 | 12 |
use plist_macros::dict; |
| 11 | 13 |
use reqwest::Method; |
| 12 |
-use std::fmt::{Display, Formatter};
|
|
| 14 |
+use thiserror::Error; |
|
| 13 | 15 |
|
| 14 | 16 |
pub async fn http_session<'lt>( |
| 15 | 17 |
device: Device, |
| ... | ... |
@@ -17,9 +19,11 @@ pub async fn http_session<'lt>( |
| 17 | 19 |
) -> Result<HTTPSession<'lt>, HTTPSessionCreationError> {
|
| 18 | 20 |
let http_session = BasicHTTPSession::new(device, client_bundle_info, None)?; |
| 19 | 21 |
|
| 22 |
+ // https://init.itunes.apple.com/WebObjects/MZInit.woa/wa/initiateSession |
|
| 20 | 23 |
let url_bag_response = http_session |
| 21 |
- .request_builder(Method::GET, "https://sandbox.itunes.apple.com/bag.xml") |
|
| 22 |
- .query(&[("ix", 6)])
|
|
| 24 |
+ .request_builder(Method::GET, "https://init.itunes.apple.com/bag.xml") |
|
| 25 |
+ .query(&[("ix", "6")])
|
|
| 26 |
+ .header("Content-Type", "application/x-apple-plist")
|
|
| 23 | 27 |
.send() |
| 24 | 28 |
.await |
| 25 | 29 |
.map_err(HTTPSessionCreationError::Reqwest)? |
| ... | ... |
@@ -32,6 +36,8 @@ pub async fn http_session<'lt>( |
| 32 | 36 |
let url_bag = parse_url_bag_response(url_bag_response) |
| 33 | 37 |
.map_err(|_| HTTPSessionCreationError::InvalidURLBagResponseStructure)?; |
| 34 | 38 |
|
| 39 |
+ println!("url_bag: {:#?}", url_bag);
|
|
| 40 |
+ |
|
| 35 | 41 |
HTTPSession::new(http_session, url_bag) |
| 36 | 42 |
} |
| 37 | 43 |
|
| ... | ... |
@@ -42,39 +48,64 @@ pub(crate) fn parse_url_bag_response(url_bag_response: Bytes) -> Result<Dictiona |
| 42 | 48 |
Ok(url_bag_plist) |
| 43 | 49 |
} |
| 44 | 50 |
|
| 45 |
-#[derive(Debug)] |
|
| 51 |
+pub async fn setup_sap(http_session: &HTTPSession<'_>) -> Result<(), Box<dyn std::error::Error>> {
|
|
| 52 |
+ // TODO: error type |
|
| 53 |
+ let sign_sap_setup_url = http_session |
|
| 54 |
+ .url_bag() |
|
| 55 |
+ .get("sign-sap-setup")
|
|
| 56 |
+ .and_then(Value::as_string) |
|
| 57 |
+ .ok_or(AuthError::InvalidURLBag)?; |
|
| 58 |
+ |
|
| 59 |
+ let sap_certificate_response = http_session |
|
| 60 |
+ .request_builder(Method::GET, sign_sap_setup_url) |
|
| 61 |
+ .send() |
|
| 62 |
+ .await? |
|
| 63 |
+ .error_for_status()? |
|
| 64 |
+ .bytes() |
|
| 65 |
+ .await?; |
|
| 66 |
+ |
|
| 67 |
+ let sap_certificate_dict: Dictionary = |
|
| 68 |
+ plist::from_bytes(&sap_certificate_response).map_err(|_| URLBagError::Parsing)?; |
|
| 69 |
+ |
|
| 70 |
+ let sap_certificate = sap_certificate_dict |
|
| 71 |
+ .get("sign-sap-setup-buffer")
|
|
| 72 |
+ .ok_or(URLBagError::Parsing)? |
|
| 73 |
+ .as_data() |
|
| 74 |
+ .ok_or(URLBagError::Parsing)?; |
|
| 75 |
+ |
|
| 76 |
+ todo!() |
|
| 77 |
+} |
|
| 78 |
+ |
|
| 79 |
+#[derive(Debug, Error)] |
|
| 46 | 80 |
pub enum AuthError {
|
| 47 |
- Apple(AppleError), |
|
| 48 |
- Anisette(ADIError), |
|
| 49 |
- Network(reqwest::Error), |
|
| 81 |
+ #[error("Could not log-in to Apple servers: {0}")]
|
|
| 82 |
+ Apple(#[from] AppleError), |
|
| 83 |
+ #[error("Cannot generate device authentication data: {0}")]
|
|
| 84 |
+ Anisette(#[from] ADIError), |
|
| 85 |
+ #[error("Network error: {0}")]
|
|
| 86 |
+ Network(#[from] reqwest::Error), |
|
| 87 |
+ #[error("Cannot find the endpoint in the URL bag.")]
|
|
| 50 | 88 |
InvalidURLBag, |
| 89 |
+ #[error("Cannot parse HTTP response")]
|
|
| 51 | 90 |
Parsing, |
| 52 | 91 |
} |
| 53 | 92 |
|
| 54 |
-impl Display for AuthError {
|
|
| 55 |
- fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
|
| 56 |
- match self {
|
|
| 57 |
- AuthError::Apple(err) => {
|
|
| 58 |
- write!(f, "Could not log-in to Apple servers: {err}")
|
|
| 59 |
- } |
|
| 60 |
- AuthError::Anisette(err) => {
|
|
| 61 |
- write!(f, "Cannot generate device authentication data: {err}")
|
|
| 62 |
- } |
|
| 63 |
- AuthError::Network(err) => {
|
|
| 64 |
- write!(f, "Network error: {err}")
|
|
| 65 |
- } |
|
| 66 |
- AuthError::InvalidURLBag => {
|
|
| 67 |
- write!(f, "Cannot find the endpoint in the URL bag.") |
|
| 68 |
- } |
|
| 69 |
- AuthError::Parsing => {
|
|
| 70 |
- write!(f, "Cannot parse HTTP response") |
|
| 71 |
- } |
|
| 72 |
- } |
|
| 73 |
- } |
|
| 74 |
-} |
|
| 75 |
- |
|
| 76 |
-impl std::error::Error for AuthError {}
|
|
| 77 |
- |
|
| 93 |
+/// |
|
| 94 |
+/// |
|
| 95 |
+/// # Arguments |
|
| 96 |
+/// |
|
| 97 |
+/// * `http_session`: The HTTPSession to use for the requests. |
|
| 98 |
+/// * `apple_id`: Apple Account identifier |
|
| 99 |
+/// * `password`: Apple Account password (can be a PET) |
|
| 100 |
+/// * `attempt`: Current attempt count. The first attempt should be numbered 1. |
|
| 101 |
+/// |
|
| 102 |
+/// returns: Result<(), AuthError> |
|
| 103 |
+/// |
|
| 104 |
+/// # Examples |
|
| 105 |
+/// |
|
| 106 |
+/// ``` |
|
| 107 |
+/// |
|
| 108 |
+/// ``` |
|
| 78 | 109 |
pub async fn login( |
| 79 | 110 |
http_session: &AnisetteHTTPSession<'_, '_>, |
| 80 | 111 |
apple_id: &str, |
| ... | ... |
@@ -85,53 +116,60 @@ pub async fn login( |
| 85 | 116 |
.url_bag() |
| 86 | 117 |
.get("authenticateAccount")
|
| 87 | 118 |
.and_then(Value::as_string) |
| 88 |
- .ok_or(AuthError::InvalidURLBag)? |
|
| 89 |
- .replace("sandbox", "p51-buy");
|
|
| 119 |
+ .ok_or(AuthError::InvalidURLBag)?; |
|
| 90 | 120 |
|
| 91 | 121 |
let adi_proxy = http_session.adi_proxy(); |
| 92 | 122 |
|
| 93 |
- /* |
|
| 94 |
- "guid": "", |
|
| 95 |
- "kbsync": vec![], |
|
| 96 |
- */ |
|
| 123 |
+ let accounts = adi_proxy |
|
| 124 |
+ .get_all_provisioned_accounts()? |
|
| 125 |
+ .iter() |
|
| 126 |
+ .map(|account| {
|
|
| 127 |
+ Value::Dictionary(dict! {
|
|
| 128 |
+ "dsid": account.ds_id, |
|
| 129 |
+ "mid": BASE64_STANDARD.encode(&account.mid), |
|
| 130 |
+ "otp": BASE64_STANDARD.encode(&account.otp), |
|
| 131 |
+ }) |
|
| 132 |
+ }) |
|
| 133 |
+ .collect::<Vec<_>>(); |
|
| 97 | 134 |
|
| 98 | 135 |
let request_plist = dict! {
|
| 99 | 136 |
"appleId": apple_id, |
| 100 | 137 |
"attempt": attempt, |
| 138 |
+ "auth-mid-otp": accounts, |
|
| 101 | 139 |
"createSession": true, |
| 140 |
+ "guid": "A0DE61112331", // TODO |
|
| 141 |
+ "machineName": "MacBook", // TODO |
|
| 102 | 142 |
"password": password, |
| 103 | 143 |
"passwordSettings": dict! {
|
| 104 |
- "free": "always", |
|
| 105 |
- "paid": "always" |
|
| 144 |
+ "free": "", |
|
| 145 |
+ "paid": "" |
|
| 106 | 146 |
}, |
| 107 |
- "rmp": "0", |
|
| 147 |
+ // "kbsync": vec![], |
|
| 148 |
+ "uuid": "3E72931A-9BFE-46EB-9EEA-3383CE091615", // TODO |
|
| 108 | 149 |
"why": "signIn", |
| 109 | 150 |
}; |
| 110 | 151 |
|
| 111 | 152 |
let mut request_body = Vec::new(); |
| 112 | 153 |
plist::to_writer_xml(&mut request_body, &request_plist).unwrap(); |
| 113 | 154 |
|
| 114 |
- /* |
|
| 155 |
+ // println!("request_body: {}", String::from_utf8(request_body).unwrap());
|
|
| 156 |
+ |
|
| 157 |
+ let signature = todo!(); |
|
| 158 |
+ |
|
| 115 | 159 |
let response = http_session |
| 116 |
- .anisette_request_builder(GRANDSLAM_DSID, Method::POST, &authenticate_url) |
|
| 117 |
- .map_err(AuthError::Anisette)? |
|
| 160 |
+ .anisette_request_builder(-2, Method::POST, authenticate_url)? |
|
| 118 | 161 |
.body(request_body) |
| 162 |
+ .header("Content-Type", "application/x-apple-plist")
|
|
| 163 |
+ // .header("X-Apple-ActionSignature", signature)
|
|
| 119 | 164 |
.send() |
| 120 | 165 |
.await |
| 121 |
- .and_then(|response| response.error_for_status()) |
|
| 122 |
- .map_err(AuthError::Network)? |
|
| 166 |
+ .and_then(|response| response.error_for_status())? |
|
| 123 | 167 |
.text() |
| 124 |
- .await |
|
| 125 |
- .map_err(AuthError::Network)?; |
|
| 168 |
+ .await?; |
|
| 126 | 169 |
|
| 127 | 170 |
println!("response: {:?}", response);
|
| 128 | 171 |
|
| 129 |
- .bytes() |
|
| 130 |
- .await |
|
| 131 |
- .map_err(AuthError::Network)?; |
|
| 132 |
- |
|
| 133 |
- |
|
| 134 |
- |
|
| 172 |
+ /* |
|
| 135 | 173 |
let response_plist: Dictionary = |
| 136 | 174 |
plist::from_bytes(&response).map_err(|err| AuthError::Parsing)?; |
| 137 | 175 |
|
| ... | ... |
@@ -141,7 +179,7 @@ pub async fn login( |
| 141 | 179 |
.ok_or(AuthError::Parsing)?; |
| 142 | 180 |
|
| 143 | 181 |
println!("{:#?}", response_dict);
|
| 144 |
- // */ |
|
| 145 | 182 |
|
| 146 | 183 |
Ok(()) |
| 184 |
+ // */ |
|
| 147 | 185 |
} |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 1 |
+use plist::{Dictionary, Value};
|
|
| 2 |
+use reqwest::Body; |
|
| 3 |
+ |
|
| 4 |
+pub fn plist_to_body(val: Value) -> Body {
|
|
| 5 |
+ // UNWRAP safety: I don't know any reason why the serializer should fail. |
|
| 6 |
+ // If it happens, I would guess it's a serious flaw in the plist crate. |
|
| 7 |
+ let mut request_body = Vec::new(); |
|
| 8 |
+ plist::to_writer_xml(&mut request_body, &val).expect("Failed to serialize plist?");
|
|
| 9 |
+ |
|
| 10 |
+ Body::from(request_body) |
|
| 11 |
+} |
|
| 12 |
+ |
|
| 13 |
+pub fn dict_to_body(dict: Dictionary) -> Body {
|
|
| 14 |
+ plist_to_body(Value::Dictionary(dict)) |
|
| 15 |
+} |
| ... | ... |
@@ -168,7 +168,9 @@ impl<'data> Library<'data> {
|
| 168 | 168 |
} |
| 169 | 169 |
}; |
| 170 | 170 |
|
| 171 |
- elf.shdr_relocs.iter().for_each(|(_, reloc_section)| relocate(reloc_section)); |
|
| 171 |
+ elf.shdr_relocs |
|
| 172 |
+ .iter() |
|
| 173 |
+ .for_each(|(_, reloc_section)| relocate(reloc_section)); |
|
| 172 | 174 |
|
| 173 | 175 |
let gnu_hash_section = elf |
| 174 | 176 |
.section_headers |
| ... | ... |
@@ -8,10 +8,13 @@ adi.workspace = true |
| 8 | 8 |
android-coreadi.workspace = true |
| 9 | 9 |
apple-account.workspace = true |
| 10 | 10 |
elf-loader.workspace = true |
| 11 |
+xcode.workspace = true |
|
| 11 | 12 |
|
| 12 | 13 |
tokio.workspace = true |
| 13 | 14 |
libc = "0.2.176" |
| 15 |
+reqwest = "0.13.1" |
|
| 14 | 16 |
env_logger = "0.11.8" |
| 17 |
+base64 = "0.22.1" |
|
| 15 | 18 |
|
| 16 | 19 |
[target.'cfg(target_os = "macos")'.dependencies] |
| 17 | 20 |
adid-proxy.workspace = true |
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
use adi::proxy::ADIProxy; |
| 2 | 2 |
use android_coreadi::AndroidCoreADIProxy; |
| 3 |
-use apple_account::bundle_information::{APPLE_TV_BUNDLE_INFORMATION, XCODE_BUNDLE_INFORMATION};
|
|
| 3 |
+use apple_account::bundle_information::APPLE_TV_BUNDLE_INFORMATION; |
|
| 4 | 4 |
use apple_account::device::Device; |
| 5 | 5 |
use apple_account::grandslam::{AuthOutcome, AuthenticatedHTTPSession};
|
| 6 | 6 |
use apple_account::http_session::AnisetteHTTPSession; |
| ... | ... |
@@ -24,7 +24,7 @@ async fn grandslam_test( |
| 24 | 24 |
// println!("{:#02X?}", proxy.get_all_provisioned_accounts());
|
| 25 | 25 |
|
| 26 | 26 |
let http_session = AnisetteHTTPSession::new( |
| 27 |
- grandslam::http_session(device, XCODE_BUNDLE_INFORMATION).await?, |
|
| 27 |
+ grandslam::http_session(device, APPLE_TV_BUNDLE_INFORMATION).await?, |
|
| 28 | 28 |
proxy, |
| 29 | 29 |
); |
| 30 | 30 |
|
| ... | ... |
@@ -32,21 +32,54 @@ async fn grandslam_test( |
| 32 | 32 |
grandslam::provision(&http_session).await?; |
| 33 | 33 |
} |
| 34 | 34 |
|
| 35 |
+ // Here we should fetch_auth_mode first to know if we should log-in with a password. |
|
| 35 | 36 |
let auth_outcome = grandslam::login(&http_session, apple_id, password).await?; |
| 36 | 37 |
|
| 37 | 38 |
match &auth_outcome {
|
| 38 | 39 |
AuthOutcome::Success(server_provided_data) |
| 39 |
- | AuthOutcome::SecondaryActionRequired(server_provided_data, _) => {
|
|
| 40 |
+ | AuthOutcome::SecondaryActionRequired(Some(server_provided_data), _) => {
|
|
| 40 | 41 |
match grandslam::parse_tokens_from_server_provided_data(server_provided_data) {
|
| 41 |
- Some((auth_token, _)) => {
|
|
| 42 |
- let http_session = AuthenticatedHTTPSession::new( |
|
| 43 |
- http_session, |
|
| 44 |
- auth_token |
|
| 45 |
- ); |
|
| 46 |
- let xcode_token = |
|
| 47 |
- http_session.get_app_token("com.apple.gs.xcode.auth")
|
|
| 42 |
+ Some((auth_token, tokens)) => {
|
|
| 43 |
+ /* |
|
| 44 |
+ let Some((_, token)) = tokens |
|
| 45 |
+ .iter() |
|
| 46 |
+ .find(|(name, _)| name == "com.apple.gs.idms.pet") |
|
| 47 |
+ else {
|
|
| 48 |
+ todo!() |
|
| 49 |
+ }; |
|
| 50 |
+ |
|
| 51 |
+ itunes_test(proxy, apple_id, token.token.as_str()).await?; |
|
| 52 |
+ // */ |
|
| 53 |
+ |
|
| 54 |
+ let url = http_session |
|
| 55 |
+ .url_bag() |
|
| 56 |
+ .get("fetchUserInfo")
|
|
| 57 |
+ .unwrap() |
|
| 58 |
+ .as_string() |
|
| 59 |
+ .unwrap() |
|
| 60 |
+ .to_owned(); |
|
| 61 |
+ |
|
| 62 |
+ let (_, hb_token) = tokens |
|
| 63 |
+ .iter() |
|
| 64 |
+ .find(|(name, _)| name == "com.apple.gs.idms.hb") |
|
| 65 |
+ .unwrap(); |
|
| 66 |
+ |
|
| 67 |
+ let http_session = |
|
| 68 |
+ AuthenticatedHTTPSession::new(http_session, auth_token, hb_token.clone()); |
|
| 69 |
+ |
|
| 70 |
+ let text = http_session |
|
| 71 |
+ .authenticated_request_builder(reqwest::Method::GET, url.as_str())? |
|
| 72 |
+ .send() |
|
| 73 |
+ .await? |
|
| 74 |
+ .text() |
|
| 48 | 75 |
.await?; |
| 49 |
- println!("token: {:?}", xcode_token);
|
|
| 76 |
+ |
|
| 77 |
+ println!("{}", text);
|
|
| 78 |
+ |
|
| 79 |
+ // let xcode_token = http_session |
|
| 80 |
+ // .get_app_token("com.apple.gs.xcode.auth")
|
|
| 81 |
+ // .await?; |
|
| 82 |
+ // println!("token: {:?}", xcode_token);
|
|
| 50 | 83 |
} |
| 51 | 84 |
None => {
|
| 52 | 85 |
let AuthOutcome::SecondaryActionRequired(_, _secondary_action) = auth_outcome |
| ... | ... |
@@ -57,7 +90,8 @@ async fn grandslam_test( |
| 57 | 90 |
} |
| 58 | 91 |
} |
| 59 | 92 |
} |
| 60 |
- AuthOutcome::AnisetteResyncRequired(_) |
|
| 93 |
+ AuthOutcome::SecondaryActionRequired(_, _) |
|
| 94 |
+ | AuthOutcome::AnisetteResyncRequired(_) |
|
| 61 | 95 |
| AuthOutcome::AnisetteReprovisionRequired |
| 62 | 96 |
| AuthOutcome::UrlSwitchingRequired(_) => todo!(), |
| 63 | 97 |
} |
| ... | ... |
@@ -83,6 +117,8 @@ async fn itunes_test( |
| 83 | 117 |
|
| 84 | 118 |
let auth_outcome = itunes::login(&http_session, apple_id, password, 1).await?; |
| 85 | 119 |
|
| 120 |
+ println!("{:?}", auth_outcome);
|
|
| 121 |
+ |
|
| 86 | 122 |
Ok(()) |
| 87 | 123 |
} |
| 88 | 124 |
|
| ... | ... |
@@ -97,7 +133,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
| 97 | 133 |
println!("{}", code);
|
| 98 | 134 |
} |
| 99 | 135 |
let proxy = {
|
| 100 |
- let core_adi_data = fs::read("nodistrib/lib/x86_64/libCoreADI.so")?;
|
|
| 136 |
+ let core_adi_data = fs::read("nodistrib/lib/arm64-v8a/libCoreADI.so")?;
|
|
| 101 | 137 |
let proxy = AndroidCoreADIProxy::load_library(core_adi_data)?; |
| 102 | 138 |
|
| 103 | 139 |
proxy.set_android_id("0123456789012345")?;
|
| ... | ... |
@@ -0,0 +1,12 @@ |
| 1 |
+use apple_account::bundle_information::BundleInformation; |
|
| 2 |
+use apple_account::grandslam::AppTokenIdentifier; |
|
| 3 |
+ |
|
| 4 |
+/// From Xcode 16.4 |
|
| 5 |
+pub const XCODE_BUNDLE_INFORMATION: BundleInformation = BundleInformation {
|
|
| 6 |
+ bundle_name: "Xcode", |
|
| 7 |
+ bundle_identifier: "com.apple.dt.Xcode", |
|
| 8 |
+ bundle_version: "23792", |
|
| 9 |
+}; |
|
| 10 |
+ |
|
| 11 |
+pub const XCODE_TOKEN_IDENTIFIER: AppTokenIdentifier = |
|
| 12 |
+ AppTokenIdentifier("com.apple.gs.xcode.auth");
|
|
| 0 | 13 |