Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect that a provisioning profile is for development or distribution, programmatically

I would like to detect if a given provisioning profile is a development profile or a distribution (adhoc or app store) profile. I need to do this purely programmatically.

I already understand how to detect adhoc vs appstore. And am specifically interested in dev vs. distribution.

I've examined the plists internal to each type of profile and cannot find a discernable difference (via security cms -D -i #{@profilePath}). I've also looked into the openssl api and am using this for some certificate manipulation.

This is for a custom xcode automated build system. As part of pre-build validation I need to ensure that the specified profile is not for development.

Is this even possible? If so, how can I programmatically differentiate between the two?

Thanks in advance for any ideas!

like image 324
Alfie Hanssen Avatar asked Apr 26 '13 19:04

Alfie Hanssen


2 Answers

I've build a more concise and efficient version of Toom's code:

I'll maintain code snippets like this in a gist, you might find a more up to date version here: https://gist.github.com/steipete/7668246

static BOOL PSPDFIsDevelopmentBuild(void) { #if TARGET_IPHONE_SIMULATOR return YES; #else static BOOL isDevelopment = NO; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{     // There is no provisioning profile in AppStore Apps.     NSData *data = [NSData dataWithContentsOfFile:[NSBundle.mainBundle pathForResource:@"embedded" ofType:@"mobileprovision"]];     if (data) {         const char *bytes = [data bytes];         NSMutableString *profile = [[NSMutableString alloc] initWithCapacity:data.length];         for (NSUInteger i = 0; i < data.length; i++) {             [profile appendFormat:@"%c", bytes[i]];         }         // Look for debug value, if detected we're a development build.         NSString *cleared = [[profile componentsSeparatedByCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet] componentsJoinedByString:@""];         isDevelopment = [cleared rangeOfString:@"<key>get-task-allow</key><true/>"].length > 0;     } }); return isDevelopment; #endif } 
like image 68
steipete Avatar answered Sep 28 '22 03:09

steipete


This was something I tackled in one of my own build systems for much the same purpose...let's take a trip back in time to Day 1 of the then 'iPhone Developer Program'. If you were around the community at that time, you may remember that the toolchain was...shall we say less friendly...than it is today.

When you wanted to build for the AppStore or for AdHoc builds you had to make this curious entitlements.plist file, then paste a blob of XML into the body of that file. You then ran the build and at that time what appeared to be magic occurred and the sheer presence of that file made the build work, allowed you to manually construct your IPA, and carry on with business as usual. Now that we are a few years older and hopefully a bit wiser than in those early days of the SDK, we have come to recognize that the magic XML blob wasn't actually so magical at all -- the 'get-task-allow' key is a setting to indicate if the binary should allow other processes (like perhaps a debugger) to attach to the binary. When signing apps using a Development Provisioning Profile, this key will be set to 'true' (and thus allow LLDB to attach and interact with your app)...and naturally when signing apps using a Distribution Provisioning Profile, this key will be set to 'false'.

Apple has provided some updates in Tech Note TN2250 about reading the XML (and by extension the entitlements) out of Provisioning Profiles:

security cms -D -i /path/to/the.app/embedded.mobileprovision

This will return the XML in the Provisioning profile -- from there you can parse out the key value pair for 'get-task-allow' and use that value to determine if the Provisioning Profile is Development or Distribution.

I absolutely agree that it would be nice to have a tool that would tell us that directly so we don't have to sniff through the profile for clues, but at the same time, at least we have a highly reliable, albeit roundabout way to make that distinction before running off and making a build we can't use.

Good luck and let me know if you need any more clarification or have other questions.

like image 45
Bryan Musial Avatar answered Sep 28 '22 02:09

Bryan Musial