ClientIdentification::GuestState *ClientIdentification::current() const { // if we have no client identification, we can't find a current guest either if (!processCode()) return NULL; SecGuestRef guestRef = Server::connection().guestRef(); // try to deliver an already-cached entry { StLock<Mutex> _(mLock); GuestMap::iterator it = mGuests.find(guestRef); if (it != mGuests.end()) return &it->second; } // okay, make a new one (this may take a while) CFRef<CFDictionaryRef> attributes = (guestRef == kSecNoGuest) ? NULL : makeCFDictionary(1, kSecGuestAttributeCanonical, CFTempNumber(guestRef).get()); Server::active().longTermActivity(); CFRef<SecCodeRef> code; switch (OSStatus rc = SecCodeCopyGuestWithAttributes(processCode(), attributes, kSecCSDefaultFlags, &code.aref())) { case noErr: break; case errSecCSUnsigned: // not signed; clearly not a host case errSecCSNotAHost: // signed but not marked as a (potential) host code = mClientProcess; break; case errSecCSNoSuchCode: // potential host, but... if (guestRef == kSecNoGuest) { // ... no guests (yet), so return the process code = mClientProcess; break; } // else fall through // ... the guest we expected to be there isn't default: MacOSError::throwMe(rc); } StLock<Mutex> _(mLock); GuestState &slot = mGuests[guestRef]; if (!slot.code) // if another thread didn't get here first... slot.code = code; return &slot; }
CFDictionaryRef PolicyEngine::update(CFTypeRef target, SecAssessmentFlags flags, CFDictionaryRef context) { // update GKE installExplicitSet(gkeAuthFile, gkeSigsFile); AuthorityType type = typeFor(context, kAuthorityInvalid); CFStringRef edit = CFStringRef(CFDictionaryGetValue(context, kSecAssessmentContextKeyUpdate)); CFDictionaryRef result; if (CFEqual(edit, kSecAssessmentUpdateOperationAdd)) result = this->add(target, type, flags, context); else if (CFEqual(edit, kSecAssessmentUpdateOperationRemove)) result = this->remove(target, type, flags, context); else if (CFEqual(edit, kSecAssessmentUpdateOperationEnable)) result = this->enable(target, type, flags, context); else if (CFEqual(edit, kSecAssessmentUpdateOperationDisable)) result = this->disable(target, type, flags, context); else if (CFEqual(edit, kSecAssessmentUpdateOperationFind)) result = this->find(target, type, flags, context); else MacOSError::throwMe(errSecCSInvalidAttributeValues); if (result == NULL) result = makeCFDictionary(0); // success, no details return result; }