我們有一個啓動守護進程(由於各種原因)必須以root身份運行,並通過網絡與服務器組件進行通信。它需要使用服務進行身份驗證,所以當它第一次獲得密碼時,我們將它保存到系統鑰匙串中。在隨後的發佈中,想法是從鑰匙鏈中檢索密碼並使用它來與網絡服務進行認證。Mac啓動守護進程保存後無法從系統鑰匙串中檢索密碼
這一直工作正常,但在MacOS 10.12現有的代碼停止工作,我們已經完全難倒如何解決這個問題。它歸結爲:
無論我們節省了一個新的密碼或檢索一箇舊的,我們獲得對系統的鑰匙串基準來此:
SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &system_keychain);
,因爲我們也禁止用戶交互好的措施,儘管我們預計它已經在守護進程中關閉了。
SecKeychainSetUserInteractionAllowed(false);
當保存一個新的密碼到鑰匙鏈,我們使用
OSStatus status = SecKeychainAddInternetPassword(
system_keychain,
urlLength, server_base_url,
0, NULL,
usernameLength, username,
0, NULL,
0,
kSecProtocolTypeAny, kSecAuthenticationTypeAny,
passwordLength, password,
NULL);
該作品不多。報告成功後,我可以在Keychain Access.app的「系統」鑰匙串中看到該項目。
檢索其後續我們守護的運行與該行完成的:
status = SecKeychainFindInternetPassword(
system_keychain,
urlLength, url,
0, NULL,
usernameLength, username,
0, NULL,
0,
kSecProtocolTypeAny, kSecAuthenticationTypeAny,
&passwordLength, &password_data,
NULL);
不幸的是,這已經開始返回errSecAuthFailed
對於那些我們不清楚原因。
我們嘗試,我們已經檢查了一些其他的細節和事情,都無濟於事:
- 守護程序二進制與開發者ID證書籤名。
- 守護程序二進制文件包含嵌入的Info.plist部分,其中包含一個包ID和版本。
- 我可以在Keychain Access.app中的密碼項目的「訪問控制」選項卡的「始終允許訪問這些應用程序」列表中看到守護進程二進制文件。
- 如果我手動切換到「允許所有應用程序訪問此項目」鑰匙串訪問,它的工作原理。然而,這有點破壞了在密鑰鏈中保存密碼的觀點。
- 我們試過玩
SecKeychainAddInternetPassword
的參數,但這似乎沒有任何區別。 - 我們試圖明確解鎖鑰匙扣
SecKeychainUnlock()
,但文檔建議,這似乎是多餘的。 - 刪除項
Keychain Access.app
原因SecKeychainFindInternetPassword()
產生errSecItemNotFound
,正如你所期望。所以它絕對可以找到保存的項目,它只是不允許閱讀它。
鑰匙鏈文檔並不完全容易閱讀,而且部分文字是相當重複的。 (「爲了做Y,你需要做Y」,而沒有提及你爲什麼想要做Y.)然而,我認爲我已經完成並且理解了它的大部分內容。我們特定設置的各個方面並未詳細介紹(從守護進程訪問),但似乎很清楚,訪問之前由同一應用保存的項目不應該要求任何特殊授權或驗證。這與我們所看到的行爲直接相矛盾。
任何想法?