1

キーチェーンを使用して、Mac OSX アプリケーションから SMTP データを保存したいと考えています。Apple の Keychain Services Programming Guide を読み、データを保存するために次のメソッドを作成しました。

    - (BOOL)saveSMPTData
{
    OSStatus err;
    SecKeychainItemRef item = nil;
    SecProtocolType protocol = kSecProtocolTypeSMTP;
    const char *accessLabelUTF8 = [KEYCHAIN_NAME UTF8String];
    const char *serverNameUTF8 = [self.serverName UTF8String];
    const char *usernameUTF8 = [self.username UTF8String];
    const char *passwordUTF8 = [self.password UTF8String];

    SecAccessRef access = createAccess(KEYCHAIN_NAME);

    SecKeychainAttribute attrs[] = {
        { kSecLabelItemAttr, (int)strlen(accessLabelUTF8), (char *)accessLabelUTF8 },
        { kSecAccountItemAttr, (int)strlen(usernameUTF8), (char *)usernameUTF8 },
        { kSecServerItemAttr, (int)strlen(serverNameUTF8), (char *)serverNameUTF8 },
        { kSecProtocolItemAttr, sizeof(SecProtocolType), (SecProtocolType *)&protocol }
    };
    SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
    err = SecKeychainItemCreateFromContent(kSecInternetPasswordItemClass,
                                           &attributes,
                                           (int)strlen(passwordUTF8),
                                           passwordUTF8,
                                           NULL,
                                           access,
                                           &item);
    if (access) CFRelease(access);
    if (item) CFRelease(item);
    return (err == noErr);
}

SecAccessRef createAccess(NSString *accessLabel)
{
    OSStatus err;
    SecAccessRef access = nil;
    NSArray *trustedApplications = nil;

    SecTrustedApplicationRef myself;
    err = SecTrustedApplicationCreateFromPath(NULL, &myself);

    trustedApplications = [NSArray arrayWithObjects:(__bridge id)myself, nil];
    err = SecAccessCreate((__bridge CFStringRef)accessLabel,
                          (__bridge CFArrayRef)trustedApplications, &access);

    if (err) return nil;
    return access;
}

もちろん、私もそれらをロードしたいです。私の最初の試みは次のようになります。

- (BOOL)loadDataFromKeychain
{
    uint32_t serverNameLength = 0;
    const char *serverName = NULL;

    uint32_t usernameLength = 0;
    const char *username = NULL;

    uint32_t passwordLength = 0;
    void **password = NULL;

    OSStatus err = SecKeychainFindInternetPassword(NULL,
                                                   serverNameLength, serverName,
                                                   0, NULL,
                                                   usernameLength, username,
                                                   0, NULL,
                                                   0, 0,
                                                   0,
                                                   &passwordLength, password,
                                                   NULL); // How do I get the ItemRef?

    return (err == noErr);
}

しかし、これは機能しません。その理由はわかっていると思います。SecKeychainFindInternetPasswordメソッドのSecKeychainItemRefを取得する方法がわかりません。

多分誰かが私を助けることができますか?

4

1 に答える 1

2

passwordavoid **を宣言する代わりに、 a を宣言し、最後から 2 番目のパラメーターにvoid *渡します。&password

達成しようとしていることに SecKeychainItemRef はおそらく必要ありません。

ところで、キーチェーン アクセスを使用してアイテムがキーチェーンに入っていることを確認してみましたか?

于 2012-12-10T06:43:48.997 に答える