2017-09-07 2 views
1

SMJobBless을 사용하는 Swift macOS 앱을 생성하여 에스컬레이션 된 권한을 가진 도우미를 만듭니다. 이것은 잘 작동하는데 도우미는 /Library/Privileged Helper Tools에 설치되고 동반 LaunchDaemon은 /Library/LaunchDaemons에 생성됩니다. 그러나 도우미는 성공적으로 시작할 수 없습니다. 대신 "Illegal instruction : 4"메시지와 충돌합니다.잘못된 명령 오류로 Swift Privileged Helper (XPC Listener)가 깨졌습니다.

NSXPCListenerDelegate 프로토콜을 구현하여 XML 연결에 응답하는 도우미를 준비했습니다.

import Foundation 

class HelperDelegate: NSObject, NSXPCListenerDelegate {  
    func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {   
    newConnection.exportedInterface = NSXPCInterface(with: HelperToolProtocol.self) 
     newConnection.exportedObject = HelperTool() 
     newConnection.resume() 
     return true 
    }  
} 

let delegate = HelperDelegate() 
let listener = NSXPCListener.service() 
listener.delegate = delegate 
listener.resume() 

충돌은 마지막 줄, listener.resume() 발생 : 여기 내 도우미 main.swift 코드입니다.

명령 줄 (LaunchDaemon과 동일한 기능)에서 수동으로 도우미 응용 프로그램을 시작하려고 시도했지만 위의 오류 메시지가 stdout에 인쇄되어 충돌합니다. 근본 원인을 테스트하는 방법에 대한 더 이상의 아이디어가 없습니다. 구현은 Apple’s guidlines for implementing XM services에 이어 초보적인 것 이상입니다. 또한 XML 서비스와 관련하여 SO에 대한 여러 게시물이이 문제를 해결하는 데 도움이되지 못했습니다. Swift에서 권한있는 도우미를 성공적으로 만들려고 노력한 사람이 있습니까? BTW, 응용 프로그램은 샌드 박스되지 않습니다.

완성도를 위해서

, 여기에 위의 내 HelperDelegate 클래스에서 참조 HelperTool 클래스의 코드는 다음과 같습니다 마지막으로 HelperToolProtocol

import Foundation 

class HelperTool: NSObject, HelperToolProtocol { 
    func getVersion(withReply reply: (NSData?) ->()) { 
     let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString" as String) as? String ?? "<unknown version>" 
     let build = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String ?? "<unknown build>" 
     if let d = "v\(version) (\(build))".data(using: .utf8, allowLossyConversion: false) { 
      reply(d as NSData) 
     } 
    } 
} 

그리고 : 어떤 도움

import Foundation 

@objc(HelperToolProtocol) protocol HelperToolProtocol { 
    func getVersion(withReply: (NSData?) ->()) 
} 

감사합니다!

답변

0

테스트를 마친 후 필자는 XPC 도우미가 올바르게 시작되어 모든 메시지에 응답 할 수있는 솔루션을 발견했습니다. 문제는 현재의 문제에 넣어, 맨 마지막 라인에 즉시 도우미 충돌을

let listener = NSXPCListener.service() 
listener.delegate = delegate 
listener.resume() 

을 읽어 main.swift 모듈의 마지막 세 줄에있다.

이 라인을 Apple’s Creating XPC Services documentation에서 직접 가져 왔습니다. service() 객체에서 호출하면

는,이 메소드는 반환하지 : 여기에 NSXPCListenerresume() 기능에 대한 설명서입니다. 따라서 원하는 초기 상태를 설정하고 수신기 자체를 구성한 후에 XPC 서비스의 주 기능 내에서 마지막 단계로 호출해야합니다.

솔루션은 NSXPCListener.service() 단일 객체를 호출 아니라 주요 응용 프로그램의 XPC 연결에 사용되는 동일한 마하 서비스 이름을 통과하는 init(machServiceName:) 초기화를 사용하여 새 NSXPCListener 개체를 인스턴스화하지 이다. 이 경우 resume()이 즉시 다시 시작되므로 도우미가 종료되므로 현재 실행 루프에 놓아 두어 불확실하게 실행해야합니다. 새로운 작업 코드는 다음과 같습니다.

let listener = NSXPCListener(machServiceName: "Privilege-Escalation-Sample.Helper") 
listener.delegate = delegate 
listener.resume() 
RunLoop.current.run() 
관련 문제