[SCAP-On-Apple-Dev] [SCAP-On-Apple] Mac OS X proposed pkginfo OVAL Test.

Josh Wisenbaker dubs at apple.com
Fri Jul 12 12:58:20 PDT 2013

On Jul 12, 2013, at 12:19 PM, Jacobsen, Jasen W. <jasenj1 at mitre.org> wrote:

> What about non application things like libraries, printer drivers or browser plug-ins?

Off the top of my head you could use simple scripting tools like 'lpinfo -m’ to list all the printer drivers on the system. 

I think in most cases things like library versions come when you are looking for a specific version though to validate you are beyond a vulnerable level.

> And can you elaborate a little on "use a metadata query and launch services to locate the apps"? Perhaps there are other OS X capabilities that OVAL should make available to system auditors.

Sure. If you are scripting things then you can use the mdfind command to find apps. For example, 

mdfind "kMDItemContentTypeTree == 'com.apple.application’"

Is going to instantly find every app on your disks, regardless of where it is stored. You can then loop through them and read the info.plists.

To my mind though it’s easier to do in Objective-C or some other object oriented language than it is to mash all that data around in a bash script. This is some really rough sample stuff code. Note that in the results processing you could also use 

NSString *appVersion = [theResult valueForAttribute:(NSString *)kMDItemVersion];

in an effort to not rely on needing to read each plist, but reading the plist lets us cover a use case for if developers don’t fill in both the short version string and the bundle version string.

Starting the search:
- (void)findApps {
    //Start our timer
    self.startDate = [NSDate timeIntervalSinceReferenceDate];
        // Create the metadata query instance. The metadataSearch @property is
        // declared as retain
        self.metadataSearch=[[NSMetadataQuery alloc] init];
        // Register the notifications for the completion updates
        [[NSNotificationCenter defaultCenter] addObserver:self
       [[NSNotificationCenter defaultCenter] addObserver:self
        // Configure the search predicate to find all apps using the com.apple.application UTI
        NSPredicate *searchPredicate;
        searchPredicate=[NSPredicate predicateWithFormat:@"kMDItemContentTypeTree == 'com.apple.application'"];
        [self.metadataSearch setPredicate:searchPredicate];
        // Set the search scope to local disks
        NSArray *searchScopes;
        [self.metadataSearch setSearchScopes:searchScopes];

        // Begin the asynchronous query
        [self.metadataSearch startQuery];

Then processing the results:
// Method invoked when the initial query gathering is completed
- (void)initalGatherComplete:sender;
        // Stop the query, the single pass is completed.
        [self.metadataSearch stopQuery];
        // Iterate the results and find our info.
        NSUInteger i=0;
        for (i=0; i < [self.metadataSearch resultCount]; i++) {
            NSMetadataItem *theResult = [self.metadataSearch resultAtIndex:i];
            NSString *appPath = [theResult valueForAttribute:(NSString *)kMDItemPath];
            // Use launch services to retrieve info and filter out invisibles and aliases
            // Launch Services is CF so we need to bridge to a CFURLRef
            CFURLRef appURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (__bridge CFStringRef)appPath, kCFURLPOSIXPathStyle, YES);
            // Create our LSItemInfoRecord
            LSItemInfoRecord itemInfoRecord;
            // Pass in our CFURLRef and filter out invisibles and aliases
            LSCopyItemInfoForURL(appURL, kLSRequestBasicFlagsOnly | kLSRequestAppTypeFlags, &itemInfoRecord);
            //We don't need the appURL anymore so set it free
            if ((itemInfoRecord.flags & kLSItemInfoIsApplication) && 
                !(itemInfoRecord.flags & kLSItemInfoIsInvisible) &&
                !(itemInfoRecord.flags & kLSItemInfoIsAliasFile))
                // Make some strings to hold our data
                NSString *nameString = nil, *versionString = nil;
                // Make sure it really is an app bundle
                if (itemInfoRecord.flags & kLSItemInfoIsContainer)
                    // Get info for app bundles
                    // Load in the Info.plist and read the keys
                    NSDictionary *infoDictionary = [NSDictionary dictionaryWithContentsOfFile: [appPath stringByAppendingPathComponent: @"/Contents/Info.plist"]];
                    nameString = infoDictionary[@"CFBundleName"];
                    versionString = infoDictionary[@"CFBundleShortVersionString"];
                    if (!versionString)
                        versionString = infoDictionary[@"CFBundleVersion"];

                   //Add our info to a mutable dict.
                    NSDictionary *dict = @{@"appName": nameString,
                                         @"appVersion": versionString};
        // Remove the notifications to clean up after ourselves.
        // Also release the metadataQuery.
        // When the Query is removed the query results are also lost.
        [[NSNotificationCenter defaultCenter] removeObserver:self
        [[NSNotificationCenter defaultCenter] removeObserver:self
        //Stop our timer and figure how long that took
        NSTimeInterval totalTime;
        self.stopDate = [NSDate timeIntervalSinceReferenceDate];
        self.theText = [NSString stringWithFormat:@"App search took: %.4f seconds", (totalTime = self.stopDate - self.startDate)];

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/scap-on-apple-dev/attachments/20130712/26b47abf/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3624 bytes
Desc: not available
URL: <http://lists.macosforge.org/pipermail/scap-on-apple-dev/attachments/20130712/26b47abf/attachment-0001.p7s>

More information about the SCAP-On-Apple-Dev mailing list