diff --git a/AltStore/Anisette/AnisetteServer.swift b/AltStore/Anisette/AnisetteServer.swift index 0d55f0a602..8ab40b4e63 100644 --- a/AltStore/Anisette/AnisetteServer.swift +++ b/AltStore/Anisette/AnisetteServer.swift @@ -53,3 +53,12 @@ extension UserDefaults } @NSManaged @objc(anisetteServers) private var _anisetteServers: [[String: Any]]? } + +extension AnisetteServer +{ + /// The client identity AltStore presents to Apple in place of the one an anisette server + /// reports, so sign-in does not depend on the identity each server chooses. + static let clientInfo = " " + + static let userAgent = "akd/1.0 CFNetwork/808.1.4" +} diff --git a/AltStore/Operations/FetchAnisetteDataOperation.swift b/AltStore/Operations/FetchAnisetteDataOperation.swift index 26be03f817..4f729a2b17 100644 --- a/AltStore/Operations/FetchAnisetteDataOperation.swift +++ b/AltStore/Operations/FetchAnisetteDataOperation.swift @@ -216,7 +216,15 @@ private extension FetchAnisetteDataOperation let decoder = Foundation.JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase - let response: Response = try await self.send(URLRequest(url: clientInfoURL), decoder: decoder, anisetteServerURL: serverURL) + let serverResponse: Response = try await self.send(URLRequest(url: clientInfoURL), decoder: decoder, anisetteServerURL: serverURL) + + // Present our own client identity rather than the server's, keeping the OS and client + // consistent so Apple grants two-factor trust. + let response = Response(clientInfo: AnisetteServer.clientInfo, userAgent: AnisetteServer.userAgent) + if serverResponse.clientInfo != response.clientInfo + { + Logger.sideload.notice("Replacing anisette client identity \(serverResponse.clientInfo, privacy: .public) with \(response.clientInfo, privacy: .public)") + } // 2. Load or generate the persisted device identity (16 random bytes -> derives identifier, localUserID, deviceID) let identity: AnisetteIdentity