Exemple #1
0
string cfString(CFTypeRef it, OSStatus err)
{
	if (it == NULL)
		MacOSError::throwMe(err);
	CFTypeID id = CFGetTypeID(it);
	if (id == CFStringGetTypeID())
		return cfString(CFStringRef(it));
	else if (id == CFURLGetTypeID())
		return cfString(CFURLRef(it));
	else if (id == CFBundleGetTypeID())
		return cfString(CFBundleRef(it));
	else
		return cfString(CFCopyDescription(it), true);
}
Exemple #2
0
int main(int argc, const char **argv)
{
    CFURLRef cfurl;
    OSStatus err = LSFindApplicationForInfo(0, CFSTR("com.apple.Xcode"), 0, 0, &cfurl);
    if (err != noErr)
        return internal_error;
    
    CFBundleRef bundle = CFBundleCreate(0, cfurl);
    if (bundle == 0)
        return internal_error;

    CFStringRef str = CFStringRef(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString")));
    const char * ptr = CFStringGetCStringPtr(str, 0);
    if (ptr == 0)
        return internal_error;        

    // self-test
    const char * fail1 = "2.4";
    const char * fail2 = "2.4.0";
    const char * fail3  ="2.3";
    const char * ok1  = "2.4.1";
    const char * ok2  ="2.5";
    const char * ok3  ="3.0";
//    ptr = fail1;
//    printf ("string: %s\n", ptr);
   
    int length = strlen(ptr);
    if (length < 3) // expect "x.y" at least
        return internal_error;

    // fail on 2.4 and below (2.4.1 is ok)

     if (ptr[0] < '2')
        return fail;

    if (ptr[0] >= '3')
        return success;

    if (ptr[2] < '4')
        return fail;

    if (length < 5)
        return fail;

    if (ptr[4] < '1')
        return fail;
    
    return success;
}
//
// Process % scan forms.
// This delivers the object value, scanf-style, somehow.
//
bool CFScan::scanformat(CFTypeRef obj)
{
	switch (*++format) {
	case F_OBJECT:
		store<CFTypeRef>(obj);
		return true;
	case F_ARRAY:	// %a*
		return typescan(obj, CFArrayGetTypeID()) == done;
	case F_BOOLEAN:
		if (Typescan rc = typescan(obj, CFBooleanGetTypeID()))
			return rc == done;
		switch (*format) {
		case 'f':	// %Bf - two arguments (value, &variable)
			{
				unsigned flag = va_arg(args, unsigned);
				unsigned *value = va_arg(args, unsigned *);
				if (obj == kCFBooleanTrue && !suppress)
					*value |= flag;
				return true;
			}
		default:	// %b - CFBoolean as int boolean
			store<int>(obj == kCFBooleanTrue);
			return true;
		}
	case F_DICTIONARY:
		return typescan(obj, CFDictionaryGetTypeID()) == done;
	case 'd':	// %d - int
		return scannumber<int>(obj);
	case F_NUMBER:
		return typescan(obj, CFNumberGetTypeID()) == done;
	case F_STRING:
	case 's':
		if (Typescan rc = typescan(obj, CFStringGetTypeID()))
			return rc == done;
		// %s
		store<std::string>(cfString(CFStringRef(obj)));
		return true;
	case 'u':
		return scannumber<unsigned int>(obj);
	case F_DATA:
		return typescan(obj, CFDataGetTypeID()) == done;
	default:
		assert(false);
		return false;
	}
}
//
// Construct and prepare an SQL query on the authority table, operating on some set of existing authority records.
// In essence, this appends a suitable WHERE clause to the stanza passed and prepares it on the statement given.
//
void PolicyEngine::selectRules(SQLite::Statement &action, std::string phrase, std::string table,
	CFTypeRef inTarget, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context, std::string suffix /* = "" */)
{
	CFDictionary ctx(context, errSecCSInvalidAttributeValues);
	CFCopyRef<CFTypeRef> target = inTarget;
	std::string filter_unsigned;	// ignored; used just to trigger ad-hoc signing
	normalizeTarget(target, ctx, &filter_unsigned);

	string label;
	if (CFStringRef lab = ctx.get<CFStringRef>(kSecAssessmentUpdateKeyLabel))
		label = cfString(CFStringRef(lab));

	if (!target) {
		if (label.empty()) {
			if (type == kAuthorityInvalid) {
				action.query(phrase + suffix);
			} else {
				action.query(phrase + " WHERE " + table + ".type = :type" + suffix);
				action.bind(":type").integer(type);
			}
		} else {	// have label
			if (type == kAuthorityInvalid) {
				action.query(phrase + " WHERE " + table + ".label = :label" + suffix);
			} else {
				action.query(phrase + " WHERE " + table + ".type = :type AND " + table + ".label = :label" + suffix);
				action.bind(":type").integer(type);
			}
			action.bind(":label") = label;
		}
	} else if (CFGetTypeID(target) == CFNumberGetTypeID()) {
		action.query(phrase + " WHERE " + table + ".id = :id" + suffix);
		action.bind(":id").integer(cfNumber<uint64_t>(target.as<CFNumberRef>()));
	} else if (CFGetTypeID(target) == SecRequirementGetTypeID()) {
		if (type == kAuthorityInvalid)
			type = kAuthorityExecute;
		CFRef<CFStringRef> requirementText;
		MacOSError::check(SecRequirementCopyString(target.as<SecRequirementRef>(), kSecCSDefaultFlags, &requirementText.aref()));
		action.query(phrase + " WHERE " + table + ".type = :type AND " + table + ".requirement = :requirement" + suffix);
		action.bind(":type").integer(type);
		action.bind(":requirement") = requirementText.get();
	} else
		MacOSError::throwMe(errSecCSInvalidObjectRef);
}
static RString GetStringProperty( io_registry_entry_t entry, CFStringRef key )
{
	CFTypeRef t = IORegistryEntryCreateCFProperty( entry, key, NULL, 0 );
	
	if( !t )
		return RString();
	if( CFGetTypeID( t ) != CFStringGetTypeID() )
	{
		CFRelease( t );
		return RString();
	}
	
	CFStringRef s = CFStringRef( t );
	RString ret;
	const size_t len = CFStringGetMaximumSizeForEncoding( CFStringGetLength(s), kCFStringEncodingUTF8 );
	char *buf = new char[len + 1];
		
	if( CFStringGetCString( s, buf, len + 1, kCFStringEncodingUTF8 ) )
		ret = buf;
	delete[] buf;
	CFRelease( t );
	return ret;
}
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;
}
//
// LaunchServices-layer document open.
// We don't cache those at present. If we ever do, we need to authenticate CoreServicesUIAgent as the source of its risk assessment.
//
void PolicyEngine::evaluateDocOpen(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result)
{
	if (context) {
		if (CFStringRef riskCategory = CFStringRef(CFDictionaryGetValue(context, kLSDownloadRiskCategoryKey))) {
			FileQuarantine qtn(cfString(path).c_str());

			if (CFEqual(riskCategory, kLSRiskCategorySafe)
				|| CFEqual(riskCategory, kLSRiskCategoryNeutral)
				|| CFEqual(riskCategory, kLSRiskCategoryUnknown)
				|| CFEqual(riskCategory, kLSRiskCategoryMayContainUnsafeExecutable)) {
				cfadd(result, "{%O=#T}", kSecAssessmentAssessmentVerdict);
				addAuthority(result, "_XProtect");
			} else if (qtn.flag(QTN_FLAG_HARD)) {
				MacOSError::throwMe(errSecCSFileHardQuarantined);
			} else if (qtn.flag(QTN_FLAG_ASSESSMENT_OK)) {
				cfadd(result, "{%O=#T}", kSecAssessmentAssessmentVerdict);
				addAuthority(result, "Prior Assessment");
			} else if (!overrideAssessment()) {		// no need to do more work if we're off
				try {
					evaluateCode(path, kAuthorityExecute, flags, context, result, false);
				} catch (...) {
					// some documents can't be code signed, so this may be quite benign
				}
				if (CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict) == NULL) {	// no code signature to help us out
				   cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
				   addAuthority(result, "_XProtect");
				}
			}
			addToAuthority(result, kLSDownloadRiskCategoryKey, riskCategory);
			return;
		}
	}
	// insufficient information from LS - deny by default
	cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
	addAuthority(result, "Insufficient Context");
}
Exemple #8
0
void f() {
  (void)CFStringRef(CFSTR("Hello"));
}
//
// Contemplate the object-to-be-signed and set up the Signer state accordingly.
//
void SecCodeSigner::Signer::prepare(SecCSFlags flags)
{
	// get the Info.plist out of the rep for some creative defaulting
	CFRef<CFDictionaryRef> infoDict;
	if (CFRef<CFDataRef> infoData = rep->component(cdInfoSlot))
		infoDict.take(makeCFDictionaryFrom(infoData));

	// work out the canonical identifier
	identifier = state.mIdentifier;
	if (identifier.empty()) {
		identifier = rep->recommendedIdentifier(state);
		if (identifier.find('.') == string::npos)
			identifier = state.mIdentifierPrefix + identifier;
		if (identifier.find('.') == string::npos && state.isAdhoc())
			identifier = identifier + "-" + uniqueName();
		secdebug("signer", "using default identifier=%s", identifier.c_str());
	} else
		secdebug("signer", "using explicit identifier=%s", identifier.c_str());
	
	// work out the CodeDirectory flags word
	if (state.mCdFlagsGiven) {
		cdFlags = state.mCdFlags;
		secdebug("signer", "using explicit cdFlags=0x%x", cdFlags);
	} else {
		cdFlags = 0;
		if (infoDict)
			if (CFTypeRef csflags = CFDictionaryGetValue(infoDict, CFSTR("CSFlags"))) {
				if (CFGetTypeID(csflags) == CFNumberGetTypeID()) {
					cdFlags = cfNumber<uint32_t>(CFNumberRef(csflags));
					secdebug("signer", "using numeric cdFlags=0x%x from Info.plist", cdFlags);
				} else if (CFGetTypeID(csflags) == CFStringGetTypeID()) {
					cdFlags = cdTextFlags(cfString(CFStringRef(csflags)));
					secdebug("signer", "using text cdFlags=0x%x from Info.plist", cdFlags);
				} else
					MacOSError::throwMe(errSecCSBadDictionaryFormat);
			}
	}
	if (state.mSigner == SecIdentityRef(kCFNull))	// ad-hoc signing requested...
		cdFlags |= kSecCodeSignatureAdhoc;	// ... so note that
	
	// prepare the resource directory, if any
	string rpath = rep->resourcesRootPath();
	if (!rpath.empty()) {
		// explicitly given resource rules always win
		CFCopyRef<CFDictionaryRef> resourceRules = state.mResourceRules;
		
		// embedded resource rules come next
		if (!resourceRules && infoDict)
			if (CFTypeRef spec = CFDictionaryGetValue(infoDict, _kCFBundleResourceSpecificationKey)) {
				if (CFGetTypeID(spec) == CFStringGetTypeID())
					if (CFRef<CFDataRef> data = cfLoadFile(rpath + "/" + cfString(CFStringRef(spec))))
						if (CFDictionaryRef dict = makeCFDictionaryFrom(data))
							resourceRules.take(dict);
				if (!resourceRules)	// embedded rules present but unacceptable
					MacOSError::throwMe(errSecCSResourceRulesInvalid);
			}

		// finally, ask the DiskRep for its default
		if (!resourceRules)
			resourceRules.take(rep->defaultResourceRules(state));
		
		// build the resource directory
		ResourceBuilder resources(rpath, cfget<CFDictionaryRef>(resourceRules, "rules"), digestAlgorithm());
		rep->adjustResources(resources);	// DiskRep-specific adjustments
		CFRef<CFDictionaryRef> rdir = resources.build();
		resourceDirectory.take(CFPropertyListCreateXMLData(NULL, rdir));
	}
	
	// screen and set the signing time
	CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
	if (state.mSigningTime == CFDateRef(kCFNull)) {
		signingTime = 0;		// no time at all
	} else if (!state.mSigningTime) {
		signingTime = now;		// default
	} else {
		CFAbsoluteTime time = CFDateGetAbsoluteTime(state.mSigningTime);
		if (time > now)	// not allowed to post-date a signature
			MacOSError::throwMe(errSecCSBadDictionaryFormat);
		signingTime = time;
	}
	
	pagesize = state.mPageSize ? cfNumber<size_t>(state.mPageSize) : rep->pageSize(state);
    
    // Timestamping setup
    CFRef<SecIdentityRef> mTSAuth;	// identity for client-side authentication to the Timestamp server
}
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format,
                                           QSettings::Scope scope,
                                           const QString &organization,
                                           const QString &application)
{
#ifndef QT_BOOTSTRAPPED
    static bool useAppLocalStorage = false;
    static bool initialized = false;

    if (!initialized) {
        bool inSandbox = false;

#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
        // If we are running on at least 10.7.0 and have the com.apple.security.app-sandbox
        // entitlement, we are in a sandbox
        SInt32 version = 0;
        Gestalt(gestaltSystemVersion, &version);
        SecCodeRef secCodeSelf;
        if (version >= 0x1070 && SecCodeCopySelf(kSecCSDefaultFlags, &secCodeSelf) == errSecSuccess) {
            SecRequirementRef sandboxReq;
            CFStringRef entitlement = CFSTR("entitlement [\"com.apple.security.app-sandbox\"]");
            if (SecRequirementCreateWithString(entitlement, kSecCSDefaultFlags, &sandboxReq) == errSecSuccess) {
                if (SecCodeCheckValidity(secCodeSelf, kSecCSDefaultFlags, sandboxReq) == errSecSuccess)
                    inSandbox = true;
                CFRelease(sandboxReq);
            }
            CFRelease(secCodeSelf);
        }
#endif

        bool forAppStore = false;
        if (!inSandbox) {
            CFTypeRef val = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("ForAppStore"));
            forAppStore = (val &&
                           CFGetTypeID(val) == CFStringGetTypeID() &&
                           CFStringCompare(CFStringRef(val), CFSTR("yes"), kCFCompareCaseInsensitive) == 0);
        }

        useAppLocalStorage = inSandbox || forAppStore;
        initialized = true;
    }

    if (useAppLocalStorage) {
        // Ensure that the global and app-local settings go to the same file, since that's
        // what we really want
        if (organization == QLatin1String("Trolltech") ||
                organization.isEmpty() ||
                (organization == qApp->organizationDomain() && application == qApp->applicationName()) ||
                (organization == qApp->organizationName()) && application == qApp->applicationName())
        {
            CFStringRef bundleIdentifier = CFBundleGetIdentifier(CFBundleGetMainBundle());
            if (!bundleIdentifier) {
                qWarning("QSettingsPrivate::create: You must set the bundle identifier when using ForAppStore");
            } else {
                QSettingsPrivate* settings = new QMacSettingsPrivate(bundleIdentifier);
                if (organization == QLatin1String("Trolltech"))
                    settings->beginGroupOrArray(QSettingsGroup("QtLibrarySettings"));
                return settings;
            }
        }
   }
