90 lines
3.0 KiB
Swift
90 lines
3.0 KiB
Swift
import Foundation
|
|
import Library
|
|
import os
|
|
|
|
private let logger = Logger(category: "RootHelper")
|
|
|
|
class RootHelperService: NSObject {
|
|
private var listener: NSXPCListener?
|
|
|
|
func start() {
|
|
listener = NSXPCListener(machServiceName: AppConfiguration.rootHelperMachService)
|
|
listener?.delegate = self
|
|
listener?.resume()
|
|
}
|
|
}
|
|
|
|
extension RootHelperService: NSXPCListenerDelegate {
|
|
func listener(_: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
|
|
let systemExtensionID = AppConfiguration.systemExtensionBundleID
|
|
let standaloneID = AppConfiguration.packageName + ".standalone"
|
|
let teamID = AppConfiguration.teamID
|
|
let requirement = "(identifier \"\(systemExtensionID)\" or identifier \"\(standaloneID)\") and anchor apple generic and certificate leaf[subject.OU] = \"\(teamID)\""
|
|
do {
|
|
try newConnection.setCodeSigningRequirement(requirement)
|
|
} catch {
|
|
logger.warning("Rejected XPC connection: \(error.localizedDescription)")
|
|
return false
|
|
}
|
|
|
|
let exportedInterface = NSXPCInterface(with: RootHelperProtocol.self)
|
|
RootHelperXPC.configureInterface(exportedInterface)
|
|
newConnection.exportedInterface = exportedInterface
|
|
newConnection.exportedObject = self
|
|
newConnection.resume()
|
|
return true
|
|
}
|
|
}
|
|
|
|
extension RootHelperService: RootHelperProtocol {
|
|
func findConnectionOwner(
|
|
ipProtocol: Int32,
|
|
sourceAddress: String,
|
|
sourcePort: Int32,
|
|
destinationAddress: String,
|
|
destinationPort: Int32,
|
|
reply: @escaping (ConnectionOwnerResult?, NSError?) -> Void
|
|
) {
|
|
guard let result = ConnectionOwnerLookup.find(
|
|
ipProtocol: ipProtocol,
|
|
sourceAddress: sourceAddress,
|
|
sourcePort: sourcePort,
|
|
destinationAddress: destinationAddress,
|
|
destinationPort: destinationPort
|
|
) else {
|
|
let error = NSError(domain: "RootHelper", code: -1, userInfo: [
|
|
NSLocalizedDescriptionKey: "Connection owner not found",
|
|
])
|
|
logger.error("findConnectionOwner: \(error.localizedDescription)")
|
|
reply(nil, error)
|
|
return
|
|
}
|
|
|
|
let ownerResult = ConnectionOwnerResult(
|
|
userId: result.userId,
|
|
userName: result.userName,
|
|
processPath: result.processPath
|
|
)
|
|
reply(ownerResult, nil)
|
|
}
|
|
|
|
func getWorkingDirectorySize(reply: @escaping (Int64, NSError?) -> Void) {
|
|
let size = WorkingDirectoryManager.getSize()
|
|
reply(size, nil)
|
|
}
|
|
|
|
func cleanWorkingDirectory(reply: @escaping (NSError?) -> Void) {
|
|
do {
|
|
try WorkingDirectoryManager.clean()
|
|
reply(nil)
|
|
} catch {
|
|
logger.error("cleanWorkingDirectory error: \(error.localizedDescription)")
|
|
reply(error as NSError)
|
|
}
|
|
}
|
|
|
|
func getVersion(reply: @escaping (String) -> Void) {
|
|
reply(Bundle.main.version)
|
|
}
|
|
}
|