From 07efd681c10853ee97676b4a48f2799599fc2dda Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Thu, 13 Feb 2020 21:41:31 -0800 Subject: [PATCH] [AltServer] Refactors Mail plug-in installation to fix notarization errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AltServer must now download the Mail plug-in at runtime, because notarization will fail if AltServer contains an unsigned binary (and as of Catalina, Mail plug-ins only work if they’re unsigned) --- AltKit/NSError+ALTServerError.m | 2 +- AltServer/AltPlugin.mailbundle.zip | Bin 10771 -> 0 bytes AltServer/AppDelegate.swift | 357 +++++++++---- AltServer/InstallPlugin.sh | 13 - AltServer/UninstallPlugin.sh | 9 - AltStore.xcodeproj/project.pbxproj | 12 - Podfile | 2 +- Podfile.lock | 16 +- .../STPrivilegedTask.podspec.json | 25 + Pods/Manifest.lock | 16 +- Pods/Pods.xcodeproj/project.pbxproj | 162 +++--- Pods/STPrivilegedTask/LICENSE | 29 + Pods/STPrivilegedTask/LICENSE.txt | 22 - Pods/STPrivilegedTask/README.md | 211 ++++++-- Pods/STPrivilegedTask/STPrivilegedTask.h | 84 ++- Pods/STPrivilegedTask/STPrivilegedTask.m | 496 +++++++----------- .../Pods-AltServer-acknowledgements.markdown | 51 +- .../Pods-AltServer-acknowledgements.plist | 51 +- .../STPrivilegedTask-Info.plist | 2 +- 19 files changed, 870 insertions(+), 690 deletions(-) delete mode 100644 AltServer/AltPlugin.mailbundle.zip delete mode 100644 AltServer/InstallPlugin.sh delete mode 100644 AltServer/UninstallPlugin.sh create mode 100644 Pods/Local Podspecs/STPrivilegedTask.podspec.json create mode 100644 Pods/STPrivilegedTask/LICENSE delete mode 100644 Pods/STPrivilegedTask/LICENSE.txt mode change 100644 => 100755 Pods/STPrivilegedTask/STPrivilegedTask.h mode change 100644 => 100755 Pods/STPrivilegedTask/STPrivilegedTask.m diff --git a/AltKit/NSError+ALTServerError.m b/AltKit/NSError+ALTServerError.m index 7688d52f..463e2fe4 100644 --- a/AltKit/NSError+ALTServerError.m +++ b/AltKit/NSError+ALTServerError.m @@ -72,7 +72,7 @@ NSErrorDomain const AltServerInstallationErrorDomain = @"com.rileytestut.AltServ return NSLocalizedString(@"Invalid anisette data.", @""); case ALTServerErrorPluginNotFound: - return NSLocalizedString(@"Could not connect to Mail plug-in. Please make sure the plug-in is installed and Mail is running, then try again.", @""); + return NSLocalizedString(@"Could not connect to Mail plug-in. Please make sure Mail is running and that you've enabled the plug-in in Mail's preferences, then try again.", @""); } } diff --git a/AltServer/AltPlugin.mailbundle.zip b/AltServer/AltPlugin.mailbundle.zip deleted file mode 100644 index c14abd9a1766c4481dc7b3ff8ed5382c1bfff440..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10771 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 diff --git a/AltServer/AppDelegate.swift b/AltServer/AppDelegate.swift index 094a50fd..c4dcca65 100644 --- a/AltServer/AppDelegate.swift +++ b/AltServer/AppDelegate.swift @@ -14,24 +14,27 @@ import AltSign import LaunchAtLogin import STPrivilegedTask +private let pluginDirectoryURL = URL(fileURLWithPath: "/Library/Mail/Bundles", isDirectory: true) +private let pluginURL = pluginDirectoryURL.appendingPathComponent("AltPlugin.mailbundle") + enum PluginError: LocalizedError { - case installationScriptNotFound - case failedToRun(Int) - case scriptError(String) + case cancelled + case unknown + case taskError(String) + case taskErrorCode(Int) var errorDescription: String? { switch self { - case .installationScriptNotFound: return NSLocalizedString("The installation script could not be found.", comment: "") - case .failedToRun(let errorCode): return String(format: NSLocalizedString("The installation script could not be run. (%@)", comment: ""), NSNumber(value: errorCode)) - case .scriptError(let output): return output + case .cancelled: return NSLocalizedString("Mail plug-in installation was cancelled.", comment: "") + case .unknown: return NSLocalizedString("Failed to install Mail plug-in.", comment: "") + 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 let pluginURL = URL(fileURLWithPath: "/Library/Mail/Bundles/AltPlugin.mailbundle") - @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @@ -108,7 +111,7 @@ private extension AppDelegate self.launchAtLoginMenuItem.state = LaunchAtLogin.isEnabled ? .on : .off self.launchAtLoginMenuItem.action = #selector(AppDelegate.toggleLaunchAtLogin(_:)) - if FileManager.default.fileExists(atPath: pluginURL.path) + if self.isMailPluginInstalled { self.installMailPluginMenuItem.title = NSLocalizedString("Uninstall Mail Plug-in", comment: "") } @@ -182,47 +185,73 @@ private extension AppDelegate let device = self.connectedDevices[index] - if !self.isMailPluginInstalled + func install() { - let result = self.installMailPlugin() - guard result else { return } + ALTDeviceManager.shared.installAltStore(to: device, appleID: username, password: password) { (result) in + switch result + { + case .success: + let content = UNMutableNotificationContent() + content.title = NSLocalizedString("Installation Succeeded", comment: "") + content.body = String(format: NSLocalizedString("AltStore was successfully installed on %@.", comment: ""), 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 as NSError): + + let alert = NSAlert() + alert.alertStyle = .critical + alert.messageText = NSLocalizedString("Installation Failed", comment: "") + + if let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? Error + { + alert.informativeText = underlyingError.localizedDescription + } + else + { + alert.informativeText = error.localizedDescription + } + + NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) + + alert.runModal() + } + } } - ALTDeviceManager.shared.installAltStore(to: device, appleID: username, password: password) { (result) in - switch result - { - case .success: - let content = UNMutableNotificationContent() - content.title = NSLocalizedString("Installation Succeeded", comment: "") - content.body = String(format: NSLocalizedString("AltStore was successfully installed on %@.", comment: ""), 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 as NSError): - - let alert = NSAlert() - alert.alertStyle = .critical - alert.messageText = NSLocalizedString("Installation Failed", comment: "") - - if let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? Error - { - alert.informativeText = underlyingError.localizedDescription + if !self.isMailPluginInstalled + { + self.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() + + install() + } } - else - { - alert.informativeText = error.localizedDescription - } - - NSRunningApplication.current.activate(options: .activateIgnoringOtherApps) - - alert.runModal() } } + else + { + install() + } } @objc func toggleLaunchAtLogin(_ item: NSMenuItem) @@ -241,71 +270,205 @@ private extension AppDelegate @objc func handleInstallMailPluginMenuItem(_ item: NSMenuItem) { - installMailPlugin() + if self.isMailPluginInstalled + { + self.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() + } + } + } + } + else + { + self.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() + } + } + } + } } - @discardableResult - func installMailPlugin() -> Bool + func installMailPlugin(completionHandler: @escaping (Result) -> Void) { do { - let previouslyInstalled = self.isMailPluginInstalled + let alert = NSAlert() + 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: "") - if !previouslyInstalled - { - let alert = NSAlert() - 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 { return false } + 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() + defer { try? FileManager.default.removeItem(at: fileURL) } + + // Unzip AltPlugin to plug-ins directory. + let authorization = try self.runAndKeepAuthorization("unzip", arguments: ["-o", fileURL.path, "-d", pluginDirectoryURL.path]) + 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)) + } } - - guard let scriptURL = Bundle.main.url(forResource: self.isMailPluginInstalled ? "UninstallPlugin" : "InstallPlugin", withExtension: "sh") else { throw PluginError.installationScriptNotFound } - - try FileManager.default.setAttributes([.posixPermissions: 0o777], ofItemAtPath: scriptURL.path) - - let task = STPrivilegedTask() - task.setLaunchPath(scriptURL.path) - task.setCurrentDirectoryPath(scriptURL.deletingLastPathComponent().path) - - let errorCode = task.launch() - guard errorCode == 0 else { throw PluginError.failedToRun(Int(errorCode)) } - - task.waitUntilExit() - - if - let outputData = task.outputFileHandle()?.readDataToEndOfFile(), - let outputString = String(data: outputData, encoding: .utf8), !outputString.isEmpty - { - throw PluginError.scriptError(outputString) - } - - if !previouslyInstalled && self.isMailPluginInstalled - { - 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() - } - - return true } catch { - let alert = NSAlert() - alert.messageText = self.isMailPluginInstalled ? NSLocalizedString("Failed to Uninstall Mail Plug-in", comment: "") : NSLocalizedString("Failed to Install Mail Plug-in", comment: "") - alert.informativeText = error.localizedDescription - alert.runModal() - - return false + completionHandler(.failure(PluginError.cancelled)) } } + + func downloadPlugin(completionHandler: @escaping (Result) -> Void) + { + let pluginURL = URL(string: "https://f000.backblazeb2.com/file/altstore/altserver/altplugin/1_0.zip")! + + let downloadTask = URLSession.shared.downloadTask(with: pluginURL) { (fileURL, response, error) in + if let fileURL = fileURL + { + print("Downloaded plugin to URL:", fileURL) + completionHandler(.success(fileURL)) + } + else + { + completionHandler(.failure(error ?? PluginError.unknown)) + } + } + + downloadTask.resume() + } + + 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 AppDelegate +{ + func run(_ program: String, arguments: [String], authorization: AuthorizationRef? = nil) throws + { + _ = try self._run(program, arguments: arguments, authorization: authorization, freeAuthorization: true) + } + + 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() + + 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 + } } extension AppDelegate: NSMenuDelegate diff --git a/AltServer/InstallPlugin.sh b/AltServer/InstallPlugin.sh deleted file mode 100644 index 302da4a4..00000000 --- a/AltServer/InstallPlugin.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# InstallAltPlugin.sh -# AltStore -# -# Created by Riley Testut on 11/16/19. -# Copyright © 2019 Riley Testut. All rights reserved. - -rm -f AltPlugin.mailbundle -unzip AltPlugin.mailbundle.zip 1>/dev/null -mkdir -p /Library/Mail/Bundles -cp -r AltPlugin.mailbundle /Library/Mail/Bundles -defaults write "/Library/Preferences/com.apple.mail" EnableBundles 1 diff --git a/AltServer/UninstallPlugin.sh b/AltServer/UninstallPlugin.sh deleted file mode 100644 index 5d3ab257..00000000 --- a/AltServer/UninstallPlugin.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# UninstallPlugin.sh -# AltStore -# -# Created by Riley Testut on 11/16/19. -# Copyright © 2019 Riley Testut. All rights reserved. - -rm -rf /Library/Mail/Bundles/AltPlugin.mailbundle diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 8e188abd..ece28c99 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -115,7 +115,6 @@ BF45884B2298D55000BD7491 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = BF4588492298D55000BD7491 /* thread.h */; }; BF4588882298DD3F00BD7491 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BF4588872298DD3F00BD7491 /* libxml2.tbd */; }; BF4C7F2523801F0800B2556E /* AltSign.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9B63C5229DD44D002F0A62 /* AltSign.framework */; }; - BF4C7F27238086EB00B2556E /* InstallPlugin.sh in Resources */ = {isa = PBXBuildFile; fileRef = BF4C7F26238086EB00B2556E /* InstallPlugin.sh */; }; BF54E8212315EF0D000AE0D8 /* ALTPatreonBenefitType.m in Sources */ = {isa = PBXBuildFile; fileRef = BF54E8202315EF0D000AE0D8 /* ALTPatreonBenefitType.m */; }; BF56D2AA23DF88310006506D /* AppID.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF56D2A923DF88310006506D /* AppID.swift */; }; BF56D2AC23DF8E170006506D /* FetchAppIDsOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF56D2AB23DF8E170006506D /* FetchAppIDsOperation.swift */; }; @@ -137,7 +136,6 @@ BF7C627423DBB78C00515A2D /* InstalledAppPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7C627323DBB78C00515A2D /* InstalledAppPolicy.swift */; }; BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8F69C122E659F700049BA1 /* AppContentViewController.swift */; }; BF8F69C422E662D300049BA1 /* AppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8F69C322E662D300049BA1 /* AppViewController.swift */; }; - BF914C262383703800E713BA /* AltPlugin.mailbundle.zip in Resources */ = {isa = PBXBuildFile; fileRef = BF914C252383703800E713BA /* AltPlugin.mailbundle.zip */; }; BF9A03C623C7DD0D000D08DB /* ClientConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9A03C523C7DD0D000D08DB /* ClientConnection.swift */; }; BF9ABA4522DCFF43008935CF /* BrowseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9ABA4422DCFF43008935CF /* BrowseViewController.swift */; }; BF9ABA4722DD0638008935CF /* BrowseCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9ABA4622DD0638008935CF /* BrowseCollectionViewCell.swift */; }; @@ -208,7 +206,6 @@ BFD5D6F4230DDB0A007955AB /* Campaign.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD5D6F3230DDB0A007955AB /* Campaign.swift */; }; BFD5D6F6230DDB12007955AB /* Tier.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD5D6F5230DDB12007955AB /* Tier.swift */; }; BFD6B03322DFF20800B86064 /* MyAppsComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD6B03222DFF20800B86064 /* MyAppsComponents.swift */; }; - BFD80D572380C0F700B9C227 /* UninstallPlugin.sh in Resources */ = {isa = PBXBuildFile; fileRef = BFD80D562380C0F700B9C227 /* UninstallPlugin.sh */; }; BFDB5B1622EE90D300F74113 /* Date+RelativeDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB5B1522EE90D300F74113 /* Date+RelativeDate.swift */; }; BFDB5B2622EFBBEA00F74113 /* BrowseCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFDB5B2522EFBBEA00F74113 /* BrowseCollectionViewCell.xib */; }; BFDB6A0522A9AFB2007EA6D6 /* Fetchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB6A0422A9AFB2007EA6D6 /* Fetchable.swift */; }; @@ -422,7 +419,6 @@ 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; }; BF4588962298DE6E00BD7491 /* libzip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = libzip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BF4713A422976CFC00784A2F /* openssl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = openssl.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BF4C7F26238086EB00B2556E /* InstallPlugin.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = InstallPlugin.sh; sourceTree = ""; }; BF54E81F2315EF0D000AE0D8 /* ALTPatreonBenefitType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTPatreonBenefitType.h; sourceTree = ""; }; BF54E8202315EF0D000AE0D8 /* ALTPatreonBenefitType.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALTPatreonBenefitType.m; sourceTree = ""; }; BF56D2A823DF87570006506D /* AltStore 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AltStore 4.xcdatamodel"; sourceTree = ""; }; @@ -456,7 +452,6 @@ BF7C627323DBB78C00515A2D /* InstalledAppPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledAppPolicy.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 = ""; }; - BF914C252383703800E713BA /* AltPlugin.mailbundle.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = AltPlugin.mailbundle.zip; sourceTree = ""; }; BF9A03C523C7DD0D000D08DB /* ClientConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientConnection.swift; sourceTree = ""; }; BF9ABA4422DCFF43008935CF /* BrowseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseViewController.swift; sourceTree = ""; }; BF9ABA4622DD0638008935CF /* BrowseCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseCollectionViewCell.swift; sourceTree = ""; }; @@ -535,7 +530,6 @@ BFD5D6F3230DDB0A007955AB /* Campaign.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Campaign.swift; sourceTree = ""; }; BFD5D6F5230DDB12007955AB /* Tier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tier.swift; sourceTree = ""; }; BFD6B03222DFF20800B86064 /* MyAppsComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyAppsComponents.swift; sourceTree = ""; }; - BFD80D562380C0F700B9C227 /* UninstallPlugin.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = UninstallPlugin.sh; sourceTree = ""; }; BFDB5B1522EE90D300F74113 /* Date+RelativeDate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+RelativeDate.swift"; sourceTree = ""; }; BFDB5B2522EFBBEA00F74113 /* BrowseCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BrowseCollectionViewCell.xib; sourceTree = ""; }; BFDB6A0422A9AFB2007EA6D6 /* Fetchable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fetchable.swift; sourceTree = ""; }; @@ -885,9 +879,6 @@ isa = PBXGroup; children = ( BF458693229872EA00BD7491 /* Assets.xcassets */, - BF914C252383703800E713BA /* AltPlugin.mailbundle.zip */, - BF4C7F26238086EB00B2556E /* InstallPlugin.sh */, - BFD80D562380C0F700B9C227 /* UninstallPlugin.sh */, ); name = Resources; sourceTree = ""; @@ -1415,11 +1406,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - BF914C262383703800E713BA /* AltPlugin.mailbundle.zip in Resources */, - BFD80D572380C0F700B9C227 /* UninstallPlugin.sh in Resources */, BF458694229872EA00BD7491 /* Assets.xcassets in Resources */, BF458697229872EA00BD7491 /* Main.storyboard in Resources */, - BF4C7F27238086EB00B2556E /* InstallPlugin.sh in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Podfile b/Podfile index 949f932f..8540553f 100644 --- a/Podfile +++ b/Podfile @@ -19,7 +19,7 @@ target 'AltServer' do use_frameworks! # Pods for AltServer - pod 'STPrivilegedTask' + pod 'STPrivilegedTask', :git => 'https://github.com/rileytestut/STPrivilegedTask.git' pod 'Sparkle' end diff --git a/Podfile.lock b/Podfile.lock index 1e9f8973..139826c2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -14,7 +14,7 @@ PODS: - Nuke (7.6.3) - Roxas (0.1) - Sparkle (1.21.3) - - STPrivilegedTask (1.0.1) + - STPrivilegedTask (1.0.7) DEPENDENCIES: - AltSign (from `Dependencies/AltSign`) @@ -22,20 +22,26 @@ DEPENDENCIES: - Nuke (~> 7.0) - Roxas (from `Dependencies/Roxas`) - Sparkle - - STPrivilegedTask + - STPrivilegedTask (from `https://github.com/rileytestut/STPrivilegedTask.git`) SPEC REPOS: trunk: - KeychainAccess - Nuke - Sparkle - - STPrivilegedTask EXTERNAL SOURCES: AltSign: :path: Dependencies/AltSign Roxas: :path: Dependencies/Roxas + STPrivilegedTask: + :git: https://github.com/rileytestut/STPrivilegedTask.git + +CHECKOUT OPTIONS: + STPrivilegedTask: + :commit: c8dd3e41b23666d4010c86b052a921a8e5a320d0 + :git: https://github.com/rileytestut/STPrivilegedTask.git SPEC CHECKSUMS: AltSign: c3693fa5a4b6d0ec6bedb74a5d768fe58bd67b87 @@ -43,8 +49,8 @@ SPEC CHECKSUMS: Nuke: 44130e95e09463f8773ae4b96b90de1eba6b3350 Roxas: 1990039f843f5dc284918dc82375feb80020ef62 Sparkle: 3f75576db8b0265adef36c43249d747f22d0b708 - STPrivilegedTask: 103f97827454e786074640cf89d303be344498c7 + STPrivilegedTask: 56c3397238a1ec07720fb877a044898373cd2c68 -PODFILE CHECKSUM: 467b50b42949f001543841f547fa6b427e29dc53 +PODFILE CHECKSUM: 1503b17048964bd0586d5470e6ee1e57917934de COCOAPODS: 1.8.4 diff --git a/Pods/Local Podspecs/STPrivilegedTask.podspec.json b/Pods/Local Podspecs/STPrivilegedTask.podspec.json new file mode 100644 index 00000000..dbc8cc86 --- /dev/null +++ b/Pods/Local Podspecs/STPrivilegedTask.podspec.json @@ -0,0 +1,25 @@ +{ + "name": "STPrivilegedTask", + "version": "1.0.7", + "summary": "An NSTask-like wrapper around Mac OS X Security Framework's AuthorizationExecuteWithPrivileges()", + "description": "An NSTask-like wrapper around AuthorizationExecuteWithPrivileges() in the Security API to run shell commands with root privileges in Mac OS X.", + "homepage": "http://github.com/sveinbjornt/STPrivilegedTask", + "license": { + "type": "BSD" + }, + "authors": { + "Sveinbjorn Thordarson": "sveinbjorn@sveinbjorn.org" + }, + "platforms": { + "osx": "10.8" + }, + "source": { + "git": "https://github.com/sveinbjornt/STPrivilegedTask.git", + "tag": "1.0.7" + }, + "source_files": "STPrivilegedTask.{h,m}", + "exclude_files": "PrivilegedTaskExample", + "public_header_files": "STPrivilegedTask.h", + "frameworks": "Security", + "requires_arc": false +} diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 1e9f8973..139826c2 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -14,7 +14,7 @@ PODS: - Nuke (7.6.3) - Roxas (0.1) - Sparkle (1.21.3) - - STPrivilegedTask (1.0.1) + - STPrivilegedTask (1.0.7) DEPENDENCIES: - AltSign (from `Dependencies/AltSign`) @@ -22,20 +22,26 @@ DEPENDENCIES: - Nuke (~> 7.0) - Roxas (from `Dependencies/Roxas`) - Sparkle - - STPrivilegedTask + - STPrivilegedTask (from `https://github.com/rileytestut/STPrivilegedTask.git`) SPEC REPOS: trunk: - KeychainAccess - Nuke - Sparkle - - STPrivilegedTask EXTERNAL SOURCES: AltSign: :path: Dependencies/AltSign Roxas: :path: Dependencies/Roxas + STPrivilegedTask: + :git: https://github.com/rileytestut/STPrivilegedTask.git + +CHECKOUT OPTIONS: + STPrivilegedTask: + :commit: c8dd3e41b23666d4010c86b052a921a8e5a320d0 + :git: https://github.com/rileytestut/STPrivilegedTask.git SPEC CHECKSUMS: AltSign: c3693fa5a4b6d0ec6bedb74a5d768fe58bd67b87 @@ -43,8 +49,8 @@ SPEC CHECKSUMS: Nuke: 44130e95e09463f8773ae4b96b90de1eba6b3350 Roxas: 1990039f843f5dc284918dc82375feb80020ef62 Sparkle: 3f75576db8b0265adef36c43249d747f22d0b708 - STPrivilegedTask: 103f97827454e786074640cf89d303be344498c7 + STPrivilegedTask: 56c3397238a1ec07720fb877a044898373cd2c68 -PODFILE CHECKSUM: 467b50b42949f001543841f547fa6b427e29dc53 +PODFILE CHECKSUM: 1503b17048964bd0586d5470e6ee1e57917934de COCOAPODS: 1.8.4 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 20debb76..4c729882 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXAggregateTarget section */ @@ -2211,7 +2211,7 @@ LastUpgradeCheck = 1100; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; - compatibilityVersion = "Xcode 9.3"; + compatibilityVersion = "Xcode 10.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -2532,45 +2532,6 @@ }; name = Debug; }; - 01FC26EF7492A83715733D6E82B58E10 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B763A613B013538736809BCA42B6DEF0 /* STPrivilegedTask.xcconfig */; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - GCC_PREFIX_HEADER = "Target Support Files/STPrivilegedTask/STPrivilegedTask-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/STPrivilegedTask/STPrivilegedTask-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.6; - MODULEMAP_FILE = "Target Support Files/STPrivilegedTask/STPrivilegedTask.modulemap"; - PRODUCT_MODULE_NAME = STPrivilegedTask; - PRODUCT_NAME = STPrivilegedTask; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; 03A826C198089C15D11AC65F5BED730D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3A44D4EBF7CD579B73B275F0F125F846 /* Pods-AltServer.debug.xcconfig */; @@ -2843,45 +2804,6 @@ }; name = Release; }; - 569B2F7FFE1A40245840B5BD14E5075B /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B763A613B013538736809BCA42B6DEF0 /* STPrivilegedTask.xcconfig */; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - GCC_PREFIX_HEADER = "Target Support Files/STPrivilegedTask/STPrivilegedTask-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/STPrivilegedTask/STPrivilegedTask-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.6; - MODULEMAP_FILE = "Target Support Files/STPrivilegedTask/STPrivilegedTask.modulemap"; - PRODUCT_MODULE_NAME = STPrivilegedTask; - PRODUCT_NAME = STPrivilegedTask; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; 5AFD67EFA6B3F27B4F0B0F8027C335F7 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 5B1BF3395506426B10A06E5307D1EEFA /* Sparkle.xcconfig */; @@ -3044,6 +2966,44 @@ }; name = Debug; }; + DAA2BB16DE5BB8A33D1F4FEBC5F6E540 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B763A613B013538736809BCA42B6DEF0 /* STPrivilegedTask.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + GCC_PREFIX_HEADER = "Target Support Files/STPrivilegedTask/STPrivilegedTask-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/STPrivilegedTask/STPrivilegedTask-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.8; + MODULEMAP_FILE = "Target Support Files/STPrivilegedTask/STPrivilegedTask.modulemap"; + PRODUCT_MODULE_NAME = STPrivilegedTask; + PRODUCT_NAME = STPrivilegedTask; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; E8921B3E2DFC77CDA00FEE1D9EA36AA0 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 1215053FA027E4CE849DAF4D00697FF1 /* Pods-AltServer.release.xcconfig */; @@ -3085,6 +3045,44 @@ }; name = Release; }; + F53E3123D6E0B1A60F1DFB065889DFD7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B763A613B013538736809BCA42B6DEF0 /* STPrivilegedTask.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + GCC_PREFIX_HEADER = "Target Support Files/STPrivilegedTask/STPrivilegedTask-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/STPrivilegedTask/STPrivilegedTask-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.8; + MODULEMAP_FILE = "Target Support Files/STPrivilegedTask/STPrivilegedTask.modulemap"; + PRODUCT_MODULE_NAME = STPrivilegedTask; + PRODUCT_NAME = STPrivilegedTask; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -3118,8 +3116,8 @@ 54208ED19403AA500F1198EEF237E880 /* Build configuration list for PBXNativeTarget "STPrivilegedTask" */ = { isa = XCConfigurationList; buildConfigurations = ( - 01FC26EF7492A83715733D6E82B58E10 /* Debug */, - 569B2F7FFE1A40245840B5BD14E5075B /* Release */, + F53E3123D6E0B1A60F1DFB065889DFD7 /* Debug */, + DAA2BB16DE5BB8A33D1F4FEBC5F6E540 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/STPrivilegedTask/LICENSE b/Pods/STPrivilegedTask/LICENSE new file mode 100644 index 00000000..61b39da5 --- /dev/null +++ b/Pods/STPrivilegedTask/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2009, Sveinbjorn Thordarson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Pods/STPrivilegedTask/LICENSE.txt b/Pods/STPrivilegedTask/LICENSE.txt deleted file mode 100644 index 5d6d508b..00000000 --- a/Pods/STPrivilegedTask/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ - # BSD License - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are met: - # * Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # * Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in the - # documentation and/or other materials provided with the distribution. - # * Neither the name of Sveinbjorn Thordarson nor that of any other - # contributors may be used to endorse or promote products - # derived from this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Pods/STPrivilegedTask/README.md b/Pods/STPrivilegedTask/README.md index 46c7d726..2bde9b43 100644 --- a/Pods/STPrivilegedTask/README.md +++ b/Pods/STPrivilegedTask/README.md @@ -1,58 +1,193 @@ # STPrivilegedTask - Objective C class -An NSTask-like wrapper around AuthorizationExecuteWithPrivileges() in the Security API to run shell commands with root privileges in Mac OS X. +An NSTask-like wrapper around [AuthorizationExecuteWithPrivileges()](https://developer.apple.com/library/mac/documentation/Security/Reference/authorization_ref/#//apple_ref/c/func/AuthorizationExecuteWithPrivileges) in the Security API to run shell commands with root privileges in Mac OS X. -Example of usage: +STPrivilegedTask was created a long time ago. It has now been updated to support ARC and is available via CocoaPods. + +## Examples + +### Create and launch task ```objective-c +// Create task STPrivilegedTask *privilegedTask = [[STPrivilegedTask alloc] init]; - [privilegedTask setLaunchPath:@"/usr/bin/touch"]; -NSArray *args = [NSArray arrayWithObject:@"/etc/my_test_file"]; -[privilegedTask setArguments:args]; -[privilegedTask setCurrentDirectoryPath:[[NSBundle mainBundle] resourcePath]]; +[privilegedTask setArguments:@[@"/etc/my_test_file"]]; -//set it off +// Setting working directory is optional, defaults to / +// NSString *path = [[NSBundle mainBundle] resourcePath]; +// [privilegedTask setCurrentDirectoryPath:path]; + +// Launch it, user is prompted for password OSStatus err = [privilegedTask launch]; -if (err != errAuthorizationSuccess) { - if (err == errAuthorizationCanceled) { - NSLog(@"User cancelled"); - } else { - NSLog(@"Something went wrong"); - } +if (err == errAuthorizationSuccess) { + NSLog(@"Task successfully launched"); } +else if (err == errAuthorizationCanceled) { + NSLog(@"User cancelled"); +} +else { + NSLog(@"Something went wrong"); +} +``` +See [Authorization.h](http://www.opensource.apple.com/source/libsecurity_authorization/libsecurity_authorization-36329/lib/Authorization.h) for a list of possible error codes. + +### Launch task one-liner + +```objective-c +OSStatus err = [STPrivilegedTask launchedPrivilegedTaskWithLaunchPath:@"/bin/sh" + arguments:@[@"/path/to/script.sh"]]; + + +``` + + +### Getting task output + +```objective-c +// ... launch task + +[privilegedTask waitUntilExit]; // Read output file handle for data -NSFileHandle *readHandle = [privilegedTask outputFileHandle]; -NSData *outputData = [readHandle readDataToEndOfFile]; +NSData *outputData = [[privilegedTask outputFileHandle] readDataToEndOfFile]; NSString *outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; ``` -# BSD License +### Getting output while task runs in background +```objective-c + +// ... launch task + +NSFileHandle *readHandle = [privilegedTask outputFileHandle]; +[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOutputData:) name:NSFileHandleReadCompletionNotification object:readHandle]; +[readHandle readInBackgroundAndNotify]; + +// ... + +- (void)getOutputData:(NSNotification *)aNotification { + //get data from notification + NSData *data = [[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem]; + + //make sure there's actual data + if ([data length]) { + // do something with the data + NSString *outputString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSLog(outputString); + + // go read more data in the background + [[aNotification object] readInBackgroundAndNotify]; + } else { + // do something else + } +} ``` - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are met: - # * Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # * Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in the - # documentation and/or other materials provided with the distribution. - # * Neither the name of Sveinbjorn Thordarson nor that of any other - # contributors may be used to endorse or promote products - # derived from this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +### Task termination -``` \ No newline at end of file +You can observe STPrivilegedTaskDidTerminateNotification: + +```objective-c +[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(privilegedTaskFinished:) name:STPrivilegedTaskDidTerminateNotification object:nil]; + +- (void)privilegedTaskFinished:(NSNotification *)aNotification { + // do something +} +``` + +Or alternately, set a termination handler: + +```objective-c +privilegedTask.terminationHandler = ^(STPrivilegedTask *privilegedTask) { + NSLog(@"Terminating task: %@", [privilegedTask description]); +}; +``` + +### Launch using external AuthorizationRef + +```objective-c +// ... Create your own AuthorizationRef + +[STPriviledTask launchedPrivilegedTaskWithLaunchPath:@"/bin/sh" + arguments:@"/path/to/script" + currentDirectory:@"/" + authorization:authRef] +``` + +### AuthorizationExecuteWithPrivileges() is deprecated + +[AuthorizationExecuteWithPrivileges()](https://developer.apple.com/library/mac/documentation/Security/Reference/authorization_ref/#//apple_ref/c/func/AuthorizationExecuteWithPrivileges) is deprecated as of macOS 10.7 but remains available +in 10.14 Mojave. If you want to be future-proof, here's how you check if STPrivilegedTask +works in the running version of macOS: + +```objective-c +OSStatus err = [privilegedTask launch]; +if (err == errAuthorizationFnNoLongerExists) { + NSLog(@"AuthorizationExecuteWithPrivileges not available"); +} +``` + +If you need to check whether STPrivilegedTask works before you launch the task: + +```objective-c +BOOL works = [STPrivilegedTask authorizationFunctionAvailable]; +``` + +## Sample app + +A sample app which makes use of STPrivilegedTask is included in the project. This app runs the following script: + +``` +#!/bin/sh + +echo "/usr/bin/whoami:" +whoami +echo "" +echo "Real User ID:" +echo $UID \($USER\) +echo "" +echo "Effective User ID:" +/usr/bin/id -u +echo "" +echo "Current working directory:" +echo "$PWD" + +exit 5 +``` + +It then presents the output of the script in a window, along with the exit code. + + + + +## BSD License + +Copyright (c) Sveinbjorn Thordarson <sveinbjorn@sveinbjorn.org> +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/Pods/STPrivilegedTask/STPrivilegedTask.h b/Pods/STPrivilegedTask/STPrivilegedTask.h old mode 100644 new mode 100755 index 77932be8..18f4da17 --- a/Pods/STPrivilegedTask/STPrivilegedTask.h +++ b/Pods/STPrivilegedTask/STPrivilegedTask.h @@ -1,7 +1,6 @@ /* - # # STPrivilegedTask - NSTask-like wrapper around AuthorizationExecuteWithPrivileges - # Copyright (C) 2009-2015 Sveinbjorn Thordarson + # Copyright (C) 2009-2017 Sveinbjorn Thordarson # # BSD License # Redistribution and use in source and binary forms, with or without @@ -11,7 +10,7 @@ # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. - # * Neither the name of Sveinbjorn Thordarson nor that of any other + # * Neither the name of the copyright holder nor that of any other # contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # @@ -28,54 +27,43 @@ */ #import -#import -#import -#import #define STPrivilegedTaskDidTerminateNotification @"STPrivilegedTaskDidTerminateNotification" -//#define TMP_STDERR_TEMPLATE @".authStderr.XXXXXX" -// Defines error value for when AuthorizationExecuteWithPrivilleges no longer -// exists anyplace. Rather than defining a new enum, we just create a global -// constant +// Defines error value for when AuthorizationExecuteWithPrivileges no longer exists +// Rather than defining a new enum, we just create a global constant extern const OSStatus errAuthorizationFnNoLongerExists; -@interface STPrivilegedTask : NSObject -{ - NSArray *arguments; - NSString *cwd; - NSString *launchPath; - BOOL isRunning; - pid_t pid; - int terminationStatus; - NSFileHandle *outputFileHandle; - NSTimer *checkStatusTimer; -} --(id)initWithLaunchPath:(NSString *)path; --(id)initWithLaunchPath:(NSString *)path arguments: (NSArray *)args; -+(STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path; -+(STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)arguments; --(NSArray *)arguments; --(NSString *)currentDirectoryPath; --(BOOL)isRunning; --(int)launch; --(NSString *)launchPath; --(int)processIdentifier; --(void)setArguments:(NSArray *)arguments; --(void)setCurrentDirectoryPath:(NSString *)path; --(void)setLaunchPath:(NSString *)path; --(NSFileHandle *)outputFileHandle; --(void)terminate; // doesn't work --(int)terminationStatus; --(void)_checkTaskStatus; --(void)waitUntilExit; +@interface STPrivilegedTask : NSObject + +@property (copy) NSArray *arguments; +@property (copy) NSString *currentDirectoryPath; +@property (copy) NSString *launchPath; +@property (assign) BOOL freeAuthorizationWhenDone; + +@property (readonly) NSFileHandle *outputFileHandle; +@property (readonly) BOOL isRunning; +@property (readonly) pid_t processIdentifier; +@property (readonly) int terminationStatus; +@property (readonly) AuthorizationRef authorization; + +@property (copy) void (^terminationHandler)(STPrivilegedTask *); + ++ (BOOL)authorizationFunctionAvailable; + +- (instancetype)initWithLaunchPath:(NSString *)path; +- (instancetype)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args; +- (instancetype)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd; + ++ (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path; ++ (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args; ++ (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd; ++ (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd authorization:(AuthorizationRef)authorization; + +- (OSStatus)launch; +- (OSStatus)launchWithAuthorization:(AuthorizationRef)authorization; +- (void)terminate; // doesn't work +- (void)waitUntilExit; + @end -/*static OSStatus AuthorizationExecuteWithPrivilegesStdErrAndPid ( - AuthorizationRef authorization, - const char *pathToTool, - AuthorizationFlags options, - char * const *arguments, - FILE **communicationsPipe, - FILE **errPipe, - pid_t* processid - );*/ + diff --git a/Pods/STPrivilegedTask/STPrivilegedTask.m b/Pods/STPrivilegedTask/STPrivilegedTask.m old mode 100644 new mode 100755 index c94c2f02..ce326d70 --- a/Pods/STPrivilegedTask/STPrivilegedTask.m +++ b/Pods/STPrivilegedTask/STPrivilegedTask.m @@ -1,7 +1,6 @@ /* - # # STPrivilegedTask - NSTask-like wrapper around AuthorizationExecuteWithPrivileges - # Copyright (C) 2009-2015 Sveinbjorn Thordarson + # Copyright (C) 2009-2017 Sveinbjorn Thordarson # # BSD License # Redistribution and use in source and binary forms, with or without @@ -11,7 +10,7 @@ # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. - # * Neither the name of Sveinbjorn Thordarson nor that of any other + # * Neither the name of the copyright holder nor that of any other # contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # @@ -25,192 +24,154 @@ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + */ #import "STPrivilegedTask.h" + +#import +#import #import #import #import -/* New error code denoting that AuthorizationExecuteWithPrivileges no longer exists */ +// New error code denoting that AuthorizationExecuteWithPrivileges no longer exists OSStatus const errAuthorizationFnNoLongerExists = -70001; +// Create fn pointer to AuthorizationExecuteWithPrivileges in case +// it doesn't exist in this version of MacOS +static OSStatus (*_AuthExecuteWithPrivsFn)(AuthorizationRef authorization, const char *pathToTool, AuthorizationFlags options, + char * const *arguments, FILE **communicationsPipe) = NULL; + + @implementation STPrivilegedTask - -- (id)init { - if ((self = [super init])) { - launchPath = @""; - cwd = [[NSString alloc] initWithString:[[NSFileManager defaultManager] currentDirectoryPath]]; - arguments = [[NSArray alloc] init]; - isRunning = NO; - outputFileHandle = nil; + NSTimer *_checkStatusTimer; +} + ++ (void)initialize; +{ + // On 10.7, AuthorizationExecuteWithPrivileges is deprecated. We want + // to still use it since there's no good alternative (without requiring + // code signing). We'll look up the function through dyld and fail if + // it is no longer accessible. If Apple removes the function entirely + // this will fail gracefully. If they keep the function and throw some + // sort of exception, this won't fail gracefully, but that's a risk + // we'll have to take for now. + // Pattern by Andy Kim from Potion Factory LLC +#pragma GCC diagnostic ignored "-Wpedantic" // stop the pedantry! +#pragma clang diagnostic push + _AuthExecuteWithPrivsFn = dlsym(RTLD_DEFAULT, "AuthorizationExecuteWithPrivileges"); +#pragma clang diagnostic pop +} + +- (instancetype)init +{ + self = [super init]; + if (self) { + _launchPath = nil; + _arguments = nil; + _freeAuthorizationWhenDone = YES; + _isRunning = NO; + _outputFileHandle = nil; + _terminationHandler = nil; + _authorization = nil; + _currentDirectoryPath = [[NSFileManager defaultManager] currentDirectoryPath]; } return self; } --(void)dealloc +- (instancetype)initWithLaunchPath:(NSString *)path { -#if !__has_feature(objc_arc) - [launchPath release]; - [arguments release]; - [cwd release]; - - if (outputFileHandle != nil) { - [outputFileHandle release]; - } - [super dealloc]; -#endif -} - --(id)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args -{ - if ((self = [self initWithLaunchPath:path])) { - [self setArguments:args]; + self = [self init]; + if (self) { + self.launchPath = path; } return self; } --(id)initWithLaunchPath:(NSString *)path +- (instancetype)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args { - if ((self = [self init])) { - [self setLaunchPath:path]; + self = [self initWithLaunchPath:path]; + if (self) { + self.arguments = args; } return self; } +- (instancetype)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd +{ + self = [self initWithLaunchPath:path arguments:args]; + if (self) { + self.currentDirectoryPath = cwd; + } + return self; +} + +- (void)dealloc +{ + if (_freeAuthorizationWhenDone && _authorization != nil) { + // free the auth ref + AuthorizationFree(_authorization, kAuthorizationFlagDefaults); + } +} + #pragma mark - -+(STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args -{ - STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:path arguments:args]; -#if !__has_feature(objc_arc) - [task autorelease]; -#endif - - [task launch]; - [task waitUntilExit]; - return task; -} - -+(STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path ++ (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path { STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:path]; -#if !__has_feature(objc_arc) - [task autorelease]; -#endif [task launch]; [task waitUntilExit]; return task; } -#pragma mark - - -- (NSArray *)arguments ++ (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args { - return arguments; + STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:path arguments:args]; + [task launch]; + [task waitUntilExit]; + return task; } -- (NSString *)currentDirectoryPath; ++ (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd { - return cwd; + STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:path arguments:args currentDirectory:cwd]; + [task launch]; + [task waitUntilExit]; + return task; } -- (BOOL)isRunning ++ (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd authorization:(AuthorizationRef)authorization { - return isRunning; -} - -- (NSString *)launchPath -{ - return launchPath; -} - -- (int)processIdentifier -{ - return pid; -} - -- (int)terminationStatus -{ - return terminationStatus; -} - -- (NSFileHandle *)outputFileHandle; -{ - return outputFileHandle; -} - -#pragma mark - - --(void)setArguments:(NSArray *)args -{ -#if !__has_feature(objc_arc) - [arguments release]; - [args retain]; -#endif - arguments = args; -} - --(void)setCurrentDirectoryPath:(NSString *)path -{ -#if !__has_feature(objc_arc) - [cwd release]; - [path retain]; -#endif - cwd = path; -} - --(void)setLaunchPath:(NSString *)path -{ -#if !__has_feature(objc_arc) - [launchPath release]; - [path retain]; -#endif - launchPath = path; + STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:path arguments:args currentDirectory:cwd]; + [task launchWithAuthorization:authorization]; + [task waitUntilExit]; + return task; } # pragma mark - // return 0 for success --(int)launch +- (OSStatus)launch { + if (_isRunning) { + NSLog(@"Task already running: %@", [self description]); + return 0; + } + + if ([STPrivilegedTask authorizationFunctionAvailable] == NO) { + NSLog(@"AuthorizationExecuteWithPrivileges() function not available on this system"); + return errAuthorizationFnNoLongerExists; + } + OSStatus err = noErr; - const char *toolPath = [launchPath fileSystemRepresentation]; + const char *toolPath = [self.launchPath fileSystemRepresentation]; AuthorizationRef authorizationRef; - AuthorizationItem myItems = {kAuthorizationRightExecute, strlen(toolPath), &toolPath, 0}; - AuthorizationRights myRights = {1, &myItems}; + AuthorizationItem myItems = { kAuthorizationRightExecute, strlen(toolPath), &toolPath, 0 }; + AuthorizationRights myRights = { 1, &myItems }; AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights; - NSUInteger numberOfArguments = [arguments count]; - char *args[numberOfArguments + 1]; - FILE *outputFile; - - // Create fn pointer to AuthorizationExecuteWithPrivileges in case it doesn't exist - // in this version of MacOS - static OSStatus (*_AuthExecuteWithPrivsFn)( - AuthorizationRef authorization, const char *pathToTool, AuthorizationFlags options, - char * const *arguments, FILE **communicationsPipe) = NULL; - - // Check to see if we have the correct function in our loaded libraries - if (!_AuthExecuteWithPrivsFn) { - // On 10.7, AuthorizationExecuteWithPrivileges is deprecated. We want - // to still use it since there's no good alternative (without requiring - // code signing). We'll look up the function through dyld and fail if - // it is no longer accessible. If Apple removes the function entirely - // this will fail gracefully. If they keep the function and throw some - // sort of exception, this won't fail gracefully, but that's a risk - // we'll have to take for now. - // Pattern by Andy Kim from Potion Factory LLC - _AuthExecuteWithPrivsFn = dlsym(RTLD_DEFAULT, "AuthorizationExecuteWithPrivileges"); - if (!_AuthExecuteWithPrivsFn) { - // This version of OS X has finally removed this function. Exit with an error. - err = errAuthorizationFnNoLongerExists; - return err; - } - } - // Use Apple's Authentication Manager APIs to get an Authorization Reference // These Apple APIs are quite possibly the most horrible of the Mac OS X APIs @@ -227,24 +188,51 @@ OSStatus const errAuthorizationFnNoLongerExists = -70001; } // OK, at this point we have received authorization for the task. + err = [self launchWithAuthorization:authorizationRef]; + + return err; +} + +- (OSStatus)launchWithAuthorization:(AuthorizationRef)authorization +{ + _authorization = authorization; + + if (_isRunning) { + NSLog(@"Task already running: %@", [self description]); + return 0; + } + + if ([STPrivilegedTask authorizationFunctionAvailable] == NO) { + NSLog(@"AuthorizationExecuteWithPrivileges() function not available on this system"); + return errAuthorizationFnNoLongerExists; + } + + // Assuming the authorization is valid for the task. // Let's prepare to launch it + NSArray *arguments = self.arguments; + NSUInteger numberOfArguments = [arguments count]; + char *args[numberOfArguments + 1]; + FILE *outputFile; + + const char *toolPath = [self.launchPath fileSystemRepresentation]; // first, construct an array of c strings from NSArray w. arguments for (int i = 0; i < numberOfArguments; i++) { NSString *argString = arguments[i]; - NSUInteger stringLength = [argString length]; + const char *fsrep = [argString fileSystemRepresentation]; + NSUInteger stringLength = strlen(fsrep); args[i] = malloc((stringLength + 1) * sizeof(char)); - snprintf(args[i], stringLength + 1, "%s", [argString fileSystemRepresentation]); + snprintf(args[i], stringLength + 1, "%s", fsrep); } args[numberOfArguments] = NULL; // change to the current dir specified char *prevCwd = (char *)getcwd(nil, 0); - chdir([cwd fileSystemRepresentation]); + chdir([self.currentDirectoryPath fileSystemRepresentation]); //use Authorization Reference to execute script with privileges - err = _AuthExecuteWithPrivsFn(authorizationRef, [launchPath fileSystemRepresentation], kAuthorizationFlagDefaults, args, &outputFile); + OSStatus err = _AuthExecuteWithPrivsFn(authorization, toolPath, kAuthorizationFlagDefaults, args, &outputFile); // OK, now we're done executing, let's change back to old dir chdir(prevCwd); @@ -254,208 +242,92 @@ OSStatus const errAuthorizationFnNoLongerExists = -70001; free(args[i]); } - // free the auth ref - AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults); - // we return err if execution failed if (err != errAuthorizationSuccess) { return err; } else { - isRunning = YES; + _isRunning = YES; } // get file handle for the command output - outputFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileno(outputFile) closeOnDealloc:YES]; - pid = fcntl(fileno(outputFile), F_GETOWN, 0); + _outputFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileno(outputFile) closeOnDealloc:YES]; + _processIdentifier = fcntl(fileno(outputFile), F_GETOWN, 0); // start monitoring task - checkStatusTimer = [NSTimer scheduledTimerWithTimeInterval:0.10 target:self selector:@selector(_checkTaskStatus) userInfo:nil repeats:YES]; - + _checkStatusTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(checkTaskStatus) userInfo:nil repeats:YES]; + return err; } - (void)terminate { - // This doesn't work without a PID, and we can't get one. Stupid Security API - /* int ret = kill(pid, SIGKILL); - - if (ret != 0) - NSLog(@"Error %d", errno);*/ + // This doesn't work without a PID, and we can't get one. Stupid Security API. +// int ret = kill(pid, SIGKILL); +// +// if (ret != 0) { +// NSLog(@"Error %d", errno); +// } } // hang until task is done - (void)waitUntilExit { - waitpid([self processIdentifier], &terminationStatus, 0); - isRunning = NO; + if (!_isRunning) { + NSLog(@"Task %@ is not running", [super description]); + return; + } + + [_checkStatusTimer invalidate]; + + int status; + pid_t pid = 0; + while ((pid = waitpid(_processIdentifier, &status, WNOHANG)) == 0) { + // do nothing + } + _terminationStatus = WEXITSTATUS(status); + _isRunning = NO; } -#pragma mark - - -// check if privileged task is still running -- (void)_checkTaskStatus -{ - // see if task has terminated - int mypid = waitpid([self processIdentifier], &terminationStatus, WNOHANG); - if (mypid != 0) { - isRunning = NO; +// check if task has terminated +- (void)checkTaskStatus +{ + int status; + pid_t pid = waitpid(_processIdentifier, &status, WNOHANG); + if (pid != 0) { + _isRunning = NO; + _terminationStatus = WEXITSTATUS(status); + [_checkStatusTimer invalidate]; [[NSNotificationCenter defaultCenter] postNotificationName:STPrivilegedTaskDidTerminateNotification object:self]; - [checkStatusTimer invalidate]; + if (_terminationHandler) { + _terminationHandler(self); + } } } #pragma mark - ++ (BOOL)authorizationFunctionAvailable +{ + if (!_AuthExecuteWithPrivsFn) { + // This version of OS X has finally removed this function. Return with an error. + return NO; + } + return YES; +} + +#pragma mark - + +// Nice description for debugging - (NSString *)description { - NSArray *args = [self arguments]; - NSString *cmd = [[self launchPath] copy]; + NSString *commandDescription = [NSString stringWithString:self.launchPath]; - for (int i = 0; i < [args count]; i++) { - cmd = [cmd stringByAppendingFormat:@" %@", args[i]]; + for (NSString *arg in self.arguments) { + commandDescription = [commandDescription stringByAppendingFormat:@" '%@'", arg]; } + [commandDescription stringByAppendingFormat:@" (CWD:%@)", self.currentDirectoryPath]; - return [[super description] stringByAppendingFormat:@" %@", cmd]; + return [[super description] stringByAppendingFormat:@" %@", commandDescription]; } @end - -/* - * - * Add the Standard err Pipe and Pid support to AuthorizationExecuteWithPrivileges() - * method - * - * @Author: Miklós Fazekas - * Modified Aug 10 2010 by Sveinbjorn Thordarson - * - */ - - -/*static OSStatus AuthorizationExecuteWithPrivilegesStdErrAndPid ( - AuthorizationRef authorization, - const char *pathToTool, - AuthorizationFlags options, - char * const *arguments, - FILE **communicationsPipe, - FILE **errPipe, - pid_t* processid - ) -{ - // get the Apple-approved secure temp directory - NSString *tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent: TMP_STDERR_TEMPLATE]; - - // copy it into a C string - const char *tempFileTemplateCString = [tempFileTemplate fileSystemRepresentation]; - char *stderrpath = (char *)malloc(strlen(tempFileTemplateCString) + 1); - strcpy(stderrpath, tempFileTemplateCString); - - printf("%s\n", stderrpath); - - // this is the command, it echoes pid and directs stderr output to pipe before running the tool w. args - const char *commandtemplate = "echo $$; \"$@\" 2>%s"; - - if (communicationsPipe == errPipe) - commandtemplate = "echo $$; \"$@\" 2>1"; - else if (errPipe == 0) - commandtemplate = "echo $$; \"$@\""; - - char command[1024]; - char **args; - OSStatus result; - int argcount = 0; - int i; - int stderrfd = 0; - FILE *commPipe = 0; - - // First, create temporary file for stderr - if (errPipe) - { - // create temp file - stderrfd = mkstemp(stderrpath); - - // close and remove it - close(stderrfd); - unlink(stderrpath); - - // create a pipe on the path of the temp file - if (mkfifo(stderrpath,S_IRWXU | S_IRWXG) != 0) - { - fprintf(stderr,"Error mkfifo:%d\n", errno); - return errAuthorizationInternal; - } - - if (stderrfd < 0) - return errAuthorizationInternal; - } - - // Create command to be executed - for (argcount = 0; arguments[argcount] != 0; ++argcount) {} - args = (char**)malloc (sizeof(char*)*(argcount + 5)); - args[0] = "-c"; - snprintf (command, sizeof (command), commandtemplate, stderrpath); - args[1] = command; - args[2] = ""; - args[3] = (char*)pathToTool; - for (i = 0; i < argcount; ++i) { - args[i+4] = arguments[i]; - } - args[argcount+4] = 0; - - // for debugging: log the executed command - printf ("Exec:\n%s", "/bin/sh"); for (i = 0; args[i] != 0; ++i) { printf (" \"%s\"", args[i]); } printf ("\n"); - - // Execute command - result = AuthorizationExecuteWithPrivileges(authorization, "/bin/sh", options, args, &commPipe ); - if (result != noErr) - { - unlink (stderrpath); - return result; - } - - // Read the first line of stdout => it's the pid - { - int stdoutfd = fileno (commPipe); - char pidnum[1024]; - pid_t pid = 0; - int i = 0; - char ch = 0; - - while ((read(stdoutfd, &ch, sizeof(ch)) == 1) && (ch != '\n') && (i < sizeof(pidnum))) - { - pidnum[i++] = ch; - } - pidnum[i] = 0; - - if (ch != '\n') - { - // we shouldn't get there - unlink (stderrpath); - return errAuthorizationInternal; - } - sscanf(pidnum, "%d", &pid); - if (processid) - { - *processid = pid; - } - NSLog(@"Have PID %d", pid); - } - - // - if (errPipe) { - stderrfd = open(stderrpath, O_RDONLY, 0); - // *errPipe = fdopen(stderrfd, "r"); - //Now it's safe to unlink the stderr file, as the opened handle will be still valid - unlink (stderrpath); - } else { - unlink(stderrpath); - } - - if (communicationsPipe) - *communicationsPipe = commPipe; - else - fclose (commPipe); - - NSLog(@"AuthExecNew function over"); - - return noErr; -}*/ diff --git a/Pods/Target Support Files/Pods-AltServer/Pods-AltServer-acknowledgements.markdown b/Pods/Target Support Files/Pods-AltServer/Pods-AltServer-acknowledgements.markdown index 02f02f9c..2221e61b 100644 --- a/Pods/Target Support Files/Pods-AltServer/Pods-AltServer-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-AltServer/Pods-AltServer-acknowledgements.markdown @@ -3,28 +3,35 @@ This application makes use of the following third party libraries: ## STPrivilegedTask - # BSD License - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are met: - # * Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # * Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in the - # documentation and/or other materials provided with the distribution. - # * Neither the name of Sveinbjorn Thordarson nor that of any other - # contributors may be used to endorse or promote products - # derived from this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +BSD 3-Clause License + +Copyright (c) 2009, Sveinbjorn Thordarson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## Sparkle diff --git a/Pods/Target Support Files/Pods-AltServer/Pods-AltServer-acknowledgements.plist b/Pods/Target Support Files/Pods-AltServer/Pods-AltServer-acknowledgements.plist index 3a9beb49..417bdcfe 100644 --- a/Pods/Target Support Files/Pods-AltServer/Pods-AltServer-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-AltServer/Pods-AltServer-acknowledgements.plist @@ -14,28 +14,35 @@ FooterText - # BSD License - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are met: - # * Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # * Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in the - # documentation and/or other materials provided with the distribution. - # * Neither the name of Sveinbjorn Thordarson nor that of any other - # contributors may be used to endorse or promote products - # derived from this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + BSD 3-Clause License + +Copyright (c) 2009, Sveinbjorn Thordarson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License BSD diff --git a/Pods/Target Support Files/STPrivilegedTask/STPrivilegedTask-Info.plist b/Pods/Target Support Files/STPrivilegedTask/STPrivilegedTask-Info.plist index 3c175b60..1bd6a77a 100644 --- a/Pods/Target Support Files/STPrivilegedTask/STPrivilegedTask-Info.plist +++ b/Pods/Target Support Files/STPrivilegedTask/STPrivilegedTask-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0.1 + 1.0.7 CFBundleSignature ???? CFBundleVersion