mirror of
https://github.com/nab138/isideload.git
synced 2026-03-02 06:26:16 +01:00
In progress small refactor
This commit is contained in:
147
isideload/src/anisette/data.rs
Normal file
147
isideload/src/anisette/data.rs
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
use crate::{
|
||||||
|
anisette::{AnisetteProvider, AnisetteProviderConfig, remote_v3::state::AnisetteState},
|
||||||
|
auth::grandslam::GrandSlam,
|
||||||
|
};
|
||||||
|
use plist::Dictionary;
|
||||||
|
use plist_macro::plist;
|
||||||
|
use reqwest::header::HeaderMap;
|
||||||
|
use rootcause::prelude::*;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::{collections::HashMap, time::SystemTime};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
pub struct AnisetteClientInfo {
|
||||||
|
pub client_info: String,
|
||||||
|
pub user_agent: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct AnisetteData {
|
||||||
|
pub routing_info: String,
|
||||||
|
pub machine_id: String,
|
||||||
|
pub one_time_password: String,
|
||||||
|
pub device_description: String,
|
||||||
|
pub device_unique_identifier: String,
|
||||||
|
pub local_user_id: String,
|
||||||
|
pub generated_at: SystemTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some headers don't seem to be required. I guess not including them is technically more efficient soooo
|
||||||
|
impl AnisetteData {
|
||||||
|
pub fn get_headers(&self) -> HashMap<String, String> {
|
||||||
|
//let dt: DateTime<Utc> = Utc::now().round_subsecs(0);
|
||||||
|
|
||||||
|
HashMap::from_iter(
|
||||||
|
[
|
||||||
|
// (
|
||||||
|
// "X-Apple-I-Client-Time".to_string(),
|
||||||
|
// dt.format("%+").to_string().replace("+00:00", "Z"),
|
||||||
|
// ),
|
||||||
|
// ("X-Apple-I-SRL-NO".to_string(), serial),
|
||||||
|
// ("X-Apple-I-TimeZone".to_string(), "UTC".to_string()),
|
||||||
|
// ("X-Apple-Locale".to_string(), "en_US".to_string()),
|
||||||
|
// ("X-Apple-I-MD-RINFO".to_string(), self.routing_info.clone()),
|
||||||
|
// ("X-Apple-I-MD-LU".to_string(), self.local_user_id.clone()),
|
||||||
|
(
|
||||||
|
"X-Mme-Device-Id".to_string(),
|
||||||
|
self.device_unique_identifier.clone(),
|
||||||
|
),
|
||||||
|
("X-Apple-I-MD".to_string(), self.one_time_password.clone()),
|
||||||
|
("X-Apple-I-MD-M".to_string(), self.machine_id.clone()),
|
||||||
|
// (
|
||||||
|
// "X-Mme-Client-Info".to_string(),
|
||||||
|
// self.device_description.clone(),
|
||||||
|
// ),
|
||||||
|
]
|
||||||
|
.into_iter(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_header_map(&self) -> HeaderMap {
|
||||||
|
let headers_map = self.get_headers();
|
||||||
|
let mut header_map = HeaderMap::new();
|
||||||
|
|
||||||
|
for (key, value) in headers_map {
|
||||||
|
header_map.insert(
|
||||||
|
reqwest::header::HeaderName::from_bytes(key.as_bytes()).unwrap(),
|
||||||
|
reqwest::header::HeaderValue::from_str(&value).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
header_map
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_client_provided_data(&self) -> Dictionary {
|
||||||
|
let headers = self.get_headers();
|
||||||
|
|
||||||
|
let mut cpd = plist!(dict {
|
||||||
|
"bootstrap": "true",
|
||||||
|
"icscrec": "true",
|
||||||
|
"loc": "en_US",
|
||||||
|
"pbe": "false",
|
||||||
|
"prkgen": "true",
|
||||||
|
"svct": "iCloud"
|
||||||
|
});
|
||||||
|
|
||||||
|
for (key, value) in headers {
|
||||||
|
cpd.insert(key.to_string(), plist::Value::String(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
cpd
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn needs_refresh(&self) -> bool {
|
||||||
|
let elapsed = self.generated_at.elapsed().unwrap();
|
||||||
|
elapsed.as_secs() > 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RenewableAnisetteData {
|
||||||
|
config: AnisetteProviderConfig,
|
||||||
|
anisette_data: Option<AnisetteData>,
|
||||||
|
client_info: Option<AnisetteClientInfo>,
|
||||||
|
state: Option<AnisetteState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenewableAnisetteData {
|
||||||
|
pub fn new(config: AnisetteProviderConfig) -> Self {
|
||||||
|
RenewableAnisetteData {
|
||||||
|
config,
|
||||||
|
anisette_data: None,
|
||||||
|
client_info: None,
|
||||||
|
state: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_anisette_data(&mut self, gs: &mut GrandSlam) -> Result<&AnisetteData, Report> {
|
||||||
|
if self
|
||||||
|
.anisette_data
|
||||||
|
.as_ref()
|
||||||
|
.map_or(true, |data| data.needs_refresh())
|
||||||
|
{
|
||||||
|
if self.client_info.is_none() || self.state.is_none() {
|
||||||
|
let mut provider = self.config.get_provider(self.client_info.clone());
|
||||||
|
let client_info = provider.get_client_info().await?;
|
||||||
|
self.client_info = Some(client_info);
|
||||||
|
let data = provider.get_anisette_data(gs).await?;
|
||||||
|
self.anisette_data = Some(data);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(self.anisette_data.as_ref().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_client_info(
|
||||||
|
&mut self,
|
||||||
|
gs: &mut GrandSlam,
|
||||||
|
) -> Result<AnisetteClientInfo, Report> {
|
||||||
|
self.get_anisette_data(gs).await?;
|
||||||
|
|
||||||
|
if let Some(client_info) = &self.client_info {
|
||||||
|
return Ok(client_info.clone());
|
||||||
|
} else {
|
||||||
|
bail!("Anisette client info not available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
anisette::{AnisetteData, AnisetteProvider},
|
anisette::{AnisetteData, AnisetteProvider},
|
||||||
auth::{
|
auth::{
|
||||||
@@ -28,7 +30,7 @@ use tracing::{debug, info, warn};
|
|||||||
pub struct AppleAccount {
|
pub struct AppleAccount {
|
||||||
pub email: String,
|
pub email: String,
|
||||||
pub spd: Option<plist::Dictionary>,
|
pub spd: Option<plist::Dictionary>,
|
||||||
pub anisette_provider: Box<dyn AnisetteProvider>,
|
pub anisette_provider: Arc<Mutex<dyn AnisetteProvider + Send>>,
|
||||||
pub anisette_data: AnisetteData,
|
pub anisette_data: AnisetteData,
|
||||||
pub grandslam_client: GrandSlam,
|
pub grandslam_client: GrandSlam,
|
||||||
login_state: LoginState,
|
login_state: LoginState,
|
||||||
@@ -62,7 +64,7 @@ impl AppleAccount {
|
|||||||
/// - `debug`: DANGER, If true, accept invalid certificates and enable verbose connection
|
/// - `debug`: DANGER, If true, accept invalid certificates and enable verbose connection
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
email: &str,
|
email: &str,
|
||||||
mut anisette_provider: Box<dyn AnisetteProvider>,
|
mut anisette_provider: Arc<Mutex<dyn AnisetteProvider + Send>>,
|
||||||
debug: bool,
|
debug: bool,
|
||||||
) -> Result<Self, Report> {
|
) -> Result<Self, Report> {
|
||||||
info!("Initializing apple account");
|
info!("Initializing apple account");
|
||||||
@@ -71,6 +73,8 @@ impl AppleAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let client_info = anisette_provider
|
let client_info = anisette_provider
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
.get_client_info()
|
.get_client_info()
|
||||||
.await
|
.await
|
||||||
.context("Failed to get anisette client info")?;
|
.context("Failed to get anisette client info")?;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use plist::Dictionary;
|
use plist::Dictionary;
|
||||||
use plist_macro::{plist, plist_to_xml_string};
|
use plist_macro::{plist, plist_to_xml_string};
|
||||||
use rootcause::prelude::*;
|
use rootcause::prelude::*;
|
||||||
@@ -6,7 +8,7 @@ use tracing::{error, warn};
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
anisette::AnisetteData,
|
anisette::{AnisetteData, AnisetteProvider},
|
||||||
auth::{
|
auth::{
|
||||||
apple_account::{AppToken, AppleAccount},
|
apple_account::{AppToken, AppleAccount},
|
||||||
grandslam::GrandSlam,
|
grandslam::GrandSlam,
|
||||||
@@ -25,7 +27,7 @@ pub struct DeveloperSession<'a> {
|
|||||||
token: AppToken,
|
token: AppToken,
|
||||||
adsid: String,
|
adsid: String,
|
||||||
client: &'a GrandSlam,
|
client: &'a GrandSlam,
|
||||||
anisette_data: &'a AnisetteData,
|
anisette_provider: Arc<Mutex<dyn AnisetteProvider + Send>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DeveloperSession<'a> {
|
impl<'a> DeveloperSession<'a> {
|
||||||
@@ -33,13 +35,13 @@ impl<'a> DeveloperSession<'a> {
|
|||||||
token: AppToken,
|
token: AppToken,
|
||||||
adsid: String,
|
adsid: String,
|
||||||
client: &'a GrandSlam,
|
client: &'a GrandSlam,
|
||||||
anisette_data: &'a AnisetteData,
|
anisette_provider: Arc<Mutex<dyn AnisetteProvider + Send>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
DeveloperSession {
|
DeveloperSession {
|
||||||
token,
|
token,
|
||||||
adsid,
|
adsid,
|
||||||
client,
|
client,
|
||||||
anisette_data,
|
anisette_provider,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user