CFDictionaryRef PolicyEngine::find(CFTypeRef target, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context) { SQLite::Statement query(*this); selectRules(query, "SELECT scan_authority.id, scan_authority.type, scan_authority.requirement, scan_authority.allow, scan_authority.label, scan_authority.priority, scan_authority.remarks, scan_authority.expires, scan_authority.disabled, bookmarkhints.bookmark FROM scan_authority LEFT OUTER JOIN bookmarkhints ON scan_authority.id = bookmarkhints.authority", "scan_authority", target, type, flags, context, " ORDER BY priority DESC"); CFRef<CFMutableArrayRef> found = makeCFMutableArray(0); while (query.nextRow()) { SQLite::int64 id = query[0]; int type = int(query[1]); const char *requirement = query[2]; int allow = int(query[3]); const char *label = query[4]; double priority = query[5]; const char *remarks = query[6]; double expires = query[7]; int disabled = int(query[8]); CFRef<CFDataRef> bookmark = query[9].data(); CFRef<CFMutableDictionaryRef> rule = makeCFMutableDictionary(5, kSecAssessmentRuleKeyID, CFTempNumber(id).get(), kSecAssessmentRuleKeyType, CFRef<CFStringRef>(typeNameFor(type)).get(), kSecAssessmentRuleKeyRequirement, CFTempString(requirement).get(), kSecAssessmentRuleKeyAllow, allow ? kCFBooleanTrue : kCFBooleanFalse, kSecAssessmentRuleKeyPriority, CFTempNumber(priority).get() ); if (label) CFDictionaryAddValue(rule, kSecAssessmentRuleKeyLabel, CFTempString(label)); if (remarks) CFDictionaryAddValue(rule, kSecAssessmentRuleKeyRemarks, CFTempString(remarks)); if (expires != never) CFDictionaryAddValue(rule, kSecAssessmentRuleKeyExpires, CFRef<CFDateRef>(julianToDate(expires))); if (disabled) CFDictionaryAddValue(rule, kSecAssessmentRuleKeyDisabled, CFTempNumber(disabled)); if (bookmark) CFDictionaryAddValue(rule, kSecAssessmentRuleKeyBookmark, bookmark); CFArrayAppendValue(found, rule); } if (CFArrayGetCount(found) == 0) MacOSError::throwMe(errSecCSNoMatches); return cfmake<CFDictionaryRef>("{%O=%O}", kSecAssessmentUpdateKeyFound, found.get()); }
// // Result-creation helpers // void PolicyEngine::addAuthority(CFMutableDictionaryRef parent, const char *label, SQLite::int64 row, CFTypeRef cacheInfo) { CFRef<CFMutableDictionaryRef> auth = makeCFMutableDictionary(); if (label && label[0]) cfadd(auth, "{%O=%s}", kSecAssessmentAssessmentSource, label); if (row) CFDictionaryAddValue(auth, kSecAssessmentAssessmentAuthorityRow, CFTempNumber(row)); if (overrideAssessment()) CFDictionaryAddValue(auth, kSecAssessmentAssessmentAuthorityOverride, kDisabledOverride); if (cacheInfo) CFDictionaryAddValue(auth, kSecAssessmentAssessmentFromCache, cacheInfo); CFDictionaryAddValue(parent, kSecAssessmentAssessmentAuthority, auth); }
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; }