From 519f31a78221444c8d33c15f0cce8a21be307438 Mon Sep 17 00:00:00 2001 From: g1ibby <3687047+g1ibby@users.noreply.github.com> Date: Fri, 23 Oct 2026 16:51:21 +0700 Subject: [PATCH] fix(core): use Mac anisette client info for `-80046` Apple now rejects GrandSlam 2FA and developer services requests that identify as Windows/iTunes. Use the client info returned by the anisette server instead of overriding it, and default to a Mac anisette server. The anisette state file is renamed so states provisioned under the old identity are not reused. fixes #298 fixes #300 --- 3rdparty/omnisette/src/lib.rs | 6 +++++- 3rdparty/omnisette/src/remote_anisette_v3.rs | 8 ++++---- apps/plumeimpactor/src/screen/settings.rs | 2 +- crates/plume_core/src/lib.rs | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/3rdparty/omnisette/src/lib.rs b/3rdparty/omnisette/src/lib.rs index 999dcad6..8722f3b5 100755 --- a/3rdparty/omnisette/src/lib.rs +++ b/3rdparty/omnisette/src/lib.rs @@ -57,7 +57,11 @@ pub enum AnisetteError { pub const DEFAULT_ANISETTE_URL: &str = "https://ani.f1sh.me/"; -pub const DEFAULT_ANISETTE_URL_V3: &str = "https://ani.sidestore.app"; +// Must be a Mac anisette server: Apple rejects non-Mac client identities at 2FA (-80046). +pub const DEFAULT_ANISETTE_URL_V3: &str = "https://mac-ani.jkcoxson.com"; + +// Renamed from `state.plist` so states provisioned under the old Windows identity are discarded. +pub const ANISETTE_STATE_FILE: &str = "mac_anisette_state.plist"; #[derive(Clone, Debug)] pub struct AnisetteConfiguration { diff --git a/3rdparty/omnisette/src/remote_anisette_v3.rs b/3rdparty/omnisette/src/remote_anisette_v3.rs index 014689a0..70e748c9 100755 --- a/3rdparty/omnisette/src/remote_anisette_v3.rs +++ b/3rdparty/omnisette/src/remote_anisette_v3.rs @@ -2,7 +2,8 @@ use std::{collections::HashMap, fs, io::Cursor, path::PathBuf}; -use crate::adi_proxy::{CLIENT_INFO_HEADER, LOOKUP_CLIENT_INFO}; +use crate::ANISETTE_STATE_FILE; +use crate::adi_proxy::LOOKUP_CLIENT_INFO; use async_trait::async_trait; use base64::Engine; use base64::engine::general_purpose; @@ -188,13 +189,12 @@ impl AnisetteClient { pub async fn new(url: String) -> Result { let path = format!("{}/v3/client_info", url); let http_client = make_reqwest()?; - let mut client_info = http_client + let client_info = http_client .get(path) .send() .await? .json::() .await?; - client_info.client_info = CLIENT_INFO_HEADER.to_string(); Ok(AnisetteClient { client_info, url }) } @@ -496,7 +496,7 @@ impl AnisetteHeadersProvider for RemoteAnisetteProviderV3 { fs::create_dir_all(&self.configuration_path)?; - let config_path = self.configuration_path.join("state.plist"); + let config_path = self.configuration_path.join(ANISETTE_STATE_FILE); if self.state.is_none() { self.state = Some(if let Ok(text) = plist::from_file(&config_path) { text diff --git a/apps/plumeimpactor/src/screen/settings.rs b/apps/plumeimpactor/src/screen/settings.rs index c2d1aa5c..11a3a495 100644 --- a/apps/plumeimpactor/src/screen/settings.rs +++ b/apps/plumeimpactor/src/screen/settings.rs @@ -93,7 +93,7 @@ impl SettingsScreen { Message::SelectTeam(_, _) => Task::none(), Message::SelectLocale(_) => Task::none(), Message::ResetAnisetteData => { - let path = crate::defaults::get_data_path().join("state.plist"); + let path = crate::defaults::get_data_path().join(plume_core::ANISETTE_STATE_FILE); let _ = std::fs::remove_file(path); Task::none() } diff --git a/crates/plume_core/src/lib.rs b/crates/plume_core/src/lib.rs index 9c7776f4..6e5e8e7c 100644 --- a/crates/plume_core/src/lib.rs +++ b/crates/plume_core/src/lib.rs @@ -4,7 +4,7 @@ mod utils; pub use apple_codesign::{AppleCodesignError, SettingsScope, SigningSettings, UnifiedSigner}; -pub use omnisette::AnisetteConfiguration; +pub use omnisette::{ANISETTE_STATE_FILE, AnisetteConfiguration}; pub use utils::{CertificateIdentity, MachO, MachOExt, MobileProvision};