76 lines
2.5 KiB
Swift
76 lines
2.5 KiB
Swift
//
|
|
// SMJobLessAuthorization.swift
|
|
// main
|
|
//
|
|
// Created by Jura on 3/12/20.
|
|
// Copyright © 2020 Juraldinio. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import ServiceManagement
|
|
|
|
final class SMJobLessAuthorization {
|
|
|
|
enum SMJobLessAuthorizationError: Error {
|
|
case message(String)
|
|
}
|
|
|
|
private static var authRef: AuthorizationRef?
|
|
|
|
// MARK: - Interface
|
|
|
|
// Install and activate the helper inside our application bundle to disk.
|
|
static func install(executable label: String) -> Bool {
|
|
|
|
guard let authRef = self.getAuthRef() else { return false }
|
|
|
|
var cfError: Unmanaged<CFError>?
|
|
let success = SMJobBless(kSMDomainSystemLaunchd, label as CFString, authRef, &cfError)
|
|
|
|
if cfError?.takeRetainedValue() != nil { return false }
|
|
|
|
return success
|
|
}
|
|
|
|
static func dropAuth() {
|
|
self.authRef = nil
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private static func getAuthRef() -> AuthorizationRef? {
|
|
|
|
if let authRef = self.authRef { return authRef }
|
|
|
|
var authItem = AuthorizationItem(name: kSMRightBlessPrivilegedHelper,
|
|
valueLength: 0,
|
|
value: UnsafeMutableRawPointer(bitPattern: 0),
|
|
flags: 0)
|
|
|
|
var authRights = AuthorizationRights(count: 1, items: &authItem)
|
|
do {
|
|
if let authRef = try self.authorizationRef(&authRights, nil, [.interactionAllowed, .extendRights, .preAuthorize]) {
|
|
self.authRef = authRef
|
|
}
|
|
} catch {}
|
|
|
|
return self.authRef
|
|
}
|
|
|
|
private static func authorizationRef(_ rights: UnsafePointer<AuthorizationRights>?,
|
|
_ environment: UnsafePointer<AuthorizationEnvironment>?,
|
|
_ flags: AuthorizationFlags) throws -> AuthorizationRef? {
|
|
var authRef: AuthorizationRef?
|
|
try executeAuthorizationFunction { AuthorizationCreate(rights, environment, flags, &authRef) }
|
|
return authRef
|
|
}
|
|
|
|
private static func executeAuthorizationFunction(_ authorizationFunction: () -> (OSStatus) ) throws {
|
|
let osStatus = authorizationFunction()
|
|
guard osStatus == errAuthorizationSuccess else {
|
|
throw SMJobLessAuthorizationError.message(String(describing: SecCopyErrorMessageString(osStatus, nil)))
|
|
}
|
|
}
|
|
|
|
}
|