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); }
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"); }
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); } }
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 ); }