最近一段時間開發(fā)公司一款MacOS平臺的App時需要用到管理員權(quán)限陪拘,于是乎上網(wǎng)查詢了MacOS App使用代碼提權(quán)的方式,目前主要有以下幾種:
1.通過ServiceManagement注冊LaunchdDaemon
這種方法是目前蘋果官方推薦的一種提權(quán)方式如迟,官方也提供了一個SMJobBless的Demo一也,但是需要用蘋果開發(fā)者賬號編譯(我會在我博客后面的文章單獨介紹一種不需要開發(fā)者賬號編譯的方式署隘,也能通過這種方式達到高權(quán)限的需求蘑秽,在本文末尾會提供思路!)饺著,而且使用起來很復(fù)雜箫攀。帶來的好處是,將高權(quán)限任務(wù)封裝到獨立的子程序幼衰,將按需調(diào)用靴跛,不會讓整個程序處于高權(quán)限的狀態(tài)會相對安全一些,子程序便能輕松實現(xiàn)開機自啟塑顺、常駐后臺汤求、高權(quán)限的需求俏险。
我通過研究官方SMJobBless的Demo严拒,發(fā)現(xiàn)其實是通過launchd工具加載一個與Daemon程序相關(guān)的標(biāo)準(zhǔn)的plist文件,由于launchd需要高權(quán)限運行竖独,所以啟動的子程序自然而然也是高權(quán)限運行裤唠。程序運行之后,會將子程序放到/Library/PrivilegedHelperTools
這個目錄莹痢,需要的plist文件會被放到/Library/LaunchDaemons
种蘸,這樣launchd加載plist時,會去啟動子程序竞膳。
在SMJobBless的Demo中是通過ServiceManagement這個框架的API來完成提權(quán)操作的航瞭,而這框架在10.6就出現(xiàn)了,所以不需要擔(dān)心兼容性的問題坦辟。本文在這里不詳細介紹如何使用相關(guān)API了刊侯,只是在這里簡單說說編譯方法吧!在Demo中的ReadMe.txt中雖然講述的很清楚锉走,但是新版xcode編譯之后的目錄有所不同滨彻。(注意:程序雖然編譯成功,但在默認(rèn)的SMJobBlessHelper-Launchd.plist
中并沒有RunAtLoad
這一屬性挪蹭,所以launchd不會啟動子程序亭饵,只會將子程序放和plist文件到相關(guān)目錄,如需啟動子程序梁厉,需在SMJobBlessHelper-Launchd.plist
中添加RunAtLoad
屬性辜羊,Boolean類型,值為YES
)
1.在xcode中編譯項目 (Product > Build或者command+b
)
2.使用終端進入項目根目錄词顾,運行以下命令:
./SMJobBlessUtil.py setreq <SMJobBlessApp.app:path> SMJobBlessApp/SMJobBlessApp-Info.plist SMJobBlessHelper/SMJobBlessHelper-Info.plist
<SMJobBlessApp.app:path>
是指在xcode左邊的Navigator的product下的編譯的APP的路徑
腳本運行成功會輸出:
SMJobBlessApp/SMJobBlessApp-Info.plist: updated
SMJobBlessHelper/SMJobBlessHelper-Info.plist: updated
3.clean項目(Product > Clean)八秃,然后再次編譯(Product > Build)。
4.在項目根目錄下计技,終端執(zhí)行:
./SMJobBlessUtil.py check <SMJobBlessApp.app:path>
腳本運行成功沒有輸出任何東西喜德,說明成功了。
5.運行編譯的APP垮媒。
這時會彈出需要輸入密碼的認(rèn)證提示框舍悯,輸入密碼之后航棱,xcode在控制臺打印Job is available!
,App上有顯示The Helper Tool is available!
字樣萌衬,表示成功運行了饮醇。
官方Demo:SMJobBless.zip
2.AuthorizationExecuteWithPrivileges函數(shù)
這個函數(shù)是Security.framework中的一函數(shù),使用很方便秕豫,而且還有一個封裝非常好的庫STPrivilegedTask朴艰,接口和NSTask幾乎一樣。但是AuthorizationExecuteWithPrivileges函數(shù)在MacOS 10.7的時候就開始被棄用了混移,在新版的10.13.3中發(fā)現(xiàn)某些時候會提權(quán)失敗祠墅,所以不推薦使用這種方法,在本文也不做過多介紹歌径!
3.使用AppleScript提權(quán)
AppleScript是蘋果獨有的腳本語言毁嗦,通過OC或者Swift都可以調(diào)用AppleScript,在這里提供一個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方法固然簡單回铛,但是還有一些缺點狗准,比如每次需要管理員權(quán)限時,都需要提示輸入密碼茵肃,會讓用戶感覺你總是在獲取權(quán)限腔长,造成用戶對你程序的不信任,在執(zhí)行需要等待結(jié)果的命令時验残,會造成UI卡住捞附,一直占有線程,所以建議在子線程中運行!
4.自創(chuàng)的提權(quán)方法(思路)
提供一個通過AppleScript啟動launchd子程序的思路(我博客后面的文章單獨做介紹)胚膊,這樣也可以實現(xiàn)高權(quán)限故俐,常駐后臺的需求。
AppleScript可以運行shell腳本(方法3提供的OC語言的方法就可以執(zhí)行腳本)紊婉,而shell腳本可以傳入?yún)?shù)药版,知道這兩點,我們就可以在自己項目中建立子程序和需要plist文件喻犁,通過AppleScript執(zhí)行管理員權(quán)限運行shell腳本槽片,shell腳本把plist文件和子程序移動到方法1中的所提到的目錄中,這樣是不是可以達到一樣的方法呢肢础?感興趣的童鞋可以試試还栓!
本文來源:https://blog.ihitun.com/posts/431360628/
未經(jīng)博主同意不得轉(zhuǎn)載!