From 55e0447e541bf04b2b708a449c62fe77b2831f9e Mon Sep 17 00:00:00 2001 From: Brandon Evans Date: Sun, 17 Jan 2021 11:57:45 -0700 Subject: [PATCH] Invalidate XPC connection after installing --- Xcodes.xcodeproj/project.pbxproj | 4 --- Xcodes/Backend/Environment.swift | 2 +- Xcodes/Backend/HelperClient.swift | 45 ++++++++++++++++++++++++++++ Xcodes/Backend/HelperInstaller.swift | 44 --------------------------- Xcodes/Backend/Logger.swift | 2 +- 5 files changed, 47 insertions(+), 50 deletions(-) delete mode 100644 Xcodes/Backend/HelperInstaller.swift diff --git a/Xcodes.xcodeproj/project.pbxproj b/Xcodes.xcodeproj/project.pbxproj index f3ea93c..0b00eb6 100644 --- a/Xcodes.xcodeproj/project.pbxproj +++ b/Xcodes.xcodeproj/project.pbxproj @@ -39,7 +39,6 @@ CA9FF8DB25959B4000E47BAF /* XPCDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF8DA25959B4000E47BAF /* XPCDelegate.swift */; }; CA9FF8E025959BAA00E47BAF /* ConnectionVerifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF8DF25959BAA00E47BAF /* ConnectionVerifier.swift */; }; CA9FF8E625959BB800E47BAF /* AuditTokenHack.m in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF8E525959BB800E47BAF /* AuditTokenHack.m */; }; - CA9FF8F525959CE000E47BAF /* HelperInstaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF8F425959CE000E47BAF /* HelperInstaller.swift */; }; CA9FF9362595B44700E47BAF /* HelperClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF9352595B44700E47BAF /* HelperClient.swift */; }; CAA1CB2D255A5262003FD669 /* AppleAPI in Frameworks */ = {isa = PBXBuildFile; productRef = CAA1CB2C255A5262003FD669 /* AppleAPI */; }; CAA1CB35255A5AD5003FD669 /* SignInCredentialsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB34255A5AD5003FD669 /* SignInCredentialsView.swift */; }; @@ -188,7 +187,6 @@ CA9FF8E425959BB800E47BAF /* AuditTokenHack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AuditTokenHack.h; sourceTree = ""; }; CA9FF8E525959BB800E47BAF /* AuditTokenHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AuditTokenHack.m; sourceTree = ""; }; CA9FF8EA25959BDD00E47BAF /* com.robotsandpencils.XcodesApp.Helper-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "com.robotsandpencils.XcodesApp.Helper-Bridging-Header.h"; sourceTree = ""; }; - CA9FF8F425959CE000E47BAF /* HelperInstaller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelperInstaller.swift; sourceTree = ""; }; CA9FF9052595A28400E47BAF /* com.robotsandpencils.XcodesApp.HelperTest.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = com.robotsandpencils.XcodesApp.HelperTest.entitlements; sourceTree = ""; }; CA9FF9252595A7EB00E47BAF /* Scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Scripts; sourceTree = ""; }; CA9FF9352595B44700E47BAF /* HelperClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelperClient.swift; sourceTree = ""; }; @@ -409,7 +407,6 @@ CABFA9B82592EEEA00380FEE /* FileManager+.swift */, CAFBDB942598FE96003DCC5A /* FocusedValues.swift */, CABFA9AC2592EEE900380FEE /* Foundation.swift */, - CA9FF8F425959CE000E47BAF /* HelperInstaller.swift */, CA9FF9352595B44700E47BAF /* HelperClient.swift */, CAC281D9259F985100B8AB0B /* InstallationStep.swift */, CA9FF8862595607900E47BAF /* InstalledXcode.swift */, @@ -754,7 +751,6 @@ CAA1CB35255A5AD5003FD669 /* SignInCredentialsView.swift in Sources */, CA9FF877259528CC00E47BAF /* Version+XcodeReleases.swift in Sources */, CABFAA2D2592FBFC00380FEE /* Configure.swift in Sources */, - CA9FF8F525959CE000E47BAF /* HelperInstaller.swift in Sources */, CA73510D257BFCEF00EA9CF8 /* NSAttributedString+.swift in Sources */, CAFBDB952598FE96003DCC5A /* FocusedValues.swift in Sources */, CAC281CD259F97FA00B8AB0B /* ObservingProgressIndicator.swift in Sources */, diff --git a/Xcodes/Backend/Environment.swift b/Xcodes/Backend/Environment.swift index b812835..16c2826 100644 --- a/Xcodes/Backend/Environment.swift +++ b/Xcodes/Backend/Environment.swift @@ -237,7 +237,7 @@ public struct Defaults { private let helperClient = HelperClient() public struct Helper { - var install: () -> Void = HelperInstaller.install + var install: () -> Void = helperClient.install var checkIfLatestHelperIsInstalled: () -> AnyPublisher = helperClient.checkIfLatestHelperIsInstalled var getVersion: () -> AnyPublisher = helperClient.getVersion var switchXcodePath: (_ absolutePath: String) -> AnyPublisher = helperClient.switchXcodePath diff --git a/Xcodes/Backend/HelperClient.swift b/Xcodes/Backend/HelperClient.swift index cc8801f..db37998 100644 --- a/Xcodes/Backend/HelperClient.swift +++ b/Xcodes/Backend/HelperClient.swift @@ -1,5 +1,7 @@ import Combine import Foundation +import os.log +import ServiceManagement final class HelperClient { private var connection: NSXPCConnection? @@ -223,4 +225,47 @@ final class HelperClient { .map { $0.0 } .eraseToAnyPublisher() } + + // MARK: - Install + // From https://github.com/securing/SimpleXPCApp/ + + func install() { + var authItem = kSMRightBlessPrivilegedHelper.withCString { name in + AuthorizationItem(name: name, valueLength: 0, value:UnsafeMutableRawPointer(bitPattern: 0), flags: 0) + } + var authRights = withUnsafeMutablePointer(to: &authItem) { authItem in + AuthorizationRights(count: 1, items: authItem) + } + + do { + let authRef = try authorizationRef(&authRights, nil, [.interactionAllowed, .extendRights, .preAuthorize]) + var cfError: Unmanaged? + SMJobBless(kSMDomainSystemLaunchd, machServiceName as CFString, authRef, &cfError) + if let error = cfError?.takeRetainedValue() { throw error } + + self.connection?.invalidate() + self.connection = nil + } catch { + Logger.helperClient.error("\(error.localizedDescription)") + } + } + + private func executeAuthorizationFunction(_ authorizationFunction: () -> (OSStatus) ) throws { + let osStatus = authorizationFunction() + guard osStatus == errAuthorizationSuccess else { + throw HelperClientError.message(String(describing: SecCopyErrorMessageString(osStatus, nil))) + } + } + + func authorizationRef(_ rights: UnsafePointer?, + _ environment: UnsafePointer?, + _ flags: AuthorizationFlags) throws -> AuthorizationRef? { + var authRef: AuthorizationRef? + try executeAuthorizationFunction { AuthorizationCreate(rights, environment, flags, &authRef) } + return authRef + } +} + +enum HelperClientError: Error { + case message(String) } diff --git a/Xcodes/Backend/HelperInstaller.swift b/Xcodes/Backend/HelperInstaller.swift deleted file mode 100644 index af70188..0000000 --- a/Xcodes/Backend/HelperInstaller.swift +++ /dev/null @@ -1,44 +0,0 @@ -// From https://github.com/securing/SimpleXPCApp/ - -import Foundation -import os.log -import ServiceManagement - -enum HelperAuthorizationError: Error { - case message(String) -} - -class HelperInstaller { - private static func executeAuthorizationFunction(_ authorizationFunction: () -> (OSStatus) ) throws { - let osStatus = authorizationFunction() - guard osStatus == errAuthorizationSuccess else { - throw HelperAuthorizationError.message(String(describing: SecCopyErrorMessageString(osStatus, nil))) - } - } - - static func authorizationRef(_ rights: UnsafePointer?, - _ environment: UnsafePointer?, - _ flags: AuthorizationFlags) throws -> AuthorizationRef? { - var authRef: AuthorizationRef? - try executeAuthorizationFunction { AuthorizationCreate(rights, environment, flags, &authRef) } - return authRef - } - - static func install() { - var authItem = kSMRightBlessPrivilegedHelper.withCString { name in - AuthorizationItem(name: name, valueLength: 0, value:UnsafeMutableRawPointer(bitPattern: 0), flags: 0) - } - var authRights = withUnsafeMutablePointer(to: &authItem) { authItem in - AuthorizationRights(count: 1, items: authItem) - } - - do { - let authRef = try authorizationRef(&authRights, nil, [.interactionAllowed, .extendRights, .preAuthorize]) - var cfError: Unmanaged? - SMJobBless(kSMDomainSystemLaunchd, machServiceName as CFString, authRef, &cfError) - if let error = cfError?.takeRetainedValue() { throw error } - } catch { - Logger.helperInstaller.error("\(error.localizedDescription)") - } - } -} diff --git a/Xcodes/Backend/Logger.swift b/Xcodes/Backend/Logger.swift index d83f9b3..57540b8 100644 --- a/Xcodes/Backend/Logger.swift +++ b/Xcodes/Backend/Logger.swift @@ -5,6 +5,6 @@ extension Logger { private static var subsystem = Bundle.main.bundleIdentifier! static let appState = Logger(subsystem: subsystem, category: "appState") - static let helperInstaller = Logger(subsystem: subsystem, category: "helperInstaller") + static let helperClient = Logger(subsystem: subsystem, category: "helperClient") static let subprocess = Logger(subsystem: subsystem, category: "subprocess") }