Skip to content

Commit

Permalink
Merge pull request #16 from thdankert/master
Browse files Browse the repository at this point in the history
Fix Issue #3: Read code signing entitlements from the application binary
  • Loading branch information
ealeksandrov authored Jan 8, 2018
2 parents f031d92 + 0e2cdb8 commit bc2d8b7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
60 changes: 55 additions & 5 deletions ProvisionQL/GeneratePreviewForURL.m
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,29 @@ void displayKeyAndValue(NSUInteger level, NSString *key, id value, NSMutableStri
return string;
}

NSData *codesignEntitlementsDataFromApp(NSData *infoPlistData, NSString *basePath) {
// read the CFBundleExecutable and extract it
NSDictionary *appPropertyList = [NSPropertyListSerialization propertyListWithData:infoPlistData options:0 format:NULL error:NULL];
NSString *bundleExecutable = [appPropertyList objectForKey:@"CFBundleExecutable"];

NSString *binaryPath = [basePath stringByAppendingPathComponent:bundleExecutable];
// get entitlements: codesign -d <AppBinary> --entitlements :-
NSPipe *codesignPipe = [NSPipe pipe];
NSFileHandle *codesignOutputFile = [codesignPipe fileHandleForReading];
NSTask *codesignTask = [NSTask new];
[codesignTask setLaunchPath:@"/usr/bin/codesign"];
[codesignTask setStandardOutput:codesignPipe];
[codesignTask setArguments:@[@"-d", binaryPath, @"--entitlements", @":-"]];
[codesignTask launch];
[codesignTask waitUntilExit];

// save output of codesign task
NSData *codesignEntitlementsData = [codesignOutputFile readDataToEndOfFile];
[codesignOutputFile closeFile];

return codesignEntitlementsData;
}

OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) {
@autoreleasepool {
// create temp directory
Expand All @@ -242,13 +265,16 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview,
NSString *dataType = (__bridge NSString *)contentTypeUTI;
NSData *provisionData = nil;
NSData *appPlist = nil;
NSData *codesignEntitlementsData = nil;
NSImage *appIcon = nil;

if([dataType isEqualToString:kDataType_app]) {
// get the embedded provisioning & plist for the iOS app
provisionData = [NSData dataWithContentsOfURL:[URL URLByAppendingPathComponent:@"embedded.mobileprovision"]];
appPlist = [NSData dataWithContentsOfURL:[URL URLByAppendingPathComponent:@"Info.plist"]];

codesignEntitlementsData = codesignEntitlementsDataFromApp(appPlist, URL.path);

} else if([dataType isEqualToString:kDataType_ipa]) {
// get the embedded provisioning & plist from an app archive using: unzip -u -j -d <currentTempDirFolder> <URL> <files to unzip>
NSTask *unzipTask = [NSTask new];
Expand All @@ -263,6 +289,19 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview,
NSString *plistPath = [currentTempDirFolder stringByAppendingPathComponent:@"Info.plist"];
appPlist = [NSData dataWithContentsOfFile:plistPath];

// read codesigning entitlements from application binary (extract it first)
NSDictionary *appPropertyList = [NSPropertyListSerialization propertyListWithData:appPlist options:0 format:NULL error:NULL];
NSString *bundleExecutable = [appPropertyList objectForKey:@"CFBundleExecutable"];

NSTask *unzipAppTask = [NSTask new];
[unzipAppTask setLaunchPath:@"/usr/bin/unzip"];
[unzipAppTask setStandardOutput:[NSPipe pipe]];
[unzipAppTask setArguments:@[@"-u", @"-j", @"-d", currentTempDirFolder, [URL path], [@"Payload/*.app/" stringByAppendingPathComponent:bundleExecutable]]];
[unzipAppTask launch];
[unzipAppTask waitUntilExit];

codesignEntitlementsData = codesignEntitlementsDataFromApp(appPlist, currentTempDirFolder);

[fileManager removeItemAtPath:tempDirFolder error:nil];
} else {
// use provisioning directly
Expand Down Expand Up @@ -428,16 +467,27 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview,
[synthesizedInfo setObject:synthesizedValue forKey:@"TeamIds"];
}

value = [propertyList objectForKey:@"Entitlements"];
if ([value isKindOfClass:[NSDictionary class]]) {
NSDictionary *dictionary = (NSDictionary *)value;
if (codesignEntitlementsData != nil) {
// read the entitlements directly from the codesign output
NSDictionary *entitlementsPropertyList = [NSPropertyListSerialization propertyListWithData:codesignEntitlementsData options:0 format:NULL error:NULL];
NSMutableString *dictionaryFormatted = [NSMutableString string];
displayKeyAndValue(0, nil, dictionary, dictionaryFormatted);
displayKeyAndValue(0, nil, entitlementsPropertyList, dictionaryFormatted);
synthesizedValue = [NSString stringWithFormat:@"<pre>%@</pre>", dictionaryFormatted];

[synthesizedInfo setObject:synthesizedValue forKey:@"EntitlementsFormatted"];
} else {
[synthesizedInfo setObject:@"No Entitlements" forKey:@"EntitlementsFormatted"];
// read the entitlements from the provisioning profile instead
value = [propertyList objectForKey:@"Entitlements"];
if ([value isKindOfClass:[NSDictionary class]]) {
NSDictionary *dictionary = (NSDictionary *)value;
NSMutableString *dictionaryFormatted = [NSMutableString string];
displayKeyAndValue(0, nil, dictionary, dictionaryFormatted);
synthesizedValue = [NSString stringWithFormat:@"<pre>%@</pre>", dictionaryFormatted];

[synthesizedInfo setObject:synthesizedValue forKey:@"EntitlementsFormatted"];
} else {
[synthesizedInfo setObject:@"No Entitlements" forKey:@"EntitlementsFormatted"];
}
}

value = [propertyList objectForKey:@"DeveloperCertificates"];
Expand Down
2 changes: 1 addition & 1 deletion ProvisionQL/Shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#import <NSBezierPath+IOS7RoundedRect.h>

static NSString * const kPluginBundleId = @"com.FerretSyndicate.ProvisionQL";
static NSString * const kPluginBundleId = @"com.ealeksandrov.ProvisionQL";
static NSString * const kDataType_ipa = @"com.apple.itunes.ipa";
static NSString * const kDataType_app = @"com.apple.application-bundle";
static NSString * const kDataType_ios_provision = @"com.apple.mobileprovision";
Expand Down
2 changes: 1 addition & 1 deletion ProvisionQL/Supporting-files/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<key>CFBundleShortVersionString</key>
<string>1</string>
<key>CFBundleVersion</key>
<string>1.3.0</string>
<string>1.3.1</string>
<key>CFPlugInDynamicRegisterFunction</key>
<string></string>
<key>CFPlugInDynamicRegistration</key>
Expand Down

0 comments on commit bc2d8b7

Please sign in to comment.