हमारे पास एक लॉन्च डेमॉन है (जरूरी है कि, विभिन्न कारणों से) रूट के रूप में चलता है, और जो नेटवर्क के माध्यम से सर्वर घटक के साथ संचार करता है। इसे सेवा के साथ प्रमाणित करने की आवश्यकता है, इसलिए जब यह पहली बार पासवर्ड प्राप्त करता है, तो हम इसे सिस्टम कीचेन में सहेजते हैं। बाद के लॉन्च पर, विचार कुंजीचैन से पासवर्ड पुनर्प्राप्त करना और नेटवर्क सेवा के साथ प्रमाणित करने के लिए इसका उपयोग करना है।मैक लॉन्च डेमन इसे सहेजने के बाद सिस्टम कीचेन से पासवर्ड पुनर्प्राप्त करने में असमर्थ
यह ठीक काम कर रहा है, लेकिन मैकोज़ 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
लौटने शुरू हो गया है।
कुछ अतिरिक्त विवरण हम जांच की है और बातें हम कोशिश की है, कोई लाभ नहीं हुआ:
- डेमॉन बाइनरी में डेवलपर आईडी प्रमाणपत्र के साथ हस्ताक्षरित किया गया है।
- डेमॉन बाइनरी में एक बंडल आईडी और संस्करण के साथ एक एम्बेडेड Info.plist अनुभाग होता है।
- मैं Keychain Access.app में पासवर्ड आइटम के "एक्सेस कंट्रोल" टैब में "हमेशा इन एप्लिकेशन द्वारा एक्सेस की अनुमति दें" सूची में डेमन बाइनरी देख सकता हूं।
- यदि मैं मैन्युअल रूप से कुंजीपैन एक्सेस में "सभी एप्लिकेशन को इस आइटम तक पहुंचने की अनुमति देता हूं" पर स्विच करता हूं, तो यह काम करता है। हालांकि, यह कुछ हद तक कुंजीचैन में पासवर्ड को सहेजने के बिंदु को हरा देता है।
- हमने पैरामीटर के साथ
SecKeychainAddInternetPassword
पर खेलने की कोशिश की है, लेकिन ऐसा कोई फर्क नहीं पड़ता है। - हमने
SecKeychainUnlock()
के साथ कीचेन को स्पष्ट रूप से अनलॉक करने का प्रयास किया है, लेकिन जैसा कि प्रलेखन सुझाव देता है, यह अनिवार्य प्रतीत होता है। Keychain Access.app
में आइटम को हटाने सेSecKeychainFindInternetPassword()
errSecItemNotFound
उत्पन्न करने के कारण होता है, जैसा कि आप उम्मीद करेंगे। तो यह निश्चित रूप से सहेजे गए आइटम को ढूंढ सकता है, इसे पढ़ने की अनुमति नहीं है।
कीचेन दस्तावेज पढ़ने और भागों में बल्कि tautological के लिए बिल्कुल आसान नहीं है। ("वाई करने के लिए, आपको वाई करने की ज़रूरत है," यह उल्लेख किए बिना कि आप वाई क्यों करना चाहते हैं।) फिर भी, मुझे लगता है कि मैंने इसे बनाया है और इसमें से अधिकांश को समझ लिया है।हमारे विशेष सेटअप के विभिन्न पहलुओं को विस्तार से शामिल नहीं किया गया है (एक डेमॉन से एक्सेस), लेकिन यह बहुत स्पष्ट लगता है कि एक ही ऐप को उसी ऐप द्वारा सहेजा गया एक आइटम तक पहुंचने से पहले को किसी विशेष प्राधिकरण या प्रमाणीकरण की आवश्यकता नहीं होनी चाहिए। जो हम देख रहे व्यवहार के प्रत्यक्ष विरोधाभास में है।
कोई भी विचार?