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);
}
Esempio n. 3
0
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;
}