Alf*_*sen 27 xcode openssl xcodebuild provisioning-profile
我想检测给定的配置文件是开发配置文件还是分发(adhoc或app store)配置文件.我需要纯粹以编程方式执行此操作.
我已经了解了如何检测adhoc vs appstore.我特别感兴趣的是开发与分销.
我检查了每种类型的配置文件内部的plists,但找不到可辨别的差异(via security cms -D -i #{@profilePath}).我也调查了opensslapi并使用它进行一些证书操作.
这适用于自定义xcode自动构建系统.作为预构建验证的一部分,我需要确保指定的配置文件不用于开发.
这甚至可能吗?如果是这样,我如何以编程方式区分这两者?
提前感谢任何想法!
ste*_*ete 22
我构建了一个更简洁有效的Toom代码版本:
我会在一个要点中维护这样的代码片段,您可以在这里找到更新的版本: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
}
Run Code Online (Sandbox Code Playgroud)
Bry*_*ial 20
这是我在我自己的一个构建系统中为了同样的目的而解决的问题......让我们回到当时的'iPhone开发者计划'的第一天.如果你当时在社区周围,你可能还记得工具链是......我们会说比现在更不友好......
当您想要为AppStore或AdHoc构建构建时,您必须制作这个好奇的entitlements.plist文件,然后将一小块XML粘贴到该文件的主体中.然后你运行了构建,那时看起来似乎是魔术,并且该文件的纯粹存在使得构建工作,允许你手动构建你的IPA,并继续照常营业.既然我们已经比SDK的早期年龄大了几年并且希望有点聪明,我们已经认识到魔术XML blob实际上并不是那么神奇 - "get-task-allow" key是一个设置,用于指示二进制文件是否应允许其他进程(如可能是调试器)附加到二进制文件.使用开发配置文件签署应用程序时,此密钥将设置为"true"(从而允许LLDB附加您的应用并与您的应用交互)...当使用分发配置文件签署应用时,自然会设置此密钥'假'.
Apple在Tech Note TN2250中提供了一些关于从配置文件中读取XML(以及扩展权利)的更新:
security cms -D -i /path/to/the.app/embedded.mobileprovision
这将返回Provisioning配置文件中的XML - 从那里您可以解析'get-task-allow'的键值对,并使用该值来确定Provisioning Profile是Development还是Distribution.
我绝对同意,拥有一个直接告诉我们的工具会很好,所以我们不必嗅探配置文件以获取线索,但与此同时,至少我们有一个高度可靠的,尽管是迂回的方式在跑掉并制作我们无法使用的构建之前做出这种区分.
祝你好运,如果你需要更多澄清或有其他问题,请告诉我.
Too*_*oom 10
基于Bryan Musial的好答案,我编写了一些代码,允许您在运行时直接从应用程序检查"get-task-allow".在我的情况下,我使用此布尔值仅登录调试应用程序:
+ (BOOL)isDevelopmentApp
{
// Special case of simulator
if (isSimulator)
{
return YES;
}
// There is no provisioning profile in AppStore Apps
NSString *profilePath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
// Check provisioning profile existence
if (profilePath)
{
// Get hex representation
NSData *profileData = [NSData dataWithContentsOfFile:profilePath];
NSString *profileString = [NSString stringWithFormat:@"%@", profileData];
// Remove brackets at beginning and end
profileString = [profileString stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@""];
profileString = [profileString stringByReplacingCharactersInRange:NSMakeRange(profileString.length - 1, 1) withString:@""];
// Remove spaces
profileString = [profileString stringByReplacingOccurrencesOfString:@" " withString:@""];
// Convert hex values to readable characters
NSMutableString *profileText = [NSMutableString new];
for (int i = 0; i < profileString.length; i += 2)
{
NSString *hexChar = [profileString substringWithRange:NSMakeRange(i, 2)];
int value = 0;
sscanf([hexChar cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
[profileText appendFormat:@"%c", (char)value];
}
// Remove whitespaces and new lines characters
NSArray *profileWords = [profileText componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *profileClearText = [profileWords componentsJoinedByString:@""];
// Look for debug value
NSRange debugRange = [profileClearText rangeOfString:@"<key>get-task-allow</key><true/>"];
if (debugRange.location != NSNotFound)
{
return YES;
}
}
// Return NO by default to avoid security leaks
return NO;
}
Run Code Online (Sandbox Code Playgroud)
这是基于@steipete的答案的Swift 3版本:
static func isDevelopmentProvisioningProfile() -> Bool {
#if IOS_SIMULATOR
return true
#else
// there will be no provisioning profile in AppStore Apps
guard let fileName = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision") else {
return false
}
let fileURL = URL(fileURLWithPath: fileName)
// the documentation says this file is in UTF-8, but that failed
// on my machine. ASCII encoding worked ¯\_(?)_/¯
guard let data = try? String(contentsOf: fileURL, encoding: .ascii) else {
return false
}
let cleared: String = data.components(separatedBy: .whitespacesAndNewlines).joined()
return cleared.contains("<key>get-task-allow</key><true/>")
#endif
}
Run Code Online (Sandbox Code Playgroud)
如果好奇,get-task-allow是一个标志,构建应用,以确定是否应该能够挂接一个调试器和其他进程一样, -所以它是因为它是一个开发建设或不十分准确。
| 归档时间: |
|
| 查看次数: |
11635 次 |
| 最近记录: |