#endif

    if (format == QSettings::NativeFormat) {
        return new QMacSettingsPrivate(scope, organization, application);
    } else {
        return new QConfFileSettingsPrivate(format, scope, organization, application);
    }
}
Exemple #11
0
void ArchHooks_MacOSX::Init()
{
	// First, handle non-fatal termination signals.
	SignalHandler::OnClose( DoCleanShutdown );
	CrashHandler::CrashHandlerHandleArgs( g_argc, g_argv );
	CrashHandler::InitializeCrashHandler();
	SignalHandler::OnClose( DoCrashSignalHandler );
	SignalHandler::OnClose( DoEmergencyShutdown );

	// Now that the crash handler is set up, disable crash reporter.
	// Breaks gdb
	// task_set_exception_ports( mach_task_self(), EXC_MASK_ALL, MACH_PORT_NULL, EXCEPTION_DEFAULT, 0 );

	// CF*Copy* functions' return values need to be released, CF*Get* functions' do not.
	CFStringRef key = CFSTR( "ApplicationBundlePath" );

	CFBundleRef bundle = CFBundleGetMainBundle();
	CFStringRef appID = CFBundleGetIdentifier( bundle );
	if( appID == NULL )
	{
		// We were probably launched through a symlink. Don't bother hunting down the real path.
		return;
	}
	CFStringRef version = CFStringRef( CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey) );
	CFPropertyListRef old = CFPreferencesCopyAppValue( key, appID );
	CFURLRef path = CFBundleCopyBundleURL( bundle );
	CFPropertyListRef value = CFURLCopyFileSystemPath( path, kCFURLPOSIXPathStyle );
	CFMutableDictionaryRef newDict = NULL;

	if( old && CFGetTypeID(old) != CFDictionaryGetTypeID() )
	{
		CFRelease( old );
		old = NULL;
	}

	if( !old )
	{
		newDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
						     &kCFTypeDictionaryValueCallBacks );
		CFDictionaryAddValue( newDict, version, value );
	}
	else
	{
		CFTypeRef oldValue;
		CFDictionaryRef dict = CFDictionaryRef( old );

		if( !CFDictionaryGetValueIfPresent(dict, version, &oldValue) || !CFEqual(oldValue, value) )
		{
			// The value is either not present or it is but it is different
			newDict = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, dict );
			CFDictionarySetValue( newDict, version, value );
		}
		CFRelease( old );
	}

	if( newDict )
	{
		CFPreferencesSetAppValue( key, newDict, appID );
		if( !CFPreferencesAppSynchronize(appID) )
			LOG->Warn( "Failed to record the run path." );
		CFRelease( newDict );
	}
	CFRelease( value );
	CFRelease( path );
}