【问题标题】:SMJobBless returning error 4098SMJobBless 返回错误 4098
【发布时间】:2012-05-30 13:56:34
【问题描述】:

我正在尝试使用 SMJobBless 安装安全帮助工具。当它失败并且在调用 SMJobBless 之前,我调用了 SMJobRemove,因为我需要删除该工具的旧版本并且这会成功。 SMJobBless 返回错误代码 4098。NSError 对象只是告诉我“操作无法完成。CodeSigning 子系统中出现错误。”

如果我重新运行我的代码,SMJobBless 函数就会起作用。我认为这是因为它之前已被删除,但为什么它第一次没有工作?然后我可以与该工具通信,一切正常。观察到一切运行正常,我相信我可以确定我满足了文档中描述的 SMJobBless 的五个要求。

如果我增加我的工具版本并重试,SMJobRemove 将起作用,但是,SMJobBless 再次出现错误代码 4098。

如果重要的话,我使用的是 OS X 10.7.3。

【问题讨论】:

    标签: macos code-signing


    【解决方案1】:

    可能是您在代码签名帮助工具上调用 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

    【讨论】:

    • 此代码将文件描述符泄露给辅助工具。 codeRef 在返回时应该是 CFRelease()d。我尝试自己编辑帖子,但由于问题“太小”而被拒绝。
    • 哇!这正是我遇到的问题,这很好地解决了它。感谢您的指针,更好的是,实际的工作代码!我只希望 Apple 为 SMJobBless 和朋友们提供的文档更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 2019-09-23
    • 1970-01-01
    • 2017-11-01
    相关资源
    最近更新 更多