Files
2020-12-25 01:03:51 +03:00

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)))
}
}
}