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:
@@ -8,27 +8,26 @@ default = []
|
||||
vendored-botan = ["botan/vendored"]
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde_json = { version = "1.0.142" }
|
||||
base64 = "0.13.1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = { version = "1" }
|
||||
base64 = "0.22"
|
||||
srp = { version = "0.6.0", path = "./rustcrypto-srp" }
|
||||
pbkdf2 = { version = "0.11.0" }
|
||||
sha2 = { version = "0.10.6" }
|
||||
rand = { version = "0.8.5" }
|
||||
rustls = { version = "0.20.7" }
|
||||
rustls-pemfile = { version = "1.0.1" }
|
||||
plist = { version = "1.7.2" }
|
||||
pbkdf2 = "0.11"
|
||||
sha2 = "0.10"
|
||||
rand = "0.9"
|
||||
rustls = "0.23"
|
||||
rustls-pemfile = "2.2"
|
||||
plist = "1.7.2"
|
||||
hmac = "0.12.1"
|
||||
num-bigint = "0.4.3"
|
||||
cbc = { version = "0.1.2", features = ["std"] }
|
||||
aes = "0.8.2"
|
||||
pkcs7 = "0.3.0"
|
||||
pkcs7 = "0.4.1"
|
||||
reqwest = { version = "0.11.14", features = ["blocking", "json", "default-tls"] }
|
||||
omnisette = {path = "../omnisette", features = ["remote-anisette-v3"]}
|
||||
thiserror = "1.0.58"
|
||||
thiserror = "2"
|
||||
tokio = "1"
|
||||
botan = { version = "0.11.1" }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
botan = "0.12.0"
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1", features = ["rt", "macros"] }
|
||||
|
||||
@@ -14,15 +14,15 @@ rust-version = "1.56"
|
||||
|
||||
[dependencies]
|
||||
num-bigint = "0.4"
|
||||
generic-array = "0.14"
|
||||
generic-array = "1"
|
||||
digest = "0.10"
|
||||
lazy_static = "1.2"
|
||||
subtle = "2.4"
|
||||
base64 = "0.21.0"
|
||||
base64 = "0.22"
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.3"
|
||||
hex-literal = "1"
|
||||
num-traits = "0.2"
|
||||
rand = "0.8"
|
||||
sha1 = "0.10.6"
|
||||
sha2 = "0.10.8"
|
||||
rand = "0.9"
|
||||
sha1 = "0.10"
|
||||
sha2 = "0.10"
|
||||
|
||||
@@ -15,11 +15,7 @@ impl AnisetteData {
|
||||
let mut b = AnisetteHeaders::get_anisette_headers_provider(config.clone())?;
|
||||
let base_headers = b.provider.get_authentication_headers().await?;
|
||||
|
||||
Ok(AnisetteData {
|
||||
base_headers,
|
||||
generated_at: SystemTime::now(),
|
||||
config,
|
||||
})
|
||||
Ok(AnisetteData { base_headers, generated_at: SystemTime::now(), config })
|
||||
}
|
||||
|
||||
pub fn needs_refresh(&self) -> bool {
|
||||
@@ -69,7 +65,7 @@ impl AnisetteData {
|
||||
"X-Apple-App-Info".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 {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::{anisette::AnisetteData, Error};
|
||||
use aes::cipher::block_padding::Pkcs7;
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
use botan::Cipher;
|
||||
use cbc::cipher::{BlockDecryptMut, KeyIvInit};
|
||||
use hmac::{Hmac, Mac};
|
||||
@@ -269,7 +270,6 @@ impl AppleAccount {
|
||||
return Err(err_check.err().unwrap());
|
||||
}
|
||||
|
||||
// --- D code logic starts here ---
|
||||
let encrypted_token = res
|
||||
.get("et")
|
||||
.ok_or(Error::Parse)?
|
||||
@@ -286,7 +286,7 @@ impl AppleAccount {
|
||||
"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..];
|
||||
|
||||
if sk.len() != 32 {
|
||||
@@ -296,8 +296,6 @@ impl AppleAccount {
|
||||
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)
|
||||
.map_err(|_| Error::Parse)?;
|
||||
cipher.set_key(sk).map_err(|_| Error::Parse)?;
|
||||
@@ -357,14 +355,17 @@ impl AppleAccount {
|
||||
///
|
||||
/// let anisette = AnisetteData::new();
|
||||
/// let account = AppleAccount::login(
|
||||
/// || ("test@waffle.me", "password")
|
||||
/// || "123123",
|
||||
/// || Ok(("test@waffle.me", "password"))
|
||||
/// || Ok("123123"),
|
||||
/// anisette
|
||||
/// );
|
||||
/// ```
|
||||
/// 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
|
||||
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,
|
||||
tfa_closure: G,
|
||||
anisette: AnisetteData,
|
||||
@@ -378,15 +379,25 @@ impl AppleAccount {
|
||||
match response {
|
||||
LoginState::NeedsDevice2FA => response = _self.send_2fa_to_devices().await?,
|
||||
LoginState::Needs2FAVerification => {
|
||||
response = _self.verify_2fa(tfa_closure().map_err(|e| {
|
||||
Error::AuthSrpWithMessage(0, format!("Failed to get 2FA code: {}", e))
|
||||
})?).await?
|
||||
response = _self
|
||||
.verify_2fa(tfa_closure().map_err(|e| {
|
||||
Error::AuthSrpWithMessage(0, format!("Failed to get 2FA code: {}", e))
|
||||
})?)
|
||||
.await?
|
||||
}
|
||||
LoginState::NeedsSMS2FA => response = _self.send_sms_2fa_to_devices(1).await?,
|
||||
LoginState::NeedsSMS2FAVerification(body) => {
|
||||
response = _self.verify_sms_2fa(tfa_closure().map_err(|e| {
|
||||
Error::AuthSrpWithMessage(0, format!("Failed to get SMS 2FA code: {}", e))
|
||||
})?, body).await?
|
||||
response = _self
|
||||
.verify_sms_2fa(
|
||||
tfa_closure().map_err(|e| {
|
||||
Error::AuthSrpWithMessage(
|
||||
0,
|
||||
format!("Failed to get SMS 2FA code: {}", e),
|
||||
)
|
||||
})?,
|
||||
body,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
LoginState::NeedsLogin => {
|
||||
response = _self.login_email_pass(&username, &password).await?
|
||||
@@ -735,7 +746,7 @@ impl AppleAccount {
|
||||
let dsid = spd.get("adsid").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;
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
// use icloud_auth::ani
|
||||
use std::sync::Arc;
|
||||
|
||||
use base64::engine::{general_purpose, Engine};
|
||||
use num_bigint::BigUint;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use srp::{
|
||||
client::{SrpClient, SrpClientVerifier},
|
||||
@@ -11,15 +8,18 @@ use srp::{
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn auth_debug() {
|
||||
// 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 password = "WaffleTest123";
|
||||
let salt = base64::decode("6fK6ailLUcp2kJswJVrKjQ==").unwrap();
|
||||
let salt = general_purpose::STANDARD
|
||||
.decode("6fK6ailLUcp2kJswJVrKjQ==")
|
||||
.unwrap();
|
||||
let iters = 20832;
|
||||
|
||||
let mut password_hasher = sha2::Sha256::new();
|
||||
@@ -41,7 +41,9 @@ mod tests {
|
||||
|
||||
// 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 a_pub_compute =
|
||||
@@ -49,14 +51,21 @@ mod tests {
|
||||
// expect it to be same to a_pub
|
||||
println!(
|
||||
"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();
|
||||
println!("fixed b_pub: {:?}", base64::encode(&b_pub));
|
||||
let b_pub = general_purpose::STANDARD.decode("HlWxsRmNi/9DCGxYCoqCTfdSvpbx3mrgFLQfOsgf3Rojn7MQQN/g63PwlBghUcVVB4//yAaRRnz/VIByl8thA9AKuVZl8k52PAHKSh4e7TuXSeYCFr0+GYu8/hFdMDl42219uzSuOXuaKGVKq6hxEAf3n3uXXgQRkXWtLFJ5nn1wq/emf46hYAHzc/pYyvckAdh9WDCw95IXbzKD8LcPw/0ZQoydMuXgW2ZKZ52fiyEs94IZ7L5RLL7jY1nVdwtsp2fxeqiZ3DNmVZ2GdNrbJGT//160tyd2evtUtehr8ygXNzjWdjV0cc4+1F38ywSPFyieVzVTYzDywRllgo3A5A==").unwrap();
|
||||
println!(
|
||||
"fixed b_pub: {:?}",
|
||||
general_purpose::STANDARD.encode(&b_pub)
|
||||
);
|
||||
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(
|
||||
&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"]
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.21"
|
||||
hex = "0.4.3"
|
||||
base64 = "0.22"
|
||||
hex = "0.4"
|
||||
plist = "1.4"
|
||||
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls", "gzip"] }
|
||||
rand = "0.8"
|
||||
sha2 = "0.10.8"
|
||||
rand = "0.9"
|
||||
sha2 = "0.10"
|
||||
uuid = { version = "1.3", features = [ "v4", "fast-rng", "macro-diagnostics" ] }
|
||||
android-loader = { git = "https://github.com/Dadoum/android-loader", branch = "bigger_pages" }
|
||||
libc = "0.2"
|
||||
@@ -23,11 +23,11 @@ log = "0.4"
|
||||
async-trait = { version = "0.1", optional = true }
|
||||
remove-async-await = { version = "1.0", optional = true }
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
serde_json = { version = "1.0.142", optional = true }
|
||||
tokio-tungstenite = { version = "0.20.1", optional = true, features = ["rustls-tls-webpki-roots"] }
|
||||
serde_json = { version = "1.0.115", optional = true }
|
||||
tokio-tungstenite = { version = "0.27.0", optional = true, features = ["rustls-tls-webpki-roots"] }
|
||||
futures-util = { version = "0.3.28", optional = true }
|
||||
chrono = { version = "0.4.37", optional = true }
|
||||
thiserror = "1.0.58"
|
||||
thiserror = "2"
|
||||
anyhow = "1.0.81"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
|
||||
@@ -46,7 +46,7 @@ pub enum ADIError {
|
||||
ReqwestError(#[from] reqwest::Error),
|
||||
Base64Error(#[from] base64::DecodeError),
|
||||
InvalidHeaderValue(#[from] InvalidHeaderValue),
|
||||
IOError(#[from] io::Error)
|
||||
IOError(#[from] io::Error),
|
||||
}
|
||||
|
||||
impl ADIError {
|
||||
@@ -95,7 +95,7 @@ pub struct RequestOTPData {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "async", async_trait::async_trait(?Send))]
|
||||
pub trait ADIProxy: Send + Sync {
|
||||
pub trait ADIProxy: Send + Sync {
|
||||
fn erase_provisioning(&mut self, ds_id: i64) -> Result<(), ADIError>;
|
||||
fn synchronize(&mut self, ds_id: i64, sim: &[u8]) -> Result<SynchronizeData, ADIError>;
|
||||
fn destroy_provisioning_session(&mut self, session: u32) -> Result<(), ADIError>;
|
||||
@@ -291,7 +291,9 @@ pub struct ADIProxyAnisetteProvider<ProxyType: ADIProxy + 'static> {
|
||||
|
||||
impl<ProxyType: ADIProxy + 'static> ADIProxyAnisetteProvider<ProxyType> {
|
||||
/// 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 })
|
||||
}
|
||||
|
||||
@@ -309,7 +311,7 @@ impl<ProxyType: ADIProxy + 'static> ADIProxyAnisetteProvider<ProxyType> {
|
||||
if identifier_file.metadata()?.len() == IDENTIFIER_LENGTH as u64 {
|
||||
identifier_file.read_exact(&mut identifier)?;
|
||||
} else {
|
||||
rand::thread_rng().fill_bytes(&mut identifier);
|
||||
rand::rng().fill_bytes(&mut identifier);
|
||||
identifier_file.write_all(&identifier)?;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
use crate::adi_proxy::{ADIProxyAnisetteProvider, ConfigurableADIProxy};
|
||||
use crate::anisette_headers_provider::AnisetteHeadersProvider;
|
||||
use adi_proxy::ADIError;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use adi_proxy::ADIError;
|
||||
use thiserror::Error;
|
||||
|
||||
pub mod adi_proxy;
|
||||
@@ -58,7 +58,7 @@ pub enum AnisetteError {
|
||||
#[error("Missing Libraries")]
|
||||
MissingLibraries,
|
||||
#[error("{0}")]
|
||||
Anyhow(#[from] anyhow::Error),
|
||||
Anyhow(#[from] anyhow::Error)
|
||||
}
|
||||
|
||||
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_v3: DEFAULT_ANISETTE_URL_V3.to_string(),
|
||||
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")]
|
||||
return Ok(AnisetteHeadersProviderRes::remote(Box::new(
|
||||
remote_anisette_v3::RemoteAnisetteProviderV3::new(
|
||||
configuration.anisette_url_v3,
|
||||
configuration.configuration_path.clone(),
|
||||
configuration.macos_serial.clone(),
|
||||
),
|
||||
remote_anisette_v3::RemoteAnisetteProviderV3::new(configuration.anisette_url_v3, configuration.configuration_path.clone(), configuration.macos_serial.clone()),
|
||||
)));
|
||||
|
||||
#[cfg(feature = "remote-anisette")]
|
||||
#[allow(unreachable_code)]
|
||||
return Ok(AnisetteHeadersProviderRes::remote(Box::new(
|
||||
remote_anisette::RemoteAnisetteProvider::new(configuration.anisette_url),
|
||||
)));
|
||||
|
||||
@@ -99,7 +99,7 @@ pub struct AnisetteState {
|
||||
impl Default for AnisetteState {
|
||||
fn default() -> Self {
|
||||
AnisetteState {
|
||||
keychain_identifier: rand::thread_rng().gen::<[u8; 16]>(),
|
||||
keychain_identifier: rand::rng().random::<[u8; 16]>(),
|
||||
adi_pb: None,
|
||||
}
|
||||
}
|
||||
@@ -211,7 +211,7 @@ impl AnisetteClient {
|
||||
.header("X-Apple-I-MD-LU", encode_hex(&state.md_lu()))
|
||||
.header("X-Mme-Device-Id", state.device_id())
|
||||
.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")
|
||||
}
|
||||
|
||||
@@ -352,7 +352,7 @@ impl AnisetteClient {
|
||||
identifier: base64_encode(&state.keychain_identifier),
|
||||
};
|
||||
connection
|
||||
.send(Message::Text(serde_json::to_string(&identifier)?))
|
||||
.send(Message::Text(serde_json::to_string(&identifier)?.into()))
|
||||
.await?;
|
||||
}
|
||||
ProvisionInput::GiveStartProvisioningData => {
|
||||
@@ -390,7 +390,7 @@ impl AnisetteClient {
|
||||
spim: spim.to_string(),
|
||||
};
|
||||
connection
|
||||
.send(Message::Text(serde_json::to_string(&spim)?))
|
||||
.send(Message::Text(serde_json::to_string(&spim)?.into()))
|
||||
.await?;
|
||||
}
|
||||
ProvisionInput::GiveEndProvisioningData { cpim } => {
|
||||
@@ -427,7 +427,9 @@ impl AnisetteClient {
|
||||
tk: response.get("tk").unwrap().as_string().unwrap(),
|
||||
};
|
||||
connection
|
||||
.send(Message::Text(serde_json::to_string(&end_provisioning)?))
|
||||
.send(Message::Text(
|
||||
serde_json::to_string(&end_provisioning)?.into(),
|
||||
))
|
||||
.await?;
|
||||
}
|
||||
ProvisionInput::ProvisioningSuccess { adi_pb } => {
|
||||
|
||||
@@ -66,11 +66,16 @@ pub struct StoreServicesCoreADIProxy<'lt> {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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.
|
||||
unsafe {
|
||||
LoaderHelpers::setup_hooks();
|
||||
@@ -104,12 +109,8 @@ impl StoreServicesCoreADIProxy<'_> {
|
||||
.ok_or(AnisetteError::InvalidLibraryFormat)?,
|
||||
);
|
||||
|
||||
let path = CString::new(
|
||||
native_library_path
|
||||
.to_str()
|
||||
.ok_or(AnisetteError::Misc)?,
|
||||
)
|
||||
.unwrap();
|
||||
let path =
|
||||
CString::new(native_library_path.to_str().ok_or(AnisetteError::Misc)?).unwrap();
|
||||
assert_eq!((adi_load_library_with_path)(path.as_ptr() as *const u8), 0);
|
||||
|
||||
let adi_set_android_id = store_services_core
|
||||
@@ -163,9 +164,7 @@ impl StoreServicesCoreADIProxy<'_> {
|
||||
adi_otp_request: std::mem::transmute(adi_otp_request),
|
||||
};
|
||||
|
||||
proxy.set_provisioning_path(
|
||||
provisioning_path.to_str().ok_or(AnisetteError::Misc)?,
|
||||
)?;
|
||||
proxy.set_provisioning_path(provisioning_path.to_str().ok_or(AnisetteError::Misc)?)?;
|
||||
|
||||
Ok(proxy)
|
||||
}
|
||||
@@ -370,7 +369,7 @@ unsafe fn __errno_location() -> *mut i32 {
|
||||
|
||||
#[sysv64]
|
||||
fn arc4random() -> u32 {
|
||||
rand::thread_rng().gen()
|
||||
rand::rng().random()
|
||||
}
|
||||
|
||||
#[sysv64]
|
||||
@@ -412,10 +411,10 @@ impl LoaderHelpers {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::AnisetteError;
|
||||
use crate::{AnisetteConfiguration, AnisetteHeaders};
|
||||
use log::info;
|
||||
use std::path::PathBuf;
|
||||
use crate::AnisetteError;
|
||||
|
||||
#[cfg(not(feature = "async"))]
|
||||
#[test]
|
||||
@@ -436,7 +435,6 @@ mod tests {
|
||||
#[cfg(feature = "async")]
|
||||
#[tokio::test]
|
||||
async fn fetch_anisette_ssc_async() -> Result<(), AnisetteError> {
|
||||
|
||||
crate::tests::init_logger();
|
||||
|
||||
let mut provider = AnisetteHeaders::get_ssc_anisette_headers_provider(
|
||||
|
||||
Reference in New Issue
Block a user