2016-11-16 16 views
5

우리는 루트를 사용하여 실행되는 시작 데몬을 가지고 있으며 네트워크를 통해 서버 구성 요소와 통신합니다. 서비스로 인증해야하기 때문에 암호를 처음 가져올 때 시스템 키 체인에 저장합니다. 후속 실행시, 키 체인에서 암호를 검색하여이를 사용하여 네트워크 서비스를 인증하는 것이 좋습니다.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의 "system"키 체인에서 항목을 볼 수 있습니다. 우리 데몬의 후속 실행에 가져

이 선으로 이루어집니다 :

status = SecKeychainFindInternetPassword(
    system_keychain, 
    urlLength, url, 
    0, NULL, 
    usernameLength, username, 
    0, NULL, 
    0, 
    kSecProtocolTypeAny, kSecAuthenticationTypeAny, 
    &passwordLength, &password_data, 
    NULL); 

불행하게도,이 우리에게 불분명 한 이유로 errSecAuthFailed 반환 시작했다. 아무 소용이

우리가 시도한 몇 가지 추가 우리가 점검 한 내용과 일

:

  • 데몬 바이너리는 개발자 아이디 인증서로 서명됩니다.
  • 데몬 바이너리에는 번들 ID와 버전이있는 Info.plist 섹션이 포함되어 있습니다.
  • Keychain Access.app의 암호 항목에있는 "Access Control"탭에서 "이 응용 프로그램의 액세스를 항상 허용"목록에서 데몬 바이너리를 볼 수 있습니다.
  • 키 체인 접근에서 "모든 응용 프로그램이이 항목에 액세스하도록 허용"으로 수동 전환하면 작동합니다. 그러나 키 체인에 비밀번호를 저장하는 데는 다소 어려움이 있습니다.
  • 우리는 매개 변수를 SecKeychainAddInternetPassword으로 사용 해보았지만 아무런 차이가 없었습니다.
  • 우리는 SecKeychainUnlock()으로 키 체인의 잠금을 해제하려했지만 문서에 나와 있듯이 이것은 불필요한 것으로 보입니다.
  • Keychain Access.app에있는 항목을 삭제하면 SecKeychainFindInternetPassword()errSecItemNotFound이됩니다 (예상대로). 그래서 그것은 확실히 찾기 항목을 저장할 수 있습니다, 그냥 읽을 수 없습니다.

키 체인 설명서는 읽기 쉽고 부분적으로 동어 반복적 인 부분이 아닙니다. ("Y를하기 위해서 당신은 Y를하고 싶다"라고 언급하지 않고 Y를 할 필요가있다.) 그럼에도 불구하고, 나는 그것을 끝내고 그것을 대부분 이해했다고 생각한다.특정 설정의 다양한 측면에 대해서는 자세히 다루지 않지만 (데몬으로부터의 액세스) 이전에 에 저장된 항목에 액세스하려면에 특별한 승인이나 인증이 필요하지 않아야합니다. 우리가 보는 행동과 직접적으로 모순이됩니다.

아이디어가 있으십니까?

답변

7

며칠에 걸쳐 더 많은 시간을 보낸 후 우리는 마침내 진행되고있는 일을 마쳤습니다.

먼저, 문제를 재현 할 수있는 최소한의 예제를 만들려고했습니다. 이것은 errSecAuthFailed으로 실패하지 않았으므로 문제가 재현되지 않았습니다. 그래서 원래의 데몬으로 돌아가서 잘못되었다는 점에 대해 특별히 뭔가가 있어야합니다.

다음 아이디어는 SecKeychainFindInternetPassword()이 호출 된 시간에 대한 시스템 로그를 확인하는 것이 었습니다. 이로 인해 다음과 같은 오류 메시지가 표시되었습니다.

securityd CSSM Exception: -2147411889 CSSMERR_CL_UNKNOWN_TAG 
securityd MacOS error: -67063 
securityd MacOS error: -67063 
securityd code requirement check failed (-67063), client is not Apple-signed 
securityd CSSM Exception: 32 CSSM_ERRCODE_OPERATION_AUTH_DENIED 
OurDaemon subsystem: com.apple.securityd, category: security_exception, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 2, enable_private_data: 0 
OurDaemon CSSM Exception: -2147416032 CSSMERR_CSP_OPERATION_AUTH_DENIED 

코드 서명과 관련된 문제 일 수 있습니다. 이상한. 바이너리의 코드 서명을 codesign -vv으로 확인하면 아무런 문제가 없습니다.

오류 메시지의 여러 부분을 웹에서 검색 한 결과 -67063 corresponds to errSecCSGuestInvalid입니다. 코멘트는 "코드 ID가 무효화되었습니다."라고 읽습니다.

오케이, 분명히 일부 코드 작성 오류가 발생하지만, 그 의미는 무엇이며 왜 발생 했습니까?

사냥 좀 더 마지막으로 설명하고, 또한 솔루션 켜져 주위 : http://lists.apple.com/archives/apple-cdsa/2010/Mar/msg00027.html

그것은 의미를 그 프로그램이 시작되었다 이후 어느 시점, 그것은 무효 그것이 일어난 뭔가.

서명 된 프로그램을 실행하면

, 다음 장소 :-)에 새 버전을 구축, 말,로 (교체하고, 커널을 새 버전을 실행 은 여전히 ​​실행 파일의 vnode에 첨부 된 이전 서명을 보유합니다. 상황에 따라 실행 파일을 제거하고 을 다시 작성하면 파일을 다시 덮어 쓸 때까지 문제가 해결됩니다 ( :-). 서명 된 코드는 항상 대체해야합니다 (mv (1), cp (1) 또는 동등한 것이 아님).

이렇게 설명했습니다. 나는

sudo cp path/to/built/daemon /usr/local/libexec/ 

은 분명히, 그 대신, 새로운 vnode에를 만드는 것을 작성하고 이전 파일을 통해 이름을 변경보다는 현재 위치에서 파일을 덮어 사용하여 제자리에 데몬의 새 버전을 복사했다. 그래서 해결 방법은 임시 디렉토리에 cp을 먼저 넣은 다음 mv을 입력하는 것입니다. 또는 cp을 사용하기 전에 대상 파일을 삭제하십시오.

내가 한 것처럼 빨리 작동했습니다!