4

SMJobBless で安全なヘルパー ツールをインストールしようとしています。失敗した場合、SMJobBless を呼び出す前に、古いバージョンのツールを削除する必要があるため、SMJobRemove を呼び出しますが、これは成功します。SMJobBless はエラー コード 4098 を返します。NSError オブジェクトは、「操作を完了できませんでした。CodeSigning サブシステムでエラーが発生しました」とだけ伝えています。

コードを再実行すると、SMJobBless 関数が機能します。これは以前に削除されたためだと思いますが、最初は機能しなかったのはなぜですか? その後、ツールと通信でき、すべてが正常に機能します。すべてが正常に機能していることから、ドキュメントに記載されている SMJobBless の 5 つの要件を満たしていると確信できます。

ツールのバージョンを上げて再試行すると、SMJobRemove は機能しますが、やはり SMJobBless でエラー コード 4098 が発生します。

問題があれば、私は OS X 10.7.3 を使用しています。

4

1 に答える 1

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;
}

当然のことながら、重要な情報はCFBundleCopyInfoDictionaryForURLIan MacLeod のSMJobKit.

于 2013-02-28T18:16:36.857 に答える