mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-18 19:23:43 +01:00
[AltServer] Works without Mail plug-in if SIP and AMFI are both disabled
This commit is contained in:
@@ -9,5 +9,6 @@
|
|||||||
// Shared
|
// Shared
|
||||||
#import "ALTConstants.h"
|
#import "ALTConstants.h"
|
||||||
#import "ALTConnection.h"
|
#import "ALTConnection.h"
|
||||||
|
#import "AltXPCProtocol.h"
|
||||||
#import "NSError+ALTServerError.h"
|
#import "NSError+ALTServerError.h"
|
||||||
#import "CFNotificationName+AltStore.h"
|
#import "CFNotificationName+AltStore.h"
|
||||||
|
|||||||
@@ -8,6 +8,28 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
private extension Bundle
|
||||||
|
{
|
||||||
|
struct ID
|
||||||
|
{
|
||||||
|
static let mail = "com.apple.mail"
|
||||||
|
static let altXPC = "com.rileytestut.AltXPC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension ALTAnisetteData
|
||||||
|
{
|
||||||
|
func sanitize(byReplacingBundleID bundleID: String)
|
||||||
|
{
|
||||||
|
guard let range = self.deviceDescription.lowercased().range(of: "(" + bundleID.lowercased()) else { return }
|
||||||
|
|
||||||
|
var adjustedDescription = self.deviceDescription[..<range.lowerBound]
|
||||||
|
adjustedDescription += "(com.apple.dt.Xcode/3594.4.19)>"
|
||||||
|
|
||||||
|
self.deviceDescription = String(adjustedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class AnisetteDataManager: NSObject
|
class AnisetteDataManager: NSObject
|
||||||
{
|
{
|
||||||
static let shared = AnisetteDataManager()
|
static let shared = AnisetteDataManager()
|
||||||
@@ -15,6 +37,13 @@ class AnisetteDataManager: NSObject
|
|||||||
private var anisetteDataCompletionHandlers: [String: (Result<ALTAnisetteData, Error>) -> Void] = [:]
|
private var anisetteDataCompletionHandlers: [String: (Result<ALTAnisetteData, Error>) -> Void] = [:]
|
||||||
private var anisetteDataTimers: [String: Timer] = [:]
|
private var anisetteDataTimers: [String: Timer] = [:]
|
||||||
|
|
||||||
|
private lazy var xpcConnection: NSXPCConnection = {
|
||||||
|
let connection = NSXPCConnection(serviceName: Bundle.ID.altXPC)
|
||||||
|
connection.remoteObjectInterface = NSXPCInterface(with: AltXPCProtocol.self)
|
||||||
|
connection.resume()
|
||||||
|
return connection
|
||||||
|
}()
|
||||||
|
|
||||||
private override init()
|
private override init()
|
||||||
{
|
{
|
||||||
super.init()
|
super.init()
|
||||||
@@ -23,6 +52,55 @@ class AnisetteDataManager: NSObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
func requestAnisetteData(_ completion: @escaping (Result<ALTAnisetteData, Error>) -> Void)
|
func requestAnisetteData(_ completion: @escaping (Result<ALTAnisetteData, Error>) -> Void)
|
||||||
|
{
|
||||||
|
self.requestAnisetteDataFromXPCService { (result) in
|
||||||
|
do
|
||||||
|
{
|
||||||
|
let anisetteData = try result.get()
|
||||||
|
completion(.success(anisetteData))
|
||||||
|
}
|
||||||
|
catch CocoaError.xpcConnectionInterrupted
|
||||||
|
{
|
||||||
|
// SIP and/or AMFI are not disabled, so fall back to Mail plug-in.
|
||||||
|
self.requestAnisetteDataFromPlugin { (result) in
|
||||||
|
completion(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isXPCAvailable(completion: @escaping (Bool) -> Void)
|
||||||
|
{
|
||||||
|
guard let proxy = self.xpcConnection.remoteObjectProxyWithErrorHandler({ (error) in
|
||||||
|
completion(false)
|
||||||
|
}) as? AltXPCProtocol else { return }
|
||||||
|
|
||||||
|
proxy.ping {
|
||||||
|
completion(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension AnisetteDataManager
|
||||||
|
{
|
||||||
|
func requestAnisetteDataFromXPCService(completion: @escaping (Result<ALTAnisetteData, Error>) -> Void)
|
||||||
|
{
|
||||||
|
guard let proxy = self.xpcConnection.remoteObjectProxyWithErrorHandler({ (error) in
|
||||||
|
print("Anisette XPC Error:", error)
|
||||||
|
completion(.failure(error))
|
||||||
|
}) as? AltXPCProtocol else { return }
|
||||||
|
|
||||||
|
proxy.requestAnisetteData { (anisetteData, error) in
|
||||||
|
anisetteData?.sanitize(byReplacingBundleID: Bundle.ID.altXPC)
|
||||||
|
completion(Result(anisetteData, error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestAnisetteDataFromPlugin(completion: @escaping (Result<ALTAnisetteData, Error>) -> Void)
|
||||||
{
|
{
|
||||||
let requestUUID = UUID().uuidString
|
let requestUUID = UUID().uuidString
|
||||||
self.anisetteDataCompletionHandlers[requestUUID] = completion
|
self.anisetteDataCompletionHandlers[requestUUID] = completion
|
||||||
@@ -36,10 +114,7 @@ class AnisetteDataManager: NSObject
|
|||||||
|
|
||||||
DistributedNotificationCenter.default().postNotificationName(Notification.Name("com.rileytestut.AltServer.FetchAnisetteData"), object: nil, userInfo: ["requestUUID": requestUUID], options: .deliverImmediately)
|
DistributedNotificationCenter.default().postNotificationName(Notification.Name("com.rileytestut.AltServer.FetchAnisetteData"), object: nil, userInfo: ["requestUUID": requestUUID], options: .deliverImmediately)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private extension AnisetteDataManager
|
|
||||||
{
|
|
||||||
@objc func handleAnisetteDataResponse(_ notification: Notification)
|
@objc func handleAnisetteDataResponse(_ notification: Notification)
|
||||||
{
|
{
|
||||||
guard let userInfo = notification.userInfo, let requestUUID = userInfo["requestUUID"] as? String else { return }
|
guard let userInfo = notification.userInfo, let requestUUID = userInfo["requestUUID"] as? String else { return }
|
||||||
@@ -48,14 +123,7 @@ private extension AnisetteDataManager
|
|||||||
let archivedAnisetteData = userInfo["anisetteData"] as? Data,
|
let archivedAnisetteData = userInfo["anisetteData"] as? Data,
|
||||||
let anisetteData = try? NSKeyedUnarchiver.unarchivedObject(ofClass: ALTAnisetteData.self, from: archivedAnisetteData)
|
let anisetteData = try? NSKeyedUnarchiver.unarchivedObject(ofClass: ALTAnisetteData.self, from: archivedAnisetteData)
|
||||||
{
|
{
|
||||||
if let range = anisetteData.deviceDescription.lowercased().range(of: "(com.apple.mail")
|
anisetteData.sanitize(byReplacingBundleID: Bundle.ID.mail)
|
||||||
{
|
|
||||||
var adjustedDescription = anisetteData.deviceDescription[..<range.lowerBound]
|
|
||||||
adjustedDescription += "(com.apple.dt.Xcode/3594.4.19)>"
|
|
||||||
|
|
||||||
anisetteData.deviceDescription = String(adjustedDescription)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.finishRequest(forUUID: requestUUID, result: .success(anisetteData))
|
self.finishRequest(forUUID: requestUUID, result: .success(anisetteData))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -173,11 +173,24 @@ private extension AppDelegate
|
|||||||
|
|
||||||
if !self.pluginManager.isMailPluginInstalled || self.pluginManager.isUpdateAvailable
|
if !self.pluginManager.isMailPluginInstalled || self.pluginManager.isUpdateAvailable
|
||||||
{
|
{
|
||||||
self.installMailPlugin { (result) in
|
AnisetteDataManager.shared.isXPCAvailable { (isAvailable) in
|
||||||
switch result
|
if isAvailable
|
||||||
{
|
{
|
||||||
case .failure: break
|
// XPC service is available, so we don't need to install/update Mail plug-in.
|
||||||
case .success: install()
|
// Users can still manually do so from the AltServer menu.
|
||||||
|
install()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.installMailPlugin { (result) in
|
||||||
|
switch result
|
||||||
|
{
|
||||||
|
case .failure: break
|
||||||
|
case .success: install()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user