我正在尝试使用SMJobBless安装一个安全的帮助工具。当它失败并且在调用SMJobBless之前,我正在调用SMJobRemove,因为我需要删除旧版本的工具并且这成功了。 SMJobBless返回的错误代码为4098. NSError对象只告诉我“操作无法完成.CodeSigning子系统出错。”
如果我重新运行我的代码,SMJobBless函数会起作用。我认为这是因为它之前已被删除,但为什么它第一次没有工作?然后我可以与工具通信,一切正常。观察一切正常运行,我相信我可以确定我符合文档中描述的SMJobBless的五个要求。
如果我增加我的工具版本并再次尝试,SMJobRemove将工作,但是,SMJobBless再次使用,错误代码为4098.
如果重要,我使用的是OS X 10.7.3。
答案 0 :(得分:4)
您是否在代码签名的帮助工具上调用CFBundleCopyInfoDictionaryForURL
?
如果是这样,似乎这个函数似乎打破了代码签名的有效性。 (大概是因为CFBundle
修改了内存中的Info.plist数据,但这只是我的猜测。)
解决方案是使用SecCodeCopySigningInformation
来阅读帮助工具的版本信息:
-(NSString *) bundleVersionForCodeSignedItemAtURL:(NSURL *)url {
OSStatus status;
// Sanity check -- nothing begets nothing
if (!url) {
return nil;
}
// Get the binary's static code
SecStaticCodeRef codeRef;
status = SecStaticCodeCreateWithPath((CFURLRef)url, kSecCSDefaultFlags, &codeRef);
if (status != noErr) {
NSLog(@"SecStatucCodeCreateWithPath() error for %@: %d", url, status);
return nil;
}
// Get the code signature info
CFDictionaryRef codeInfo;
status = SecCodeCopySigningInformation(codeRef, kSecCSDefaultFlags, &codeInfo);
if (status != noErr) {
NSLog(@"SecCodeCopySigningInformation() error for %@: %d", url, status);
CFRelease(codeRef);
return nil;
}
// The code signature info gives us the Info.plist that was signed, and
// from there we can retrieve the version
NSDictionary *bundleInfo = (NSDictionary *) CFDictionaryGetValue(codeInfo, kSecCodeInfoPList);
NSString *version = [bundleInfo objectForKey:@"CFBundleVersion"];
// We have ownership of the code signature info, so we must release it.
// Before we do that, we need to hold onto the version otherwise we go
// crashing and burning.
[[version retain] autorelease];
CFRelease(codeInfo);
CFRelease(codeRef);
return version;
}
给予应有的信用:关于CFBundleCopyInfoDictionaryForURL
的重要信息来自Ian MacLeod's SMJobKit
。