MacOS App代碼提權(quán)詳解

最近一段時(shí)間開發(fā)公司一款MacOS平臺(tái)的App時(shí)需要用到管理員權(quán)限,于是乎上網(wǎng)查詢了MacOS App使用代碼提權(quán)的方式,目前主要有以下幾種:

1.通過ServiceManagement注冊(cè)LaunchdDaemon

這種方法是目前蘋果官方推薦的一種提權(quán)方式,官方也提供了一個(gè)SMJobBless的Demo,但是需要用蘋果開發(fā)者賬號(hào)編譯(我會(huì)在我博客后面的文章單獨(dú)介紹一種不需要開發(fā)者賬號(hào)編譯的方式,也能通過這種方式達(dá)到高權(quán)限的需求,在本文末尾會(huì)提供思路!),而且使用起來很復(fù)雜。帶來的好處是,將高權(quán)限任務(wù)封裝到獨(dú)立的子程序,將按需調(diào)用,不會(huì)讓整個(gè)程序處于高權(quán)限的狀態(tài)會(huì)相對(duì)安全一些,子程序便能輕松實(shí)現(xiàn)開機(jī)自啟、常駐后臺(tái)、高權(quán)限的需求。

我通過研究官方SMJobBless的Demo,發(fā)現(xiàn)其實(shí)是通過launchd工具加載一個(gè)與Daemon程序相關(guān)的標(biāo)準(zhǔn)的plist文件,由于launchd需要高權(quán)限運(yùn)行,所以啟動(dòng)的子程序自然而然也是高權(quán)限運(yùn)行。程序運(yùn)行之后,會(huì)將子程序放到/Library/PrivilegedHelperTools這個(gè)目錄,需要的plist文件會(huì)被放到/Library/LaunchDaemons,這樣launchd加載plist時(shí),會(huì)去啟動(dòng)子程序。

在SMJobBless的Demo中是通過ServiceManagement這個(gè)框架的API來完成提權(quán)操作的,而這框架在10.6就出現(xiàn)了,所以不需要擔(dān)心兼容性的問題。本文在這里不詳細(xì)介紹如何使用相關(guān)API了,只是在這里簡(jiǎn)單說說編譯方法吧!在Demo中的ReadMe.txt中雖然講述的很清楚,但是新版xcode編譯之后的目錄有所不同。(注意:程序雖然編譯成功,但在默認(rèn)的SMJobBlessHelper-Launchd.plist中并沒有RunAtLoad這一屬性,所以launchd不會(huì)啟動(dòng)子程序,只會(huì)將子程序放和plist文件到相關(guān)目錄,如需啟動(dòng)子程序,需在SMJobBlessHelper-Launchd.plist中添加RunAtLoad屬性,Boolean類型,值為YES)

1.在xcode中編譯項(xiàng)目 (Product > Build或者command+b)
2.使用終端進(jìn)入項(xiàng)目根目錄,運(yùn)行以下命令:
./SMJobBlessUtil.py setreq <SMJobBlessApp.app:path> SMJobBlessApp/SMJobBlessApp-Info.plist SMJobBlessHelper/SMJobBlessHelper-Info.plist 

<SMJobBlessApp.app:path>是指在xcode左邊的Navigator的product下的編譯的APP的路徑

腳本運(yùn)行成功會(huì)輸出:

SMJobBlessApp/SMJobBlessApp-Info.plist: updated
SMJobBlessHelper/SMJobBlessHelper-Info.plist: updated
3.clean項(xiàng)目(Product > Clean),然后再次編譯(Product > Build)。
4.在項(xiàng)目根目錄下,終端執(zhí)行:
./SMJobBlessUtil.py check <SMJobBlessApp.app:path>

腳本運(yùn)行成功沒有輸出任何東西,說明成功了。

5.運(yùn)行編譯的APP。

這時(shí)會(huì)彈出需要輸入密碼的認(rèn)證提示框,輸入密碼之后,xcode在控制臺(tái)打印Job is available!,App上有顯示The Helper Tool is available!字樣,表示成功運(yùn)行了。

官方Demo:SMJobBless.zip

2.AuthorizationExecuteWithPrivileges函數(shù)

