// From https://github.com/securing/SimpleXPCApp/ // MIT License // // Copyright (c) 2020 securing // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Installer implemented basing on https://github.com/erikberglund/SwiftPrivilegedHelper import Foundation 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) } catch let err { print("Error in installing the helper -> \(err.localizedDescription)") } } }