diff --git a/AltPlugin/ALTPluginService.h b/AltPlugin/ALTPluginService.h deleted file mode 100644 index b87f972a..00000000 --- a/AltPlugin/ALTPluginService.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// ALTPluginService.h -// AltPlugin -// -// Created by Riley Testut on 11/14/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -#import - -@class ALTAnisetteData; - -NS_ASSUME_NONNULL_BEGIN - -@interface ALTPluginService : NSObject - -@property (class, nonatomic, readonly) ALTPluginService *sharedService; - -- (ALTAnisetteData *)requestAnisetteData; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltPlugin/ALTPluginService.m b/AltPlugin/ALTPluginService.m deleted file mode 100644 index 9bbd6c29..00000000 --- a/AltPlugin/ALTPluginService.m +++ /dev/null @@ -1,105 +0,0 @@ -// -// ALTPluginService.m -// AltPlugin -// -// Created by Riley Testut on 11/14/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -#import "ALTPluginService.h" - -#import - -#import "ALTAnisetteData.h" - -@import AppKit; - -@interface AKAppleIDSession : NSObject -- (id)appleIDHeadersForRequest:(id)arg1; -@end - -@interface AKDevice -+ (AKDevice *)currentDevice; -- (NSString *)uniqueDeviceIdentifier; -- (nullable NSString *)serialNumber; -- (NSString *)serverFriendlyDescription; -@end - -@interface ALTPluginService () - -@property (nonatomic, readonly) NSISO8601DateFormatter *dateFormatter; - -@end - -@implementation ALTPluginService - -+ (instancetype)sharedService -{ - static ALTPluginService *_service = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - _service = [[self alloc] init]; - }); - - return _service; -} - -- (instancetype)init -{ - self = [super init]; - if (self) - { - _dateFormatter = [[NSISO8601DateFormatter alloc] init]; - } - - return self; -} - -+ (void)initialize -{ - [[ALTPluginService sharedService] start]; -} - -- (void)start -{ - dlopen("/System/Library/PrivateFrameworks/AuthKit.framework/AuthKit", RTLD_NOW); - - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:@"com.rileytestut.AltServer.FetchAnisetteData" object:nil]; -} - -- (ALTAnisetteData *)requestAnisetteData -{ - NSMutableURLRequest* req = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://developerservices2.apple.com/services/QH65B2/listTeams.action?clientId=XABBG36SBA"]]; - [req setHTTPMethod:@"POST"]; - - AKAppleIDSession *session = [[NSClassFromString(@"AKAppleIDSession") alloc] initWithIdentifier:@"com.apple.gs.xcode.auth"]; - NSDictionary *headers = [session appleIDHeadersForRequest:req]; - - AKDevice *device = [NSClassFromString(@"AKDevice") currentDevice]; - NSDate *date = [self.dateFormatter dateFromString:headers[@"X-Apple-I-Client-Time"]]; - - ALTAnisetteData *anisetteData = [[NSClassFromString(@"ALTAnisetteData") alloc] initWithMachineID:headers[@"X-Apple-I-MD-M"] - oneTimePassword:headers[@"X-Apple-I-MD"] - localUserID:headers[@"X-Apple-I-MD-LU"] - routingInfo:[headers[@"X-Apple-I-MD-RINFO"] longLongValue] - deviceUniqueIdentifier:device.uniqueDeviceIdentifier - deviceSerialNumber:device.serialNumber ?: @"C02LKHBBFD57" // serialNumber can be nil, so provide valid fallback serial number. - deviceDescription:device.serverFriendlyDescription - date:date - locale:[NSLocale currentLocale] - timeZone:[NSTimeZone localTimeZone]]; - - return anisetteData; -} - -- (void)receiveNotification:(NSNotification *)notification -{ - NSString *requestUUID = notification.userInfo[@"requestUUID"]; - - ALTAnisetteData *anisetteData = [self requestAnisetteData]; - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:anisetteData requiringSecureCoding:YES error:nil]; - - [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.rileytestut.AltServer.AnisetteDataResponse" object:nil userInfo:@{@"requestUUID": requestUUID, @"anisetteData": data} deliverImmediately:YES]; -} - -@end diff --git a/AltPlugin/Info.plist b/AltPlugin/Info.plist deleted file mode 100644 index 03abe87f..00000000 --- a/AltPlugin/Info.plist +++ /dev/null @@ -1,171 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSHumanReadableCopyright - Copyright © 2019 Riley Testut. All rights reserved. - NSPrincipalClass - ALTPluginService - Supported10.14PluginCompatibilityUUIDs - - # UUIDs for versions from 10.12 to 99.99.99 - # For mail version 10.0 (3226) on OS X Version 10.12 (build 16A319) - 36CCB8BB-2207-455E-89BC-B9D6E47ABB5B - # For mail version 10.1 (3251) on OS X Version 10.12.1 (build 16B2553a) - 9054AFD9-2607-489E-8E63-8B09A749BC61 - # For mail version 10.2 (3259) on OS X Version 10.12.2 (build 16D12b) - 1CD3B36A-0E3B-4A26-8F7E-5BDF96AAC97E - # For mail version 10.3 (3273) on OS X Version 10.12.4 (build 16G1036) - 21560BD9-A3CC-482E-9B99-95B7BF61EDC1 - # For mail version 11.0 (3441.0.1) on OS X Version 10.13 (build 17A315i) - C86CD990-4660-4E36-8CDA-7454DEB2E199 - # For mail version 12.0 (3445.100.39) on OS X Version 10.14.1 (build 18B45d) - A4343FAF-AE18-40D0-8A16-DFAE481AF9C1 - # For mail version 13.0 (3594.4.2) on OS X Version 10.15 (build 19A558d) - 6EEA38FB-1A0B-469B-BB35-4C2E0EEA9053 - - Supported10.15PluginCompatibilityUUIDs - - # UUIDs for versions from 10.12 to 99.99.99 - # For mail version 10.0 (3226) on OS X Version 10.12 (build 16A319) - 36CCB8BB-2207-455E-89BC-B9D6E47ABB5B - # For mail version 10.1 (3251) on OS X Version 10.12.1 (build 16B2553a) - 9054AFD9-2607-489E-8E63-8B09A749BC61 - # For mail version 10.2 (3259) on OS X Version 10.12.2 (build 16D12b) - 1CD3B36A-0E3B-4A26-8F7E-5BDF96AAC97E - # For mail version 10.3 (3273) on OS X Version 10.12.4 (build 16G1036) - 21560BD9-A3CC-482E-9B99-95B7BF61EDC1 - # For mail version 11.0 (3441.0.1) on OS X Version 10.13 (build 17A315i) - C86CD990-4660-4E36-8CDA-7454DEB2E199 - # For mail version 12.0 (3445.100.39) on OS X Version 10.14.1 (build 18B45d) - A4343FAF-AE18-40D0-8A16-DFAE481AF9C1 - # For mail version 13.0 (3594.4.2) on OS X Version 10.15 (build 19A558d) - 6EEA38FB-1A0B-469B-BB35-4C2E0EEA9053 - - Supported11.0PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.10PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.1PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.2PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.3PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.4PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.5PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.6PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.7PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.8PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported11.9PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - - Supported12.0PluginCompatibilityUUIDs - - D985F0E4-3BBC-4B95-BBA1-12056AC4A531 - 224E7F96-2099-499C-A501-63FB68C79CD2 - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - - Supported12.1PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - - Supported12.2PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - - Supported12.3PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - A4B49485-0377-4FAB-8D8E-E3B8018CFC21 - - Supported12.4PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - A4B49485-0377-4FAB-8D8E-E3B8018CFC21 - - Supported12.5PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - A4B49485-0377-4FAB-8D8E-E3B8018CFC21 - - Supported12.6PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - A4B49485-0377-4FAB-8D8E-E3B8018CFC21 - - Supported12.7PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - A4B49485-0377-4FAB-8D8E-E3B8018CFC21 - - Supported12.8PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - A4B49485-0377-4FAB-8D8E-E3B8018CFC21 - - Supported12.9PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - A4B49485-0377-4FAB-8D8E-E3B8018CFC21 - - Supported13.0PluginCompatibilityUUIDs - - 25288CEF-7D9B-49A8-BE6B-E41DA6277CF3 - 6FF8B077-81FA-45A4-BD57-17CDE79F13A5 - A4B49485-0377-4FAB-8D8E-E3B8018CFC21 - 890E3F5B-9490-4828-8F3F-B6561E513FCC - - - diff --git a/AltServer.xcconfig b/AltServer.xcconfig deleted file mode 100644 index 7816cc9a..00000000 --- a/AltServer.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Build.xcconfig" diff --git a/AltServer/AltPlugin.zip b/AltServer/AltPlugin.zip deleted file mode 100644 index 389f9e7c..00000000 Binary files a/AltServer/AltPlugin.zip and /dev/null differ diff --git a/AltServer/AltServer-Bridging-Header.h b/AltServer/AltServer-Bridging-Header.h deleted file mode 100644 index c42bab66..00000000 --- a/AltServer/AltServer-Bridging-Header.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - -#import "ALTDeviceManager.h" -#import "ALTWiredConnection.h" -#import "ALTNotificationConnection.h" -#import "ALTDebugConnection.h" - -// Shared -#import "ALTConstants.h" -#import "ALTConnection.h" -#import "AltXPCProtocol.h" -#import "NSError+ALTServerError.h" -#import "CFNotificationName+AltStore.h" diff --git a/AltServer/AltServer.entitlements b/AltServer/AltServer.entitlements deleted file mode 100644 index 53b24dcc..00000000 --- a/AltServer/AltServer.entitlements +++ /dev/null @@ -1,11 +0,0 @@ - - - - - com.apple.security.temporary-exception.mach-lookup.global-name - - $(PRODUCT_BUNDLE_IDENTIFIER)-spks - $(PRODUCT_BUNDLE_IDENTIFIER)-spki - - - diff --git a/AltServer/AnisetteDataManager.swift b/AltServer/AnisetteDataManager.swift deleted file mode 100644 index c5799d3a..00000000 --- a/AltServer/AnisetteDataManager.swift +++ /dev/null @@ -1,163 +0,0 @@ -// -// AnisetteDataManager.swift -// AltServer -// -// Created by Riley Testut on 11/16/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -import Foundation -import AppKit - -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[..) -> Void] = [:] - 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() - { - super.init() - - DistributedNotificationCenter.default().addObserver(self, selector: #selector(AnisetteDataManager.handleAnisetteDataResponse(_:)), name: Notification.Name("com.rileytestut.AltServer.AnisetteDataResponse"), object: nil) - } - - func requestAnisetteData(_ completion: @escaping (Result) -> Void) - { - if #available(macOS 10.15, *) - { - 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)) - } - } - } - else - { - self.requestAnisetteDataFromPlugin { (result) in - completion(result) - } - } - } - - 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 -{ - @available(macOS 10.15, *) - func requestAnisetteDataFromXPCService(completion: @escaping (Result) -> 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) -> Void) - { - let requestUUID = UUID().uuidString - self.anisetteDataCompletionHandlers[requestUUID] = completion - - let isMailRunning = NSWorkspace.shared.runningApplications.map { $0.bundleIdentifier }.contains { $0 == "com.apple.mail" } - - if !isMailRunning, let mailApp = FileManager.default.urls(for: .applicationDirectory,in: .systemDomainMask).first?.appendingPathComponent("Mail.app") { - NSWorkspace.shared.open(mailApp) - } - - let timer = Timer(timeInterval: 5.0, repeats: false) { (timer) in - self.finishRequest(forUUID: requestUUID, result: .failure(ALTServerError(.pluginNotFound))) - } - self.anisetteDataTimers[requestUUID] = timer - - RunLoop.main.add(timer, forMode: .default) - - DistributedNotificationCenter.default().postNotificationName(Notification.Name("com.rileytestut.AltServer.FetchAnisetteData"), object: nil, userInfo: ["requestUUID": requestUUID], options: .deliverImmediately) - } - - @objc func handleAnisetteDataResponse(_ notification: Notification) - { - guard let userInfo = notification.userInfo, let requestUUID = userInfo["requestUUID"] as? String else { return } - - if - let archivedAnisetteData = userInfo["anisetteData"] as? Data, - let anisetteData = try? NSKeyedUnarchiver.unarchivedObject(ofClass: ALTAnisetteData.self, from: archivedAnisetteData) - { - anisetteData.sanitize(byReplacingBundleID: Bundle.ID.mail) - self.finishRequest(forUUID: requestUUID, result: .success(anisetteData)) - } - else - { - self.finishRequest(forUUID: requestUUID, result: .failure(ALTServerError(.invalidAnisetteData))) - } - } - - func finishRequest(forUUID requestUUID: String, result: Result) - { - let completionHandler = self.anisetteDataCompletionHandlers[requestUUID] - self.anisetteDataCompletionHandlers[requestUUID] = nil - - let timer = self.anisetteDataTimers[requestUUID] - self.anisetteDataTimers[requestUUID] = nil - - timer?.invalidate() - completionHandler?(result) - } -} diff --git a/AltServer/AppDelegate.swift b/AltServer/AppDelegate.swift deleted file mode 100644 index 0fdbfa92..00000000 --- a/AltServer/AppDelegate.swift +++ /dev/null @@ -1,617 +0,0 @@ -// -// AppDelegate.swift -// AltServer -// -// Created by Riley Testut on 5/24/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -import Cocoa -import UserNotifications - -import AltSign - -import LaunchAtLogin -import Sparkle - -#if STAGING -private let altstoreAppURL = URL(string: "https://f000.backblazeb2.com/file/altstore-staging/altstore.ipa")! -#elseif BETA -private let altstoreAppURL = URL(string: "https://cdn.altstore.io/file/altstore/altstore-beta.ipa")! -#else -private let altstoreAppURL = URL(string: "https://cdn.altstore.io/file/altstore/altstore.ipa")! -#endif - -extension ALTDevice: MenuDisplayable {} - -@NSApplicationMain -class AppDelegate: NSObject, NSApplicationDelegate { - - private let pluginManager = PluginManager() - - private var statusItem: NSStatusItem? - - private var connectedDevices = [ALTDevice]() - - private weak var authenticationAlert: NSAlert? - - @IBOutlet private var appMenu: NSMenu! - @IBOutlet private var connectedDevicesMenu: NSMenu! - @IBOutlet private var sideloadIPAConnectedDevicesMenu: NSMenu! - @IBOutlet private var enableJITMenu: NSMenu! - - @IBOutlet private var launchAtLoginMenuItem: NSMenuItem! - @IBOutlet private var installMailPluginMenuItem: NSMenuItem! - @IBOutlet private var installAltStoreMenuItem: NSMenuItem! - @IBOutlet private var sideloadAppMenuItem: NSMenuItem! - @IBOutlet private var checkForUpdatesMenuItem: NSMenuItem! - - private weak var authenticationAppleIDTextField: NSTextField? - private weak var authenticationPasswordTextField: NSSecureTextField? - - private var connectedDevicesMenuController: MenuController! - private var sideloadIPAConnectedDevicesMenuController: MenuController! - private var enableJITMenuController: MenuController! - - private var _jitAppListMenuControllers = [AnyObject]() - - private var isAltPluginUpdateAvailable = false - - @IBOutlet private var updaterController: SPUStandardUpdaterController! = { - return SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil) - }() - - func applicationDidFinishLaunching(_ aNotification: Notification) { - UserDefaults.standard.registerDefaults() - - UNUserNotificationCenter.current().delegate = self - - ServerConnectionManager.shared.start() - ALTDeviceManager.shared.start() - - let item = NSStatusBar.system.statusItem(withLength: -1) - item.menu = self.appMenu - item.button?.image = NSImage(named: "MenuBarIcon") - self.statusItem = item - - self.appMenu.delegate = self - - self.sideloadAppMenuItem.keyEquivalentModifierMask = .option - self.sideloadAppMenuItem.isAlternate = true - - let placeholder = NSLocalizedString("No Connected Devices", comment: "") - - self.connectedDevicesMenuController = MenuController(menu: self.connectedDevicesMenu, items: []) - self.connectedDevicesMenuController.placeholder = placeholder - self.connectedDevicesMenuController.action = { [weak self] device in - self?.installAltStore(to: device) - } - - self.sideloadIPAConnectedDevicesMenuController = MenuController(menu: self.sideloadIPAConnectedDevicesMenu, items: []) - self.sideloadIPAConnectedDevicesMenuController.placeholder = placeholder - self.sideloadIPAConnectedDevicesMenuController.action = { [weak self] device in - self?.sideloadIPA(to: device) - } - - self.enableJITMenuController = MenuController(menu: self.enableJITMenu, items: []) - self.enableJITMenuController.placeholder = placeholder - - UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) { (success, error) in - guard success else { return } - - if !UserDefaults.standard.didPresentInitialNotification - { - let content = UNMutableNotificationContent() - content.title = NSLocalizedString("AltServer Running", comment: "") - content.body = NSLocalizedString("AltServer runs in the background as a menu bar app listening for AltStore.", comment: "") - - let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) - UNUserNotificationCenter.current().add(request) - - UserDefaults.standard.didPresentInitialNotification = true - } - } - - self.pluginManager.isUpdateAvailable { result in - guard let isUpdateAvailable = try? result.get() else { return } - self.isAltPluginUpdateAvailable = isUpdateAvailable - - if isUpdateAvailable - { - self.installMailPlugin() - } - } - } - - func applicationWillTerminate(_ aNotification: Notification) - { - // Insert code here to tear down your application - } -} - -private extension AppDelegate -{ - @objc func installAltStore(to device: ALTDevice) - { - self.installApplication(at: altstoreAppURL, to: device) - } - - @objc func sideloadIPA(to device: ALTDevice) - { - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - let openPanel = NSOpenPanel() - openPanel.canChooseDirectories = false - openPanel.allowsMultipleSelection = false - openPanel.allowedFileTypes = ["ipa"] - openPanel.begin { (response) in - guard let fileURL = openPanel.url, response == .OK else { return } - self.installApplication(at: fileURL, to: device) - } - } - - func enableJIT(for app: InstalledApp, on device: ALTDevice) - { - func finish(_ result: Result) - { - DispatchQueue.main.async { - switch result - { - case .failure(let error): - self.showErrorAlert(error: error, localizedFailure: String(format: NSLocalizedString("JIT compilation could not be enabled for %@.", comment: ""), app.name)) - - case .success: - let alert = NSAlert() - alert.messageText = String(format: NSLocalizedString("Successfully enabled JIT for %@.", comment: ""), app.name) - alert.informativeText = String(format: NSLocalizedString("JIT will remain enabled until you quit the app. You can now disconnect %@ from your computer.", comment: ""), device.name) - alert.runModal() - } - } - } - - ALTDeviceManager.shared.prepare(device) { (result) in - switch result - { - case .failure(let error as NSError): return finish(.failure(error)) - case .success: - ALTDeviceManager.shared.startDebugConnection(to: device) { (connection, error) in - guard let connection = connection else { - return finish(.failure(error! as NSError)) - } - - connection.enableUnsignedCodeExecutionForProcess(withName: app.executableName) { (success, error) in - guard success else { - return finish(.failure(error!)) - } - - finish(.success(())) - } - } - } - } - } - - func installApplication(at url: URL, to device: ALTDevice) - { - let alert = NSAlert() - alert.messageText = NSLocalizedString("Please enter your Apple ID and password.", comment: "") - alert.informativeText = NSLocalizedString("Your Apple ID and password are not saved and are only sent to Apple for authentication.", comment: "") - - let textFieldSize = NSSize(width: 300, height: 22) - - let appleIDTextField = NSTextField(frame: NSRect(x: 0, y: 0, width: textFieldSize.width, height: textFieldSize.height)) - appleIDTextField.delegate = self - appleIDTextField.translatesAutoresizingMaskIntoConstraints = false - appleIDTextField.placeholderString = NSLocalizedString("Apple ID", comment: "") - alert.window.initialFirstResponder = appleIDTextField - self.authenticationAppleIDTextField = appleIDTextField - - let passwordTextField = NSSecureTextField(frame: NSRect(x: 0, y: 0, width: textFieldSize.width, height: textFieldSize.height)) - passwordTextField.delegate = self - passwordTextField.translatesAutoresizingMaskIntoConstraints = false - passwordTextField.placeholderString = NSLocalizedString("Password", comment: "") - self.authenticationPasswordTextField = passwordTextField - - appleIDTextField.nextKeyView = passwordTextField - - let stackView = NSStackView(frame: NSRect(x: 0, y: 0, width: textFieldSize.width, height: textFieldSize.height * 2)) - stackView.orientation = .vertical - stackView.distribution = .equalSpacing - stackView.spacing = 0 - stackView.addArrangedSubview(appleIDTextField) - stackView.addArrangedSubview(passwordTextField) - alert.accessoryView = stackView - - alert.addButton(withTitle: NSLocalizedString("Install", comment: "")) - alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) - - self.authenticationAlert = alert - self.validate() - - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - let response = alert.runModal() - guard response == .alertFirstButtonReturn else { return } - - let username = appleIDTextField.stringValue - let password = passwordTextField.stringValue - - func finish(_ result: Result) - { - switch result - { - case .success(let application): - let content = UNMutableNotificationContent() - content.title = NSLocalizedString("Installation Succeeded", comment: "") - content.body = String(format: NSLocalizedString("%@ was successfully installed on %@.", comment: ""), application.name, device.name) - - let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) - UNUserNotificationCenter.current().add(request) - - case .failure(InstallError.cancelled), .failure(ALTAppleAPIError.requiresTwoFactorAuthentication): - // Ignore - break - - case .failure(let error): - DispatchQueue.main.async { - self.showErrorAlert(error: error, localizedFailure: String(format: NSLocalizedString("Could not install app to %@.", comment: ""), device.name)) - } - } - } - - func install() - { - ALTDeviceManager.shared.installApplication(at: url, to: device, appleID: username, password: password, completion: finish(_:)) - } - - AnisetteDataManager.shared.isXPCAvailable { isAvailable in - if isAvailable - { - // XPC service is available, so we don't need to install/update Mail plug-in. - // Users can still manually do so from the AltServer menu. - install() - } - else - { - self.pluginManager.isUpdateAvailable { result in - switch result - { - case .failure(let error): finish(.failure(error)) - case .success(let isUpdateAvailable): - self.isAltPluginUpdateAvailable = isUpdateAvailable - - if !self.pluginManager.isMailPluginInstalled || isUpdateAvailable - { - self.installMailPlugin { result in - switch result - { - case .failure: break - case .success: install() - } - } - } - else - { - install() - } - } - } - } - } - } - - func showErrorAlert(error: Error, localizedFailure: String) - { - let nsError = error as NSError - - let alert = NSAlert() - alert.alertStyle = .critical - alert.messageText = localizedFailure - - var messageComponents = [String]() - - let separator: String - switch error - { - case ALTServerError.maximumFreeAppLimitReached: separator = "\n\n" - default: separator = " " - } - - if let errorFailure = nsError.localizedFailure - { - if let debugDescription = nsError.localizedDebugDescription - { - alert.messageText = errorFailure - messageComponents.append(debugDescription) - } - else if let failureReason = nsError.localizedFailureReason - { - if nsError.localizedDescription.starts(with: errorFailure) - { - alert.messageText = errorFailure - messageComponents.append(failureReason) - } - else - { - alert.messageText = errorFailure - messageComponents.append(nsError.localizedDescription) - } - } - else - { - // No failure reason given. - - if nsError.localizedDescription.starts(with: errorFailure) - { - // No need to duplicate errorFailure in both title and message. - alert.messageText = localizedFailure - messageComponents.append(nsError.localizedDescription) - } - else - { - alert.messageText = errorFailure - messageComponents.append(nsError.localizedDescription) - } - } - } - else - { - alert.messageText = localizedFailure - - if let debugDescription = nsError.localizedDebugDescription - { - messageComponents.append(debugDescription) - } - else - { - messageComponents.append(nsError.localizedDescription) - } - } - - if let recoverySuggestion = nsError.localizedRecoverySuggestion - { - messageComponents.append(recoverySuggestion) - } - - let informativeText = messageComponents.joined(separator: separator) - alert.informativeText = informativeText - - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - alert.runModal() - } - - @objc func toggleLaunchAtLogin(_ item: NSMenuItem) - { - LaunchAtLogin.isEnabled.toggle() - } - - @objc func handleInstallMailPluginMenuItem(_ item: NSMenuItem) - { - if !self.pluginManager.isMailPluginInstalled || self.isAltPluginUpdateAvailable - { - self.installMailPlugin() - } - else - { - self.uninstallMailPlugin() - } - } - - private func installMailPlugin(completion: ((Result) -> Void)? = nil) - { - self.pluginManager.installMailPlugin { (result) in - DispatchQueue.main.async { - switch result - { - case .failure(PluginError.cancelled): break - case .failure(let error): - let alert = NSAlert() - alert.messageText = NSLocalizedString("Failed to Install Mail Plug-in", comment: "") - alert.informativeText = error.localizedDescription - alert.runModal() - - case .success: - let alert = NSAlert() - alert.messageText = NSLocalizedString("Mail Plug-in Installed", comment: "") - alert.informativeText = NSLocalizedString("Please restart Mail and enable AltPlugin in Mail's Preferences. Mail must be running when installing or refreshing apps with AltServer.", comment: "") - alert.runModal() - - self.isAltPluginUpdateAvailable = false - } - - completion?(result) - } - } - } - - private func uninstallMailPlugin() - { - self.pluginManager.uninstallMailPlugin { (result) in - DispatchQueue.main.async { - switch result - { - case .failure(PluginError.cancelled): break - case .failure(let error): - let alert = NSAlert() - alert.messageText = NSLocalizedString("Failed to Uninstall Mail Plug-in", comment: "") - alert.informativeText = error.localizedDescription - alert.runModal() - - case .success: - let alert = NSAlert() - alert.messageText = NSLocalizedString("Mail Plug-in Uninstalled", comment: "") - alert.informativeText = NSLocalizedString("Please restart Mail for changes to take effect. You will not be able to use AltServer until the plug-in is reinstalled.", comment: "") - alert.runModal() - } - } - } - } -} - -extension AppDelegate: NSMenuDelegate -{ - func menuWillOpen(_ menu: NSMenu) - { - guard menu == self.appMenu else { return } - - // Clear any cached _jitAppListMenuControllers. - self._jitAppListMenuControllers.removeAll() - - self.connectedDevices = ALTDeviceManager.shared.availableDevices - - self.connectedDevicesMenuController.items = self.connectedDevices - self.sideloadIPAConnectedDevicesMenuController.items = self.connectedDevices - self.enableJITMenuController.items = self.connectedDevices - - self.launchAtLoginMenuItem.target = self - self.launchAtLoginMenuItem.action = #selector(AppDelegate.toggleLaunchAtLogin(_:)) - self.launchAtLoginMenuItem.state = LaunchAtLogin.isEnabled ? .on : .off - - if self.isAltPluginUpdateAvailable - { - self.installMailPluginMenuItem.title = NSLocalizedString("Update Mail Plug-in…", comment: "") - } - else if self.pluginManager.isMailPluginInstalled - { - self.installMailPluginMenuItem.title = NSLocalizedString("Uninstall Mail Plug-in…", comment: "") - } - else - { - self.installMailPluginMenuItem.title = NSLocalizedString("Install Mail Plug-in…", comment: "") - } - self.installMailPluginMenuItem.target = self - self.installMailPluginMenuItem.action = #selector(AppDelegate.handleInstallMailPluginMenuItem(_:)) - - // Need to re-set this every time menu appears so we can refresh device app list. - self.enableJITMenuController.submenuHandler = { [weak self] device in - let submenu = NSMenu(title: NSLocalizedString("Sideloaded Apps", comment: "")) - - guard let `self` = self else { return submenu } - - let submenuController = MenuController(menu: submenu, items: []) - submenuController.placeholder = NSLocalizedString("Loading...", comment: "") - submenuController.action = { [weak self] (appInfo) in - self?.enableJIT(for: appInfo, on: device) - } - - // Keep strong reference - self._jitAppListMenuControllers.append(submenuController) - - ALTDeviceManager.shared.fetchInstalledApps(on: device) { (installedApps, error) in - DispatchQueue.main.async { - guard let installedApps = installedApps else { - print("Failed to fetch installed apps from \(device).", error!) - submenuController.placeholder = error?.localizedDescription - return - } - - print("Fetched \(installedApps.count) apps for \(device).") - - let sortedApps = installedApps.sorted { (app1, app2) in - if app1.name == app2.name - { - return app1.bundleIdentifier < app2.bundleIdentifier - } - else - { - return app1.name < app2.name - } - } - - submenuController.items = sortedApps - - if submenuController.items.isEmpty - { - submenuController.placeholder = NSLocalizedString("No Sideloaded Apps", comment: "") - } - } - } - - return submenu - } - } - - func menuDidClose(_ menu: NSMenu) - { - guard menu == self.appMenu else { return } - - // Clearing _jitAppListMenuControllers now prevents action handler from being called. - // self._jitAppListMenuControllers = [] - - // Set `submenuHandler` to nil to prevent prematurely fetching installed apps in menuWillOpen(_:) - // when assigning self.connectedDevices to `items` (which implicitly calls `submenuHandler`) - self.enableJITMenuController.submenuHandler = nil - } - - func menu(_ menu: NSMenu, willHighlight item: NSMenuItem?) - { - guard menu == self.appMenu else { return } - - // The submenu won't update correctly if the user holds/releases - // the Option key while the submenu is visible. - // Workaround: temporarily set submenu to nil to dismiss it, - // which will then cause the correct submenu to appear. - - let previousItem: NSMenuItem - switch item - { - case self.sideloadAppMenuItem: previousItem = self.installAltStoreMenuItem - case self.installAltStoreMenuItem: previousItem = self.sideloadAppMenuItem - default: return - } - - let submenu = previousItem.submenu - previousItem.submenu = nil - previousItem.submenu = submenu - } -} - -extension AppDelegate: NSTextFieldDelegate -{ - func controlTextDidChange(_ obj: Notification) - { - self.validate() - } - - func controlTextDidEndEditing(_ obj: Notification) - { - self.validate() - } - - private func validate() - { - guard - let appleID = self.authenticationAppleIDTextField?.stringValue.trimmingCharacters(in: .whitespacesAndNewlines), - let password = self.authenticationPasswordTextField?.stringValue.trimmingCharacters(in: .whitespacesAndNewlines) - else { return } - - if appleID.isEmpty || password.isEmpty - { - self.authenticationAlert?.buttons.first?.isEnabled = false - } - else - { - self.authenticationAlert?.buttons.first?.isEnabled = true - } - - self.authenticationAlert?.layout() - } -} - -extension AppDelegate: UNUserNotificationCenterDelegate -{ - func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) - { - completionHandler([.alert, .sound, .badge]) - } -} - -// MARK: - Sparkle -//extension AppDelegate: SPUUpdaterDelegate { -// -//} -// -//extension AppDelegate: SPUStandardUserDriverDelegate { -// -//} diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Contents.json b/AltServer/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index e20d34e5..00000000 --- a/AltServer/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "Icon@16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "Icon@32-1.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "Icon@32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "Icon@64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "Icon@128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "Icon@256-1.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "Icon@256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "Icon@512-1.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "Icon@512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "Icon@1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@1024.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@1024.png deleted file mode 100644 index f93aed92..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@1024.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@128.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@128.png deleted file mode 100644 index c1bd9fff..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@128.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@16.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@16.png deleted file mode 100644 index 41bc9989..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@16.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@256-1.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@256-1.png deleted file mode 100644 index cca771f2..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@256-1.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@256.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@256.png deleted file mode 100644 index cca771f2..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@256.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@32-1.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@32-1.png deleted file mode 100644 index 82334a85..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@32-1.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@32.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@32.png deleted file mode 100644 index 82334a85..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@32.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@512-1.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@512-1.png deleted file mode 100644 index ccf5340b..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@512-1.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@512.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@512.png deleted file mode 100644 index ccf5340b..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@512.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@64.png b/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@64.png deleted file mode 100644 index 4db3dea3..00000000 Binary files a/AltServer/Assets.xcassets/AppIcon.appiconset/Icon@64.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/Contents.json b/AltServer/Assets.xcassets/Contents.json deleted file mode 100644 index da4a164c..00000000 --- a/AltServer/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/AltServer/Assets.xcassets/MenuBarIcon.imageset/Contents.json b/AltServer/Assets.xcassets/MenuBarIcon.imageset/Contents.json deleted file mode 100644 index 4b85493e..00000000 --- a/AltServer/Assets.xcassets/MenuBarIcon.imageset/Contents.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "MenuBar@19.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "MenuBar@38.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - }, - "properties" : { - "template-rendering-intent" : "template" - } -} \ No newline at end of file diff --git a/AltServer/Assets.xcassets/MenuBarIcon.imageset/MenuBar@19.png b/AltServer/Assets.xcassets/MenuBarIcon.imageset/MenuBar@19.png deleted file mode 100644 index 344e5bd6..00000000 Binary files a/AltServer/Assets.xcassets/MenuBarIcon.imageset/MenuBar@19.png and /dev/null differ diff --git a/AltServer/Assets.xcassets/MenuBarIcon.imageset/MenuBar@38.png b/AltServer/Assets.xcassets/MenuBarIcon.imageset/MenuBar@38.png deleted file mode 100644 index 1222aa43..00000000 Binary files a/AltServer/Assets.xcassets/MenuBarIcon.imageset/MenuBar@38.png and /dev/null differ diff --git a/AltServer/Base.lproj/Main.storyboard b/AltServer/Base.lproj/Main.storyboard deleted file mode 100644 index 061518b9..00000000 --- a/AltServer/Base.lproj/Main.storyboard +++ /dev/null @@ -1,390 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NSAllRomanInputSourcesLocaleIdentifier - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AltServer/Categories/NSError+libimobiledevice.h b/AltServer/Categories/NSError+libimobiledevice.h deleted file mode 100644 index 5a711529..00000000 --- a/AltServer/Categories/NSError+libimobiledevice.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// NSError+libimobiledevice.h -// AltServer -// -// Created by Riley Testut on 3/23/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -#import -#import -#import - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface NSError (libimobiledevice) - -+ (nullable instancetype)errorWithMobileImageMounterError:(mobile_image_mounter_error_t)error device:(nullable ALTDevice *)device; -+ (nullable instancetype)errorWithDebugServerError:(debugserver_error_t)error device:(nullable ALTDevice *)device; -+ (nullable instancetype)errorWithInstallationProxyError:(instproxy_error_t)error device:(nullable ALTDevice *)device; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltServer/Categories/NSError+libimobiledevice.mm b/AltServer/Categories/NSError+libimobiledevice.mm deleted file mode 100644 index cbeb3c22..00000000 --- a/AltServer/Categories/NSError+libimobiledevice.mm +++ /dev/null @@ -1,86 +0,0 @@ -// -// NSError+libimobiledevice.m -// AltServer -// -// Created by Riley Testut on 3/23/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -#import "NSError+libimobiledevice.h" -#import "NSError+ALTServerError.h" - -@implementation NSError (libimobiledevice) - -+ (nullable instancetype)errorWithMobileImageMounterError:(mobile_image_mounter_error_t)error device:(nullable ALTDevice *)device -{ - NSMutableDictionary *userInfo = [@{ - ALTUnderlyingErrorDomainErrorKey: @"Mobile Image Mounter", - ALTUnderlyingErrorCodeErrorKey: [@(error) description], - } mutableCopy]; - - if (device) - { - userInfo[ALTDeviceNameErrorKey] = device.name; - } - - switch (error) - { - case MOBILE_IMAGE_MOUNTER_E_SUCCESS: return nil; - case MOBILE_IMAGE_MOUNTER_E_INVALID_ARG: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidRequest userInfo:userInfo]; - case MOBILE_IMAGE_MOUNTER_E_PLIST_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidResponse userInfo:userInfo]; - case MOBILE_IMAGE_MOUNTER_E_CONN_FAILED: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUsbmuxd userInfo:userInfo]; - case MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidRequest userInfo:userInfo]; - case MOBILE_IMAGE_MOUNTER_E_DEVICE_LOCKED: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorDeviceLocked userInfo:userInfo]; - case MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:userInfo]; - } -} - -+ (nullable instancetype)errorWithDebugServerError:(debugserver_error_t)error device:(nullable ALTDevice *)device -{ - NSMutableDictionary *userInfo = [@{ - ALTUnderlyingErrorDomainErrorKey: @"Debug Server", - ALTUnderlyingErrorCodeErrorKey: [@(error) description], - } mutableCopy]; - - if (device) - { - userInfo[ALTDeviceNameErrorKey] = device.name; - } - - switch (error) - { - case DEBUGSERVER_E_SUCCESS: return nil; - case DEBUGSERVER_E_INVALID_ARG: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidRequest userInfo:userInfo]; - case DEBUGSERVER_E_MUX_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUsbmuxd userInfo:userInfo]; - case DEBUGSERVER_E_SSL_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorSSL userInfo:userInfo]; - case DEBUGSERVER_E_RESPONSE_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidResponse userInfo:userInfo]; - case DEBUGSERVER_E_TIMEOUT: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorTimedOut userInfo:userInfo]; - case DEBUGSERVER_E_UNKNOWN_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:userInfo]; - } -} - -+ (nullable instancetype)errorWithInstallationProxyError:(instproxy_error_t)error device:(nullable ALTDevice *)device -{ - NSMutableDictionary *userInfo = [@{ - ALTUnderlyingErrorDomainErrorKey: @"Installation Proxy", - ALTUnderlyingErrorCodeErrorKey: [@(error) description], - } mutableCopy]; - - if (device) - { - userInfo[ALTDeviceNameErrorKey] = device.name; - } - - switch (error) - { - case INSTPROXY_E_SUCCESS: return nil; - case INSTPROXY_E_INVALID_ARG: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidRequest userInfo:userInfo]; - case INSTPROXY_E_PLIST_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidResponse userInfo:userInfo]; - case INSTPROXY_E_CONN_FAILED: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUsbmuxd userInfo:userInfo]; - case INSTPROXY_E_RECEIVE_TIMEOUT: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorTimedOut userInfo:userInfo]; -// case INSTPROXY_E_DEVICE_OS_VERSION_TOO_LOW: return [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorUnsupportediOSVersion userInfo:nil]; // Error message assumes we're installing AltStore - default: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:userInfo]; - } -} - -@end diff --git a/AltServer/Connections/ALTDebugConnection+Private.h b/AltServer/Connections/ALTDebugConnection+Private.h deleted file mode 100644 index 74d9b442..00000000 --- a/AltServer/Connections/ALTDebugConnection+Private.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// ALTDebugConnection+Private.h -// AltServer -// -// Created by Riley Testut on 2/19/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -#import "ALTDebugConnection.h" - -#include -#include - -NS_ASSUME_NONNULL_BEGIN - -@interface ALTDebugConnection () - -@property (nonatomic, readonly) dispatch_queue_t connectionQueue; - -@property (nonatomic, nullable) debugserver_client_t client; - -- (instancetype)initWithDevice:(ALTDevice *)device; - -- (void)connectWithCompletionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltServer/Connections/ALTDebugConnection.h b/AltServer/Connections/ALTDebugConnection.h deleted file mode 100644 index fba2abd2..00000000 --- a/AltServer/Connections/ALTDebugConnection.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// ALTDebugConnection.h -// AltServer -// -// Created by Riley Testut on 2/19/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -#import "AltSign.h" - -NS_ASSUME_NONNULL_BEGIN - -NS_SWIFT_NAME(DebugConnection) -@interface ALTDebugConnection : NSObject - -@property (nonatomic, copy, readonly) ALTDevice *device; - -- (void)enableUnsignedCodeExecutionForProcessWithName:(NSString *)processName completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; -- (void)enableUnsignedCodeExecutionForProcessWithID:(NSInteger)pid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; - -- (void)disconnect; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltServer/Connections/ALTDebugConnection.mm b/AltServer/Connections/ALTDebugConnection.mm deleted file mode 100644 index e7e2598a..00000000 --- a/AltServer/Connections/ALTDebugConnection.mm +++ /dev/null @@ -1,315 +0,0 @@ -// -// ALTDebugConnection.m -// AltServer -// -// Created by Riley Testut on 2/19/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -#import "ALTDebugConnection+Private.h" - -#import "NSError+ALTServerError.h" -#import "NSError+libimobiledevice.h" - -char *bin2hex(const unsigned char *bin, size_t length) -{ - if (bin == NULL || length == 0) - { - return NULL; - } - - char *hex = (char *)malloc(length * 2 + 1); - for (size_t i = 0; i < length; i++) - { - hex[i * 2] = "0123456789ABCDEF"[bin[i] >> 4]; - hex[i * 2 + 1] = "0123456789ABCDEF"[bin[i] & 0x0F]; - } - hex[length * 2] = '\0'; - - return hex; -} - -@implementation ALTDebugConnection - -- (instancetype)initWithDevice:(ALTDevice *)device -{ - self = [super init]; - if (self) - { - _device = device; - _connectionQueue = dispatch_queue_create_with_target("io.altstore.AltServer.DebugConnection", - DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL, - dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)); - } - - return self; -} - -- (void)dealloc -{ - [self disconnect]; -} - -- (void)disconnect -{ - if (_client == nil) - { - return; - } - - debugserver_client_free(_client); - _client = nil; -} - -- (void)connectWithCompletionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler -{ - __block idevice_t device = NULL; - - void (^finish)(BOOL, NSError *) = ^(BOOL success, NSError *error) { - if (device) - { - idevice_free(device); - } - - completionHandler(success, error); - }; - - dispatch_async(self.connectionQueue, ^{ - /* Find Device */ - if (idevice_new_with_options(&device, self.device.identifier.UTF8String, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS) - { - return finish(NO, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to debugserver */ - debugserver_client_t client = NULL; - debugserver_error_t error = debugserver_client_start_service(device, &client, "AltServer"); - if (error != DEBUGSERVER_E_SUCCESS) - { - return finish(NO, [NSError errorWithDebugServerError:error device:self.device]); - } - - self.client = client; - - finish(YES, nil); - }); -} - -- (void)enableUnsignedCodeExecutionForProcessWithName:(NSString *)processName completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler -{ - [self _enableUnsignedCodeExecutionForProcessWithName:processName pid:0 completionHandler:completionHandler]; -} - -- (void)enableUnsignedCodeExecutionForProcessWithID:(NSInteger)pid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler -{ - [self _enableUnsignedCodeExecutionForProcessWithName:nil pid:(int32_t)pid completionHandler:completionHandler]; -} - -- (void)_enableUnsignedCodeExecutionForProcessWithName:(nullable NSString *)processName pid:(int32_t)pid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler -{ - dispatch_async(self.connectionQueue, ^{ - NSString *name = processName ?: NSLocalizedString(@"this app", @""); - NSString *localizedFailure = [NSString stringWithFormat:NSLocalizedString(@"JIT could not be enabled for %@.", comment: @""), name]; - - NSString *attachCommand = nil; - - if (processName) - { - NSString *encodedName = @(bin2hex((const unsigned char *)processName.UTF8String, (size_t)strlen(processName.UTF8String))); - attachCommand = [NSString stringWithFormat:@"vAttachOrWait;%@", encodedName]; - } - else - { - // Convert to Big-endian. - int32_t rawPID = CFSwapInt32HostToBig(pid); - - NSString *encodedName = @(bin2hex((const unsigned char *)&rawPID, 4)); - attachCommand = [NSString stringWithFormat:@"vAttach;%@", encodedName]; - } - - NSError *error = nil; - if (![self sendCommand:attachCommand arguments:nil error:&error]) - { - NSMutableDictionary *userInfo = [error.userInfo mutableCopy]; - userInfo[ALTAppNameErrorKey] = processName; - userInfo[ALTDeviceNameErrorKey] = self.device.name; - userInfo[NSLocalizedFailureErrorKey] = localizedFailure; - - NSError *returnError = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; - return completionHandler(NO, returnError); - } - - NSString *detachCommand = @"D"; - if (![self sendCommand:detachCommand arguments:nil error:&error]) - { - NSMutableDictionary *userInfo = [error.userInfo mutableCopy]; - userInfo[ALTAppNameErrorKey] = processName; - userInfo[ALTDeviceNameErrorKey] = self.device.name; - userInfo[NSLocalizedFailureErrorKey] = localizedFailure; - - NSError *returnError = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; - return completionHandler(NO, returnError); - } - - completionHandler(YES, nil); - }); -} - -#pragma mark - Private - - -- (BOOL)sendCommand:(NSString *)command arguments:(nullable NSArray *)arguments error:(NSError **)error -{ - int argc = (int)arguments.count; - char **argv = new char*[argc + 1]; - - for (int i = 0; i < argc; i++) - { - NSString *argument = arguments[i]; - argv[i] = (char *)argument.UTF8String; - } - - argv[argc] = NULL; - - debugserver_command_t debugCommand = NULL; - debugserver_command_new(command.UTF8String, argc, argv, &debugCommand); - - delete[] argv; - - char *response = NULL; - size_t responseSize = 0; - debugserver_error_t debugServerError = debugserver_client_send_command(self.client, debugCommand, &response, &responseSize); - debugserver_command_free(debugCommand); - - if (debugServerError != DEBUGSERVER_E_SUCCESS) - { - if (error) - { - *error = [NSError errorWithDebugServerError:debugServerError device:self.device]; - } - - return NO; - } - - NSString *rawResponse = (response != nil) ? @(response) : nil; - if (![self processResponse:rawResponse error:error]) - { - return NO; - } - - return YES; -} - -- (BOOL)processResponse:(NSString *)rawResponse error:(NSError **)error -{ - if (rawResponse == nil) - { - if (error) - { - *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorRequestedAppNotRunning userInfo:nil]; - return NO; - } - } - - if (rawResponse.length == 0 || [rawResponse isEqualToString:@"OK"]) - { - return YES; - } - - char type = [rawResponse characterAtIndex:0]; - NSString *response = [rawResponse substringFromIndex:1]; - - switch (type) - { - case 'O': - { - // stdout/stderr - - char *decodedResponse = NULL; - debugserver_decode_string(response.UTF8String, response.length, &decodedResponse); - - NSLog(@"Response: %@", @(decodedResponse)); - - if (decodedResponse) - { - free(decodedResponse); - } - - return YES; - } - - case 'T': - { - // Thread Information - - NSLog(@"Thread stopped. Details:\n%s", response.UTF8String + 1); - - // Parse thread state to determine if app is running. - NSArray *components = [response componentsSeparatedByString:@";"]; - if (components.count <= 1) - { - if (error) - { - *error = [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:@{NSLocalizedFailureReasonErrorKey: response}]; - } - - return NO; - } - - NSString *mainThread = components[1]; - NSString *threadState = [[mainThread componentsSeparatedByString:@":"] lastObject]; - - NSScanner *scanner = [NSScanner scannerWithString:threadState]; - - unsigned long long mainThreadState = 0; - [scanner scanHexLongLong:&mainThreadState]; - - // If main thread state == 0, app is not running. - if (mainThreadState == 0) - { - if (error) - { - *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorRequestedAppNotRunning userInfo:nil]; - } - - return NO; - } - - return YES; - } - - case 'E': - { - // Error - - if (error) - { - NSInteger errorCode = [[[response componentsSeparatedByString:@";"] firstObject] integerValue]; - - switch (errorCode) - { - case 96: - *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorRequestedAppNotRunning userInfo:nil]; - break; - - default: - *error = [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:@{NSLocalizedFailureReasonErrorKey: response}]; - break; - } - } - - return NO; - } - - case 'W': - { - // Warning - - NSLog(@"WARNING: %@", response); - return YES; - } - } - - return YES; -} - -@end diff --git a/AltServer/Connections/ALTNotificationConnection+Private.h b/AltServer/Connections/ALTNotificationConnection+Private.h deleted file mode 100644 index ee484915..00000000 --- a/AltServer/Connections/ALTNotificationConnection+Private.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// ALTNotificationConnection+Private.h -// AltServer -// -// Created by Riley Testut on 1/10/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -#import "ALTNotificationConnection.h" - -#include -#include - -NS_ASSUME_NONNULL_BEGIN - -@interface ALTNotificationConnection () - -@property (nonatomic, readonly) np_client_t client; - -- (instancetype)initWithDevice:(ALTDevice *)device client:(np_client_t)client; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltServer/Connections/ALTNotificationConnection.h b/AltServer/Connections/ALTNotificationConnection.h deleted file mode 100644 index 4654ab2e..00000000 --- a/AltServer/Connections/ALTNotificationConnection.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// ALTNotificationConnection.h -// AltServer -// -// Created by Riley Testut on 1/10/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -#import "AltSign.h" - -NS_ASSUME_NONNULL_BEGIN - -NS_SWIFT_NAME(NotificationConnection) -@interface ALTNotificationConnection : NSObject - -@property (nonatomic, copy, readonly) ALTDevice *device; - -@property (nonatomic, copy, nullable) void (^receivedNotificationHandler)(CFNotificationName notification); - -- (void)startListeningForNotifications:(NSArray *)notifications - completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; - -- (void)sendNotification:(CFNotificationName)notification - completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; - -- (void)disconnect; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltServer/Connections/ALTNotificationConnection.mm b/AltServer/Connections/ALTNotificationConnection.mm deleted file mode 100644 index 4c486d05..00000000 --- a/AltServer/Connections/ALTNotificationConnection.mm +++ /dev/null @@ -1,94 +0,0 @@ -// -// ALTNotificationConnection.m -// AltServer -// -// Created by Riley Testut on 1/10/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -#import "ALTNotificationConnection+Private.h" - -#import "NSError+ALTServerError.h" - -void ALTDeviceReceivedNotification(const char *notification, void *user_data); - -@implementation ALTNotificationConnection - -- (instancetype)initWithDevice:(ALTDevice *)device client:(np_client_t)client -{ - self = [super init]; - if (self) - { - _device = [device copy]; - _client = client; - } - - return self; -} - -- (void)dealloc -{ - [self disconnect]; -} - -- (void)disconnect -{ - np_client_free(self.client); - _client = nil; -} - -- (void)startListeningForNotifications:(NSArray *)notifications completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler -{ - dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ - const char **notificationNames = (const char **)malloc((notifications.count + 1) * sizeof(char *)); - for (int i = 0; i < notifications.count; i++) - { - NSString *name = notifications[i]; - notificationNames[i] = name.UTF8String; - } - notificationNames[notifications.count] = NULL; // Must have terminating NULL entry. - - np_error_t result = np_observe_notifications(self.client, notificationNames); - if (result != NP_E_SUCCESS) - { - return completionHandler(NO, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorLostConnection userInfo:nil]); - } - - result = np_set_notify_callback(self.client, ALTDeviceReceivedNotification, (__bridge void *)self); - if (result != NP_E_SUCCESS) - { - return completionHandler(NO, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorLostConnection userInfo:nil]); - } - - completionHandler(YES, nil); - - free(notificationNames); - }); -} - -- (void)sendNotification:(CFNotificationName)notification completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler -{ - dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ - np_error_t result = np_post_notification(self.client, [(__bridge NSString *)notification UTF8String]); - if (result == NP_E_SUCCESS) - { - completionHandler(YES, nil); - } - else - { - completionHandler(NO, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorLostConnection userInfo:nil]); - } - }); -} - -@end - -void ALTDeviceReceivedNotification(const char *notification, void *user_data) -{ - ALTNotificationConnection *connection = (__bridge ALTNotificationConnection *)user_data; - - if (connection.receivedNotificationHandler) - { - connection.receivedNotificationHandler((__bridge CFNotificationName)@(notification)); - } -} diff --git a/AltServer/Connections/ALTWiredConnection+Private.h b/AltServer/Connections/ALTWiredConnection+Private.h deleted file mode 100644 index a6c64d14..00000000 --- a/AltServer/Connections/ALTWiredConnection+Private.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// ALTWiredConnection+Private.h -// AltServer -// -// Created by Riley Testut on 1/10/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -#import "ALTWiredConnection.h" - -#include - -NS_ASSUME_NONNULL_BEGIN - -@interface ALTWiredConnection () - -@property (nonatomic, readwrite, getter=isConnected) BOOL connected; - -@property (nonatomic, readonly) idevice_connection_t connection; - -- (instancetype)initWithDevice:(ALTDevice *)device connection:(idevice_connection_t)connection; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltServer/Connections/ALTWiredConnection.h b/AltServer/Connections/ALTWiredConnection.h deleted file mode 100644 index d6fde691..00000000 --- a/AltServer/Connections/ALTWiredConnection.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// ALTWiredConnection.h -// AltServer -// -// Created by Riley Testut on 1/10/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -#import "AltSign.h" - -#import "ALTConnection.h" - -NS_ASSUME_NONNULL_BEGIN - -NS_SWIFT_NAME(WiredConnection) -@interface ALTWiredConnection : NSObject - -@property (nonatomic, readonly, getter=isConnected) BOOL connected; - -@property (nonatomic, copy, readonly) ALTDevice *device; - -- (void)sendData:(NSData *)data completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler; -- (void)receiveDataWithExpectedSize:(NSInteger)expectedSize completionHandler:(void (^)(NSData * _Nullable, NSError * _Nullable))completionHandler; - -- (void)disconnect; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltServer/Connections/ALTWiredConnection.mm b/AltServer/Connections/ALTWiredConnection.mm deleted file mode 100644 index 6ad1f3f8..00000000 --- a/AltServer/Connections/ALTWiredConnection.mm +++ /dev/null @@ -1,119 +0,0 @@ -// -// ALTWiredConnection.m -// AltServer -// -// Created by Riley Testut on 1/10/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -#import "ALTWiredConnection+Private.h" - -#import "ALTConnection.h" -#import "NSError+ALTServerError.h" - -@implementation ALTWiredConnection - -- (instancetype)initWithDevice:(ALTDevice *)device connection:(idevice_connection_t)connection -{ - self = [super init]; - if (self) - { - _device = [device copy]; - _connection = connection; - - self.connected = YES; - } - - return self; -} - -- (void)dealloc -{ - [self disconnect]; -} - -- (void)disconnect -{ - if (![self isConnected]) - { - return; - } - - idevice_disconnect(self.connection); - _connection = nil; - - self.connected = NO; -} - -- (void)sendData:(NSData *)data completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler -{ - void (^finish)(NSError *error) = ^(NSError *error) { - if (error != nil) - { - NSLog(@"Send Error: %@", error); - completionHandler(NO, error); - } - else - { - completionHandler(YES, nil); - } - }; - - dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ - NSMutableData *mutableData = [data mutableCopy]; - while (mutableData.length > 0) - { - uint32_t sentBytes = 0; - if (idevice_connection_send(self.connection, (const char *)mutableData.bytes, (int32_t)mutableData.length, &sentBytes) != IDEVICE_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorLostConnection userInfo:nil]); - } - - [mutableData replaceBytesInRange:NSMakeRange(0, sentBytes) withBytes:NULL length:0]; - } - - finish(nil); - }); -} - -- (void)receiveDataWithExpectedSize:(NSInteger)expectedSize completionHandler:(void (^)(NSData * _Nullable, NSError * _Nullable))completionHandler -{ - void (^finish)(NSData *data, NSError *error) = ^(NSData *data, NSError *error) { - if (error != nil) - { - NSLog(@"Receive Data Error: %@", error); - } - - completionHandler(data, error); - }; - - dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ - char bytes[4096]; - NSMutableData *receivedData = [NSMutableData dataWithCapacity:expectedSize]; - - while (receivedData.length < expectedSize) - { - uint32_t size = MIN(4096, (uint32_t)expectedSize - (uint32_t)receivedData.length); - - uint32_t receivedBytes = 0; - if (idevice_connection_receive_timeout(self.connection, bytes, size, &receivedBytes, 10000) != IDEVICE_E_SUCCESS) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorLostConnection userInfo:nil]); - } - - NSData *data = [NSData dataWithBytesNoCopy:bytes length:receivedBytes freeWhenDone:NO]; - [receivedData appendData:data]; - } - - finish(receivedData, nil); - }); -} - -#pragma mark - NSObject - - -- (NSString *)description -{ - return [NSString stringWithFormat:@"%@ (Wired)", self.device.name]; -} - -@end diff --git a/AltServer/Connections/RequestHandler.swift b/AltServer/Connections/RequestHandler.swift deleted file mode 100644 index 6d879951..00000000 --- a/AltServer/Connections/RequestHandler.swift +++ /dev/null @@ -1,263 +0,0 @@ -// -// RequestHandler.swift -// AltServer -// -// Created by Riley Testut on 5/23/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -import Foundation - -typealias ServerConnectionManager = ConnectionManager - -private let connectionManager = ConnectionManager(requestHandler: ServerRequestHandler(), - connectionHandlers: [WirelessConnectionHandler(), WiredConnectionHandler()]) - -extension ServerConnectionManager -{ - static var shared: ConnectionManager { - return connectionManager - } -} - -struct ServerRequestHandler: RequestHandler -{ - func handleAnisetteDataRequest(_ request: AnisetteDataRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) - { - AnisetteDataManager.shared.requestAnisetteData { (result) in - switch result - { - case .failure(let error): completionHandler(.failure(error)) - case .success(let anisetteData): - let response = AnisetteDataResponse(anisetteData: anisetteData) - completionHandler(.success(response)) - } - } - } - - func handlePrepareAppRequest(_ request: PrepareAppRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) - { - var temporaryURL: URL? - - func finish(_ result: Result) - { - if let temporaryURL = temporaryURL - { - do { try FileManager.default.removeItem(at: temporaryURL) } - catch { print("Failed to remove .ipa.", error) } - } - - completionHandler(result) - } - - self.receiveApp(for: request, from: connection) { (result) in - print("Received app with result:", result) - - switch result - { - case .failure(let error): finish(.failure(error)) - case .success(let fileURL): - temporaryURL = fileURL - - print("Awaiting begin installation request...") - - connection.receiveRequest() { (result) in - print("Received begin installation request with result:", result) - - switch result - { - case .failure(let error): finish(.failure(error)) - case .success(.beginInstallation(let installRequest)): - print("Installing app to device \(request.udid)...") - - self.installApp(at: fileURL, toDeviceWithUDID: request.udid, activeProvisioningProfiles: installRequest.activeProfiles, connection: connection) { (result) in - print("Installed app to device with result:", result) - switch result - { - case .failure(let error): finish(.failure(error)) - case .success: - let response = InstallationProgressResponse(progress: 1.0) - finish(.success(response)) - } - } - - case .success: finish(.failure(ALTServerError(.unknownRequest))) - } - } - } - } - } - - func handleInstallProvisioningProfilesRequest(_ request: InstallProvisioningProfilesRequest, for connection: Connection, - completionHandler: @escaping (Result) -> Void) - { - ALTDeviceManager.shared.installProvisioningProfiles(request.provisioningProfiles, toDeviceWithUDID: request.udid, activeProvisioningProfiles: request.activeProfiles) { (success, error) in - if let error = error, !success - { - print("Failed to install profiles \(request.provisioningProfiles.map { $0.bundleIdentifier }):", error) - completionHandler(.failure(ALTServerError(error))) - } - else - { - print("Installed profiles:", request.provisioningProfiles.map { $0.bundleIdentifier }) - - let response = InstallProvisioningProfilesResponse() - completionHandler(.success(response)) - } - } - } - - func handleRemoveProvisioningProfilesRequest(_ request: RemoveProvisioningProfilesRequest, for connection: Connection, - completionHandler: @escaping (Result) -> Void) - { - ALTDeviceManager.shared.removeProvisioningProfiles(forBundleIdentifiers: request.bundleIdentifiers, fromDeviceWithUDID: request.udid) { (success, error) in - if let error = error, !success - { - print("Failed to remove profiles \(request.bundleIdentifiers):", error) - completionHandler(.failure(ALTServerError(error))) - } - else - { - print("Removed profiles:", request.bundleIdentifiers) - - let response = RemoveProvisioningProfilesResponse() - completionHandler(.success(response)) - } - } - } - - func handleRemoveAppRequest(_ request: RemoveAppRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) - { - ALTDeviceManager.shared.removeApp(forBundleIdentifier: request.bundleIdentifier, fromDeviceWithUDID: request.udid) { (success, error) in - if let error = error, !success - { - print("Failed to remove app \(request.bundleIdentifier):", error) - completionHandler(.failure(ALTServerError(error))) - } - else - { - print("Removed app:", request.bundleIdentifier) - - let response = RemoveAppResponse() - completionHandler(.success(response)) - } - } - } - - func handleEnableUnsignedCodeExecutionRequest(_ request: EnableUnsignedCodeExecutionRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) - { - guard let device = ALTDeviceManager.shared.availableDevices.first(where: { $0.identifier == request.udid }) else { return completionHandler(.failure(ALTServerError(.deviceNotFound))) } - - ALTDeviceManager.shared.prepare(device) { result in - switch result - { - case .failure(let error): completionHandler(.failure(error)) - case .success: - ALTDeviceManager.shared.startDebugConnection(to: device) { (connection, error) in - guard let connection = connection else { return completionHandler(.failure(error!)) } - - func finish(success: Bool, error: Error?) - { - if let error = error, !success - { - print("Failed to enable unsigned code execution for process \(request.processID?.description ?? request.processName ?? "nil"):", error) - completionHandler(.failure(ALTServerError(error))) - } - else - { - print("Enabled unsigned code execution for process:", request.processID ?? request.processName ?? "nil") - - let response = EnableUnsignedCodeExecutionResponse() - completionHandler(.success(response)) - } - } - - if let processID = request.processID - { - connection.enableUnsignedCodeExecutionForProcess(withID: processID, completionHandler: finish) - } - else if let processName = request.processName - { - connection.enableUnsignedCodeExecutionForProcess(withName: processName, completionHandler: finish) - } - else - { - finish(success: false, error: ALTServerError(.invalidRequest)) - } - } - } - } - } -} - -private extension RequestHandler -{ - func receiveApp(for request: PrepareAppRequest, from connection: Connection, completionHandler: @escaping (Result) -> Void) - { - connection.receiveData(expectedSize: request.contentSize) { (result) in - do - { - print("Received app data!") - - let data = try result.get() - - guard ALTDeviceManager.shared.availableDevices.contains(where: { $0.identifier == request.udid }) else { throw ALTServerError(.deviceNotFound) } - - print("Writing app data...") - - let temporaryURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString + ".ipa") - try data.write(to: temporaryURL, options: .atomic) - - print("Wrote app to URL:", temporaryURL) - - completionHandler(.success(temporaryURL)) - } - catch - { - print("Error processing app data:", error) - - completionHandler(.failure(ALTServerError(error))) - } - } - } - - func installApp(at fileURL: URL, toDeviceWithUDID udid: String, activeProvisioningProfiles: Set?, connection: Connection, completionHandler: @escaping (Result) -> Void) - { - let serialQueue = DispatchQueue(label: "com.altstore.ConnectionManager.installQueue", qos: .default) - var isSending = false - - var observation: NSKeyValueObservation? - - let progress = ALTDeviceManager.shared.installApp(at: fileURL, toDeviceWithUDID: udid, activeProvisioningProfiles: activeProvisioningProfiles) { (success, error) in - print("Installed app with result:", error == nil ? "Success" : error!.localizedDescription) - - if let error = error.map({ ALTServerError($0) }) - { - completionHandler(.failure(error)) - } - else - { - completionHandler(.success(())) - } - - observation?.invalidate() - observation = nil - } - - observation = progress.observe(\.fractionCompleted, changeHandler: { (progress, change) in - serialQueue.async { - guard !isSending else { return } - isSending = true - - print("Progress:", progress.fractionCompleted) - let response = InstallationProgressResponse(progress: progress.fractionCompleted) - - connection.send(response) { (result) in - serialQueue.async { - isSending = false - } - } - } - }) - } -} diff --git a/AltServer/Connections/WiredConnectionHandler.swift b/AltServer/Connections/WiredConnectionHandler.swift deleted file mode 100644 index c5f4c002..00000000 --- a/AltServer/Connections/WiredConnectionHandler.swift +++ /dev/null @@ -1,122 +0,0 @@ -// -// WiredConnectionHandler.swift -// AltServer -// -// Created by Riley Testut on 6/1/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation - -class WiredConnectionHandler: ConnectionHandler -{ - var connectionHandler: ((Connection) -> Void)? - var disconnectionHandler: ((Connection) -> Void)? - - private var notificationConnections = [ALTDevice: NotificationConnection]() - private let queue = DispatchQueue(label: "WiredConnectionHandler", autoreleaseFrequency: .workItem, target: .global(qos: .utility)) - - func startListening() - { - NotificationCenter.default.addObserver(self, selector: #selector(WiredConnectionHandler.deviceDidConnect(_:)), name: .deviceManagerDeviceDidConnect, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(WiredConnectionHandler.deviceDidDisconnect(_:)), name: .deviceManagerDeviceDidDisconnect, object: nil) - } - - func stopListening() - { - NotificationCenter.default.removeObserver(self, name: .deviceManagerDeviceDidConnect, object: nil) - NotificationCenter.default.removeObserver(self, name: .deviceManagerDeviceDidDisconnect, object: nil) - } -} - -private extension WiredConnectionHandler -{ - func startNotificationConnection(to device: ALTDevice) - { - self.queue.async { - ALTDeviceManager.shared.startNotificationConnection(to: device) { (connection, error) in - guard let connection = connection else { return } - - let notifications: [CFNotificationName] = [.wiredServerConnectionAvailableRequest, .wiredServerConnectionStartRequest] - connection.startListening(forNotifications: notifications.map { String($0.rawValue) }) { (success, error) in - guard success else { return } - - self.queue.async { - connection.receivedNotificationHandler = { [weak self, weak connection] (notification) in - guard let self = self, let connection = connection else { return } - self.handle(notification, for: connection) - } - - self.notificationConnections[device] = connection - } - } - } - } - } - - func stopNotificationConnection(to device: ALTDevice) - { - self.queue.async { - guard let connection = self.notificationConnections[device] else { return } - connection.disconnect() - - self.notificationConnections[device] = nil - } - } - - func handle(_ notification: CFNotificationName, for connection: NotificationConnection) - { - switch notification - { - case .wiredServerConnectionAvailableRequest: - connection.sendNotification(.wiredServerConnectionAvailableResponse) { (success, error) in - if let error = error, !success - { - print("Error sending wired server connection response.", error) - } - else - { - print("Sent wired server connection available response!") - } - } - - case .wiredServerConnectionStartRequest: - ALTDeviceManager.shared.startWiredConnection(to: connection.device) { (wiredConnection, error) in - if let wiredConnection = wiredConnection - { - print("Started wired server connection!") - self.connectionHandler?(wiredConnection) - - var observation: NSKeyValueObservation? - observation = wiredConnection.observe(\.isConnected) { [weak self] (connection, change) in - guard !connection.isConnected else { return } - self?.disconnectionHandler?(connection) - - observation?.invalidate() - } - } - else if let error = error - { - print("Error starting wired server connection.", error) - } - } - - default: break - } - } -} - -private extension WiredConnectionHandler -{ - @objc func deviceDidConnect(_ notification: Notification) - { - guard let device = notification.object as? ALTDevice else { return } - self.startNotificationConnection(to: device) - } - - @objc func deviceDidDisconnect(_ notification: Notification) - { - guard let device = notification.object as? ALTDevice else { return } - self.stopNotificationConnection(to: device) - } -} diff --git a/AltServer/Connections/WirelessConnectionHandler.swift b/AltServer/Connections/WirelessConnectionHandler.swift deleted file mode 100644 index 1db96c54..00000000 --- a/AltServer/Connections/WirelessConnectionHandler.swift +++ /dev/null @@ -1,153 +0,0 @@ -// -// WirelessConnectionHandler.swift -// AltKit -// -// Created by Riley Testut on 6/1/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation -import Network - -extension WirelessConnectionHandler -{ - public enum State - { - case notRunning - case connecting - case running(NWListener.Service) - case failed(Swift.Error) - } -} - -public class WirelessConnectionHandler: ConnectionHandler -{ - public var connectionHandler: ((Connection) -> Void)? - public var disconnectionHandler: ((Connection) -> Void)? - - public var stateUpdateHandler: ((State) -> Void)? - - public private(set) var state: State = .notRunning { - didSet { - self.stateUpdateHandler?(self.state) - } - } - - private lazy var listener = self.makeListener() - private let dispatchQueue = DispatchQueue(label: "io.altstore.WirelessConnectionListener", qos: .utility) - - public func startListening() - { - switch self.state - { - case .notRunning, .failed: self.listener.start(queue: self.dispatchQueue) - default: break - } - } - - public func stopListening() - { - switch self.state - { - case .running: self.listener.cancel() - default: break - } - } -} - -private extension WirelessConnectionHandler -{ - func makeListener() -> NWListener - { - let listener = try! NWListener(using: .tcp) - - let service: NWListener.Service - - if let serverID = UserDefaults.standard.serverID?.data(using: .utf8) - { - let txtDictionary = ["serverID": serverID] - let txtData = NetService.data(fromTXTRecord: txtDictionary) - - service = NWListener.Service(name: nil, type: ALTServerServiceType, domain: nil, txtRecord: txtData) - } - else - { - service = NWListener.Service(type: ALTServerServiceType) - } - - listener.service = service - - listener.serviceRegistrationUpdateHandler = { (serviceChange) in - switch serviceChange - { - case .add(.service(let name, let type, let domain, _)): - let service = NWListener.Service(name: name, type: type, domain: domain, txtRecord: nil) - self.state = .running(service) - - default: break - } - } - - listener.stateUpdateHandler = { (state) in - switch state - { - case .ready: break - case .waiting, .setup: self.state = .connecting - case .cancelled: self.state = .notRunning - case .failed(let error): self.state = .failed(error) - @unknown default: break - } - } - - listener.newConnectionHandler = { [weak self] (connection) in - self?.prepare(connection) - } - - return listener - } - - func prepare(_ nwConnection: NWConnection) - { - print("Preparing:", nwConnection) - - // Use same instance for all callbacks. - let connection = NetworkConnection(nwConnection) - - nwConnection.stateUpdateHandler = { [weak self] (state) in - switch state - { - case .setup, .preparing: break - - case .ready: - print("Connected to client:", connection) - self?.connectionHandler?(connection) - - case .waiting: - print("Waiting for connection...") - - case .failed(let error): - print("Failed to connect to service \(nwConnection.endpoint).", error) - self?.disconnect(connection) - - case .cancelled: - self?.disconnect(connection) - - @unknown default: break - } - } - - nwConnection.start(queue: self.dispatchQueue) - } - - func disconnect(_ connection: Connection) - { - connection.disconnect() - - self.disconnectionHandler?(connection) - - if let networkConnection = connection as? NetworkConnection - { - networkConnection.nwConnection.stateUpdateHandler = nil - } - } -} diff --git a/AltServer/DeveloperDiskManager.swift b/AltServer/DeveloperDiskManager.swift deleted file mode 100644 index 3830c912..00000000 --- a/AltServer/DeveloperDiskManager.swift +++ /dev/null @@ -1,327 +0,0 @@ -// -// DeveloperDiskManager.swift -// AltServer -// -// Created by Riley Testut on 2/19/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -import Foundation - -import AltSign - -enum DeveloperDiskError: LocalizedError -{ - case unknownDownloadURL - case unsupportedOperatingSystem - case downloadedDiskNotFound - - var errorDescription: String? { - switch self - { - case .unknownDownloadURL: return NSLocalizedString("The URL to download the Developer disk image could not be determined.", comment: "") - case .unsupportedOperatingSystem: return NSLocalizedString("The device's operating system does not support installing Developer disk images.", comment: "") - case .downloadedDiskNotFound: return NSLocalizedString("DeveloperDiskImage.dmg and its signature could not be found in the downloaded archive.", comment: "") - } - } -} - -private extension URL -{ - #if STAGING - static let developerDiskDownloadURLs = URL(string: "https://f000.backblazeb2.com/file/altstore-staging/altserver/developerdisks.json")! - #else - static let developerDiskDownloadURLs = URL(string: "https://cdn.altstore.io/file/altstore/altserver/developerdisks.json")! - #endif -} - -private extension DeveloperDiskManager -{ - struct FetchURLsResponse: Decodable - { - struct Disks: Decodable - { - var iOS: [String: DeveloperDiskURL]? - var tvOS: [String: DeveloperDiskURL]? - } - - var version: Int - var disks: Disks - } - - enum DeveloperDiskURL: Decodable - { - case archive(URL) - case separate(diskURL: URL, signatureURL: URL) - - private enum CodingKeys: CodingKey - { - case archive - case disk - case signature - } - - init(from decoder: Decoder) throws - { - let container = try decoder.container(keyedBy: CodingKeys.self) - - if container.contains(.archive) - { - let archiveURL = try container.decode(URL.self, forKey: .archive) - self = .archive(archiveURL) - } - else - { - let diskURL = try container.decode(URL.self, forKey: .disk) - let signatureURL = try container.decode(URL.self, forKey: .signature) - self = .separate(diskURL: diskURL, signatureURL: signatureURL) - } - } - } -} - -class DeveloperDiskManager -{ - private let session = URLSession(configuration: .ephemeral) - - func downloadDeveloperDisk(for device: ALTDevice, completionHandler: @escaping (Result<(URL, URL), Error>) -> Void) - { - do - { - guard let osName = device.type.osName else { throw DeveloperDiskError.unsupportedOperatingSystem } - - let osKeyPath: KeyPath - switch device.type - { - case .iphone, .ipad: osKeyPath = \FetchURLsResponse.Disks.iOS - case .appletv: osKeyPath = \FetchURLsResponse.Disks.tvOS - default: throw DeveloperDiskError.unsupportedOperatingSystem - } - - var osVersion = device.osVersion - osVersion.patchVersion = 0 // Patch is irrelevant for developer disks - - let osDirectoryURL = FileManager.default.developerDisksDirectory.appendingPathComponent(osName) - let developerDiskDirectoryURL = osDirectoryURL.appendingPathComponent(osVersion.stringValue, isDirectory: true) - try FileManager.default.createDirectory(at: developerDiskDirectoryURL, withIntermediateDirectories: true, attributes: nil) - - let developerDiskURL = developerDiskDirectoryURL.appendingPathComponent("DeveloperDiskImage.dmg") - let developerDiskSignatureURL = developerDiskDirectoryURL.appendingPathComponent("DeveloperDiskImage.dmg.signature") - - let isCachedDiskCompatible = self.isDeveloperDiskCompatible(with: device) - if isCachedDiskCompatible && FileManager.default.fileExists(atPath: developerDiskURL.path) && FileManager.default.fileExists(atPath: developerDiskSignatureURL.path) - { - // The developer disk is cached and we've confirmed it works, so re-use it. - return completionHandler(.success((developerDiskURL, developerDiskSignatureURL))) - } - - func finish(_ result: Result<(URL, URL), Error>) - { - do - { - let (diskFileURL, signatureFileURL) = try result.get() - - if FileManager.default.fileExists(atPath: developerDiskURL.path) - { - try FileManager.default.removeItem(at: developerDiskURL) - } - - if FileManager.default.fileExists(atPath: developerDiskSignatureURL.path) - { - try FileManager.default.removeItem(at: developerDiskSignatureURL) - } - - try FileManager.default.copyItem(at: diskFileURL, to: developerDiskURL) - try FileManager.default.copyItem(at: signatureFileURL, to: developerDiskSignatureURL) - - completionHandler(.success((developerDiskURL, developerDiskSignatureURL))) - } - catch - { - completionHandler(.failure(error)) - } - } - - self.fetchDeveloperDiskURLs { (result) in - do - { - let developerDiskURLs = try result.get() - guard let diskURL = developerDiskURLs[keyPath: osKeyPath]?[osVersion.stringValue] else { throw DeveloperDiskError.unknownDownloadURL } - - switch diskURL - { - case .archive(let archiveURL): self.downloadDiskArchive(from: archiveURL, completionHandler: finish(_:)) - case .separate(let diskURL, let signatureURL): self.downloadDisk(from: diskURL, signatureURL: signatureURL, completionHandler: finish(_:)) - } - } - catch - { - finish(.failure(error)) - } - } - } - catch - { - completionHandler(.failure(error)) - } - } - - func setDeveloperDiskCompatible(_ isCompatible: Bool, with device: ALTDevice) - { - guard let id = self.developerDiskCompatibilityID(for: device) else { return } - UserDefaults.standard.set(isCompatible, forKey: id) - } - - func isDeveloperDiskCompatible(with device: ALTDevice) -> Bool - { - guard let id = self.developerDiskCompatibilityID(for: device) else { return false } - - let isCompatible = UserDefaults.standard.bool(forKey: id) - return isCompatible - } -} - -private extension DeveloperDiskManager -{ - func developerDiskCompatibilityID(for device: ALTDevice) -> String? - { - guard let osName = device.type.osName else { return nil } - - var osVersion = device.osVersion - osVersion.patchVersion = 0 // Patch is irrelevant for developer disks - - let id = ["ALTDeveloperDiskCompatible", osName, device.osVersion.stringValue].joined(separator: "_") - return id - } - - func fetchDeveloperDiskURLs(completionHandler: @escaping (Result) -> Void) - { - let dataTask = self.session.dataTask(with: .developerDiskDownloadURLs) { (data, response, error) in - do - { - guard let data = data else { throw error! } - - let response = try JSONDecoder().decode(FetchURLsResponse.self, from: data) - completionHandler(.success(response.disks)) - } - catch - { - completionHandler(.failure(error)) - } - } - - dataTask.resume() - } - - func downloadDiskArchive(from url: URL, completionHandler: @escaping (Result<(URL, URL), Error>) -> Void) - { - let downloadTask = URLSession.shared.downloadTask(with: url) { (fileURL, response, error) in - do - { - guard let fileURL = fileURL else { throw error! } - defer { try? FileManager.default.removeItem(at: fileURL) } - - let temporaryDirectory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - try FileManager.default.createDirectory(at: temporaryDirectory, withIntermediateDirectories: true, attributes: nil) - defer { try? FileManager.default.removeItem(at: temporaryDirectory) } - - try FileManager.default.unzipArchive(at: fileURL, toDirectory: temporaryDirectory) - - guard let enumerator = FileManager.default.enumerator(at: temporaryDirectory, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles, .skipsPackageDescendants]) else { - throw CocoaError(.fileNoSuchFile, userInfo: [NSURLErrorKey: temporaryDirectory]) - } - - var tempDiskFileURL: URL? - var tempSignatureFileURL: URL? - - for case let fileURL as URL in enumerator - { - switch fileURL.pathExtension.lowercased() - { - case "dmg": tempDiskFileURL = fileURL - case "signature": tempSignatureFileURL = fileURL - default: break - } - } - - guard let diskFileURL = tempDiskFileURL, let signatureFileURL = tempSignatureFileURL else { throw DeveloperDiskError.downloadedDiskNotFound } - - completionHandler(.success((diskFileURL, signatureFileURL))) - } - catch - { - completionHandler(.failure(error)) - } - } - - downloadTask.resume() - } - - func downloadDisk(from diskURL: URL, signatureURL: URL, completionHandler: @escaping (Result<(URL, URL), Error>) -> Void) - { - let temporaryDirectory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - - do { try FileManager.default.createDirectory(at: temporaryDirectory, withIntermediateDirectories: true, attributes: nil) } - catch { return completionHandler(.failure(error)) } - - var diskFileURL: URL? - var signatureFileURL: URL? - - var downloadError: Error? - - let dispatchGroup = DispatchGroup() - dispatchGroup.enter() - dispatchGroup.enter() - - let diskDownloadTask = URLSession.shared.downloadTask(with: diskURL) { (fileURL, response, error) in - do - { - guard let fileURL = fileURL else { throw error! } - - let destinationURL = temporaryDirectory.appendingPathComponent("DeveloperDiskImage.dmg") - try FileManager.default.copyItem(at: fileURL, to: destinationURL) - - diskFileURL = destinationURL - } - catch - { - downloadError = error - } - - dispatchGroup.leave() - } - - let signatureDownloadTask = URLSession.shared.downloadTask(with: signatureURL) { (fileURL, response, error) in - do - { - guard let fileURL = fileURL else { throw error! } - - let destinationURL = temporaryDirectory.appendingPathComponent("DeveloperDiskImage.dmg.signature") - try FileManager.default.copyItem(at: fileURL, to: destinationURL) - - signatureFileURL = destinationURL - } - catch - { - downloadError = error - } - - dispatchGroup.leave() - } - - diskDownloadTask.resume() - signatureDownloadTask.resume() - - dispatchGroup.notify(queue: .global(qos: .userInitiated)) { - defer { - try? FileManager.default.removeItem(at: temporaryDirectory) - } - - guard let diskFileURL = diskFileURL, let signatureFileURL = signatureFileURL else { - return completionHandler(.failure(downloadError ?? DeveloperDiskError.downloadedDiskNotFound)) - } - - completionHandler(.success((diskFileURL, signatureFileURL))) - } - } -} diff --git a/AltServer/Devices/ALTDeviceManager+Installation.swift b/AltServer/Devices/ALTDeviceManager+Installation.swift deleted file mode 100644 index 74fbe3ab..00000000 --- a/AltServer/Devices/ALTDeviceManager+Installation.swift +++ /dev/null @@ -1,941 +0,0 @@ -// -// ALTDeviceManager+Installation.swift -// AltServer -// -// Created by Riley Testut on 7/1/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -import Cocoa -import UserNotifications -import ObjectiveC - -private let appGroupsSemaphore = DispatchSemaphore(value: 1) - -private let developerDiskManager = DeveloperDiskManager() - -enum InstallError: Int, LocalizedError, _ObjectiveCBridgeableError -{ - case cancelled - case noTeam - case missingPrivateKey - case missingCertificate - - var errorDescription: String? { - switch self - { - case .cancelled: return NSLocalizedString("The operation was cancelled.", comment: "") - case .noTeam: return "You are not a member of any developer teams." - case .missingPrivateKey: return "The developer certificate's private key could not be found." - case .missingCertificate: return "The developer certificate could not be found." - } - } - - init?(_bridgedNSError error: NSError) - { - guard error.domain == InstallError.cancelled._domain else { return nil } - - if let installError = InstallError(rawValue: error.code) - { - self = installError - } - else - { - return nil - } - } -} - -extension ALTDeviceManager -{ - func installApplication(at url: URL, to altDevice: ALTDevice, appleID: String, password: String, completion: @escaping (Result) -> Void) - { - let destinationDirectoryURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - - var appName = (url.isFileURL) ? url.deletingPathExtension().lastPathComponent : NSLocalizedString("AltStore", comment: "") - - func finish(_ result: Result, title: String = "") - { - DispatchQueue.main.async { - switch result - { - case .success(let app): completion(.success(app)) - case .failure(var error as NSError): - if error.localizedFailure == nil - { - error = error.withLocalizedFailure(String(format: NSLocalizedString("Could not install %@ to %@.", comment: ""), appName, altDevice.name)) - } - - completion(.failure(error)) - } - } - - try? FileManager.default.removeItem(at: destinationDirectoryURL) - } - - AnisetteDataManager.shared.requestAnisetteData { (result) in - do - { - let anisetteData = try result.get() - - self.authenticate(appleID: appleID, password: password, anisetteData: anisetteData) { (result) in - do - { - let (account, session) = try result.get() - - self.fetchTeam(for: account, session: session) { (result) in - do - { - let team = try result.get() - - self.register(altDevice, team: team, session: session) { (result) in - do - { - let device = try result.get() - device.osVersion = altDevice.osVersion - - self.fetchCertificate(for: team, session: session) { (result) in - do - { - let certificate = try result.get() - - if !url.isFileURL - { - // Show alert before downloading remote .ipa. - self.showInstallationAlert(appName: NSLocalizedString("AltStore", comment: ""), deviceName: device.name) - } - - self.prepare(device) { (result) in - switch result - { - case .failure(let error): - print("Failed to install DeveloperDiskImage.dmg to \(device).", error) - fallthrough // Continue installing app even if we couldn't install Developer disk image. - - case .success: - self.downloadApp(from: url) { (result) in - do - { - let fileURL = try result.get() - - try FileManager.default.createDirectory(at: destinationDirectoryURL, withIntermediateDirectories: true, attributes: nil) - - let appBundleURL = try FileManager.default.unzipAppBundle(at: fileURL, toDirectory: destinationDirectoryURL) - guard let application = ALTApplication(fileURL: appBundleURL) else { throw ALTError(.invalidApp) } - - if url.isFileURL - { - // Show alert after "downloading" local .ipa. - self.showInstallationAlert(appName: application.name, deviceName: device.name) - } - - appName = application.name - - // Refresh anisette data to prevent session timeouts. - AnisetteDataManager.shared.requestAnisetteData { (result) in - do - { - let anisetteData = try result.get() - session.anisetteData = anisetteData - - self.prepareAllProvisioningProfiles(for: application, device: device, team: team, session: session) { (result) in - do - { - let profiles = try result.get() - - self.install(application, to: device, team: team, certificate: certificate, profiles: profiles) { (result) in - finish(result.map { application }, title: "Failed to Install AltStore") - } - } - catch - { - finish(.failure(error), title: "Failed to Fetch Provisioning Profiles") - } - } - } - catch - { - finish(.failure(error), title: "Failed to Refresh Anisette Data") - } - } - } - catch - { - finish(.failure(error), title: "Failed to Download AltStore") - } - } - } - } - } - catch - { - finish(.failure(error), title: "Failed to Fetch Certificate") - } - } - } - catch - { - finish(.failure(error), title: "Failed to Register Device") - } - } - } - catch - { - finish(.failure(error), title: "Failed to Fetch Team") - } - } - } - catch - { - finish(.failure(error), title: "Failed to Authenticate") - } - } - } - catch - { - finish(.failure(error), title: "Failed to Fetch Anisette Data") - } - } - } -} - -extension ALTDeviceManager -{ - func prepare(_ device: ALTDevice, completionHandler: @escaping (Result) -> Void) - { - ALTDeviceManager.shared.isDeveloperDiskImageMounted(for: device) { (isMounted, error) in - switch (isMounted, error) - { - case (_, let error?): return completionHandler(.failure(error)) - case (true, _): return completionHandler(.success(())) - case (false, _): - developerDiskManager.downloadDeveloperDisk(for: device) { (result) in - switch result - { - case .failure(let error): completionHandler(.failure(error)) - case .success((let diskFileURL, let signatureFileURL)): - ALTDeviceManager.shared.installDeveloperDiskImage(at: diskFileURL, signatureURL: signatureFileURL, to: device) { (success, error) in - switch Result(success, error) - { - case .failure(let error as ALTServerError) where error.code == .incompatibleDeveloperDisk: - developerDiskManager.setDeveloperDiskCompatible(false, with: device) - completionHandler(.failure(error)) - - case .failure(let error): - // Don't mark developer disk as incompatible because it probably failed for a different reason. - completionHandler(.failure(error)) - - case .success: - developerDiskManager.setDeveloperDiskCompatible(true, with: device) - completionHandler(.success(())) - } - } - } - } - } - } - } -} - -private extension ALTDeviceManager -{ - func downloadApp(from url: URL, completionHandler: @escaping (Result) -> Void) - { - guard !url.isFileURL else { return completionHandler(.success(url)) } - - let downloadTask = URLSession.shared.downloadTask(with: url) { (fileURL, response, error) in - do - { - let (fileURL, _) = try Result((fileURL, response), error).get() - completionHandler(.success(fileURL)) - - do { try FileManager.default.removeItem(at: fileURL) } - catch { print("Failed to remove downloaded .ipa.", error) } - } - catch - { - completionHandler(.failure(error)) - } - } - - downloadTask.resume() - } - - func authenticate(appleID: String, password: String, anisetteData: ALTAnisetteData, completionHandler: @escaping (Result<(ALTAccount, ALTAppleAPISession), Error>) -> Void) - { - func handleVerificationCode(_ completionHandler: @escaping (String?) -> Void) - { - DispatchQueue.main.async { - let alert = NSAlert() - alert.messageText = NSLocalizedString("Two-Factor Authentication Enabled", comment: "") - alert.informativeText = NSLocalizedString("Please enter the 6-digit verification code that was sent to your Apple devices.", comment: "") - - let textField = NSTextField(frame: NSRect(x: 0, y: 0, width: 300, height: 22)) - textField.delegate = self - textField.translatesAutoresizingMaskIntoConstraints = false - textField.placeholderString = NSLocalizedString("123456", comment: "") - alert.accessoryView = textField - alert.window.initialFirstResponder = textField - - alert.addButton(withTitle: NSLocalizedString("Continue", comment: "")) - alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) - - self.securityCodeAlert = alert - self.securityCodeTextField = textField - self.validate() - - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - let response = alert.runModal() - if response == .alertFirstButtonReturn - { - let code = textField.stringValue - completionHandler(code) - } - else - { - completionHandler(nil) - } - } - } - - ALTAppleAPI.shared.authenticate(appleID: appleID, password: password, anisetteData: anisetteData, verificationHandler: handleVerificationCode) { (account, session, error) in - if let account = account, let session = session - { - completionHandler(.success((account, session))) - } - else - { - completionHandler(.failure(error ?? ALTAppleAPIError(.unknown))) - } - } - } - - func fetchTeam(for account: ALTAccount, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) - { - ALTAppleAPI.shared.fetchTeams(for: account, session: session) { (teams, error) in - do - { - let teams = try Result(teams, error).get() - - if let team = teams.first(where: { $0.type == .individual }) - { - return completionHandler(.success(team)) - } - else if let team = teams.first(where: { $0.type == .free }) - { - return completionHandler(.success(team)) - } - else if let team = teams.first - { - return completionHandler(.success(team)) - } - else - { - throw InstallError.noTeam - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - - func fetchCertificate(for team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) - { - ALTAppleAPI.shared.fetchCertificates(for: team, session: session) { (certificates, error) in - do - { - let certificates = try Result(certificates, error).get() - - let certificateFileURL = FileManager.default.certificatesDirectory.appendingPathComponent(team.identifier + ".p12") - try FileManager.default.createDirectory(at: FileManager.default.certificatesDirectory, withIntermediateDirectories: true, attributes: nil) - - var isCancelled = false - - // Check if there is another AltStore certificate, which means AltStore has been installed with this Apple ID before. - let altstoreCertificate = certificates.first { $0.machineName?.starts(with: "AltStore") == true } - if let previousCertificate = altstoreCertificate - { - if FileManager.default.fileExists(atPath: certificateFileURL.path), - let data = try? Data(contentsOf: certificateFileURL), - let certificate = ALTCertificate(p12Data: data, password: previousCertificate.machineIdentifier) - { - // Manually set machineIdentifier so we can encrypt + embed certificate if needed. - certificate.machineIdentifier = previousCertificate.machineIdentifier - return completionHandler(.success(certificate)) - } - - DispatchQueue.main.sync { - let alert = NSAlert() - alert.messageText = NSLocalizedString("Multiple AltServers Not Supported", comment: "") - alert.informativeText = NSLocalizedString("Please use the same AltServer you previously used with this Apple ID, or else apps installed with other AltServers will stop working.\n\nAre you sure you want to continue?", comment: "") - - alert.addButton(withTitle: NSLocalizedString("Continue", comment: "")) - alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) - - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - let buttonIndex = alert.runModal() - if buttonIndex == NSApplication.ModalResponse.alertSecondButtonReturn - { - isCancelled = true - } - } - - guard !isCancelled else { return completionHandler(.failure(InstallError.cancelled)) } - } - - func addCertificate() - { - ALTAppleAPI.shared.addCertificate(machineName: "AltStore", to: team, session: session) { (certificate, error) in - do - { - let certificate = try Result(certificate, error).get() - guard let privateKey = certificate.privateKey else { throw InstallError.missingPrivateKey } - - ALTAppleAPI.shared.fetchCertificates(for: team, session: session) { (certificates, error) in - do - { - let certificates = try Result(certificates, error).get() - - guard let certificate = certificates.first(where: { $0.serialNumber == certificate.serialNumber }) else { - throw InstallError.missingCertificate - } - - certificate.privateKey = privateKey - - completionHandler(.success(certificate)) - - if let machineIdentifier = certificate.machineIdentifier, - let encryptedData = certificate.encryptedP12Data(withPassword: machineIdentifier) - { - // Cache certificate. - do { try encryptedData.write(to: certificateFileURL, options: .atomic) } - catch { print("Failed to cache certificate:", error) } - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - - if let certificate = altstoreCertificate ?? certificates.first - { - if team.type != .free - { - DispatchQueue.main.sync { - let alert = NSAlert() - alert.messageText = NSLocalizedString("Installing this app will revoke your iOS development certificate.", comment: "") - alert.informativeText = NSLocalizedString(""" - This will not affect apps you've submitted to the App Store, but may cause apps you've installed to your devices with Xcode to stop working until you reinstall them. - - To prevent this from happening, feel free to try again with another Apple ID. - """, comment: "") - - alert.addButton(withTitle: NSLocalizedString("Continue", comment: "")) - alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) - - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - let buttonIndex = alert.runModal() - if buttonIndex == NSApplication.ModalResponse.alertSecondButtonReturn - { - isCancelled = true - } - } - - guard !isCancelled else { return completionHandler(.failure(InstallError.cancelled)) } - } - - ALTAppleAPI.shared.revoke(certificate, for: team, session: session) { (success, error) in - do - { - try Result(success, error).get() - addCertificate() - } - catch - { - completionHandler(.failure(error)) - } - } - } - else - { - addCertificate() - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - - func prepareAllProvisioningProfiles(for application: ALTApplication, device: ALTDevice, team: ALTTeam, session: ALTAppleAPISession, - completion: @escaping (Result<[String: ALTProvisioningProfile], Error>) -> Void) - { - self.prepareProvisioningProfile(for: application, parentApp: nil, device: device, team: team, session: session) { (result) in - do - { - let profile = try result.get() - - var profiles = [application.bundleIdentifier: profile] - var error: Error? - - let dispatchGroup = DispatchGroup() - - for appExtension in application.appExtensions - { - dispatchGroup.enter() - - self.prepareProvisioningProfile(for: appExtension, parentApp: application, device: device, team: team, session: session) { (result) in - switch result - { - case .failure(let e): error = e - case .success(let profile): profiles[appExtension.bundleIdentifier] = profile - } - - dispatchGroup.leave() - } - } - - dispatchGroup.notify(queue: .global()) { - if let error = error - { - completion(.failure(error)) - } - else - { - completion(.success(profiles)) - } - } - } - catch - { - completion(.failure(error)) - } - } - } - - func prepareProvisioningProfile(for application: ALTApplication, parentApp: ALTApplication?, device: ALTDevice, team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) - { - let parentBundleID = parentApp?.bundleIdentifier ?? application.bundleIdentifier - let updatedParentBundleID: String - - if application.isAltStoreApp - { - // Use legacy bundle ID format for AltStore (and its extensions). - updatedParentBundleID = "com.\(team.identifier).\(parentBundleID)" - } - else - { - updatedParentBundleID = parentBundleID + "." + team.identifier // Append just team identifier to make it harder to track. - } - - let bundleID = application.bundleIdentifier.replacingOccurrences(of: parentBundleID, with: updatedParentBundleID) - - let preferredName: String - - if let parentApp = parentApp - { - preferredName = parentApp.name + " " + application.name - } - else - { - preferredName = application.name - } - - self.registerAppID(name: preferredName, bundleID: bundleID, team: team, session: session) { (result) in - do - { - let appID = try result.get() - - self.updateFeatures(for: appID, app: application, team: team, session: session) { (result) in - do - { - let appID = try result.get() - - self.updateAppGroups(for: appID, app: application, team: team, session: session) { (result) in - do - { - let appID = try result.get() - - self.fetchProvisioningProfile(for: appID, device: device, team: team, session: session) { (result) in - completionHandler(result) - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - - func registerAppID(name appName: String, bundleID: String, team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) - { - ALTAppleAPI.shared.fetchAppIDs(for: team, session: session) { (appIDs, error) in - do - { - let appIDs = try Result(appIDs, error).get() - - if let appID = appIDs.first(where: { $0.bundleIdentifier == bundleID }) - { - completionHandler(.success(appID)) - } - else - { - ALTAppleAPI.shared.addAppID(withName: appName, bundleIdentifier: bundleID, team: team, session: session) { (appID, error) in - completionHandler(Result(appID, error)) - } - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - - func updateFeatures(for appID: ALTAppID, app: ALTApplication, team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) - { - let requiredFeatures = app.entitlements.compactMap { (entitlement, value) -> (ALTFeature, Any)? in - guard let feature = ALTFeature(entitlement: entitlement) else { return nil } - return (feature, value) - } - - var features = requiredFeatures.reduce(into: [ALTFeature: Any]()) { $0[$1.0] = $1.1 } - - if let applicationGroups = app.entitlements[.appGroups] as? [String], !applicationGroups.isEmpty - { - // App uses app groups, so assign `true` to enable the feature. - features[.appGroups] = true - } - else - { - // App has no app groups, so assign `false` to disable the feature. - features[.appGroups] = false - } - - var updateFeatures = false - - // Determine whether the required features are already enabled for the AppID. - for (feature, value) in features - { - if let appIDValue = appID.features[feature] as AnyObject?, (value as AnyObject).isEqual(appIDValue) - { - // AppID already has this feature enabled and the values are the same. - continue - } - else if appID.features[feature] == nil, let shouldEnableFeature = value as? Bool, !shouldEnableFeature - { - // AppID doesn't already have this feature enabled, but we want it disabled anyway. - continue - } - else - { - // AppID either doesn't have this feature enabled or the value has changed, - // so we need to update it to reflect new values. - updateFeatures = true - break - } - } - - if updateFeatures - { - let appID = appID.copy() as! ALTAppID - appID.features = features - - ALTAppleAPI.shared.update(appID, team: team, session: session) { (appID, error) in - completionHandler(Result(appID, error)) - } - } - else - { - completionHandler(.success(appID)) - } - } - - func updateAppGroups(for appID: ALTAppID, app: ALTApplication, team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) - { - guard let applicationGroups = app.entitlements[.appGroups] as? [String], !applicationGroups.isEmpty else { - // Assigning an App ID to an empty app group array fails, - // so just do nothing if there are no app groups. - return completionHandler(.success(appID)) - } - - // Dispatch onto global queue to prevent appGroupsSemaphore deadlock. - DispatchQueue.global().async { - - // Ensure we're not concurrently fetching and updating app groups, - // which can lead to race conditions such as adding an app group twice. - appGroupsSemaphore.wait() - - func finish(_ result: Result) - { - appGroupsSemaphore.signal() - completionHandler(result) - } - - ALTAppleAPI.shared.fetchAppGroups(for: team, session: session) { (groups, error) in - switch Result(groups, error) - { - case .failure(let error): finish(.failure(error)) - case .success(let fetchedGroups): - let dispatchGroup = DispatchGroup() - - var groups = [ALTAppGroup]() - var errors = [Error]() - - for groupIdentifier in applicationGroups - { - let adjustedGroupIdentifier = groupIdentifier + "." + team.identifier - - if let group = fetchedGroups.first(where: { $0.groupIdentifier == adjustedGroupIdentifier }) - { - groups.append(group) - } - else - { - dispatchGroup.enter() - - // Not all characters are allowed in group names, so we replace periods with spaces (like Apple does). - let name = "AltStore " + groupIdentifier.replacingOccurrences(of: ".", with: " ") - - ALTAppleAPI.shared.addAppGroup(withName: name, groupIdentifier: adjustedGroupIdentifier, team: team, session: session) { (group, error) in - switch Result(group, error) - { - case .success(let group): groups.append(group) - case .failure(let error): errors.append(error) - } - - dispatchGroup.leave() - } - } - } - - dispatchGroup.notify(queue: .global()) { - if let error = errors.first - { - finish(.failure(error)) - } - else - { - ALTAppleAPI.shared.assign(appID, to: Array(groups), team: team, session: session) { (success, error) in - let result = Result(success, error) - finish(result.map { _ in appID }) - } - } - } - } - } - } - } - - func register(_ device: ALTDevice, team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) - { - ALTAppleAPI.shared.fetchDevices(for: team, types: device.type, session: session) { (devices, error) in - do - { - let devices = try Result(devices, error).get() - - if let device = devices.first(where: { $0.identifier == device.identifier }) - { - completionHandler(.success(device)) - } - else - { - ALTAppleAPI.shared.registerDevice(name: device.name, identifier: device.identifier, type: device.type, team: team, session: session) { (device, error) in - completionHandler(Result(device, error)) - } - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - - func fetchProvisioningProfile(for appID: ALTAppID, device: ALTDevice, team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) - { - ALTAppleAPI.shared.fetchProvisioningProfile(for: appID, deviceType: device.type, team: team, session: session) { (profile, error) in - completionHandler(Result(profile, error)) - } - } - - func install(_ application: ALTApplication, to device: ALTDevice, team: ALTTeam, certificate: ALTCertificate, profiles: [String: ALTProvisioningProfile], completionHandler: @escaping (Result) -> Void) - { - func prepare(_ bundle: Bundle, additionalInfoDictionaryValues: [String: Any] = [:]) throws - { - guard let identifier = bundle.bundleIdentifier else { throw ALTError(.missingAppBundle) } - guard let profile = profiles[identifier] else { throw ALTError(.missingProvisioningProfile) } - guard var infoDictionary = bundle.completeInfoDictionary else { throw ALTError(.missingInfoPlist) } - - infoDictionary[kCFBundleIdentifierKey as String] = profile.bundleIdentifier - infoDictionary[Bundle.Info.altBundleID] = identifier - - if (infoDictionary.keys.contains(Bundle.Info.deviceID)) { - infoDictionary[Bundle.Info.deviceID] = device.identifier - } - - for (key, value) in additionalInfoDictionaryValues - { - infoDictionary[key] = value - } - - if let appGroups = profile.entitlements[.appGroups] as? [String] - { - infoDictionary[Bundle.Info.appGroups] = appGroups - } - - try (infoDictionary as NSDictionary).write(to: bundle.infoPlistURL) - } - - DispatchQueue.global().async { - do - { - guard let appBundle = Bundle(url: application.fileURL) else { throw ALTError(.missingAppBundle) } - guard let infoDictionary = appBundle.completeInfoDictionary else { throw ALTError(.missingInfoPlist) } - - let openAppURL = URL(string: "altstore-" + application.bundleIdentifier + "://")! - - var allURLSchemes = infoDictionary[Bundle.Info.urlTypes] as? [[String: Any]] ?? [] - - // Embed open URL so AltBackup can return to AltStore. - let altstoreURLScheme = ["CFBundleTypeRole": "Editor", - "CFBundleURLName": application.bundleIdentifier, - "CFBundleURLSchemes": [openAppURL.scheme!]] as [String : Any] - allURLSchemes.append(altstoreURLScheme) - - var additionalValues: [String: Any] = [Bundle.Info.urlTypes: allURLSchemes] - - if application.isAltStoreApp - { - additionalValues[Bundle.Info.deviceID] = device.identifier - additionalValues[Bundle.Info.serverID] = UserDefaults.standard.serverID - - if - let machineIdentifier = certificate.machineIdentifier, - let encryptedData = certificate.encryptedP12Data(withPassword: machineIdentifier) - { - additionalValues[Bundle.Info.certificateID] = certificate.serialNumber - - let certificateURL = application.fileURL.appendingPathComponent("ALTCertificate.p12") - try encryptedData.write(to: certificateURL, options: .atomic) - } - } - else if infoDictionary.keys.contains(Bundle.Info.deviceID) - { - // There is an ALTDeviceID entry, so assume the app is using AltKit and replace it with the device's UDID. - additionalValues[Bundle.Info.deviceID] = device.identifier - additionalValues[Bundle.Info.serverID] = UserDefaults.standard.serverID - } - - try prepare(appBundle, additionalInfoDictionaryValues: additionalValues) - - for appExtension in application.appExtensions - { - guard let bundle = Bundle(url: appExtension.fileURL) else { throw ALTError(.missingAppBundle) } - try prepare(bundle) - } - - let resigner = ALTSigner(team: team, certificate: certificate) - resigner.signApp(at: application.fileURL, provisioningProfiles: Array(profiles.values)) { (success, error) in - do - { - try Result(success, error).get() - - let activeProfiles: Set? = (team.type == .free && application.isAltStoreApp) ? Set(profiles.values.map(\.bundleIdentifier)) : nil - ALTDeviceManager.shared.installApp(at: application.fileURL, toDeviceWithUDID: device.identifier, activeProvisioningProfiles: activeProfiles) { (success, error) in - completionHandler(Result(success, error)) - } - } - catch - { - print("Failed to install app", error) - completionHandler(.failure(error)) - } - } - } - catch - { - print("Failed to install AltStore", error) - completionHandler(.failure(error)) - } - } - } - - func showInstallationAlert(appName: String, deviceName: String) - { - let content = UNMutableNotificationContent() - content.title = String(format: NSLocalizedString("Installing %@ to %@...", comment: ""), appName, deviceName) - content.body = NSLocalizedString("This may take a few seconds.", comment: "") - - let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) - UNUserNotificationCenter.current().add(request) - } -} - -private var securityCodeAlertKey = 0 -private var securityCodeTextFieldKey = 0 - -extension ALTDeviceManager: NSTextFieldDelegate -{ - var securityCodeAlert: NSAlert? { - get { return objc_getAssociatedObject(self, &securityCodeAlertKey) as? NSAlert } - set { objc_setAssociatedObject(self, &securityCodeAlertKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } - } - - var securityCodeTextField: NSTextField? { - get { return objc_getAssociatedObject(self, &securityCodeTextFieldKey) as? NSTextField } - set { objc_setAssociatedObject(self, &securityCodeTextFieldKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } - } - - public func controlTextDidChange(_ obj: Notification) - { - self.validate() - } - - public func controlTextDidEndEditing(_ obj: Notification) - { - self.validate() - } - - private func validate() - { - guard let code = self.securityCodeTextField?.stringValue.trimmingCharacters(in: .whitespacesAndNewlines) else { return } - - if code.count == 6 - { - self.securityCodeAlert?.buttons.first?.isEnabled = true - } - else - { - self.securityCodeAlert?.buttons.first?.isEnabled = false - } - - self.securityCodeAlert?.layout() - } -} diff --git a/AltServer/Devices/ALTDeviceManager.h b/AltServer/Devices/ALTDeviceManager.h deleted file mode 100644 index 12295a2b..00000000 --- a/AltServer/Devices/ALTDeviceManager.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// ALTDeviceManager.h -// AltServer -// -// Created by Riley Testut on 5/24/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -#import -#import "AltSign.h" - -@class ALTWiredConnection; -@class ALTNotificationConnection; -@class ALTDebugConnection; - -@class ALTInstalledApp; - -NS_ASSUME_NONNULL_BEGIN - -extern NSNotificationName const ALTDeviceManagerDeviceDidConnectNotification NS_SWIFT_NAME(deviceManagerDeviceDidConnect); -extern NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification NS_SWIFT_NAME(deviceManagerDeviceDidDisconnect); - -@interface ALTDeviceManager : NSObject - -@property (class, nonatomic, readonly) ALTDeviceManager *sharedManager; - -@property (nonatomic, readonly) NSArray *connectedDevices; -@property (nonatomic, readonly) NSArray *availableDevices; - -- (void)start; - -/* App Installation */ -- (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; -- (void)removeAppForBundleIdentifier:(NSString *)bundleIdentifier fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; - -/* Provisioning Profiles */ -- (void)installProvisioningProfiles:(NSSet *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; -- (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; - -/* Developer Disk Image */ -- (void)isDeveloperDiskImageMountedForDevice:(ALTDevice *)device - completionHandler:(void (^)(BOOL isMounted, NSError *_Nullable error))completionHandler; -- (void)installDeveloperDiskImageAtURL:(NSURL *)diskURL signatureURL:(NSURL *)signatureURL toDevice:(ALTDevice *)device - completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler; - -/* Apps */ -- (void)fetchInstalledAppsOnDevice:(ALTDevice *)altDevice completionHandler:(void (^)(NSSet *_Nullable installedApps, NSError *_Nullable error))completionHandler; - -/* Connections */ -- (void)startWiredConnectionToDevice:(ALTDevice *)device completionHandler:(void (^)(ALTWiredConnection *_Nullable connection, NSError *_Nullable error))completionHandler; -- (void)startNotificationConnectionToDevice:(ALTDevice *)device completionHandler:(void (^)(ALTNotificationConnection *_Nullable connection, NSError *_Nullable error))completionHandler; -- (void)startDebugConnectionToDevice:(ALTDevice *)device completionHandler:(void (^)(ALTDebugConnection *_Nullable connection, NSError * _Nullable error))completionHandler; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltServer/Devices/ALTDeviceManager.mm b/AltServer/Devices/ALTDeviceManager.mm deleted file mode 100644 index a7d6aff7..00000000 --- a/AltServer/Devices/ALTDeviceManager.mm +++ /dev/null @@ -1,1786 +0,0 @@ -// -// ALTDeviceManager.m -// AltServer -// -// Created by Riley Testut on 5/24/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -#import "ALTDeviceManager.h" - -#import "ALTWiredConnection+Private.h" -#import "ALTNotificationConnection+Private.h" -#import "ALTDebugConnection+Private.h" - -#import "ALTConstants.h" -#import "NSError+ALTServerError.h" -#import "NSError+libimobiledevice.h" - -#import -#import -#import "AltServer-Swift.h" - -#include -#include -#include -#include -#include -#include -#include - -void ALTDeviceManagerUpdateStatus(plist_t command, plist_t status, void *udid); -void ALTDeviceManagerUpdateAppDeletionStatus(plist_t command, plist_t status, void *uuid); -void ALTDeviceDidChangeConnectionStatus(const idevice_event_t *event, void *user_data); -ssize_t ALTDeviceManagerUploadFile(void *buffer, size_t size, void *user_data); - -NSNotificationName const ALTDeviceManagerDeviceDidConnectNotification = @"ALTDeviceManagerDeviceDidConnectNotification"; -NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALTDeviceManagerDeviceDidDisconnectNotification"; - -@interface ALTDeviceManager () - -@property (nonatomic, readonly) NSMutableDictionary *installationCompletionHandlers; -@property (nonatomic, readonly) NSMutableDictionary *deletionCompletionHandlers; - -@property (nonatomic, readonly) NSMutableDictionary *installationProgress; - -@property (nonatomic, readonly) dispatch_queue_t installationQueue; -@property (nonatomic, readonly) dispatch_queue_t devicesQueue; - -@property (nonatomic, readonly) NSMutableSet *cachedDevices; - -@end - -@implementation ALTDeviceManager - -+ (ALTDeviceManager *)sharedManager -{ - static ALTDeviceManager *_manager = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - _manager = [[self alloc] init]; - }); - - return _manager; -} - -- (instancetype)init -{ - self = [super init]; - if (self) - { - _installationCompletionHandlers = [NSMutableDictionary dictionary]; - _deletionCompletionHandlers = [NSMutableDictionary dictionary]; - - _installationProgress = [NSMutableDictionary dictionary]; - - _installationQueue = dispatch_queue_create("com.rileytestut.AltServer.Installation", DISPATCH_QUEUE_SERIAL); - _devicesQueue = dispatch_queue_create("com.rileytestut.AltServer.Devices", DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL); - - _cachedDevices = [NSMutableSet set]; - } - - return self; -} - -- (void)start -{ - idevice_event_subscribe(ALTDeviceDidChangeConnectionStatus, nil); -} - -#pragma mark - App Installation - - -- (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet *)activeProvisioningProfiles completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler -{ - NSProgress *progress = [NSProgress discreteProgressWithTotalUnitCount:4]; - - dispatch_async(self.installationQueue, ^{ - NSUUID *UUID = [NSUUID UUID]; - __block char *uuidString = (char *)malloc(UUID.UUIDString.length + 1); - strncpy(uuidString, (const char *)UUID.UUIDString.UTF8String, UUID.UUIDString.length); - uuidString[UUID.UUIDString.length] = '\0'; - - __block idevice_t device = NULL; - __block lockdownd_client_t client = NULL; - __block instproxy_client_t ipc = NULL; - __block afc_client_t afc = NULL; - __block misagent_client_t mis = NULL; - __block lockdownd_service_descriptor_t service = NULL; - - NSMutableDictionary *cachedProfiles = [NSMutableDictionary dictionary]; - NSMutableSet *installedProfiles = [NSMutableSet set]; - - void (^finish)(NSError *error) = ^(NSError *e) { - __block NSError *error = e; - - if (activeProvisioningProfiles != nil) - { - // Remove installed provisioning profiles if they're not active. - - for (ALTProvisioningProfile *installedProfile in installedProfiles) - { - if (![activeProvisioningProfiles containsObject:installedProfile.bundleIdentifier]) - { - NSError *removeError = nil; - if (![self removeProvisioningProfile:installedProfile misagent:mis error:&removeError]) - { - if (error == nil) - { - error = removeError; - } - } - } - } - } - - [cachedProfiles enumerateKeysAndObjectsUsingBlock:^(NSString *bundleID, ALTProvisioningProfile *profile, BOOL * _Nonnull stop) { - for (ALTProvisioningProfile *installedProfile in installedProfiles) - { - if ([installedProfile.bundleIdentifier isEqualToString:profile.bundleIdentifier]) - { - // Don't reinstall cached profile because it was installed with the app. - return; - } - } - - NSError *installError = nil; - if (![self installProvisioningProfile:profile misagent:mis error:&installError]) - { - if (error == nil) - { - error = installError; - } - } - }]; - - instproxy_client_free(ipc); - afc_client_free(afc); - lockdownd_client_free(client); - misagent_client_free(mis); - idevice_free(device); - lockdownd_service_descriptor_free(service); - - free(uuidString); - uuidString = NULL; - - if (error != nil) - { - completionHandler(NO, error); - } - else - { - completionHandler(YES, nil); - } - }; - - NSURL *appBundleURL = nil; - NSURL *temporaryDirectoryURL = nil; - - if ([fileURL.pathExtension.lowercaseString isEqualToString:@"app"]) - { - appBundleURL = fileURL; - temporaryDirectoryURL = nil; - } - else if ([fileURL.pathExtension.lowercaseString isEqualToString:@"ipa"]) - { - NSLog(@"Unzipping .ipa..."); - - temporaryDirectoryURL = [NSFileManager.defaultManager.temporaryDirectory URLByAppendingPathComponent:[[NSUUID UUID] UUIDString] isDirectory:YES]; - - NSError *error = nil; - if (![[NSFileManager defaultManager] createDirectoryAtURL:temporaryDirectoryURL withIntermediateDirectories:YES attributes:nil error:&error]) - { - return finish(error); - } - - appBundleURL = [[NSFileManager defaultManager] unzipAppBundleAtURL:fileURL toDirectory:temporaryDirectoryURL error:&error]; - if (appBundleURL == nil) - { - return finish(error); - } - } - else - { - return finish([NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadCorruptFileError userInfo:@{NSURLErrorKey: fileURL}]); - } - - ALTApplication *application = [[ALTApplication alloc] initWithFileURL:appBundleURL]; - if (application.provisioningProfile) - { - [installedProfiles addObject:application.provisioningProfile]; - } - - for (ALTApplication *appExtension in application.appExtensions) - { - if (appExtension.provisioningProfile) - { - [installedProfiles addObject:appExtension.provisioningProfile]; - } - } - - /* Find Device */ - if (idevice_new_with_options(&device, udid.UTF8String, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to Device */ - if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - /* Connect to Installation Proxy */ - if ((lockdownd_start_service(client, "com.apple.mobile.installation_proxy", &service) != LOCKDOWN_E_SUCCESS) || service == NULL) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if (instproxy_client_new(device, service, &ipc) != INSTPROXY_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if (service) - { - lockdownd_service_descriptor_free(service); - service = NULL; - } - - - /* Connect to Misagent */ - // Must connect now, since if we take too long writing files to device, connecting may fail later when managing profiles. - if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - - /* Connect to AFC service */ - if ((lockdownd_start_service(client, "com.apple.afc", &service) != LOCKDOWN_E_SUCCESS) || service == NULL) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if (afc_client_new(device, service, &afc) != AFC_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - NSURL *stagingURL = [NSURL fileURLWithPath:@"PublicStaging" isDirectory:YES]; - - /* Prepare for installation */ - char **files = NULL; - if (afc_get_file_info(afc, stagingURL.relativePath.fileSystemRepresentation, &files) != AFC_E_SUCCESS) - { - if (afc_make_directory(afc, stagingURL.relativePath.fileSystemRepresentation) != AFC_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceWriteFailed userInfo:nil]); - } - } - - if (files) - { - int i = 0; - - while (files[i]) - { - free(files[i]); - i++; - } - - free(files); - } - - NSLog(@"Writing to device..."); - - plist_t options = instproxy_client_options_new(); - instproxy_client_options_add(options, "PackageType", "Developer", NULL); - - NSURL *destinationURL = [stagingURL URLByAppendingPathComponent:appBundleURL.lastPathComponent]; - - // Writing files to device should be worth 3/4 of total work. - [progress becomeCurrentWithPendingUnitCount:3]; - - NSError *writeError = nil; - if (![self writeDirectory:appBundleURL toDestinationURL:destinationURL client:afc progress:nil error:&writeError]) - { - int removeResult = afc_remove_path_and_contents(afc, stagingURL.relativePath.fileSystemRepresentation); - NSLog(@"Remove staging app result: %@", @(removeResult)); - - return finish(writeError); - } - - NSLog(@"Finished writing to device."); - - if (service) - { - lockdownd_service_descriptor_free(service); - service = NULL; - } - - BOOL shouldManageProfiles = (activeProvisioningProfiles != nil || [application.provisioningProfile isFreeProvisioningProfile]); - if (shouldManageProfiles) - { - // Free developer account was used to sign this app, so we need to remove all - // provisioning profiles in order to remain under sideloaded app limit. - - NSError *error = nil; - NSDictionary *removedProfiles = [self removeAllFreeProfilesExcludingBundleIdentifiers:nil misagent:mis error:&error]; - if (removedProfiles == nil) - { - return finish(error); - } - - [removedProfiles enumerateKeysAndObjectsUsingBlock:^(NSString *bundleID, ALTProvisioningProfile *profile, BOOL * _Nonnull stop) { - if (activeProvisioningProfiles != nil) - { - if ([activeProvisioningProfiles containsObject:bundleID]) - { - // Only cache active profiles to reinstall afterwards. - cachedProfiles[bundleID] = profile; - } - } - else - { - // Cache all profiles to reinstall afterwards if we didn't provide activeProvisioningProfiles. - cachedProfiles[bundleID] = profile; - } - }]; - } - - lockdownd_client_free(client); - client = NULL; - - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - - NSProgress *installationProgress = [NSProgress progressWithTotalUnitCount:100 parent:progress pendingUnitCount:1]; - - self.installationProgress[UUID] = installationProgress; - self.installationCompletionHandlers[UUID] = ^(NSError *error) { - finish(error); - - if (temporaryDirectoryURL != nil) - { - NSError *error = nil; - if (![[NSFileManager defaultManager] removeItemAtURL:temporaryDirectoryURL error:&error]) - { - NSLog(@"Error removing temporary directory. %@", error); - } - } - - dispatch_semaphore_signal(semaphore); - }; - - NSLog(@"Installing to device %@...", udid); - - instproxy_install(ipc, destinationURL.relativePath.fileSystemRepresentation, options, ALTDeviceManagerUpdateStatus, uuidString); - instproxy_client_options_free(options); - - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - }); - - return progress; -} - -- (BOOL)writeDirectory:(NSURL *)directoryURL toDestinationURL:(NSURL *)destinationURL client:(afc_client_t)afc progress:(NSProgress *)progress error:(NSError **)error -{ - afc_make_directory(afc, destinationURL.relativePath.fileSystemRepresentation); - - if (progress == nil) - { - NSDirectoryEnumerator *countEnumerator = [[NSFileManager defaultManager] enumeratorAtURL:directoryURL - includingPropertiesForKeys:@[] - options:0 - errorHandler:^BOOL(NSURL * _Nonnull url, NSError * _Nonnull error) { - if (error) { - NSLog(@"[Error] %@ (%@)", error, url); - return NO; - } - - return YES; - }]; - - NSInteger totalCount = 0; - for (NSURL *__unused fileURL in countEnumerator) - { - totalCount++; - } - - progress = [NSProgress progressWithTotalUnitCount:totalCount]; - } - - NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:directoryURL - includingPropertiesForKeys:@[NSURLIsDirectoryKey] - options:NSDirectoryEnumerationSkipsSubdirectoryDescendants - errorHandler:^BOOL(NSURL * _Nonnull url, NSError * _Nonnull error) { - if (error) { - NSLog(@"[Error] %@ (%@)", error, url); - return NO; - } - - return YES; - }]; - - for (NSURL *fileURL in enumerator) - { - NSNumber *isDirectory = nil; - if (![fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:error]) - { - return NO; - } - - if ([isDirectory boolValue]) - { - NSURL *destinationDirectoryURL = [destinationURL URLByAppendingPathComponent:fileURL.lastPathComponent isDirectory:YES]; - if (![self writeDirectory:fileURL toDestinationURL:destinationDirectoryURL client:afc progress:progress error:error]) - { - return NO; - } - } - else - { - NSURL *destinationFileURL = [destinationURL URLByAppendingPathComponent:fileURL.lastPathComponent isDirectory:NO]; - if (![self writeFile:fileURL toDestinationURL:destinationFileURL progress:progress client:afc error:error]) - { - return NO; - } - } - - progress.completedUnitCount += 1; - } - - return YES; -} - -- (BOOL)writeFile:(NSURL *)fileURL toDestinationURL:(NSURL *)destinationURL progress:(NSProgress *)progress client:(afc_client_t)afc error:(NSError **)error -{ - NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:fileURL.path]; - if (fileHandle == nil) - { - if (error) - { - *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileNoSuchFileError userInfo:@{NSURLErrorKey: fileURL}]; - } - - return NO; - } - - NSData *data = [fileHandle readDataToEndOfFile]; - - uint64_t af = 0; - - int openResult = afc_file_open(afc, destinationURL.relativePath.fileSystemRepresentation, AFC_FOPEN_WRONLY, &af); - if (openResult != AFC_E_SUCCESS || af == 0) - { - if (openResult == AFC_E_OBJECT_IS_DIR) - { - NSLog(@"Treating file as directory: %@ %@", fileURL, destinationURL); - return [self writeDirectory:fileURL toDestinationURL:destinationURL client:afc progress:progress error:error]; - } - - if (error) - { - *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileWriteUnknownError userInfo:@{NSURLErrorKey: destinationURL}]; - } - - return NO; - } - - BOOL success = YES; - uint32_t bytesWritten = 0; - - while (bytesWritten < data.length) - { - uint32_t count = 0; - - int writeResult = afc_file_write(afc, af, (const char *)data.bytes + bytesWritten, (uint32_t)data.length - bytesWritten, &count); - if (writeResult != AFC_E_SUCCESS) - { - if (error) - { - NSLog(@"Failed writing file with error: %@ (%@ %@)", @(writeResult), fileURL, destinationURL); - *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileWriteUnknownError userInfo:@{NSURLErrorKey: destinationURL}]; - } - - success = NO; - break; - } - - bytesWritten += count; - } - - if (bytesWritten != data.length) - { - if (error) - { - NSLog(@"Failed writing file due to mismatched sizes: %@ vs %@ (%@ %@)", @(bytesWritten), @(data.length), fileURL, destinationURL); - *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileWriteUnknownError userInfo:@{NSURLErrorKey: destinationURL}]; - } - - success = NO; - } - - afc_file_close(afc, af); - - return success; -} - -- (void)removeAppForBundleIdentifier:(NSString *)bundleIdentifier fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler -{ - __block idevice_t device = NULL; - __block lockdownd_client_t client = NULL; - __block instproxy_client_t ipc = NULL; - __block lockdownd_service_descriptor_t service = NULL; - - void (^finish)(NSError *error) = ^(NSError *e) { - __block NSError *error = e; - - lockdownd_service_descriptor_free(service); - instproxy_client_free(ipc); - lockdownd_client_free(client); - idevice_free(device); - - if (error != nil) - { - completionHandler(NO, error); - } - else - { - completionHandler(YES, nil); - } - }; - - /* Find Device */ - if (idevice_new_with_options(&device, udid.UTF8String, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to Device */ - if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - /* Connect to Installation Proxy */ - if ((lockdownd_start_service(client, "com.apple.mobile.installation_proxy", &service) != LOCKDOWN_E_SUCCESS) || service == NULL) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if (instproxy_client_new(device, service, &ipc) != INSTPROXY_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if (service) - { - lockdownd_service_descriptor_free(service); - service = NULL; - } - - NSUUID *UUID = [NSUUID UUID]; - __block char *uuidString = (char *)malloc(UUID.UUIDString.length + 1); - strncpy(uuidString, (const char *)UUID.UUIDString.UTF8String, UUID.UUIDString.length); - uuidString[UUID.UUIDString.length] = '\0'; - - self.deletionCompletionHandlers[UUID] = ^(NSError *error) { - if (error != nil) - { - NSString *localizedFailure = [NSString stringWithFormat:NSLocalizedString(@"Could not remove “%@”.", @""), bundleIdentifier]; - - NSMutableDictionary *userInfo = [error.userInfo mutableCopy]; - userInfo[NSLocalizedFailureErrorKey] = localizedFailure; - - NSError *localizedError = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; - finish(localizedError); - } - else - { - finish(nil); - } - - free(uuidString); - }; - - instproxy_uninstall(ipc, bundleIdentifier.UTF8String, NULL, ALTDeviceManagerUpdateAppDeletionStatus, uuidString); -} - -#pragma mark - Provisioning Profiles - - -- (void)installProvisioningProfiles:(NSSet *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *error))completionHandler -{ - dispatch_async(self.installationQueue, ^{ - __block idevice_t device = NULL; - __block lockdownd_client_t client = NULL; - __block afc_client_t afc = NULL; - __block misagent_client_t mis = NULL; - __block lockdownd_service_descriptor_t service = NULL; - - void (^finish)(NSError *_Nullable) = ^(NSError *error) { - lockdownd_service_descriptor_free(service); - misagent_client_free(mis); - afc_client_free(afc); - lockdownd_client_free(client); - idevice_free(device); - - completionHandler(error == nil, error); - }; - - /* Find Device */ - if (idevice_new_with_options(&device, udid.UTF8String, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to Device */ - if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - /* Connect to Misagent */ - if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - NSError *error = nil; - - if (activeProvisioningProfiles != nil) - { - // Remove all non-active free provisioning profiles. - - NSMutableSet *excludedBundleIdentifiers = [activeProvisioningProfiles mutableCopy]; - for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles) - { - // Ensure we DO remove old versions of profiles we're about to install, even if they are active. - [excludedBundleIdentifiers removeObject:provisioningProfile.bundleIdentifier]; - } - - if (![self removeAllFreeProfilesExcludingBundleIdentifiers:excludedBundleIdentifiers misagent:mis error:&error]) - { - return finish(error); - } - } - else - { - // Remove only older versions of provisioning profiles we're about to install. - - NSMutableSet *bundleIdentifiers = [NSMutableSet set]; - for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles) - { - [bundleIdentifiers addObject:provisioningProfile.bundleIdentifier]; - } - - if (![self removeProvisioningProfilesForBundleIdentifiers:bundleIdentifiers misagent:mis error:&error]) - { - return finish(error); - } - } - - for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles) - { - if (![self installProvisioningProfile:provisioningProfile misagent:mis error:&error]) - { - return finish(error); - } - } - - finish(nil); - }); -} - -- (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL success, NSError *error))completionHandler -{ - dispatch_async(self.installationQueue, ^{ - __block idevice_t device = NULL; - __block lockdownd_client_t client = NULL; - __block afc_client_t afc = NULL; - __block misagent_client_t mis = NULL; - __block lockdownd_service_descriptor_t service = NULL; - - void (^finish)(NSError *_Nullable) = ^(NSError *error) { - lockdownd_service_descriptor_free(service); - misagent_client_free(mis); - afc_client_free(afc); - lockdownd_client_free(client); - idevice_free(device); - - completionHandler(error == nil, error); - }; - - /* Find Device */ - if (idevice_new_with_options(&device, udid.UTF8String, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to Device */ - if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - /* Connect to Misagent */ - if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - NSError *error = nil; - if (![self removeProvisioningProfilesForBundleIdentifiers:bundleIdentifiers misagent:mis error:&error]) - { - return finish(error); - } - - finish(nil); - }); -} - -- (NSDictionary *)removeProvisioningProfilesForBundleIdentifiers:(NSSet *)bundleIdentifiers misagent:(misagent_client_t)mis error:(NSError **)error -{ - return [self removeAllProfilesForBundleIdentifiers:bundleIdentifiers excludingBundleIdentifiers:nil limitedToFreeProfiles:NO misagent:mis error:error]; -} - -- (NSDictionary *)removeAllFreeProfilesExcludingBundleIdentifiers:(nullable NSSet *)bundleIdentifiers misagent:(misagent_client_t)mis error:(NSError **)error -{ - return [self removeAllProfilesForBundleIdentifiers:nil excludingBundleIdentifiers:bundleIdentifiers limitedToFreeProfiles:YES misagent:mis error:error]; -} - -- (NSDictionary *)removeAllProfilesForBundleIdentifiers:(nullable NSSet *)includedBundleIdentifiers - excludingBundleIdentifiers:(nullable NSSet *)excludedBundleIdentifiers - limitedToFreeProfiles:(BOOL)limitedToFreeProfiles - misagent:(misagent_client_t)mis - error:(NSError **)error -{ - NSMutableDictionary *ignoredProfiles = [NSMutableDictionary dictionary]; - NSMutableDictionary *removedProfiles = [NSMutableDictionary dictionary]; - - NSArray *provisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:error]; - if (provisioningProfiles == nil) - { - return nil; - } - - for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles) - { - if (limitedToFreeProfiles && ![provisioningProfile isFreeProvisioningProfile]) - { - continue; - } - - if (includedBundleIdentifiers != nil && ![includedBundleIdentifiers containsObject:provisioningProfile.bundleIdentifier]) - { - continue; - } - - if (excludedBundleIdentifiers != nil && [excludedBundleIdentifiers containsObject:provisioningProfile.bundleIdentifier]) - { - // This provisioning profile has an excluded bundle identifier. - // Ignore it, unless we've already ignored one with the same bundle identifier, - // in which case remove whichever profile is the oldest. - - ALTProvisioningProfile *previousProfile = ignoredProfiles[provisioningProfile.bundleIdentifier]; - if (previousProfile != nil) - { - // We've already ignored a profile with this bundle identifier, - // so make sure we only ignore the newest one and remove the oldest one. - BOOL isNewerThanPreviousProfile = ([provisioningProfile.expirationDate compare:previousProfile.expirationDate] == NSOrderedDescending); - ALTProvisioningProfile *oldestProfile = isNewerThanPreviousProfile ? previousProfile : provisioningProfile; - ALTProvisioningProfile *newestProfile = isNewerThanPreviousProfile ? provisioningProfile : previousProfile; - - ignoredProfiles[provisioningProfile.bundleIdentifier] = newestProfile; - - // Don't cache this profile or else it will be reinstalled, so just remove it without caching. - if (![self removeProvisioningProfile:oldestProfile misagent:mis error:error]) - { - return nil; - } - } - else - { - ignoredProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile; - } - - continue; - } - - ALTProvisioningProfile *preferredProfile = removedProfiles[provisioningProfile.bundleIdentifier]; - if (preferredProfile != nil) - { - if ([provisioningProfile.expirationDate compare:preferredProfile.expirationDate] == NSOrderedDescending) - { - removedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile; - } - } - else - { - removedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile; - } - - if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:error]) - { - return nil; - } - } - - return removedProfiles; -} - -- (BOOL)installProvisioningProfile:(ALTProvisioningProfile *)provisioningProfile misagent:(misagent_client_t)mis error:(NSError **)error -{ - plist_t pdata = plist_new_data((const char *)provisioningProfile.data.bytes, provisioningProfile.data.length); - - misagent_error_t result = misagent_install(mis, pdata); - plist_free(pdata); - - if (result == MISAGENT_E_SUCCESS) - { - NSLog(@"Installed profile: %@ (%@)", provisioningProfile.bundleIdentifier, provisioningProfile.UUID); - return YES; - } - else - { - int statusCode = misagent_get_status_code(mis); - NSLog(@"Failed to install provisioning profile %@ (%@). Error Code: %@", provisioningProfile.bundleIdentifier, provisioningProfile.UUID, @(statusCode)); - - if (error) - { - switch (statusCode) - { - case -402620383: - *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorMaximumFreeAppLimitReached userInfo:nil]; - break; - - default: - NSString *localizedFailure = [NSString stringWithFormat:NSLocalizedString(@"Could not install profile “%@”", @""), provisioningProfile.bundleIdentifier]; - - *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorUnderlyingError userInfo:@{ - NSLocalizedFailureErrorKey: localizedFailure, - ALTUnderlyingErrorCodeErrorKey: [@(statusCode) description], - ALTProvisioningProfileBundleIDErrorKey: provisioningProfile.bundleIdentifier - }]; - } - } - - return NO; - } -} - -- (BOOL)removeProvisioningProfile:(ALTProvisioningProfile *)provisioningProfile misagent:(misagent_client_t)mis error:(NSError **)error -{ - misagent_error_t result = misagent_remove(mis, provisioningProfile.UUID.UUIDString.lowercaseString.UTF8String); - if (result == MISAGENT_E_SUCCESS) - { - NSLog(@"Removed provisioning profile: %@ (%@)", provisioningProfile.bundleIdentifier, provisioningProfile.UUID); - return YES; - } - else - { - int statusCode = misagent_get_status_code(mis); - NSLog(@"Failed to remove provisioning profile %@ (%@). Error Code: %@", provisioningProfile.bundleIdentifier, provisioningProfile.UUID, @(statusCode)); - - if (error) - { - switch (statusCode) - { - case -402620405: - *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorProfileNotFound userInfo:nil]; - break; - - default: - { - NSString *localizedFailure = [NSString stringWithFormat:NSLocalizedString(@"Could not remove profile “%@”", @""), provisioningProfile.bundleIdentifier]; - - *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorUnderlyingError userInfo:@{ - NSLocalizedFailureErrorKey: localizedFailure, - ALTUnderlyingErrorCodeErrorKey: [@(statusCode) description], - ALTProvisioningProfileBundleIDErrorKey: provisioningProfile.bundleIdentifier - }]; - } - } - } - - return NO; - } -} - -- (nullable NSArray *)copyProvisioningProfilesWithClient:(misagent_client_t)mis error:(NSError **)error -{ - plist_t rawProfiles = NULL; - misagent_error_t result = misagent_copy_all(mis, &rawProfiles); - if (result != MISAGENT_E_SUCCESS) - { - int statusCode = misagent_get_status_code(mis); - - if (error) - { - *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorUnderlyingError userInfo:@{ - NSLocalizedFailureErrorKey: NSLocalizedString(@"Could not copy provisioning profiles.", @""), - ALTUnderlyingErrorCodeErrorKey: [@(statusCode) description] - }]; - } - - return nil; - } - - /* Copy all provisioning profiles */ - - // For some reason, libplist now fails to parse `rawProfiles` correctly. - // Specifically, it no longer recognizes the nodes in the plist array as "data" nodes. - // However, if we encode it as XML then decode it again, it'll work ¯\_(ツ)_/¯ - char *plistXML = nullptr; - uint32_t plistLength = 0; - plist_to_xml(rawProfiles, &plistXML, &plistLength); - - plist_t profiles = NULL; - plist_from_xml(plistXML, plistLength, &profiles); - - free(plistXML); - - NSMutableArray *provisioningProfiles = [NSMutableArray array]; - - uint32_t profileCount = plist_array_get_size(profiles); - for (int i = 0; i < profileCount; i++) - { - plist_t profile = plist_array_get_item(profiles, i); - if (plist_get_node_type(profile) != PLIST_DATA) - { - continue; - } - - char *bytes = NULL; - uint64_t length = 0; - - plist_get_data_val(profile, &bytes, &length); - if (bytes == NULL) - { - continue; - } - - NSData *data = [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:YES]; - ALTProvisioningProfile *provisioningProfile = [[ALTProvisioningProfile alloc] initWithData:data]; - if (provisioningProfile == nil) - { - continue; - } - - [provisioningProfiles addObject:provisioningProfile]; - } - - plist_free(rawProfiles); - plist_free(profiles); - - return provisioningProfiles; -} - -#pragma mark - Developer Disk Image - - -- (void)isDeveloperDiskImageMountedForDevice:(ALTDevice *)altDevice completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler -{ - __block idevice_t device = NULL; - __block instproxy_client_t ipc = NULL; - __block lockdownd_client_t client = NULL; - __block lockdownd_service_descriptor_t service = NULL; - __block mobile_image_mounter_client_t mim = NULL; - - __block BOOL isMounted = NO; - - void (^finish)(NSError *) = ^(NSError *error) { - if (mim) { - mobile_image_mounter_hangup(mim); - mobile_image_mounter_free(mim); - } - - if (service) { - lockdownd_service_descriptor_free(service); - } - - if (client) { - lockdownd_client_free(client); - } - - if (ipc) { - instproxy_client_free(ipc); - } - - if (device) { - idevice_free(device); - } - - completionHandler(isMounted, error); - }; - - dispatch_async(self.installationQueue, ^{ - - /* Find Device */ - if (idevice_new_with_options(&device, altDevice.identifier.UTF8String, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to Device */ - if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - /* Connect to Mobile Image Mounter Proxy */ - if ((lockdownd_start_service(client, "com.apple.mobile.mobile_image_mounter", &service) != LOCKDOWN_E_SUCCESS) || service == NULL) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - mobile_image_mounter_error_t err = mobile_image_mounter_new(device, service, &mim); - if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS) - { - return finish([NSError errorWithMobileImageMounterError:err device:altDevice]); - } - - plist_t result = NULL; - err = mobile_image_mounter_lookup_image(mim, "Developer", &result); - if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS) - { - return finish([NSError errorWithMobileImageMounterError:err device:altDevice]); - } - - plist_dict_iter it = NULL; - plist_dict_new_iter(result, &it); - - char* key = NULL; - plist_t subnode = NULL; - plist_dict_next_item(result, it, &key, &subnode); - - while (subnode) - { - // If the ImageSignature key in the returned plist contains a subentry the disk image is already uploaded. - // Hopefully this works for older iOS versions as well. - // (via https://github.com/Schlaubischlump/LocationSimulator/blob/fdbd93ad16be5f69111b571d71ed6151e850144b/LocationSimulator/MobileDevice/devicemount/deviceimagemounter.c) - plist_type type = plist_get_node_type(subnode); - if (strcmp(key, "ImageSignature") == 0 && PLIST_ARRAY == type) - { - isMounted = (plist_array_get_size(subnode) != 0); - } - - free(key); - key = NULL; - - if (isMounted) - { - break; - } - - plist_dict_next_item(result, it, &key, &subnode); - } - - free(it); - - finish(nil); - }); -} - -- (void)installDeveloperDiskImageAtURL:(NSURL *)diskURL signatureURL:(NSURL *)signatureURL toDevice:(ALTDevice *)altDevice - completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler -{ - __block idevice_t device = NULL; - __block instproxy_client_t ipc = NULL; - __block lockdownd_client_t client = NULL; - __block lockdownd_service_descriptor_t service = NULL; - __block mobile_image_mounter_client_t mim = NULL; - - void (^finish)(NSError *) = ^(NSError *error) { - if (mim) { - mobile_image_mounter_hangup(mim); - mobile_image_mounter_free(mim); - } - - if (service) { - lockdownd_service_descriptor_free(service); - } - - if (client) { - lockdownd_client_free(client); - } - - if (ipc) { - instproxy_client_free(ipc); - } - - if (device) { - idevice_free(device); - } - - if (error) - { - error = [error alt_errorWithLocalizedFailure:[NSString stringWithFormat:NSLocalizedString(@"The Developer disk image could not be installed onto %@.", @""), altDevice.name]]; - } - - completionHandler(error == nil, error); - }; - - dispatch_async(self.installationQueue, ^{ - - /* Find Device */ - if (idevice_new_with_options(&device, altDevice.identifier.UTF8String, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to Device */ - if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - /* Connect to Mobile Image Mounter Proxy */ - if ((lockdownd_start_service(client, "com.apple.mobile.mobile_image_mounter", &service) != LOCKDOWN_E_SUCCESS) || service == NULL) - { - return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - mobile_image_mounter_error_t err = mobile_image_mounter_new(device, service, &mim); - if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS) - { - return finish([NSError errorWithMobileImageMounterError:err device:altDevice]); - } - - NSError *error = nil; - NSDictionary *diskAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:diskURL.path error:&error]; - if (diskAttributes == nil) - { - return finish(error); - } - - NSDictionary *signatureAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:signatureURL.path error:&error]; - if (signatureAttributes == nil) - { - return finish(error); - } - - size_t diskSize = [diskAttributes fileSize]; - - NSData *signature = [[NSData alloc] initWithContentsOfURL:signatureURL options:0 error:&error]; - if (signature == nil) - { - return finish(error); - } - - FILE *file = fopen(diskURL.fileSystemRepresentation, "rb"); - err = mobile_image_mounter_upload_image(mim, "Developer", diskSize, (const char *)signature.bytes, (size_t)signature.length, ALTDeviceManagerUploadFile, file); - fclose(file); - - if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS) - { - return finish([NSError errorWithMobileImageMounterError:err device:altDevice]); - } - - NSString *diskPath = @"/private/var/mobile/Media/PublicStaging/staging.dimage"; - - plist_t result = NULL; - err = mobile_image_mounter_mount_image(mim, diskPath.UTF8String, (const char *)signature.bytes, (size_t)signature.length, "Developer", &result); - if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS) - { - return finish([NSError errorWithMobileImageMounterError:err device:altDevice]); - } - - plist_t errorDescriptionNode = plist_dict_get_item(result, "DetailedError"); - if (errorDescriptionNode != NULL) - { - char *errorDescription = NULL; - plist_get_string_val(errorDescriptionNode, &errorDescription); - - NSString *nsErrorDescription = @(errorDescription); - plist_free(result); - - NSError *returnError = nil; - - if ([nsErrorDescription containsString:@"Failed to verify"]) - { - // iOS device needs to be rebooted in order to mount disk to /Developer. - NSString *recoverySuggestion = [NSString stringWithFormat:NSLocalizedString(@"Please reboot %@ and try again.", @""), altDevice.name]; - - // ALTServerErrorUnderlyingError uses its underlying error's failure reason as its error description (if one exists), - // so assign our recovery suggestion to NSLocalizedFailureReasonErrorKey to make sure it's always displayed on client. - NSError *underlyingError = [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:@{NSLocalizedFailureReasonErrorKey: recoverySuggestion}]; - - returnError = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorUnderlyingError userInfo:@{NSUnderlyingErrorKey: underlyingError}]; - } - else - { - // Installation failed, so we assume the developer disk is NOT compatible with this iOS version. - - NSMutableDictionary *userInfo = [@{ - ALTOperatingSystemVersionErrorKey: NSStringFromOperatingSystemVersion(altDevice.osVersion), - NSFilePathErrorKey: diskURL.path, - } mutableCopy]; - - NSString *osName = ALTOperatingSystemNameForDeviceType(altDevice.type); - if (osName != nil) - { - userInfo[ALTOperatingSystemNameErrorKey] = osName; - } - - returnError = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorIncompatibleDeveloperDisk userInfo:userInfo]; - } - - return finish(returnError); - } - - plist_free(result); - - // Verify that the developer disk has been successfully installed. - ALTDebugConnection *testConnection = [[ALTDebugConnection alloc] initWithDevice:altDevice]; - [testConnection connectWithCompletionHandler:^(BOOL success, NSError * _Nullable error) { - [testConnection disconnect]; - - if (success) - { - finish(nil); - } - else - { - finish(error); - } - }]; - }); -} - -#pragma mark - Apps - - -- (void)fetchInstalledAppsOnDevice:(ALTDevice *)altDevice completionHandler:(void (^)(NSSet *_Nullable installedApps, NSError *_Nullable error))completionHandler -{ - __block idevice_t device = NULL; - __block instproxy_client_t ipc = NULL; - __block lockdownd_client_t client = NULL; - __block lockdownd_service_descriptor_t service = NULL; - __block plist_t options = NULL; - - void (^finish)(NSSet *, NSError *) = ^(NSSet *installedApps, NSError *error) { - if (error != nil) { - NSLog(@"Notification Connection Error: %@", error); - } - - if (options) { - instproxy_client_options_free(options); - } - - if (service) { - lockdownd_service_descriptor_free(service); - } - - if (client) { - lockdownd_client_free(client); - } - - if (ipc) { - instproxy_client_free(ipc); - } - - if (device) { - idevice_free(device); - } - - completionHandler(installedApps, error); - }; - - // Don't use installationQueue since this operation can potentially take a very long time and will block other operations. - // dispatch_async(self.installationQueue, ^{ - dispatch_async(self.devicesQueue, ^{ - /* Find Device */ - if (idevice_new_with_options(&device, altDevice.identifier.UTF8String, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &client, "AltServer")) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - if ((lockdownd_start_service(client, "com.apple.mobile.installation_proxy", &service) != LOCKDOWN_E_SUCCESS) || !service) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - instproxy_error_t err = instproxy_client_new(device, service, &ipc); - if (err != INSTPROXY_E_SUCCESS) - { - return finish(nil, [NSError errorWithInstallationProxyError:err device:altDevice]); - } - - options = instproxy_client_options_new(); - instproxy_client_options_add(options, "ApplicationType", "User", NULL); - - plist_t plist = NULL; - err = instproxy_browse(ipc, options, &plist); - if (err != INSTPROXY_E_SUCCESS) - { - return finish(nil, [NSError errorWithInstallationProxyError:err device:altDevice]); - } - - char *plistXML = NULL; - uint32_t length = 0; - plist_to_xml(plist, &plistXML, &length); - - NSData *plistData = [@(plistXML) dataUsingEncoding:NSUTF8StringEncoding]; - free(plistXML); - plist_free(plist); - - NSError *error = nil; - NSArray *appDictionaries = [NSPropertyListSerialization propertyListWithData:plistData options:0 format:nil error:&error]; - if (appDictionaries == nil) - { - return finish(nil, error); - } - - NSMutableSet *installedApps = [NSMutableSet set]; - for (NSDictionary *appInfo in appDictionaries) - { - if (appInfo[@"ALTBundleIdentifier"] != nil) - { - // Only return apps installed with AltStore. - - ALTInstalledApp *installedApp = [[ALTInstalledApp alloc] initWithDictionary:appInfo]; - if (installedApp) - { - [installedApps addObject:installedApp]; - } - } - } - - finish(installedApps, nil); - }); -} - -#pragma mark - Connections - - -- (void)startWiredConnectionToDevice:(ALTDevice *)altDevice completionHandler:(void (^)(ALTWiredConnection * _Nullable, NSError * _Nullable))completionHandler -{ - void (^finish)(ALTWiredConnection *connection, NSError *error) = ^(ALTWiredConnection *connection, NSError *error) { - if (error != nil) - { - NSLog(@"Wired Connection Error: %@", error); - } - - completionHandler(connection, error); - }; - - idevice_t device = NULL; - idevice_connection_t connection = NULL; - - /* Find Device */ - if (idevice_new_with_options(&device, altDevice.identifier.UTF8String, IDEVICE_LOOKUP_USBMUX) != IDEVICE_E_SUCCESS) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to Listening Socket */ - if (idevice_connect(device, ALTDeviceListeningSocket, &connection) != IDEVICE_E_SUCCESS) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - idevice_free(device); - - ALTWiredConnection *wiredConnection = [[ALTWiredConnection alloc] initWithDevice:altDevice connection:connection]; - finish(wiredConnection, nil); -} - -- (void)startNotificationConnectionToDevice:(ALTDevice *)altDevice completionHandler:(void (^)(ALTNotificationConnection * _Nullable, NSError * _Nullable))completionHandler -{ - void (^finish)(ALTNotificationConnection *, NSError *) = ^(ALTNotificationConnection *connection, NSError *error) { - if (error != nil) - { - NSLog(@"Notification Connection Error: %@", error); - } - - completionHandler(connection, error); - }; - - idevice_t device = NULL; - lockdownd_client_t lockdownClient = NULL; - lockdownd_service_descriptor_t service = NULL; - - np_client_t client = NULL; - - /* Find Device */ - if (idevice_new_with_options(&device, altDevice.identifier.UTF8String, IDEVICE_LOOKUP_USBMUX) != IDEVICE_E_SUCCESS) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]); - } - - /* Connect to Device */ - if (lockdownd_client_new_with_handshake(device, &lockdownClient, "altserver") != LOCKDOWN_E_SUCCESS) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - /* Connect to Notification Proxy */ - if ((lockdownd_start_service(lockdownClient, "com.apple.mobile.notification_proxy", &service) != LOCKDOWN_E_SUCCESS) || service == NULL) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - /* Connect to Client */ - if (np_client_new(device, service, &client) != NP_E_SUCCESS) - { - return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]); - } - - lockdownd_service_descriptor_free(service); - lockdownd_client_free(lockdownClient); - idevice_free(device); - - ALTNotificationConnection *notificationConnection = [[ALTNotificationConnection alloc] initWithDevice:altDevice client:client]; - completionHandler(notificationConnection, nil); -} - -- (void)startDebugConnectionToDevice:(ALTDevice *)device completionHandler:(void (^)(ALTDebugConnection * _Nullable, NSError * _Nullable))completionHandler -{ - ALTDebugConnection *connection = [[ALTDebugConnection alloc] initWithDevice:device]; - [connection connectWithCompletionHandler:^(BOOL success, NSError * _Nullable error) { - if (success) - { - completionHandler(connection, nil); - } - else - { - completionHandler(nil, error); - } - }]; -} -#pragma mark - Getters - - -- (NSArray *)connectedDevices -{ - return [self availableDevicesIncludingNetworkDevices:NO]; -} - -- (NSArray *)availableDevices -{ - return [self availableDevicesIncludingNetworkDevices:YES]; -} - -- (NSArray *)availableDevicesIncludingNetworkDevices:(BOOL)includingNetworkDevices -{ - NSMutableSet *connectedDevices = [NSMutableSet set]; - - int count = 0; - idevice_info_t *devices = NULL; - - if (idevice_get_device_list_extended(&devices, &count) < 0) - { - fprintf(stderr, "ERROR: Unable to retrieve device list!\n"); - return @[]; - } - - for (int i = 0; i < count; i++) - { - idevice_info_t device_info = devices[i]; - char *udid = device_info->udid; - - idevice_t device = NULL; - lockdownd_client_t client = NULL; - - char *device_name = NULL; - char *device_type_string = NULL; - char *device_version_string = NULL; - - plist_t device_type_plist = NULL; - plist_t device_version_plist = NULL; - - void (^cleanUp)(void) = ^{ - if (device_version_plist) { - plist_free(device_version_plist); - } - - if (device_type_plist) { - plist_free(device_type_plist); - } - - if (device_version_string) { - free(device_version_string); - } - - if (device_type_string) { - free(device_type_string); - } - - if (device_name) { - free(device_name); - } - - if (client) { - lockdownd_client_free(client); - } - - if (device) { - idevice_free(device); - } - }; - - if (includingNetworkDevices) - { - idevice_new_with_options(&device, udid, (enum idevice_options)((int)IDEVICE_LOOKUP_NETWORK | (int)IDEVICE_LOOKUP_USBMUX)); - } - else - { - idevice_new_with_options(&device, udid, IDEVICE_LOOKUP_USBMUX); - } - - if (!device) - { - continue; - } - - int result = lockdownd_client_new(device, &client, "altserver"); - if (result != LOCKDOWN_E_SUCCESS) - { - fprintf(stderr, "ERROR: Connecting to device %s failed! (%d)\n", udid, result); - - cleanUp(); - continue; - } - - if (lockdownd_get_device_name(client, &device_name) != LOCKDOWN_E_SUCCESS || device_name == NULL) - { - fprintf(stderr, "ERROR: Could not get device name!\n"); - - cleanUp(); - continue; - } - - if (lockdownd_get_value(client, NULL, "ProductType", &device_type_plist) != LOCKDOWN_E_SUCCESS) - { - fprintf(stderr, "ERROR: Could not get device type for %s!\n", device_name); - - cleanUp(); - continue; - } - - plist_get_string_val(device_type_plist, &device_type_string); - - ALTDeviceType deviceType = ALTDeviceTypeiPhone; - if ([@(device_type_string) hasPrefix:@"iPhone"]) - { - deviceType = ALTDeviceTypeiPhone; - } - else if ([@(device_type_string) hasPrefix:@"iPad"]) - { - deviceType = ALTDeviceTypeiPad; - } - else if ([@(device_type_string) hasPrefix:@"AppleTV"]) - { - deviceType = ALTDeviceTypeAppleTV; - } - else - { - fprintf(stderr, "ERROR: Unknown device type %s for %s!\n", device_type_string, device_name); - - cleanUp(); - continue; - } - - if (lockdownd_get_value(client, NULL, "ProductVersion", &device_version_plist) != LOCKDOWN_E_SUCCESS) - { - fprintf(stderr, "ERROR: Could not get device type for %s!\n", device_name); - - cleanUp(); - continue; - } - - plist_get_string_val(device_version_plist, &device_version_string); - NSOperatingSystemVersion osVersion = NSOperatingSystemVersionFromString(@(device_version_string)); - - NSString *name = [NSString stringWithCString:device_name encoding:NSUTF8StringEncoding]; - NSString *identifier = [NSString stringWithCString:udid encoding:NSUTF8StringEncoding]; - - ALTDevice *altDevice = [[ALTDevice alloc] initWithName:name identifier:identifier type:deviceType]; - altDevice.osVersion = osVersion; - [connectedDevices addObject:altDevice]; - - cleanUp(); - } - - idevice_device_list_extended_free(devices); - - return connectedDevices.allObjects; -} - -@end - -#pragma mark - Callbacks - - -void ALTDeviceManagerUpdateStatus(plist_t command, plist_t status, void *uuid) -{ - NSUUID *UUID = [[NSUUID alloc] initWithUUIDString:[NSString stringWithUTF8String:(const char *)uuid]]; - - NSProgress *progress = ALTDeviceManager.sharedManager.installationProgress[UUID]; - if (progress == nil) - { - return; - } - - int percent = -1; - instproxy_status_get_percent_complete(status, &percent); - - char *name = NULL; - char *description = NULL; - uint64_t code = 0; - instproxy_status_get_error(status, &name, &description, &code); - - if ((percent == -1 && progress.completedUnitCount > 0) || code != 0 || name != NULL) - { - void (^completionHandler)(NSError *) = ALTDeviceManager.sharedManager.installationCompletionHandlers[UUID]; - if (completionHandler != nil) - { - NSString *localizedDescription = @(description ?: ""); - - if (code != 0 || name != NULL) - { - NSLog(@"Error installing app. %@ (%@). %@", @(code), @(name ?: ""), localizedDescription); - - NSError *error = nil; - - if (code == 3892346913) - { - NSDictionary *userInfo = (localizedDescription.length != 0) ? @{NSLocalizedDescriptionKey: localizedDescription} : nil; - error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorMaximumFreeAppLimitReached userInfo:userInfo]; - } - else - { - NSString *errorName = [NSString stringWithCString:name ?: "" encoding:NSUTF8StringEncoding]; - if ([errorName isEqualToString:@"DeviceOSVersionTooLow"]) - { - error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorUnsupportediOSVersion userInfo:nil]; - } - else - { - NSError *underlyingError = [NSError errorWithDomain:AltServerInstallationErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: localizedDescription}]; - error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorInstallationFailed userInfo:@{NSUnderlyingErrorKey: underlyingError}]; - } - } - - completionHandler(error); - } - else - { - NSLog(@"Finished installing app!"); - completionHandler(nil); - } - - ALTDeviceManager.sharedManager.installationCompletionHandlers[UUID] = nil; - ALTDeviceManager.sharedManager.installationProgress[UUID] = nil; - } - } - else if (progress.completedUnitCount < percent) - { - progress.completedUnitCount = percent; - - NSLog(@"Installation Progress: %@", @(percent)); - } -} - -void ALTDeviceManagerUpdateAppDeletionStatus(plist_t command, plist_t status, void *uuid) -{ - NSUUID *UUID = [[NSUUID alloc] initWithUUIDString:[NSString stringWithUTF8String:(const char *)uuid]]; - - char *statusName = NULL; - instproxy_status_get_name(status, &statusName); - - char *errorName = NULL; - char *errorDescription = NULL; - uint64_t code = 0; - instproxy_status_get_error(status, &errorName, &errorDescription, &code); - - if ([@(statusName) isEqualToString:@"Complete"] || code != 0 || errorName != NULL) - { - void (^completionHandler)(NSError *) = ALTDeviceManager.sharedManager.deletionCompletionHandlers[UUID]; - if (completionHandler != nil) - { - if (code != 0 || errorName != NULL) - { - NSLog(@"Error removing app. %@ (%@). %@", @(code), @(errorName ?: ""), @(errorDescription ?: "")); - - NSError *underlyingError = [NSError errorWithDomain:AltServerInstallationErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: @(errorDescription ?: "")}]; - NSError *error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorAppDeletionFailed userInfo:@{NSUnderlyingErrorKey: underlyingError}]; - - completionHandler(error); - } - else - { - NSLog(@"Finished removing app!"); - completionHandler(nil); - } - - ALTDeviceManager.sharedManager.deletionCompletionHandlers[UUID] = nil; - } - } -} - -void ALTDeviceDidChangeConnectionStatus(const idevice_event_t *event, void *user_data) -{ - ALTDevice * (^deviceForUDID)(NSString *, NSArray *) = ^ALTDevice *(NSString *udid, NSArray *devices) { - for (ALTDevice *device in devices) - { - if ([device.identifier isEqualToString:udid]) - { - return device; - } - } - - return nil; - }; - - switch (event->event) - { - case IDEVICE_DEVICE_ADD: - { - ALTDevice *device = deviceForUDID(@(event->udid), ALTDeviceManager.sharedManager.connectedDevices); - [[NSNotificationCenter defaultCenter] postNotificationName:ALTDeviceManagerDeviceDidConnectNotification object:device]; - - if (device) - { - [ALTDeviceManager.sharedManager.cachedDevices addObject:device]; - } - - break; - } - - case IDEVICE_DEVICE_REMOVE: - { - ALTDevice *device = deviceForUDID(@(event->udid), ALTDeviceManager.sharedManager.cachedDevices.allObjects); - [[NSNotificationCenter defaultCenter] postNotificationName:ALTDeviceManagerDeviceDidDisconnectNotification object:device]; - - if (device) - { - [ALTDeviceManager.sharedManager.cachedDevices removeObject:device]; - } - - break; - } - - default: break; - } -} - -ssize_t ALTDeviceManagerUploadFile(void *buffer, size_t size, void *user_data) -{ - return fread(buffer, 1, size, (FILE*)user_data); -} diff --git a/AltServer/Extensions/FileManager+URLs.swift b/AltServer/Extensions/FileManager+URLs.swift deleted file mode 100644 index 81b5a77e..00000000 --- a/AltServer/Extensions/FileManager+URLs.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// FileManager+URLs.swift -// AltServer -// -// Created by Riley Testut on 2/23/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -import Foundation - -extension FileManager -{ - var altserverDirectory: URL { - let applicationSupportDirectoryURL = self.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] - - let altserverDirectoryURL = applicationSupportDirectoryURL.appendingPathComponent("com.rileytestut.AltServer") - return altserverDirectoryURL - } - - var certificatesDirectory: URL { - let certificatesDirectoryURL = self.altserverDirectory.appendingPathComponent("Certificates") - return certificatesDirectoryURL - } - - var developerDisksDirectory: URL { - let developerDisksDirectoryURL = self.altserverDirectory.appendingPathComponent("DeveloperDiskImages") - return developerDisksDirectoryURL - } -} diff --git a/AltServer/Extensions/UserDefaults+AltServer.swift b/AltServer/Extensions/UserDefaults+AltServer.swift deleted file mode 100644 index 499cf69e..00000000 --- a/AltServer/Extensions/UserDefaults+AltServer.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// UserDefaults+AltServer.swift -// AltServer -// -// Created by Riley Testut on 7/31/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -import Foundation - -extension UserDefaults -{ - var serverID: String? { - get { - return self.string(forKey: "serverID") - } - set { - self.set(newValue, forKey: "serverID") - } - } - - var didPresentInitialNotification: Bool { - get { - return self.bool(forKey: "didPresentInitialNotification") - } - set { - self.set(newValue, forKey: "didPresentInitialNotification") - } - } - - func registerDefaults() - { - if self.serverID == nil - { - self.serverID = UUID().uuidString - } - } -} diff --git a/AltServer/Info.plist b/AltServer/Info.plist deleted file mode 100644 index df713a6b..00000000 --- a/AltServer/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - LSUIElement - - NSHumanReadableCopyright - Copyright © 2019 Riley Testut. All rights reserved. - NSMainStoryboardFile - Main - NSPrincipalClass - NSApplication - SUFeedURL - https://altstore.io/altserver/sparkle-macos.xml - SUFeedURL-Staging - https://altstore.io/altserver/sparkle-macos-staging.xml - - diff --git a/AltServer/InstalledApp.swift b/AltServer/InstalledApp.swift deleted file mode 100644 index 003dcbf6..00000000 --- a/AltServer/InstalledApp.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// InstalledApp.swift -// AltServer -// -// Created by Riley Testut on 5/25/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -import Foundation - -@objc(ALTInstalledApp) @objcMembers -class InstalledApp: NSObject, MenuDisplayable -{ - let name: String - let bundleIdentifier: String - let executableName: String - - init?(dictionary: [String: Any]) - { - guard let name = dictionary[kCFBundleNameKey as String] as? String, - let bundleIdentifier = dictionary[kCFBundleIdentifierKey as String] as? String, - let executableName = dictionary[kCFBundleExecutableKey as String] as? String - else { return nil } - - self.name = name - self.bundleIdentifier = bundleIdentifier - self.executableName = executableName - } -} diff --git a/AltServer/MenuController.swift b/AltServer/MenuController.swift deleted file mode 100644 index 67715344..00000000 --- a/AltServer/MenuController.swift +++ /dev/null @@ -1,115 +0,0 @@ -// -// MenuController.swift -// AltServer -// -// Created by Riley Testut on 3/3/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -import Foundation -import AppKit - -protocol MenuDisplayable -{ - var name: String { get } -} - -class MenuController: NSObject, NSMenuDelegate -{ - let menu: NSMenu - - var items: [T] { - didSet { - self.submenus.removeAll() - self.updateMenu() - } - } - - var placeholder: String? { - didSet { - self.updateMenu() - } - } - - var action: ((T) -> Void)? - - var submenuHandler: ((T) -> NSMenu)? - private var submenus = [T: NSMenu]() - - init(menu: NSMenu, items: [T]) - { - self.menu = menu - self.items = items - - super.init() - - self.menu.delegate = self - } - - @objc - private func performAction(_ menuItem: NSMenuItem) - { - guard case let index = self.menu.index(of: menuItem), index != -1 else { return } - - let item = self.items[index] - self.action?(item) - } - - @objc - func numberOfItems(in menu: NSMenu) -> Int - { - let numberOfItems = (self.items.isEmpty && self.placeholder != nil) ? 1 : self.items.count - return numberOfItems - } - - @objc - func menu(_ menu: NSMenu, update menuItem: NSMenuItem, at index: Int, shouldCancel: Bool) -> Bool - { - if let text = self.placeholder, self.items.isEmpty - { - menuItem.title = text - menuItem.isEnabled = false - menuItem.target = nil - menuItem.action = nil - } - else - { - let item = self.items[index] - - menuItem.title = item.name - menuItem.isEnabled = true - menuItem.target = self - menuItem.action = #selector(MenuController.performAction(_:)) - menuItem.tag = index - - if let submenu = self.submenus[item] ?? self.submenuHandler?(item) - { - menuItem.submenu = submenu - - // Cache submenu to prevent duplicate calls to submenuHandler. - self.submenus[item] = submenu - } - } - - return true - } -} - -private extension MenuController -{ - func updateMenu() - { - self.menu.removeAllItems() - - let numberOfItems = self.numberOfItems(in: self.menu) - for index in 0 ..< numberOfItems - { - let menuItem = NSMenuItem(title: "", action: nil, keyEquivalent: "") - guard self.menu(self.menu, update: menuItem, at: index, shouldCancel: false) else { break } - - self.menu.addItem(menuItem) - } - - self.menu.update() - } -} diff --git a/AltServer/Plugin/PluginManager.swift b/AltServer/Plugin/PluginManager.swift deleted file mode 100644 index fb2e9c09..00000000 --- a/AltServer/Plugin/PluginManager.swift +++ /dev/null @@ -1,372 +0,0 @@ -// -// PluginManager.swift -// AltServer -// -// Created by Riley Testut on 9/16/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation -import AppKit -import CryptoKit - -import STPrivilegedTask - -private let pluginDirectoryURL = URL(fileURLWithPath: "/Library/Mail/Bundles", isDirectory: true) -private let pluginURL = pluginDirectoryURL.appendingPathComponent("AltPlugin.mailbundle") - -enum PluginError: LocalizedError -{ - case cancelled - case unknown - case notFound - case mismatchedHash(hash: String, expectedHash: String) - case taskError(String) - case taskErrorCode(Int) - - var errorDescription: String? { - switch self - { - case .cancelled: return NSLocalizedString("Mail plug-in installation was cancelled.", comment: "") - case .unknown: return NSLocalizedString("Failed to install Mail plug-in.", comment: "") - case .notFound: return NSLocalizedString("The Mail plug-in does not exist at the requested URL.", comment: "") - case .mismatchedHash(let hash, let expectedHash): return String(format: NSLocalizedString("The hash of the downloaded Mail plug-in does not match the expected hash.\n\nHash:\n%@\n\nExpected Hash:\n%@", comment: ""), hash, expectedHash) - case .taskError(let output): return output - case .taskErrorCode(let errorCode): return String(format: NSLocalizedString("There was an error installing the Mail plug-in. (Error Code: %@)", comment: ""), NSNumber(value: errorCode)) - } - } -} - -private extension URL -{ - #if STAGING - static let altPluginUpdateURL = URL(string: "https://f000.backblazeb2.com/file/altstore-staging/altserver/altplugin/altplugin.json")! - #else - static let altPluginUpdateURL = URL(string: "https://cdn.altstore.io/file/altstore/altserver/altplugin/altplugin.json")! - #endif -} - -class PluginManager -{ - private let session = URLSession(configuration: .ephemeral) - private var latestPluginVersion: PluginVersion? - - var isMailPluginInstalled: Bool { - let isMailPluginInstalled = FileManager.default.fileExists(atPath: pluginURL.path) - return isMailPluginInstalled - } - - func isUpdateAvailable(completionHandler: @escaping (Result) -> Void) - { - self.isUpdateAvailable(useCache: false, completionHandler: completionHandler) - } - - private func isUpdateAvailable(useCache: Bool, completionHandler: @escaping (Result) -> Void) - { - do - { - // If Mail plug-in is not yet installed, then there is no update available. - var isDirectory: ObjCBool = false - guard FileManager.default.fileExists(atPath: pluginURL.path, isDirectory: &isDirectory), isDirectory.boolValue else { return completionHandler(.success(false)) } - - // Load Info.plist from disk because Bundle.infoDictionary is cached by system. - let infoDictionaryURL = pluginURL.appendingPathComponent("Contents/Info.plist") - guard let infoDictionary = NSDictionary(contentsOf: infoDictionaryURL) as? [String: Any], - let localVersion = infoDictionary["CFBundleShortVersionString"] as? String - else { throw CocoaError(.fileReadCorruptFile, userInfo: [NSURLErrorKey: infoDictionaryURL]) } - - if let pluginVersion = self.latestPluginVersion, useCache - { - let isUpdateAvailable = (localVersion != pluginVersion.version) - completionHandler(.success(isUpdateAvailable)) - } - else - { - self.fetchLatestPluginVersion(useCache: useCache) { result in - switch result - { - case .failure(let error): completionHandler(.failure(error)) - case .success(let pluginVersion): - let isUpdateAvailable = (localVersion != pluginVersion.version) - completionHandler(.success(isUpdateAvailable)) - } - } - } - } - catch - { - completionHandler(.failure(error)) - } - } -} - -extension PluginManager -{ - func installMailPlugin(completionHandler: @escaping (Result) -> Void) - { - self.isUpdateAvailable(useCache: true) { result in - DispatchQueue.main.async { - do - { - let isUpdateAvailable = try result.get() - - let alert = NSAlert() - if isUpdateAvailable - { - alert.messageText = NSLocalizedString("Update Mail Plug-in", comment: "") - alert.informativeText = NSLocalizedString("An update is available for AltServer's Mail plug-in. Please update the plug-in now in order to keep using AltStore.", comment: "") - - alert.addButton(withTitle: NSLocalizedString("Update Plug-in", comment: "")) - alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) - } - else - { - alert.messageText = NSLocalizedString("Install Mail Plug-in", comment: "") - alert.informativeText = NSLocalizedString("AltServer requires a Mail plug-in in order to retrieve necessary information about your Apple ID. Would you like to install it now?", comment: "") - - alert.addButton(withTitle: NSLocalizedString("Install Plug-in", comment: "")) - alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) - } - - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - let response = alert.runModal() - guard response == .alertFirstButtonReturn else { throw PluginError.cancelled } - - self.downloadPlugin { (result) in - do - { - let fileURL = try result.get() - - // Ensure plug-in directory exists. - let authorization = try self.runAndKeepAuthorization("mkdir", arguments: ["-p", pluginDirectoryURL.path]) - - // Create temporary directory. - let temporaryDirectoryURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - try FileManager.default.createDirectory(at: temporaryDirectoryURL, withIntermediateDirectories: true, attributes: nil) - defer { try? FileManager.default.removeItem(at: temporaryDirectoryURL) } - - // Unzip AltPlugin to temporary directory. - try self.runAndKeepAuthorization("unzip", arguments: ["-o", fileURL.path, "-d", temporaryDirectoryURL.path], authorization: authorization) - - if FileManager.default.fileExists(atPath: pluginURL.path) - { - // Delete existing Mail plug-in. - try self.runAndKeepAuthorization("rm", arguments: ["-rf", pluginURL.path], authorization: authorization) - } - - // Copy AltPlugin to Mail plug-ins directory. - // Must be separate step than unzip to prevent macOS from considering plug-in corrupted. - let unzippedPluginURL = temporaryDirectoryURL.appendingPathComponent(pluginURL.lastPathComponent) - try self.runAndKeepAuthorization("cp", arguments: ["-R", unzippedPluginURL.path, pluginDirectoryURL.path], authorization: authorization) - - guard self.isMailPluginInstalled else { throw PluginError.unknown } - - // Enable Mail plug-in preferences. - try self.run("defaults", arguments: ["write", "/Library/Preferences/com.apple.mail", "EnableBundles", "-bool", "YES"], authorization: authorization) - - print("Finished installing Mail plug-in!") - - completionHandler(.success(())) - } - catch - { - completionHandler(.failure(error)) - } - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - } - - func uninstallMailPlugin(completionHandler: @escaping (Result) -> Void) - { - let alert = NSAlert() - alert.messageText = NSLocalizedString("Uninstall Mail Plug-in", comment: "") - alert.informativeText = NSLocalizedString("Are you sure you want to uninstall the AltServer Mail plug-in? You will no longer be able to install or refresh apps with AltStore.", comment: "") - - alert.addButton(withTitle: NSLocalizedString("Uninstall Plug-in", comment: "")) - alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "")) - - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - let response = alert.runModal() - guard response == .alertFirstButtonReturn else { return completionHandler(.failure(PluginError.cancelled)) } - - DispatchQueue.global().async { - do - { - if FileManager.default.fileExists(atPath: pluginURL.path) - { - // Delete Mail plug-in from privileged directory. - try self.run("rm", arguments: ["-rf", pluginURL.path]) - } - - completionHandler(.success(())) - } - catch - { - completionHandler(.failure(error)) - } - } - } -} - -private extension PluginManager -{ - func fetchLatestPluginVersion(useCache: Bool, completionHandler: @escaping (Result) -> Void) - { - if let pluginVersion = self.latestPluginVersion, useCache - { - return completionHandler(.success(pluginVersion)) - } - - guard #available(macOS 11, *) else { - // macOS versions prior to 11.0 require Mail plug-ins be *unsigned*, - // so we hardcode these versions to use the unsigned AltPlugin v1.0. - return completionHandler(.success(.v1_0)) - } - - let dataTask = self.session.dataTask(with: .altPluginUpdateURL) { (data, response, error) in - do - { - if let response = response as? HTTPURLResponse - { - guard response.statusCode != 404 else { return completionHandler(.failure(PluginError.notFound)) } - } - - guard let data = data else { throw error! } - - let response = try JSONDecoder().decode(PluginVersionResponse.self, from: data) - completionHandler(.success(response.pluginVersion)) - } - catch - { - completionHandler(.failure(error)) - } - } - - dataTask.resume() - } - - func downloadPlugin(completion: @escaping (Result) -> Void) - { - self.fetchLatestPluginVersion(useCache: true) { result in - switch result - { - case .failure(let error): completion(.failure(error)) - case .success(let pluginVersion): - - func finish(_ result: Result) - { - do - { - let fileURL = try result.get() - - if #available(OSX 10.15, *) - { - let data = try Data(contentsOf: fileURL) - let sha256Hash = SHA256.hash(data: data) - let hashString = sha256Hash.compactMap { String(format: "%02x", $0) }.joined() - - print("Comparing Mail plug-in hash (\(hashString)) against expected hash (\(pluginVersion.sha256Hash))...") - guard hashString == pluginVersion.sha256Hash else { throw PluginError.mismatchedHash(hash: hashString, expectedHash: pluginVersion.sha256Hash) } - } - - completion(.success(fileURL)) - } - catch - { - completion(.failure(error)) - } - } - - if pluginVersion.url.isFileURL - { - finish(.success(pluginVersion.url)) - } - else - { - let downloadTask = URLSession.shared.downloadTask(with: pluginVersion.url) { (fileURL, response, error) in - if let response = response as? HTTPURLResponse - { - guard response.statusCode != 404 else { return finish(.failure(PluginError.notFound)) } - } - - let result = Result(fileURL, error) - finish(result) - - if let fileURL = fileURL - { - try? FileManager.default.removeItem(at: fileURL) - } - } - - downloadTask.resume() - } - } - } - } - - func run(_ program: String, arguments: [String], authorization: AuthorizationRef? = nil) throws - { - _ = try self._run(program, arguments: arguments, authorization: authorization, freeAuthorization: true) - } - - @discardableResult - func runAndKeepAuthorization(_ program: String, arguments: [String], authorization: AuthorizationRef? = nil) throws -> AuthorizationRef - { - return try self._run(program, arguments: arguments, authorization: authorization, freeAuthorization: false) - } - - func _run(_ program: String, arguments: [String], authorization: AuthorizationRef? = nil, freeAuthorization: Bool) throws -> AuthorizationRef - { - var launchPath = "/usr/bin/" + program - if !FileManager.default.fileExists(atPath: launchPath) - { - launchPath = "/bin/" + program - } - - print("Running program:", launchPath) - - let task = STPrivilegedTask() - task.launchPath = launchPath - task.arguments = arguments - task.freeAuthorizationWhenDone = freeAuthorization - - let errorCode: OSStatus - - if let authorization = authorization - { - errorCode = task.launch(withAuthorization: authorization) - } - else - { - errorCode = task.launch() - } - - guard errorCode == 0 else { throw PluginError.taskErrorCode(Int(errorCode)) } - - task.waitUntilExit() - - print("Exit code:", task.terminationStatus) - - guard task.terminationStatus == 0 else { - let outputData = task.outputFileHandle.readDataToEndOfFile() - - if let outputString = String(data: outputData, encoding: .utf8), !outputString.isEmpty - { - throw PluginError.taskError(outputString) - } - - throw PluginError.taskErrorCode(Int(task.terminationStatus)) - } - - guard let authorization = task.authorization else { throw PluginError.unknown } - return authorization - } -} diff --git a/AltServer/Plugin/PluginVersion.swift b/AltServer/Plugin/PluginVersion.swift deleted file mode 100644 index 72f7bcb5..00000000 --- a/AltServer/Plugin/PluginVersion.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// PluginVersion.swift -// AltServer -// -// Created by Riley Testut and Weedles on 2/15/22 <3 -// Copyright © 2022 Riley Testut. All rights reserved. -// - -import Foundation - -struct PluginVersion: Decodable -{ - var url: URL - var sha256Hash: String - var version: String - - static let v1_0 = PluginVersion(url: URL(string: "https://f000.backblazeb2.com/file/altstore/altserver/altplugin/1_0.zip")!, - sha256Hash: "070e9b7e1f74e7a6474d36253ab5a3623ff93892acc9e1043c3581f2ded12200", - version: "1.0") - - static let v1_9 = PluginVersion(url: Bundle.main.url(forResource: "AltPlugin", withExtension: "zip")!, - sha256Hash: "83ead26d8776ef6850e06fe3d1c5c5559aca284718b1cf3cc49785ba6b1e2849", - version: "1.9") - - private enum CodingKeys: String, CodingKey - { - case url - case sha256Hash = "sha256" - case version - } -} - -struct PluginVersionResponse: Decodable -{ - var version: Int - var pluginVersion: PluginVersion -} diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 7c9c859e..06114a39 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ B3146ED2284F581E00BBC3FD /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; }; B3146ED3284F581E00BBC3FD /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; B376FE3E29258C8900E18883 /* OSLog+SideStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B376FE3D29258C8900E18883 /* OSLog+SideStore.swift */; }; + B3919A52292DBE5400519575 /* ProgressRing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D504F42528AD72C50014BB5D /* ProgressRing.swift */; }; B39575F5284F29E20080B4FF /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B39575F4284F29E20080B4FF /* Roxas.framework */; }; B39F16132918D7C5002E9404 /* Consts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B39F16122918D7C5002E9404 /* Consts.swift */; }; B39F16152918D7DA002E9404 /* Consts+Proxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B39F16142918D7DA002E9404 /* Consts+Proxy.swift */; }; @@ -43,11 +44,8 @@ B3C395F4284F35DD00DA9E2F /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = B3C395F3284F35DD00DA9E2F /* Nuke */; }; B3C395F7284F362400DA9E2F /* AppCenterAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = B3C395F6284F362400DA9E2F /* AppCenterAnalytics */; }; B3C395F9284F362400DA9E2F /* AppCenterCrashes in Frameworks */ = {isa = PBXBuildFile; productRef = B3C395F8284F362400DA9E2F /* AppCenterCrashes */; }; - B3C395FC284F3B2400DA9E2F /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = B3C395FB284F3B2400DA9E2F /* Sparkle */; }; - B3C395FF284F3C0900DA9E2F /* STPrivilegedTask in Frameworks */ = {isa = PBXBuildFile; productRef = B3C395FE284F3C0900DA9E2F /* STPrivilegedTask */; }; B3EE16B62925E27D00B3B1F5 /* AnisetteManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3EE16B52925E27D00B3B1F5 /* AnisetteManager.swift */; }; BF02419622F2199300129732 /* RefreshAttemptsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02419522F2199300129732 /* RefreshAttemptsViewController.swift */; }; - BF0241AA22F29CCD00129732 /* UserDefaults+AltServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0241A922F29CCD00129732 /* UserDefaults+AltServer.swift */; }; BF08858322DE795100DE9F1E /* MyAppsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF08858222DE795100DE9F1E /* MyAppsViewController.swift */; }; BF08858522DE7EC800DE9F1E /* UpdateCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF08858422DE7EC800DE9F1E /* UpdateCollectionViewCell.swift */; }; BF0C4EBD22A1BD8B009A2DD7 /* AppManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0C4EBC22A1BD8B009A2DD7 /* AppManager.swift */; }; @@ -56,11 +54,8 @@ BF1614F1250822F100767AEA /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFD247862284BB3B00981D42 /* Roxas.framework */; }; BF1614F2250822F100767AEA /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFD247862284BB3B00981D42 /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BF18B0F122E25DF9005C4CF5 /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18B0F022E25DF9005C4CF5 /* ToastView.swift */; }; - BF18BFFD2485A1E400DD5981 /* WiredConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFFC2485A1E400DD5981 /* WiredConnectionHandler.swift */; }; - BF1E312B229F474900370A3C /* RequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E3129229F474900370A3C /* RequestHandler.swift */; }; BF1FE358251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1FE357251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift */; }; BF1FE359251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1FE357251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift */; }; - BF265D1925F843A000080DC9 /* NSError+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6C336124197D700034FD24 /* NSError+AltStore.swift */; }; BF29012F2318F6B100D88A45 /* AppBannerView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF29012E2318F6B100D88A45 /* AppBannerView.xib */; }; BF2901312318F7A800D88A45 /* AppBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2901302318F7A800D88A45 /* AppBannerView.swift */; }; BF340E9A250AD39500A192CB /* ViewApp.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = BF989191250AAE86002ACF50 /* ViewApp.intentdefinition */; }; @@ -70,17 +65,12 @@ BF3D649D22E7AC1B00E9056B /* PermissionPopoverViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3D649C22E7AC1B00E9056B /* PermissionPopoverViewController.swift */; }; BF3D649F22E7B24C00E9056B /* CollapsingTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3D649E22E7B24C00E9056B /* CollapsingTextView.swift */; }; BF3D64B022E8D4B800E9056B /* AppContentViewControllerCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3D64AF22E8D4B800E9056B /* AppContentViewControllerCells.swift */; }; - BF3F786422CAA41E008FBD20 /* ALTDeviceManager+Installation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3F786322CAA41E008FBD20 /* ALTDeviceManager+Installation.swift */; }; BF41B806233423AE00C593A3 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF41B805233423AE00C593A3 /* TabBarController.swift */; }; BF41B808233433C100C593A3 /* LoadingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF41B807233433C100C593A3 /* LoadingState.swift */; }; BF42345A25101C35006D1EB2 /* WidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF42345825101C1D006D1EB2 /* WidgetView.swift */; }; BF44EEF0246B08BA002A52F2 /* BackupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF44EEEF246B08BA002A52F2 /* BackupController.swift */; }; BF44EEF3246B3A17002A52F2 /* AltBackup.ipa in Resources */ = {isa = PBXBuildFile; fileRef = BF44EEF2246B3A17002A52F2 /* AltBackup.ipa */; }; BF44EEFC246B4550002A52F2 /* RemoveAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */; }; - BF458690229872EA00BD7491 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF45868F229872EA00BD7491 /* AppDelegate.swift */; }; - BF458694229872EA00BD7491 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF458693229872EA00BD7491 /* Assets.xcassets */; }; - BF458697229872EA00BD7491 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF458695229872EA00BD7491 /* Main.storyboard */; }; - BF4586C52298CDB800BD7491 /* ALTDeviceManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = BF4586C42298CDB800BD7491 /* ALTDeviceManager.mm */; }; BF4587F82298D3AB00BD7491 /* service.h in Headers */ = {isa = PBXBuildFile; fileRef = BF4587C82298D3A800BD7491 /* service.h */; }; BF4587F92298D3AB00BD7491 /* diagnostics_relay.c in Sources */ = {isa = PBXBuildFile; fileRef = BF4587C92298D3A800BD7491 /* diagnostics_relay.c */; }; BF4587FA2298D3AB00BD7491 /* diagnostics_relay.h in Headers */ = {isa = PBXBuildFile; fileRef = BF4587CA2298D3A800BD7491 /* diagnostics_relay.h */; }; @@ -137,10 +127,7 @@ BF45883C2298D3C100BD7491 /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = BF4588322298D3C100BD7491 /* utils.h */; }; BF4588402298D3F800BD7491 /* collection.h in Headers */ = {isa = PBXBuildFile; fileRef = BF45883E2298D3F800BD7491 /* collection.h */; }; BF4588432298D40000BD7491 /* libusbmuxd.c in Sources */ = {isa = PBXBuildFile; fileRef = BF4588422298D40000BD7491 /* libusbmuxd.c */; }; - BF4588472298D4B000BD7491 /* libimobiledevice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BF45872B2298D31600BD7491 /* libimobiledevice.a */; }; - BF4588882298DD3F00BD7491 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BF4588872298DD3F00BD7491 /* libxml2.tbd */; }; BF4B78FE24B3D1DB008AB4AC /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF4B78FD24B3D1DB008AB4AC /* SceneDelegate.swift */; }; - BF541C0B25E5A5FA00CD46B2 /* FileManager+URLs.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF541C0A25E5A5FA00CD46B2 /* FileManager+URLs.swift */; }; BF56D2AC23DF8E170006506D /* FetchAppIDsOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF56D2AB23DF8E170006506D /* FetchAppIDsOperation.swift */; }; BF56D2AF23DF9E310006506D /* AppIDsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF56D2AE23DF9E310006506D /* AppIDsViewController.swift */; }; BF58047E246A28F7008AE704 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF58047D246A28F7008AE704 /* AppDelegate.swift */; }; @@ -150,7 +137,6 @@ BF580496246A3CB5008AE704 /* UIColor+AltBackup.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF580495246A3CB5008AE704 /* UIColor+AltBackup.swift */; }; BF580498246A3D19008AE704 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF580497246A3D19008AE704 /* UIKit.framework */; }; BF58049B246A432D008AE704 /* NSError+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6C336124197D700034FD24 /* NSError+AltStore.swift */; }; - BF5C5FCF237DF69100EDD0C6 /* ALTPluginService.m in Sources */ = {isa = PBXBuildFile; fileRef = BF5C5FCE237DF69100EDD0C6 /* ALTPluginService.m */; }; BF663C4F2433ED8200DAA738 /* FileManager+DirectorySize.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF663C4E2433ED8200DAA738 /* FileManager+DirectorySize.swift */; }; BF66EE822501AE50007EE018 /* AltStoreCore.h in Headers */ = {isa = PBXBuildFile; fileRef = BF66EE802501AE50007EE018 /* AltStoreCore.h */; settings = {ATTRIBUTES = (Public, ); }; }; BF66EE852501AE50007EE018 /* AltStoreCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */; }; @@ -201,16 +187,12 @@ BF6C8FAE2429597900125131 /* BannerCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6C8FAD2429597900125131 /* BannerCollectionViewCell.swift */; }; BF6C8FB02429599900125131 /* TextCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6C8FAF2429599900125131 /* TextCollectionReusableView.swift */; }; BF6F439223644C6E00A0B879 /* RefreshAltStoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6F439123644C6E00A0B879 /* RefreshAltStoreViewController.swift */; }; - BF718BD123C91BD300A89F2D /* ALTWiredConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = BF718BD023C91BD300A89F2D /* ALTWiredConnection.mm */; }; - BF718BD523C928A300A89F2D /* ALTNotificationConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = BF718BD423C928A300A89F2D /* ALTNotificationConnection.mm */; }; BF74989B23621C0700CED65F /* ForwardingNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF74989A23621C0700CED65F /* ForwardingNavigationController.swift */; }; BF770E5122BB1CF6002A40FE /* InstallAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF770E5022BB1CF6002A40FE /* InstallAppOperation.swift */; }; BF770E5422BC044E002A40FE /* OperationContexts.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF770E5322BC044E002A40FE /* OperationContexts.swift */; }; BF770E5822BC3D0F002A40FE /* RefreshGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF770E5722BC3D0F002A40FE /* RefreshGroup.swift */; }; BF770E6722BD57C4002A40FE /* BackgroundTaskManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF770E6622BD57C3002A40FE /* BackgroundTaskManager.swift */; }; BF770E6922BD57DD002A40FE /* Silence.m4a in Resources */ = {isa = PBXBuildFile; fileRef = BF770E6822BD57DD002A40FE /* Silence.m4a */; }; - BF77A67025795A5600BFE477 /* AltXPC.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF77A66F25795A5600BFE477 /* AltXPC.swift */; }; - BF77A67E25795BBE00BFE477 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF77A67D25795BBE00BFE477 /* main.swift */; }; BF88F97224F8727D00BB75DF /* AppManagerErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF88F97124F8727D00BB75DF /* AppManagerErrors.swift */; }; BF8B17EB250AC40000F8157F /* FileManager+SharedDirectories.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6A531F246DC1B0004F59C8 /* FileManager+SharedDirectories.swift */; }; BF8CAE452489E772004D6CCE /* AnisetteDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE422489E772004D6CCE /* AnisetteDataManager.swift */; }; @@ -219,7 +201,6 @@ BF8CAE4E248AEABA004D6CCE /* UIDevice+Jailbreak.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE4D248AEABA004D6CCE /* UIDevice+Jailbreak.swift */; }; BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8F69C122E659F700049BA1 /* AppContentViewController.swift */; }; BF8F69C422E662D300049BA1 /* AppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8F69C322E662D300049BA1 /* AppViewController.swift */; }; - BF904DEA265DAE9A00E86C2A /* InstalledApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF904DE9265DAE9A00E86C2A /* InstalledApp.swift */; }; BF989171250AABF4002ACF50 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF989170250AABF4002ACF50 /* Assets.xcassets */; }; BF989177250AABF4002ACF50 /* AltWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = BF989167250AABF3002ACF50 /* AltWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; BF98917E250AAC4F002ACF50 /* Countdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF98917C250AAC4F002ACF50 /* Countdown.swift */; }; @@ -232,8 +213,6 @@ BF9ABA4B22DD1380008935CF /* NavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9ABA4A22DD137F008935CF /* NavigationBar.swift */; }; BF9ABA4D22DD16DE008935CF /* PillButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9ABA4C22DD16DE008935CF /* PillButton.swift */; }; BFA8172B23C5633D001B5953 /* FetchAnisetteDataOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA8172A23C5633D001B5953 /* FetchAnisetteDataOperation.swift */; }; - BFAD678E25E0649500D4C4D1 /* ALTDebugConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = BFAD678D25E0649500D4C4D1 /* ALTDebugConnection.mm */; }; - BFAD67A325E0854500D4C4D1 /* DeveloperDiskManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAD67A225E0854500D4C4D1 /* DeveloperDiskManager.swift */; }; BFAECC522501B0A400528F27 /* CodableServerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD44605241188C300EAB90A /* CodableServerError.swift */; }; BFAECC532501B0A400528F27 /* ServerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E3128229F474900370A3C /* ServerProtocol.swift */; }; BFAECC542501B0A400528F27 /* NSError+ALTServerError.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314922A060F400370A3C /* NSError+ALTServerError.m */; }; @@ -251,19 +230,16 @@ BFAECC602501B0BF00528F27 /* NSError+ALTServerError.h in Headers */ = {isa = PBXBuildFile; fileRef = BF1E314822A060F400370A3C /* NSError+ALTServerError.h */; settings = {ATTRIBUTES = (Public, ); }; }; BFB39B5C252BC10E00D1BE50 /* Managed.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB39B5B252BC10E00D1BE50 /* Managed.swift */; }; BFB4323F22DE852000B7F8BC /* UpdateCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFB4323E22DE852000B7F8BC /* UpdateCollectionViewCell.xib */; }; - BFB49AAA23834CF900D542D9 /* ALTAnisetteData.m in Sources */ = {isa = PBXBuildFile; fileRef = BFB49AA823834CF900D542D9 /* ALTAnisetteData.m */; }; BFB6B21E231870160022A802 /* NewsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB6B21D231870160022A802 /* NewsViewController.swift */; }; BFB6B220231870B00022A802 /* NewsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB6B21F231870B00022A802 /* NewsCollectionViewCell.swift */; }; BFB6B22423187A3D0022A802 /* NewsCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFB6B22323187A3D0022A802 /* NewsCollectionViewCell.xib */; }; BFBE0004250ACFFB0080826E /* ViewApp.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = BF989191250AAE86002ACF50 /* ViewApp.intentdefinition */; settings = {ATTRIBUTES = (no_codegen, ); }; }; BFBE0007250AD0E70080826E /* ViewAppIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF989190250AAE86002ACF50 /* ViewAppIntentHandler.swift */; }; BFBF331B2526762200B7B8C9 /* AltStore8ToAltStore9.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = BFBF331A2526762200B7B8C9 /* AltStore8ToAltStore9.xcmappingmodel */; }; - BFC15ADA27BC352300ED2FB4 /* PluginVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC15AD927BC352300ED2FB4 /* PluginVersion.swift */; }; BFC1F38D22AEE3A4003AC21A /* DownloadAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC1F38C22AEE3A4003AC21A /* DownloadAppOperation.swift */; }; BFC57A652416C72400EB891E /* DeactivateAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC57A642416C72400EB891E /* DeactivateAppOperation.swift */; }; BFC57A6E2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC57A6D2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift */; }; BFC57A702416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFC57A6F2416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib */; }; - BFC712BB2512B9CF00AB5EBE /* PluginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC712BA2512B9CF00AB5EBE /* PluginManager.swift */; }; BFC712C32512D5F100AB5EBE /* XPCConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC712C12512D5F100AB5EBE /* XPCConnection.swift */; }; BFC712C42512D5F100AB5EBE /* XPCConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC712C12512D5F100AB5EBE /* XPCConnection.swift */; }; BFC712C52512D5F100AB5EBE /* XPCConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC712C22512D5F100AB5EBE /* XPCConnectionHandler.swift */; }; @@ -317,8 +293,6 @@ BFE00A202503097F00EB4D0C /* INInteraction+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE00A1F2503097F00EB4D0C /* INInteraction+AltStore.swift */; }; BFE338DF22F0EADB002E24B9 /* FetchSourceOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE338DE22F0EADB002E24B9 /* FetchSourceOperation.swift */; }; BFE338E822F10E56002E24B9 /* LaunchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE338E722F10E56002E24B9 /* LaunchViewController.swift */; }; - BFE48975238007CE003239E0 /* AnisetteDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE48974238007CE003239E0 /* AnisetteDataManager.swift */; }; - BFE4FFB6251BF7BA0018CF9B /* AltPlugin.zip in Resources */ = {isa = PBXBuildFile; fileRef = BFE4FFB5251BF7BA0018CF9B /* AltPlugin.zip */; }; BFE60738231ADF49002B0E8E /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFE60737231ADF49002B0E8E /* Settings.storyboard */; }; BFE6073A231ADF82002B0E8E /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE60739231ADF82002B0E8E /* SettingsViewController.swift */; }; BFE6073C231AE1E7002B0E8E /* SettingsHeaderFooterView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFE6073B231AE1E7002B0E8E /* SettingsHeaderFooterView.xib */; }; @@ -326,16 +300,6 @@ BFE60742231B07E6002B0E8E /* SettingsHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */; }; BFE6325A22A83BEB00F30809 /* Authentication.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFE6325922A83BEB00F30809 /* Authentication.storyboard */; }; BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */; }; - BFE972E3260A8B2700D0BDAC /* NSError+libimobiledevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = BFE972E2260A8B2700D0BDAC /* NSError+libimobiledevice.mm */; }; - BFECAC7F24FD950B0077C41F /* CodableServerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD44605241188C300EAB90A /* CodableServerError.swift */; }; - BFECAC8024FD950B0077C41F /* ConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF22485828200DD5981 /* ConnectionManager.swift */; }; - BFECAC8124FD950B0077C41F /* ALTServerError+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */; }; - BFECAC8224FD950B0077C41F /* ServerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E3128229F474900370A3C /* ServerProtocol.swift */; }; - BFECAC8324FD950B0077C41F /* NetworkConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767CD2489ABE90097E58C /* NetworkConnection.swift */; }; - BFECAC8424FD950B0077C41F /* ALTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = BF718BD723C93DB700A89F2D /* ALTConstants.m */; }; - BFECAC8524FD950B0077C41F /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF624858BDE00DD5981 /* Connection.swift */; }; - BFECAC8624FD950B0077C41F /* Result+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBAC8852295C90300587369 /* Result+Conveniences.swift */; }; - BFECAC8724FD950B0077C41F /* Bundle+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314122A05D4C00370A3C /* Bundle+AltStore.swift */; }; BFECAC8824FD950E0077C41F /* CodableServerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD44605241188C300EAB90A /* CodableServerError.swift */; }; BFECAC8924FD950E0077C41F /* ConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF22485828200DD5981 /* ConnectionManager.swift */; }; BFECAC8A24FD950E0077C41F /* ALTServerError+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */; }; @@ -344,14 +308,11 @@ BFECAC8E24FD950E0077C41F /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF624858BDE00DD5981 /* Connection.swift */; }; BFECAC8F24FD950E0077C41F /* Result+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBAC8852295C90300587369 /* Result+Conveniences.swift */; }; BFECAC9024FD950E0077C41F /* Bundle+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314122A05D4C00370A3C /* Bundle+AltStore.swift */; }; - BFECAC9324FD98BA0077C41F /* CFNotificationName+AltStore.m in Sources */ = {isa = PBXBuildFile; fileRef = BF718BC823C919E300A89F2D /* CFNotificationName+AltStore.m */; }; - BFECAC9424FD98BA0077C41F /* NSError+ALTServerError.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314922A060F400370A3C /* NSError+ALTServerError.m */; }; BFECAC9524FD98BB0077C41F /* CFNotificationName+AltStore.m in Sources */ = {isa = PBXBuildFile; fileRef = BF718BC823C919E300A89F2D /* CFNotificationName+AltStore.m */; }; BFECAC9624FD98BB0077C41F /* NSError+ALTServerError.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314922A060F400370A3C /* NSError+ALTServerError.m */; }; BFF00D302501BD7D00746320 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = BFF00D2F2501BD7D00746320 /* Intents.intentdefinition */; }; BFF00D322501BDA100746320 /* BackgroundRefreshAppsOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF00D312501BDA100746320 /* BackgroundRefreshAppsOperation.swift */; }; BFF00D342501BDCF00746320 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF00D332501BDCF00746320 /* IntentHandler.swift */; }; - BFF0394B25F0551600BE607D /* MenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0394A25F0551600BE607D /* MenuController.swift */; }; BFF0B68E23219520007A79E1 /* PatreonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B68D23219520007A79E1 /* PatreonViewController.swift */; }; BFF0B69023219C6D007A79E1 /* PatreonComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B68F23219C6D007A79E1 /* PatreonComponents.swift */; }; BFF0B6922321A305007A79E1 /* AboutPatreonHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFF0B6912321A305007A79E1 /* AboutPatreonHeaderView.xib */; }; @@ -360,13 +321,7 @@ BFF0B6982322CAB8007A79E1 /* InstructionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B6972322CAB8007A79E1 /* InstructionsViewController.swift */; }; BFF0B69A2322D7D0007A79E1 /* UIScreen+CompactHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B6992322D7D0007A79E1 /* UIScreen+CompactHeight.swift */; }; BFF435D8255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF435D7255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift */; }; - BFF435D9255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF435D7255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift */; }; BFF615A82510042B00484D3B /* AltStoreCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */; }; - BFF767C82489A74E0097E58C /* WirelessConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767C72489A74E0097E58C /* WirelessConnectionHandler.swift */; }; - BFF7C90F257844C900E55F36 /* AltXPC.xpc in Embed XPC Services */ = {isa = PBXBuildFile; fileRef = BFF7C904257844C900E55F36 /* AltXPC.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - BFF7C920257844FA00E55F36 /* ALTPluginService.m in Sources */ = {isa = PBXBuildFile; fileRef = BF5C5FCE237DF69100EDD0C6 /* ALTPluginService.m */; }; - BFF7C9342578492100E55F36 /* ALTAnisetteData.m in Sources */ = {isa = PBXBuildFile; fileRef = BFB49AA823834CF900D542D9 /* ALTAnisetteData.m */; }; - D504F42628AD72C50014BB5D /* ProgressRing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D504F42528AD72C50014BB5D /* ProgressRing.swift */; }; D533E8B72727841800A9B5DD /* libAppleArchive.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D533E8B62727841800A9B5DD /* libAppleArchive.tbd */; settings = {ATTRIBUTES = (Weak, ); }; }; D533E8BC2727BBEE00A9B5DD /* libfragmentzip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D533E8BB2727BBEE00A9B5DD /* libfragmentzip.a */; }; D533E8BE2727BBF800A9B5DD /* libcurl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D533E8BD2727BBF800A9B5DD /* libcurl.a */; }; @@ -375,7 +330,6 @@ D57DF63F271E51E400677701 /* ALTAppPatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = D57DF63E271E51E400677701 /* ALTAppPatcher.m */; }; D57F2C9126E0070200B9FA39 /* EnableJITOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57F2C9026E0070200B9FA39 /* EnableJITOperation.swift */; }; D57F2C9426E01BC700B9FA39 /* UIDevice+Vibration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57F2C9326E01BC700B9FA39 /* UIDevice+Vibration.swift */; }; - D58D5F2E26DFE68E00E55E38 /* LaunchAtLogin in Frameworks */ = {isa = PBXBuildFile; productRef = D58D5F2D26DFE68E00E55E38 /* LaunchAtLogin */; }; D593F1942717749A006E82DE /* PatchAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D593F1932717749A006E82DE /* PatchAppOperation.swift */; }; D5CA0C4B280E141900469595 /* ManagedPatron.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4A280E141900469595 /* ManagedPatron.swift */; }; D5CA0C4E280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4D280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel */; }; @@ -428,13 +382,6 @@ remoteGlobalIDString = BFADB00319AE7BB80050CF31; remoteInfo = RoxasTests; }; - BF4588442298D48B00BD7491 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFD247622284B9A500981D42 /* Project object */; - proxyType = 1; - remoteGlobalIDString = BF45872A2298D31600BD7491; - remoteInfo = libimobiledevice; - }; BF66EE832501AE50007EE018 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFD247622284B9A500981D42 /* Project object */; @@ -456,44 +403,9 @@ remoteGlobalIDString = BF66EE7D2501AE50007EE018; remoteInfo = AltStoreCore; }; - BFF7C90D257844C900E55F36 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFD247622284B9A500981D42 /* Project object */; - proxyType = 1; - remoteGlobalIDString = BFF7C903257844C900E55F36; - remoteInfo = AltXPC; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 19104DB02909C06C00C49C7B /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 191E5FA9290A5D92001A3B7C /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BF0201BC22C2EFA3000B93E4 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; BF088D2B2501A087008082D9 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -507,15 +419,6 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; - BF5C5FE9237E438C00EDD0C6 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; BF98917B250AABF4002ACF50 /* Embed App Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -527,17 +430,6 @@ name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; }; - BFF7C910257844C900E55F36 /* Embed XPC Services */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; - dstSubfolderSpec = 16; - files = ( - BFF7C90F257844C900E55F36 /* AltXPC.xpc in Embed XPC Services */, - ); - name = "Embed XPC Services"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -573,15 +465,12 @@ B3C39606284F4C8400DA9E2F /* CodeSigning.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CodeSigning.xcconfig; sourceTree = ""; }; B3C39607284F4C8400DA9E2F /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = ""; }; B3C39608284F4C8400DA9E2F /* CodeSigning.xcconfig.sample */ = {isa = PBXFileReference; lastKnownFileType = text; path = CodeSigning.xcconfig.sample; sourceTree = ""; }; - B3C39609284F4C9800DA9E2F /* AltServer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltServer.xcconfig; sourceTree = ""; }; B3C3960B284F4C9800DA9E2F /* AltStore.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltStore.xcconfig; sourceTree = ""; }; - B3C3960C284F4CDC00DA9E2F /* AltXPC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltXPC.xcconfig; sourceTree = ""; }; B3C3960D284F4E4B00DA9E2F /* AltWidgetExtension.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltWidgetExtension.xcconfig; sourceTree = ""; }; B3C3960E284F4F9100DA9E2F /* AltStoreCore.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltStoreCore.xcconfig; sourceTree = ""; }; B3C3960F284F53E900DA9E2F /* AltBackup.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltBackup.xcconfig; sourceTree = ""; }; B3EE16B52925E27D00B3B1F5 /* AnisetteManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnisetteManager.swift; sourceTree = ""; }; BF02419522F2199300129732 /* RefreshAttemptsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshAttemptsViewController.swift; sourceTree = ""; }; - BF0241A922F29CCD00129732 /* UserDefaults+AltServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+AltServer.swift"; sourceTree = ""; }; BF08858222DE795100DE9F1E /* MyAppsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyAppsViewController.swift; sourceTree = ""; }; BF08858422DE7EC800DE9F1E /* UpdateCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateCollectionViewCell.swift; sourceTree = ""; }; BF0C4EBC22A1BD8B009A2DD7 /* AppManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppManager.swift; sourceTree = ""; }; @@ -591,11 +480,9 @@ BF18BFE724857D7900DD5981 /* AltDaemon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = AltDaemon; sourceTree = BUILT_PRODUCTS_DIR; }; BF18BFF22485828200DD5981 /* ConnectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionManager.swift; sourceTree = ""; }; BF18BFF624858BDE00DD5981 /* Connection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Connection.swift; sourceTree = ""; }; - BF18BFFC2485A1E400DD5981 /* WiredConnectionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WiredConnectionHandler.swift; sourceTree = ""; }; BF18BFFE2485A42800DD5981 /* ALTConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTConnection.h; sourceTree = ""; }; BF18C0032485B4DE00DD5981 /* AltDaemon-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AltDaemon-Bridging-Header.h"; sourceTree = ""; }; BF1E3128229F474900370A3C /* ServerProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServerProtocol.swift; sourceTree = ""; }; - BF1E3129229F474900370A3C /* RequestHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestHandler.swift; sourceTree = ""; }; BF1E314122A05D4C00370A3C /* Bundle+AltStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+AltStore.swift"; sourceTree = ""; }; BF1E314722A060F300370A3C /* AltStore-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AltStore-Bridging-Header.h"; sourceTree = ""; }; BF1E314822A060F400370A3C /* NSError+ALTServerError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+ALTServerError.h"; sourceTree = ""; }; @@ -610,22 +497,12 @@ BF3D649C22E7AC1B00E9056B /* PermissionPopoverViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionPopoverViewController.swift; sourceTree = ""; }; BF3D649E22E7B24C00E9056B /* CollapsingTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsingTextView.swift; sourceTree = ""; }; BF3D64AF22E8D4B800E9056B /* AppContentViewControllerCells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppContentViewControllerCells.swift; sourceTree = ""; }; - BF3F786322CAA41E008FBD20 /* ALTDeviceManager+Installation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ALTDeviceManager+Installation.swift"; sourceTree = ""; }; BF41B805233423AE00C593A3 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; BF41B807233433C100C593A3 /* LoadingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingState.swift; sourceTree = ""; }; BF42345825101C1D006D1EB2 /* WidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetView.swift; sourceTree = ""; }; BF44EEEF246B08BA002A52F2 /* BackupController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupController.swift; sourceTree = ""; }; BF44EEF2246B3A17002A52F2 /* AltBackup.ipa */ = {isa = PBXFileReference; lastKnownFileType = file; path = AltBackup.ipa; sourceTree = ""; }; BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAppOperation.swift; sourceTree = ""; }; - BF45868D229872EA00BD7491 /* AltServer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AltServer.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BF45868F229872EA00BD7491 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - BF458693229872EA00BD7491 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - BF458696229872EA00BD7491 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - BF458698229872EA00BD7491 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - BF458699229872EA00BD7491 /* AltServer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltServer.entitlements; sourceTree = ""; }; - BF4586C22298CDB800BD7491 /* AltServer-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AltServer-Bridging-Header.h"; sourceTree = ""; }; - BF4586C32298CDB800BD7491 /* ALTDeviceManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTDeviceManager.h; sourceTree = ""; }; - BF4586C42298CDB800BD7491 /* ALTDeviceManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ALTDeviceManager.mm; sourceTree = ""; }; BF45872B2298D31600BD7491 /* libimobiledevice.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libimobiledevice.a; sourceTree = BUILT_PRODUCTS_DIR; }; BF4587C82298D3A800BD7491 /* service.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = service.h; path = Dependencies/libimobiledevice/src/service.h; sourceTree = SOURCE_ROOT; }; BF4587C92298D3A800BD7491 /* diagnostics_relay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = diagnostics_relay.c; path = Dependencies/libimobiledevice/src/diagnostics_relay.c; sourceTree = SOURCE_ROOT; }; @@ -690,7 +567,6 @@ BF4588492298D55000BD7491 /* thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = thread.h; path = Dependencies/libusbmuxd/common/thread.h; sourceTree = SOURCE_ROOT; }; BF4588872298DD3F00BD7491 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib/libxml2.tbd; sourceTree = DEVELOPER_DIR; }; BF4B78FD24B3D1DB008AB4AC /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - BF541C0A25E5A5FA00CD46B2 /* FileManager+URLs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+URLs.swift"; sourceTree = ""; }; BF56D2AB23DF8E170006506D /* FetchAppIDsOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchAppIDsOperation.swift; sourceTree = ""; }; BF56D2AE23DF9E310006506D /* AppIDsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIDsViewController.swift; sourceTree = ""; }; BF58047B246A28F7008AE704 /* AltBackup.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AltBackup.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -702,10 +578,6 @@ BF580495246A3CB5008AE704 /* UIColor+AltBackup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+AltBackup.swift"; sourceTree = ""; }; BF580497246A3D19008AE704 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; BF580499246A4153008AE704 /* AltBackup.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltBackup.entitlements; sourceTree = ""; }; - BF5C5FC5237DF5AE00EDD0C6 /* AltPlugin.mailbundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AltPlugin.mailbundle; sourceTree = BUILT_PRODUCTS_DIR; }; - BF5C5FC7237DF5AE00EDD0C6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - BF5C5FCD237DF69100EDD0C6 /* ALTPluginService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTPluginService.h; sourceTree = ""; }; - BF5C5FCE237DF69100EDD0C6 /* ALTPluginService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALTPluginService.m; sourceTree = ""; }; BF663C4E2433ED8200DAA738 /* FileManager+DirectorySize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+DirectorySize.swift"; sourceTree = ""; }; BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AltStoreCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BF66EE802501AE50007EE018 /* AltStoreCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AltStoreCore.h; sourceTree = ""; }; @@ -766,12 +638,6 @@ BF6F439123644C6E00A0B879 /* RefreshAltStoreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshAltStoreViewController.swift; sourceTree = ""; }; BF718BC723C919CC00A89F2D /* CFNotificationName+AltStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CFNotificationName+AltStore.h"; sourceTree = ""; }; BF718BC823C919E300A89F2D /* CFNotificationName+AltStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CFNotificationName+AltStore.m"; sourceTree = ""; }; - BF718BCF23C91BD300A89F2D /* ALTWiredConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTWiredConnection.h; sourceTree = ""; }; - BF718BD023C91BD300A89F2D /* ALTWiredConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ALTWiredConnection.mm; sourceTree = ""; }; - BF718BD223C91C7000A89F2D /* ALTWiredConnection+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ALTWiredConnection+Private.h"; sourceTree = ""; }; - BF718BD323C928A300A89F2D /* ALTNotificationConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTNotificationConnection.h; sourceTree = ""; }; - BF718BD423C928A300A89F2D /* ALTNotificationConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ALTNotificationConnection.mm; sourceTree = ""; }; - BF718BD623C92B3700A89F2D /* ALTNotificationConnection+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ALTNotificationConnection+Private.h"; sourceTree = ""; }; BF718BD723C93DB700A89F2D /* ALTConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALTConstants.m; sourceTree = ""; }; BF74989A23621C0700CED65F /* ForwardingNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardingNavigationController.swift; sourceTree = ""; }; BF770E5022BB1CF6002A40FE /* InstallAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallAppOperation.swift; sourceTree = ""; }; @@ -779,9 +645,6 @@ BF770E5722BC3D0F002A40FE /* RefreshGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshGroup.swift; sourceTree = ""; }; BF770E6622BD57C3002A40FE /* BackgroundTaskManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundTaskManager.swift; sourceTree = ""; }; BF770E6822BD57DD002A40FE /* Silence.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = Silence.m4a; sourceTree = ""; }; - BF77A66E25795A5600BFE477 /* AltXPC-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AltXPC-Bridging-Header.h"; sourceTree = ""; }; - BF77A66F25795A5600BFE477 /* AltXPC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltXPC.swift; sourceTree = ""; }; - BF77A67D25795BBE00BFE477 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; BF88F97124F8727D00BB75DF /* AppManagerErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppManagerErrors.swift; sourceTree = ""; }; BF8B17F0250AC62400F8157F /* AltWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltWidgetExtension.entitlements; sourceTree = ""; }; BF8CAE422489E772004D6CCE /* AnisetteDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnisetteDataManager.swift; sourceTree = ""; }; @@ -790,7 +653,6 @@ BF8CAE4D248AEABA004D6CCE /* UIDevice+Jailbreak.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+Jailbreak.swift"; sourceTree = ""; }; BF8F69C122E659F700049BA1 /* AppContentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppContentViewController.swift; sourceTree = ""; }; BF8F69C322E662D300049BA1 /* AppViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppViewController.swift; sourceTree = ""; }; - BF904DE9265DAE9A00E86C2A /* InstalledApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledApp.swift; sourceTree = ""; }; BF989167250AABF3002ACF50 /* AltWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = AltWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; BF989170250AABF4002ACF50 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; BF989172250AABF4002ACF50 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -804,27 +666,19 @@ BF9ABA4A22DD137F008935CF /* NavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationBar.swift; sourceTree = ""; }; BF9ABA4C22DD16DE008935CF /* PillButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillButton.swift; sourceTree = ""; }; BFA8172A23C5633D001B5953 /* FetchAnisetteDataOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchAnisetteDataOperation.swift; sourceTree = ""; }; - BFAD678C25E0649500D4C4D1 /* ALTDebugConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTDebugConnection.h; sourceTree = ""; }; - BFAD678D25E0649500D4C4D1 /* ALTDebugConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ALTDebugConnection.mm; sourceTree = ""; }; - BFAD679525E064D400D4C4D1 /* ALTDebugConnection+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ALTDebugConnection+Private.h"; sourceTree = ""; }; - BFAD67A225E0854500D4C4D1 /* DeveloperDiskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperDiskManager.swift; sourceTree = ""; }; BFB1169C22932DB100BB457C /* apps.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = apps.json; sourceTree = ""; }; BFB39B5B252BC10E00D1BE50 /* Managed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Managed.swift; sourceTree = ""; }; BFB4323E22DE852000B7F8BC /* UpdateCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UpdateCollectionViewCell.xib; sourceTree = ""; }; - BFB49AA823834CF900D542D9 /* ALTAnisetteData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ALTAnisetteData.m; path = "Dependencies/AltSign/AltSign/Model/Apple API/ALTAnisetteData.m"; sourceTree = SOURCE_ROOT; }; - BFB49AA923834CF900D542D9 /* ALTAnisetteData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ALTAnisetteData.h; path = "Dependencies/AltSign/AltSign/Model/Apple API/ALTAnisetteData.h"; sourceTree = SOURCE_ROOT; }; BFB6B21D231870160022A802 /* NewsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsViewController.swift; sourceTree = ""; }; BFB6B21F231870B00022A802 /* NewsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsCollectionViewCell.swift; sourceTree = ""; }; BFB6B22323187A3D0022A802 /* NewsCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NewsCollectionViewCell.xib; sourceTree = ""; }; BFBAC8852295C90300587369 /* Result+Conveniences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Result+Conveniences.swift"; sourceTree = ""; }; BFBF33142526754700B7B8C9 /* AltStore 9.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AltStore 9.xcdatamodel"; sourceTree = ""; }; BFBF331A2526762200B7B8C9 /* AltStore8ToAltStore9.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore8ToAltStore9.xcmappingmodel; sourceTree = ""; }; - BFC15AD927BC352300ED2FB4 /* PluginVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginVersion.swift; sourceTree = ""; }; BFC1F38C22AEE3A4003AC21A /* DownloadAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadAppOperation.swift; sourceTree = ""; }; BFC57A642416C72400EB891E /* DeactivateAppOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeactivateAppOperation.swift; sourceTree = ""; }; BFC57A6D2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledAppsCollectionHeaderView.swift; sourceTree = ""; }; BFC57A6F2416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InstalledAppsCollectionHeaderView.xib; sourceTree = ""; }; - BFC712BA2512B9CF00AB5EBE /* PluginManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginManager.swift; sourceTree = ""; }; BFC712C12512D5F100AB5EBE /* XPCConnection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XPCConnection.swift; sourceTree = ""; }; BFC712C22512D5F100AB5EBE /* XPCConnectionHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XPCConnectionHandler.swift; sourceTree = ""; }; BFC84A4C2421A19100853474 /* SourcesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourcesViewController.swift; sourceTree = ""; }; @@ -884,8 +738,6 @@ BFE00A1F2503097F00EB4D0C /* INInteraction+AltStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "INInteraction+AltStore.swift"; sourceTree = ""; }; BFE338DE22F0EADB002E24B9 /* FetchSourceOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchSourceOperation.swift; sourceTree = ""; }; BFE338E722F10E56002E24B9 /* LaunchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchViewController.swift; sourceTree = ""; }; - BFE48974238007CE003239E0 /* AnisetteDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnisetteDataManager.swift; sourceTree = ""; }; - BFE4FFB5251BF7BA0018CF9B /* AltPlugin.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = AltPlugin.zip; sourceTree = ""; }; BFE60737231ADF49002B0E8E /* Settings.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = ""; }; BFE60739231ADF82002B0E8E /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; BFE6073B231AE1E7002B0E8E /* SettingsHeaderFooterView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SettingsHeaderFooterView.xib; sourceTree = ""; }; @@ -893,12 +745,9 @@ BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeaderFooterView.swift; sourceTree = ""; }; BFE6325922A83BEB00F30809 /* Authentication.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Authentication.storyboard; sourceTree = ""; }; BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationOperation.swift; sourceTree = ""; }; - BFE972E1260A8B2700D0BDAC /* NSError+libimobiledevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+libimobiledevice.h"; sourceTree = ""; }; - BFE972E2260A8B2700D0BDAC /* NSError+libimobiledevice.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSError+libimobiledevice.mm"; sourceTree = ""; }; BFF00D2F2501BD7D00746320 /* Intents.intentdefinition */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.intentdefinition; path = Intents.intentdefinition; sourceTree = ""; }; BFF00D312501BDA100746320 /* BackgroundRefreshAppsOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundRefreshAppsOperation.swift; sourceTree = ""; }; BFF00D332501BDCF00746320 /* IntentHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = ""; }; - BFF0394A25F0551600BE607D /* MenuController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuController.swift; sourceTree = ""; }; BFF0B68D23219520007A79E1 /* PatreonViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatreonViewController.swift; sourceTree = ""; }; BFF0B68F23219C6D007A79E1 /* PatreonComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatreonComponents.swift; sourceTree = ""; }; BFF0B6912321A305007A79E1 /* AboutPatreonHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AboutPatreonHeaderView.xib; sourceTree = ""; }; @@ -907,13 +756,9 @@ BFF0B6972322CAB8007A79E1 /* InstructionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstructionsViewController.swift; sourceTree = ""; }; BFF0B6992322D7D0007A79E1 /* UIScreen+CompactHeight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScreen+CompactHeight.swift"; sourceTree = ""; }; BFF435D7255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ALTApplication+AltStoreApp.swift"; sourceTree = ""; }; - BFF767C72489A74E0097E58C /* WirelessConnectionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WirelessConnectionHandler.swift; sourceTree = ""; }; BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ALTServerError+Conveniences.swift"; sourceTree = ""; }; BFF767CD2489ABE90097E58C /* NetworkConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConnection.swift; sourceTree = ""; }; - BFF7C904257844C900E55F36 /* AltXPC.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = AltXPC.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; BFF7C906257844C900E55F36 /* AltXPCProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AltXPCProtocol.h; sourceTree = ""; }; - BFF7C90C257844C900E55F36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - BFF7C93B257849C600E55F36 /* AltXPC.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltXPC.entitlements; sourceTree = ""; }; BFF7EC4C25081E9300BDE521 /* AltStore 8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AltStore 8.xcdatamodel"; sourceTree = ""; }; BFFCFA45248835530077BFCE /* AltDaemon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltDaemon.entitlements; sourceTree = ""; }; D504F42528AD72C50014BB5D /* ProgressRing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressRing.swift; sourceTree = ""; }; @@ -969,18 +814,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BF4588462298D4AA00BD7491 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D58D5F2E26DFE68E00E55E38 /* LaunchAtLogin in Frameworks */, - B3C395FF284F3C0900DA9E2F /* STPrivilegedTask in Frameworks */, - BF4588882298DD3F00BD7491 /* libxml2.tbd in Frameworks */, - B3C395FC284F3B2400DA9E2F /* Sparkle in Frameworks */, - BF4588472298D4B000BD7491 /* libimobiledevice.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; BF580478246A28F7008AE704 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -989,13 +822,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BF5C5FC2237DF5AE00EDD0C6 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; BF66EE7B2501AE50007EE018 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1035,13 +861,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BFF7C901257844C900E55F36 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -1098,15 +917,6 @@ path = Consts; sourceTree = ""; }; - BF055B4A233B528B0086DEA9 /* Extensions */ = { - isa = PBXGroup; - children = ( - BF0241A922F29CCD00129732 /* UserDefaults+AltServer.swift */, - BF541C0A25E5A5FA00CD46B2 /* FileManager+URLs.swift */, - ); - path = Extensions; - sourceTree = ""; - }; BF0DCA642433BDE200E3A595 /* Analytics */ = { isa = PBXGroup; children = ( @@ -1173,26 +983,6 @@ path = "App Detail"; sourceTree = ""; }; - BF45868E229872EA00BD7491 /* AltServer */ = { - isa = PBXGroup; - children = ( - BF45868F229872EA00BD7491 /* AppDelegate.swift */, - BF458695229872EA00BD7491 /* Main.storyboard */, - BFE48974238007CE003239E0 /* AnisetteDataManager.swift */, - BFAD67A225E0854500D4C4D1 /* DeveloperDiskManager.swift */, - BFF0394A25F0551600BE607D /* MenuController.swift */, - BF904DE9265DAE9A00E86C2A /* InstalledApp.swift */, - BFC15ADB27BC3AD100ED2FB4 /* Plugin */, - BF703195229F36FF006E110F /* Devices */, - BFD52BDC22A0A659000B7ED1 /* Connections */, - BF055B4A233B528B0086DEA9 /* Extensions */, - BFE972E0260A8B0700D0BDAC /* Categories */, - BF703194229F36F6006E110F /* Resources */, - BF703196229F370F006E110F /* Supporting Files */, - ); - path = AltServer; - sourceTree = ""; - }; BF45872C2298D31600BD7491 /* libimobiledevice */ = { isa = PBXGroup; children = ( @@ -1361,18 +1151,6 @@ path = AltBackup; sourceTree = ""; }; - BF5C5FC6237DF5AE00EDD0C6 /* AltPlugin */ = { - isa = PBXGroup; - children = ( - BF5C5FCD237DF69100EDD0C6 /* ALTPluginService.h */, - BF5C5FCE237DF69100EDD0C6 /* ALTPluginService.m */, - BFB49AA923834CF900D542D9 /* ALTAnisetteData.h */, - BFB49AA823834CF900D542D9 /* ALTAnisetteData.m */, - BF5C5FC7237DF5AE00EDD0C6 /* Info.plist */, - ); - path = AltPlugin; - sourceTree = ""; - }; BF66EE7F2501AE50007EE018 /* AltStoreCore */ = { isa = PBXGroup; children = ( @@ -1520,35 +1298,6 @@ name = MarkdownAttributedString; sourceTree = ""; }; - BF703194229F36F6006E110F /* Resources */ = { - isa = PBXGroup; - children = ( - BFE4FFB5251BF7BA0018CF9B /* AltPlugin.zip */, - BF458693229872EA00BD7491 /* Assets.xcassets */, - ); - name = Resources; - sourceTree = ""; - }; - BF703195229F36FF006E110F /* Devices */ = { - isa = PBXGroup; - children = ( - BF4586C32298CDB800BD7491 /* ALTDeviceManager.h */, - BF4586C42298CDB800BD7491 /* ALTDeviceManager.mm */, - BF3F786322CAA41E008FBD20 /* ALTDeviceManager+Installation.swift */, - ); - path = Devices; - sourceTree = ""; - }; - BF703196229F370F006E110F /* Supporting Files */ = { - isa = PBXGroup; - children = ( - BF458698229872EA00BD7491 /* Info.plist */, - BF458699229872EA00BD7491 /* AltServer.entitlements */, - BF4586C22298CDB800BD7491 /* AltServer-Bridging-Header.h */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; BF7B44062725A4B8005288A4 /* Patch App */ = { isa = PBXGroup; children = ( @@ -1622,15 +1371,6 @@ path = "My Apps"; sourceTree = ""; }; - BFC15ADB27BC3AD100ED2FB4 /* Plugin */ = { - isa = PBXGroup; - children = ( - BFC15AD927BC352300ED2FB4 /* PluginVersion.swift */, - BFC712BA2512B9CF00AB5EBE /* PluginManager.swift */, - ); - path = Plugin; - sourceTree = ""; - }; BFC84A4B2421A13000853474 /* Sources */ = { isa = PBXGroup; children = ( @@ -1655,20 +1395,15 @@ B3C39608284F4C8400DA9E2F /* CodeSigning.xcconfig.sample */, B3C3960B284F4C9800DA9E2F /* AltStore.xcconfig */, B3C3960F284F53E900DA9E2F /* AltBackup.xcconfig */, - B3C39609284F4C9800DA9E2F /* AltServer.xcconfig */, - B3C3960C284F4CDC00DA9E2F /* AltXPC.xcconfig */, B3C3960D284F4E4B00DA9E2F /* AltWidgetExtension.xcconfig */, B3C3960E284F4F9100DA9E2F /* AltStoreCore.xcconfig */, BFD2476C2284B9A500981D42 /* AltStore */, BF66EE7F2501AE50007EE018 /* AltStoreCore */, - BF45868E229872EA00BD7491 /* AltServer */, BF1E315122A0616100370A3C /* Shared */, BF45872C2298D31600BD7491 /* libimobiledevice */, - BF5C5FC6237DF5AE00EDD0C6 /* AltPlugin */, BF58047C246A28F7008AE704 /* AltBackup */, BF18BFE824857D7900DD5981 /* AltDaemon */, BF98916C250AABF3002ACF50 /* AltWidget */, - BFF7C905257844C900E55F36 /* AltXPC */, 19104DB32909C06D00C49C7B /* EmotionalDamage */, 191E5FAC290A5D92001A3B7C /* minimuxer */, BFD247852284BB3300981D42 /* Frameworks */, @@ -1681,14 +1416,11 @@ isa = PBXGroup; children = ( BFD2476A2284B9A500981D42 /* SideStore.app */, - BF45868D229872EA00BD7491 /* AltServer.app */, BF45872B2298D31600BD7491 /* libimobiledevice.a */, - BF5C5FC5237DF5AE00EDD0C6 /* AltPlugin.mailbundle */, BF58047B246A28F7008AE704 /* AltBackup.app */, BF18BFE724857D7900DD5981 /* AltDaemon */, BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */, BF989167250AABF3002ACF50 /* AltWidgetExtension.appex */, - BFF7C904257844C900E55F36 /* AltXPC.xpc */, 19104DB22909C06C00C49C7B /* libEmotionalDamage.a */, 191E5FAB290A5D92001A3B7C /* libminimuxer.a */, ); @@ -1804,25 +1536,6 @@ path = Extensions; sourceTree = ""; }; - BFD52BDC22A0A659000B7ED1 /* Connections */ = { - isa = PBXGroup; - children = ( - BF1E3129229F474900370A3C /* RequestHandler.swift */, - BFF767C72489A74E0097E58C /* WirelessConnectionHandler.swift */, - BF18BFFC2485A1E400DD5981 /* WiredConnectionHandler.swift */, - BF718BCF23C91BD300A89F2D /* ALTWiredConnection.h */, - BF718BD223C91C7000A89F2D /* ALTWiredConnection+Private.h */, - BF718BD023C91BD300A89F2D /* ALTWiredConnection.mm */, - BF718BD323C928A300A89F2D /* ALTNotificationConnection.h */, - BF718BD623C92B3700A89F2D /* ALTNotificationConnection+Private.h */, - BF718BD423C928A300A89F2D /* ALTNotificationConnection.mm */, - BFAD678C25E0649500D4C4D1 /* ALTDebugConnection.h */, - BFAD679525E064D400D4C4D1 /* ALTDebugConnection+Private.h */, - BFAD678D25E0649500D4C4D1 /* ALTDebugConnection.mm */, - ); - path = Connections; - sourceTree = ""; - }; BFDB69FB22A9A7A6007EA6D6 /* Settings */ = { isa = PBXGroup; children = ( @@ -1884,15 +1597,6 @@ path = Authentication; sourceTree = ""; }; - BFE972E0260A8B0700D0BDAC /* Categories */ = { - isa = PBXGroup; - children = ( - BFE972E1260A8B2700D0BDAC /* NSError+libimobiledevice.h */, - BFE972E2260A8B2700D0BDAC /* NSError+libimobiledevice.mm */, - ); - path = Categories; - sourceTree = ""; - }; BFF00D2E2501BD4B00746320 /* Intents */ = { isa = PBXGroup; children = ( @@ -1938,18 +1642,6 @@ path = Connections; sourceTree = ""; }; - BFF7C905257844C900E55F36 /* AltXPC */ = { - isa = PBXGroup; - children = ( - BFF7C93B257849C600E55F36 /* AltXPC.entitlements */, - BF77A67D25795BBE00BFE477 /* main.swift */, - BF77A66F25795A5600BFE477 /* AltXPC.swift */, - BF77A66E25795A5600BFE477 /* AltXPC-Bridging-Header.h */, - BFF7C90C257844C900E55F36 /* Info.plist */, - ); - path = AltXPC; - sourceTree = ""; - }; BFF7C92D2578464D00E55F36 /* XPC */ = { isa = PBXGroup; children = ( @@ -2036,7 +1728,6 @@ buildPhases = ( 19104DAE2909C06C00C49C7B /* Sources */, 19104DAF2909C06C00C49C7B /* Frameworks */, - 19104DB02909C06C00C49C7B /* CopyFiles */, ); buildRules = ( ); @@ -2054,7 +1745,6 @@ 191E5FD4290A6EE0001A3B7C /* Headers */, 191E5FA7290A5D92001A3B7C /* Sources */, 191E5FA8290A5D92001A3B7C /* Frameworks */, - 191E5FA9290A5D92001A3B7C /* CopyFiles */, ); buildRules = ( ); @@ -2083,32 +1773,6 @@ productReference = BF18BFE724857D7900DD5981 /* AltDaemon */; productType = "com.apple.product-type.library.dynamic"; }; - BF45868C229872EA00BD7491 /* AltServer */ = { - isa = PBXNativeTarget; - buildConfigurationList = BF45869A229872EA00BD7491 /* Build configuration list for PBXNativeTarget "AltServer" */; - buildPhases = ( - BF458689229872EA00BD7491 /* Sources */, - BF45868B229872EA00BD7491 /* Resources */, - BF4588462298D4AA00BD7491 /* Frameworks */, - BF0201BC22C2EFA3000B93E4 /* Embed Frameworks */, - BFF7C910257844C900E55F36 /* Embed XPC Services */, - ); - buildRules = ( - ); - dependencies = ( - BF4588452298D48B00BD7491 /* PBXTargetDependency */, - BFF7C90E257844C900E55F36 /* PBXTargetDependency */, - ); - name = AltServer; - packageProductDependencies = ( - D58D5F2D26DFE68E00E55E38 /* LaunchAtLogin */, - B3C395FB284F3B2400DA9E2F /* Sparkle */, - B3C395FE284F3C0900DA9E2F /* STPrivilegedTask */, - ); - productName = AltServer; - productReference = BF45868D229872EA00BD7491 /* AltServer.app */; - productType = "com.apple.product-type.application"; - }; BF45872A2298D31600BD7491 /* libimobiledevice */ = { isa = PBXNativeTarget; buildConfigurationList = BF4587332298D31600BD7491 /* Build configuration list for PBXNativeTarget "libimobiledevice" */; @@ -2147,24 +1811,6 @@ productReference = BF58047B246A28F7008AE704 /* AltBackup.app */; productType = "com.apple.product-type.application"; }; - BF5C5FC4237DF5AE00EDD0C6 /* AltPlugin */ = { - isa = PBXNativeTarget; - buildConfigurationList = BF5C5FC8237DF5AE00EDD0C6 /* Build configuration list for PBXNativeTarget "AltPlugin" */; - buildPhases = ( - BF5C5FC1237DF5AE00EDD0C6 /* Sources */, - BF5C5FC2237DF5AE00EDD0C6 /* Frameworks */, - BF5C5FC3237DF5AE00EDD0C6 /* Resources */, - BF5C5FE9237E438C00EDD0C6 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = AltPlugin; - productName = AltPlugin; - productReference = BF5C5FC5237DF5AE00EDD0C6 /* AltPlugin.mailbundle */; - productType = "com.apple.product-type.bundle"; - }; BF66EE7D2501AE50007EE018 /* AltStoreCore */ = { isa = PBXNativeTarget; buildConfigurationList = BF66EE892501AE50007EE018 /* Build configuration list for PBXNativeTarget "AltStoreCore" */; @@ -2235,23 +1881,6 @@ productReference = BFD2476A2284B9A500981D42 /* SideStore.app */; productType = "com.apple.product-type.application"; }; - BFF7C903257844C900E55F36 /* AltXPC */ = { - isa = PBXNativeTarget; - buildConfigurationList = BFF7C913257844C900E55F36 /* Build configuration list for PBXNativeTarget "AltXPC" */; - buildPhases = ( - BFF7C900257844C900E55F36 /* Sources */, - BFF7C901257844C900E55F36 /* Frameworks */, - BFF7C902257844C900E55F36 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = AltXPC; - productName = AltXPC; - productReference = BFF7C904257844C900E55F36 /* AltXPC.xpc */; - productType = "com.apple.product-type.xpc-service"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -2272,28 +1901,12 @@ CreatedOnToolsVersion = 11.5; LastSwiftMigration = 1150; }; - BF45868C229872EA00BD7491 = { - CreatedOnToolsVersion = 10.2.1; - LastSwiftMigration = 1020; - SystemCapabilities = { - com.apple.HardenedRuntime = { - enabled = 1; - }; - com.apple.Sandbox = { - enabled = 0; - }; - }; - }; BF45872A2298D31600BD7491 = { CreatedOnToolsVersion = 10.2.1; }; BF58047A246A28F7008AE704 = { CreatedOnToolsVersion = 11.4.1; }; - BF5C5FC4237DF5AE00EDD0C6 = { - CreatedOnToolsVersion = 11.2; - LastSwiftMigration = 1120; - }; BF66EE7D2501AE50007EE018 = { CreatedOnToolsVersion = 12.0; }; @@ -2313,10 +1926,6 @@ }; }; }; - BFF7C903257844C900E55F36 = { - CreatedOnToolsVersion = 12.3; - LastSwiftMigration = 1230; - }; }; }; buildConfigurationList = BFD247652284B9A500981D42 /* Build configuration list for PBXProject "AltStore" */; @@ -2349,14 +1958,11 @@ projectRoot = ""; targets = ( BFD247692284B9A500981D42 /* SideStore */, - BF45868C229872EA00BD7491 /* AltServer */, BF45872A2298D31600BD7491 /* libimobiledevice */, - BF5C5FC4237DF5AE00EDD0C6 /* AltPlugin */, BF58047A246A28F7008AE704 /* AltBackup */, BF18BFE624857D7900DD5981 /* AltDaemon */, BF66EE7D2501AE50007EE018 /* AltStoreCore */, BF989166250AABF3002ACF50 /* AltWidgetExtension */, - BFF7C903257844C900E55F36 /* AltXPC */, 19104DB12909C06C00C49C7B /* EmotionalDamage */, 191E5FAA290A5D92001A3B7C /* minimuxer */, ); @@ -2388,16 +1994,6 @@ /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ - BF45868B229872EA00BD7491 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - BFE4FFB6251BF7BA0018CF9B /* AltPlugin.zip in Resources */, - BF458694229872EA00BD7491 /* Assets.xcassets in Resources */, - BF458697229872EA00BD7491 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; BF580479246A28F7008AE704 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2407,13 +2003,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BF5C5FC3237DF5AE00EDD0C6 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; BF66EE7C2501AE50007EE018 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2453,13 +2042,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BFF7C902257844C900E55F36 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -2503,44 +2085,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BF458689229872EA00BD7491 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - BFF767C82489A74E0097E58C /* WirelessConnectionHandler.swift in Sources */, - BFF0394B25F0551600BE607D /* MenuController.swift in Sources */, - BFECAC8024FD950B0077C41F /* ConnectionManager.swift in Sources */, - BFC15ADA27BC352300ED2FB4 /* PluginVersion.swift in Sources */, - BFECAC8324FD950B0077C41F /* NetworkConnection.swift in Sources */, - BF541C0B25E5A5FA00CD46B2 /* FileManager+URLs.swift in Sources */, - BFECAC8724FD950B0077C41F /* Bundle+AltStore.swift in Sources */, - BF3F786422CAA41E008FBD20 /* ALTDeviceManager+Installation.swift in Sources */, - BF18BFFD2485A1E400DD5981 /* WiredConnectionHandler.swift in Sources */, - BFC712BB2512B9CF00AB5EBE /* PluginManager.swift in Sources */, - BFECAC8224FD950B0077C41F /* ServerProtocol.swift in Sources */, - BFECAC8124FD950B0077C41F /* ALTServerError+Conveniences.swift in Sources */, - BFECAC7F24FD950B0077C41F /* CodableServerError.swift in Sources */, - BFECAC8624FD950B0077C41F /* Result+Conveniences.swift in Sources */, - BF265D1925F843A000080DC9 /* NSError+AltStore.swift in Sources */, - BF904DEA265DAE9A00E86C2A /* InstalledApp.swift in Sources */, - BFF435D9255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift in Sources */, - BF718BD523C928A300A89F2D /* ALTNotificationConnection.mm in Sources */, - BF1E312B229F474900370A3C /* RequestHandler.swift in Sources */, - BF718BD123C91BD300A89F2D /* ALTWiredConnection.mm in Sources */, - BFAD678E25E0649500D4C4D1 /* ALTDebugConnection.mm in Sources */, - BFECAC8524FD950B0077C41F /* Connection.swift in Sources */, - BF458690229872EA00BD7491 /* AppDelegate.swift in Sources */, - BFECAC8424FD950B0077C41F /* ALTConstants.m in Sources */, - BF4586C52298CDB800BD7491 /* ALTDeviceManager.mm in Sources */, - BF0241AA22F29CCD00129732 /* UserDefaults+AltServer.swift in Sources */, - BFECAC9424FD98BA0077C41F /* NSError+ALTServerError.m in Sources */, - BFAD67A325E0854500D4C4D1 /* DeveloperDiskManager.swift in Sources */, - BFECAC9324FD98BA0077C41F /* CFNotificationName+AltStore.m in Sources */, - BFE48975238007CE003239E0 /* AnisetteDataManager.swift in Sources */, - BFE972E3260A8B2700D0BDAC /* NSError+libimobiledevice.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; BF4587282298D31600BD7491 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2623,15 +2167,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BF5C5FC1237DF5AE00EDD0C6 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - BFB49AAA23834CF900D542D9 /* ALTAnisetteData.m in Sources */, - BF5C5FCF237DF69100EDD0C6 /* ALTPluginService.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; BF66EE7A2501AE50007EE018 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2705,7 +2240,7 @@ BF42345A25101C35006D1EB2 /* WidgetView.swift in Sources */, D55E163728776CB700A627A1 /* ComplicationView.swift in Sources */, BF98917F250AAC4F002ACF50 /* AltWidget.swift in Sources */, - D504F42628AD72C50014BB5D /* ProgressRing.swift in Sources */, + B3919A52292DBE5400519575 /* ProgressRing.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2805,17 +2340,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BFF7C900257844C900E55F36 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - BFF7C9342578492100E55F36 /* ALTAnisetteData.m in Sources */, - BFF7C920257844FA00E55F36 /* ALTPluginService.m in Sources */, - BF77A67E25795BBE00BFE477 /* main.swift in Sources */, - BF77A67025795A5600BFE477 /* AltXPC.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -2838,11 +2362,6 @@ isa = PBXTargetDependency; productRef = 191E5FD9290AFA49001A3B7C /* OpenSSL */; }; - BF4588452298D48B00BD7491 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = BF45872A2298D31600BD7491 /* libimobiledevice */; - targetProxy = BF4588442298D48B00BD7491 /* PBXContainerItemProxy */; - }; BF66EE842501AE50007EE018 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = BF66EE7D2501AE50007EE018 /* AltStoreCore */; @@ -2858,22 +2377,9 @@ target = BF66EE7D2501AE50007EE018 /* AltStoreCore */; targetProxy = BFF615AA2510042B00484D3B /* PBXContainerItemProxy */; }; - BFF7C90E257844C900E55F36 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = BFF7C903257844C900E55F36 /* AltXPC */; - targetProxy = BFF7C90D257844C900E55F36 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - BF458695229872EA00BD7491 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - BF458696229872EA00BD7491 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; BF580488246A28F9008AE704 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -3088,105 +2594,6 @@ }; name = Release; }; - BF45869B229872EA00BD7491 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B3C39609284F4C9800DA9E2F /* AltServer.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = AltServer/AltServer.entitlements; - CODE_SIGN_IDENTITY = "Mac Developer"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 66; - DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)"; - ENABLE_HARDENED_RUNTIME = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - HAVE_OPENSSL, - HAVE_STPNCPY, - HAVE_STPCPY, - HAVE_VASPRINTF, - HAVE_ASPRINTF, - "\"PACKAGE_STRING=\\\"AltServer 1.0\\\"\"", - ); - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/ldid/libplist/include\"", - "\"$(SRCROOT)/Dependencies/libimobiledevice\"", - "\"$(SRCROOT)/Dependencies/libimobiledevice/include\"", - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/OpenSSL/macos/include\"", - "\"$(SRCROOT)/Dependencies/libusbmuxd/include\"", - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/libzip/lib\"", - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/ldid/libplist/libcnary/include\"", - "\"${SDKROOT}/usr/include/libxml2\"", - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/libzip/xcode\"", - ); - INFOPLIST_FILE = AltServer/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14.4; - MARKETING_VERSION = 0.1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltServer; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SUPPORTED_PLATFORMS = macosx; - SWIFT_OBJC_BRIDGING_HEADER = "AltServer/AltServer-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - BF45869C229872EA00BD7491 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B3C39609284F4C9800DA9E2F /* AltServer.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = AltServer/AltServer.entitlements; - CODE_SIGN_IDENTITY = "Mac Developer"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 66; - DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)"; - ENABLE_HARDENED_RUNTIME = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - HAVE_OPENSSL, - HAVE_STPNCPY, - HAVE_STPCPY, - HAVE_VASPRINTF, - HAVE_ASPRINTF, - "\"PACKAGE_STRING=\\\"AltServer 1.0\\\"\"", - ); - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/ldid/libplist/include\"", - "\"$(SRCROOT)/Dependencies/libimobiledevice\"", - "\"$(SRCROOT)/Dependencies/libimobiledevice/include\"", - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/OpenSSL/macos/include\"", - "\"$(SRCROOT)/Dependencies/libusbmuxd/include\"", - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/libzip/lib\"", - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/ldid/libplist/libcnary/include\"", - "\"${SDKROOT}/usr/include/libxml2\"", - "\"$(SRCROOT)/Dependencies/AltSign/Dependencies/libzip/xcode\"", - ); - INFOPLIST_FILE = AltServer/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14.4; - MARKETING_VERSION = 0.1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltServer; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SUPPORTED_PLATFORMS = macosx; - SWIFT_OBJC_BRIDGING_HEADER = "AltServer/AltServer-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; BF4587342298D31600BD7491 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3310,67 +2717,6 @@ }; name = Release; }; - BF5C5FC9237DF5AE00EDD0C6 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 11; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = AltPlugin/Info.plist; - INSTALL_PATH = "$(HOME)/Library/Mail/Bundles/"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - "/Users/Riley/Library/Developer/Xcode/DerivedData/AltStore-bhqnkrahfutztzeudtxhcxccgtlo/Build/Products/Debug", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = 1.10; - PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltPlugin; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SKIP_INSTALL = NO; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - WRAPPER_EXTENSION = mailbundle; - }; - name = Debug; - }; - BF5C5FCA237DF5AE00EDD0C6 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 11; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = AltPlugin/Info.plist; - INSTALL_PATH = "$(HOME)/Library/Mail/Bundles/"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - "/Users/Riley/Library/Developer/Xcode/DerivedData/AltStore-bhqnkrahfutztzeudtxhcxccgtlo/Build/Products/Debug", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = 1.10; - PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltPlugin; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SKIP_INSTALL = NO; - SWIFT_VERSION = 5.0; - WRAPPER_EXTENSION = mailbundle; - }; - name = Release; - }; BF66EE872501AE50007EE018 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = B3C3960E284F4F9100DA9E2F /* AltStoreCore.xcconfig */; @@ -3708,66 +3054,6 @@ }; name = Release; }; - BFF7C911257844C900E55F36 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B3C3960C284F4CDC00DA9E2F /* AltXPC.xcconfig */; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CODE_SIGN_ENTITLEMENTS = AltXPC/AltXPC.entitlements; - CODE_SIGN_IDENTITY = "Mac Developer"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)"; - ENABLE_HARDENED_RUNTIME = YES; - INFOPLIST_FILE = AltXPC/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14.4; - PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltXPC; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_OBJC_BRIDGING_HEADER = "AltXPC/AltXPC-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - BFF7C912257844C900E55F36 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B3C3960C284F4CDC00DA9E2F /* AltXPC.xcconfig */; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CODE_SIGN_ENTITLEMENTS = AltXPC/AltXPC.entitlements; - CODE_SIGN_IDENTITY = "Mac Developer"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)"; - ENABLE_HARDENED_RUNTIME = YES; - INFOPLIST_FILE = AltXPC/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14.4; - PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltXPC; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_OBJC_BRIDGING_HEADER = "AltXPC/AltXPC-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -3798,15 +3084,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - BF45869A229872EA00BD7491 /* Build configuration list for PBXNativeTarget "AltServer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BF45869B229872EA00BD7491 /* Debug */, - BF45869C229872EA00BD7491 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; BF4587332298D31600BD7491 /* Build configuration list for PBXNativeTarget "libimobiledevice" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3825,15 +3102,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - BF5C5FC8237DF5AE00EDD0C6 /* Build configuration list for PBXNativeTarget "AltPlugin" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BF5C5FC9237DF5AE00EDD0C6 /* Debug */, - BF5C5FCA237DF5AE00EDD0C6 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; BF66EE892501AE50007EE018 /* Build configuration list for PBXNativeTarget "AltStoreCore" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3870,15 +3138,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - BFF7C913257844C900E55F36 /* Build configuration list for PBXNativeTarget "AltXPC" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BFF7C911257844C900E55F36 /* Debug */, - BFF7C912257844C900E55F36 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -3989,21 +3248,6 @@ package = B3C395F5284F362400DA9E2F /* XCRemoteSwiftPackageReference "appcenter-sdk-apple" */; productName = AppCenterCrashes; }; - B3C395FB284F3B2400DA9E2F /* Sparkle */ = { - isa = XCSwiftPackageProductDependency; - package = B3C395FA284F3B2400DA9E2F /* XCRemoteSwiftPackageReference "Sparkle" */; - productName = Sparkle; - }; - B3C395FE284F3C0900DA9E2F /* STPrivilegedTask */ = { - isa = XCSwiftPackageProductDependency; - package = B3C395FD284F3C0900DA9E2F /* XCRemoteSwiftPackageReference "STPrivilegedTask" */; - productName = STPrivilegedTask; - }; - D58D5F2D26DFE68E00E55E38 /* LaunchAtLogin */ = { - isa = XCSwiftPackageProductDependency; - package = D58D5F2C26DFE68E00E55E38 /* XCRemoteSwiftPackageReference "LaunchAtLogin" */; - productName = LaunchAtLogin; - }; /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ diff --git a/AltXPC.xcconfig b/AltXPC.xcconfig deleted file mode 100644 index 7816cc9a..00000000 --- a/AltXPC.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Build.xcconfig" diff --git a/AltXPC/AltXPC-Bridging-Header.h b/AltXPC/AltXPC-Bridging-Header.h deleted file mode 100644 index 8d7fdbf3..00000000 --- a/AltXPC/AltXPC-Bridging-Header.h +++ /dev/null @@ -1,7 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - -#import "ALTAnisetteData.h" -#import "AltXPCProtocol.h" -#import "ALTPluginService.h" diff --git a/AltXPC/AltXPC.entitlements b/AltXPC/AltXPC.entitlements deleted file mode 100644 index 760f348f..00000000 --- a/AltXPC/AltXPC.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.authkit.client.internal - - - diff --git a/AltXPC/AltXPC.swift b/AltXPC/AltXPC.swift deleted file mode 100644 index c91b65d7..00000000 --- a/AltXPC/AltXPC.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// AltXPC.swift -// AltXPC -// -// Created by Riley Testut on 12/3/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation - -@objc(AltXPC) -class AltXPC: NSObject, AltXPCProtocol -{ - func ping(_ completionHandler: @escaping () -> Void) - { - completionHandler() - } - - func requestAnisetteData(completionHandler: @escaping (ALTAnisetteData?, Error?) -> Void) - { - let anisetteData = ALTPluginService.shared.requestAnisetteData() - completionHandler(anisetteData, nil) - } -} diff --git a/AltXPC/Info.plist b/AltXPC/Info.plist deleted file mode 100644 index 5e394254..00000000 --- a/AltXPC/Info.plist +++ /dev/null @@ -1,31 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - AltXPC - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - NSHumanReadableCopyright - Copyright © 2020 Riley Testut. All rights reserved. - XPCService - - ServiceType - Application - - - diff --git a/AltXPC/main.swift b/AltXPC/main.swift deleted file mode 100644 index 42c0ad36..00000000 --- a/AltXPC/main.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// main.swift -// AltXPC -// -// Created by Riley Testut on 12/3/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation - -class ServiceDelegate : NSObject, NSXPCListenerDelegate -{ - func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool - { - newConnection.exportedInterface = NSXPCInterface(with: AltXPCProtocol.self) - - let exportedObject = AltXPC() - newConnection.exportedObject = exportedObject - newConnection.resume() - return true - } -} - -let serviceDelegate = ServiceDelegate() - -let listener = NSXPCListener.service() -listener.delegate = serviceDelegate -listener.resume() - -RunLoop.main.run() -