這個(gè)函數(shù)是Security.framework中的一函數(shù),使用很方便,而且還有一個(gè)封裝非常好的庫(kù)STPrivilegedTask,接口和NSTask幾乎一樣。但是AuthorizationExecuteWithPrivileges函數(shù)在MacOS 10.7的時(shí)候就開始被棄用了,在新版的10.13.3中發(fā)現(xiàn)某些時(shí)候會(huì)提權(quán)失敗,所以不推薦使用這種方法,在本文也不做過多介紹!

3.使用AppleScript提權(quán)

AppleScript是蘋果獨(dú)有的腳本語言,通過OC或者Swift都可以調(diào)用AppleScript,在這里提供一個(gè)OC寫的方法:

-(NSDictionary*)doAppleScript:(NSString*)cmd{
    cmd=[NSString stringWithFormat:@"do shell script \"%@\" with administrator privileges",cmd];
    NSAppleScript *script= [[NSAppleScript alloc] initWithSource:cmd];
    NSDictionary *scriptError = nil;
    NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&scriptError];
    NSMutableDictionary *dicResult=[NSMutableDictionary dictionary];
    if(scriptError) {
        [dicResult setObject:@NO forKey:@"id"];
        [dicResult setObject:[scriptError objectForKey:NSAppleScriptErrorMessage] forKey:@"result"];
    } else {
        NSAppleEventDescriptor *unicode = [descriptor coerceToDescriptorType:typeUnicodeText];
        NSData *data = [unicode data];
        NSString *result = [[NSString alloc] initWithCharacters:(unichar*)[data bytes] length:[data length] / sizeof(unichar)];
        [dicResult setObject:@YES forKey:@"id"];
        [dicResult setObject:result forKey:@"result"];
    }
    return dicResult;
}

AppleScript方法固然簡(jiǎn)單,但是還有一些缺點(diǎn),比如每次需要管理員權(quán)限時(shí),都需要提示輸入密碼,會(huì)讓用戶感覺你總是在獲取權(quán)限,造成用戶對(duì)你程序的不信任,在執(zhí)行需要等待結(jié)果的命令時(shí),會(huì)造成UI卡住,一直占有線程,所以建議在子線程中運(yùn)行!

4.自創(chuàng)的提權(quán)方法(思路)

提供一個(gè)通過AppleScript啟動(dòng)launchd子程序的思路(我博客后面的文章單獨(dú)做介紹),這樣也可以實(shí)現(xiàn)高權(quán)限,常駐后臺(tái)的需求。

AppleScript可以運(yùn)行shell腳本(方法3提供的OC語言的方法就可以執(zhí)行腳本),而shell腳本可以傳入?yún)?shù),知道這兩點(diǎn),我們就可以在自己項(xiàng)目中建立子程序和需要plist文件,通過AppleScript執(zhí)行管理員權(quán)限運(yùn)行shell腳本,shell腳本把plist文件和子程序移動(dòng)到方法1中的所提到的目錄中,這樣是不是可以達(dá)到一樣的方法呢?感興趣的童鞋可以試試!

本文來源:https://blog.ihitun.com/posts/431360628/
未經(jīng)博主同意不得轉(zhuǎn)載!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評(píng)論 25 708
  • mac上有自帶的腳本工具,腳本編輯器。AppleScript 是 Mac OS X內(nèi)置的一種功能強(qiáng)大的腳本語言。 ...
    Curry_J_X閱讀 11,077評(píng)論 2 8
  • 你說:人都是越活越現(xiàn)實(shí)的,只有你每天天真的以為著什麼都沒變都不會(huì)變 你說:我們總有一天會(huì)分開??!沒有人會(huì)一輩子在一...
    一期一會(huì)8閱讀 219評(píng)論 3 2
  • 1.我還是很喜歡你,像風(fēng)走了八千里,不問歸期。 2.我還是很喜歡你,像雨灑落在熱帶與極地,不遠(yuǎn)萬里。 3.我還是很...
    mmmm演員閱讀 299評(píng)論 0 0
  • 來京參賽,碰巧一位攝影師朋友也在同天抵京,一起約午飯。 她是會(huì)計(jì)專業(yè)轉(zhuǎn)攝影專業(yè),家境優(yōu)渥,準(zhǔn)備出國(guó)留學(xué)。 之前因?yàn)?..
    _SSharon閱讀 236評(píng)論 0 0

友情鏈接更多精彩內(nèi)容