知道如何在命令或 AppleScript 中删除 system.keychain 中的项目吗?

发布于 2024-10-05 20:08:27 字数 729 浏览 4 评论 0原文

目前我正在开发一个小应用程序,我想删除机场设置。

首先,我使用shell命令networksetup删除首选网络,然后通过AppleScript删除keychain中记录的密码。但我发现机场的密码记录在system.keychain和login.keychain中。我编写了 AppleScript,例如:

tell application "Keychain Scripting"
set keychainName to "Login.keychain" -- "system.keychain"
set gkeyCount to count generic key of keychain keychainName

repeat with keyIndex from 1 to gkeyCount
    log keyIndex
    if (account of generic key keyIndex of keychain keychainName is "ABCD") then
        delete generic key keyIndex of keychain keychainName
        log "find the key"
    end if
end repeat

end Tell

对于钥匙串“login.keychain”,没问题,但是对于钥匙串“System.keychain”,它失败并显示弹出窗口“钥匙串脚本出现错误:文件未以写入权限打开” ”。

有什么想法吗?

Currently I am developing a small application that I wanna to remove the airport settings.

Firstly, I use shell command networksetup to delete the preferred networks, and then delete the recorded-password in keychain by AppleScript. But I found that the airports' passwords recorded in both system.keychain and login.keychain. I write the AppleScript such as:

tell application "Keychain Scripting"
set keychainName to "Login.keychain" -- "system.keychain"
set gkeyCount to count generic key of keychain keychainName

repeat with keyIndex from 1 to gkeyCount
    log keyIndex
    if (account of generic key keyIndex of keychain keychainName is "ABCD") then
        delete generic key keyIndex of keychain keychainName
        log "find the key"
    end if
end repeat

end tell

For keychain "login.keychain", it's no problem, but for keychain "System.keychain", it failed with a popup show me "Keychain Scripting got an error: File not open with write permission."

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅语花开 2024-10-12 20:08:27

编辑:这不起作用。啊,好吧,无论如何,这只是一个猜测。我将答案留给后代。


我的猜测是问题是系统钥匙串被锁定。我无法真正测试这一点,因为我不想从我的钥匙串中删除东西,但我确实确认我的系统钥匙串默认为锁定状态,这似乎会导致您看到的错误。因此,我会做这样的事情:

tell application "Keychain Scripting"
    set keychainName to "Login.keychain" -- "system.keychain"
    set doRelock to false
    set kc to keychain keychainName
    if locked of kc then
        unlock kc
        set doRelock to true
    end if
    try
        set gkeyCount to count generic key of kc

        repeat with keyIndex from 1 to gkeyCount
            log keyIndex
            if (account of generic key keyIndex of kc is "ABCD") then
                delete generic key keyIndex of keychain keychainName
                log "find the key"
            end if
        end repeat
        if doRelock then
            lock kc
            set doRelock to false
        end if
    on error
        if doRelock then lock kc
    end try
end tell

这个想法是,如果需要的话,首先解锁钥匙串,然后确保在完成后重新锁定它。让我知道这是否有效——就像我说的,我没有任何想要测试的东西。

Edit: This doesn't work. Ah well, it was just a guess anyway. I'm leaving the answer up for posterity.


My guess is that the problem is that the system keychain is locked. I can't really test this, since I don't want to delete things from my keychain, but I did confirm that my system keychain defaults to being locked, and this seems like the sort of thing which would cause the error you see. Thus, I'd do something like this:

tell application "Keychain Scripting"
    set keychainName to "Login.keychain" -- "system.keychain"
    set doRelock to false
    set kc to keychain keychainName
    if locked of kc then
        unlock kc
        set doRelock to true
    end if
    try
        set gkeyCount to count generic key of kc

        repeat with keyIndex from 1 to gkeyCount
            log keyIndex
            if (account of generic key keyIndex of kc is "ABCD") then
                delete generic key keyIndex of keychain keychainName
                log "find the key"
            end if
        end repeat
        if doRelock then
            lock kc
            set doRelock to false
        end if
    on error
        if doRelock then lock kc
    end try
end tell

The idea is to first unlocked the keychain if you need to, and then make sure you relock it when you're done. Let me know if this does or doesn't work—like I said, I had nothing I wanted to test this on.

や三分注定 2024-10-12 20:08:27

我用 Objective-C 得到了解决方案:

BOOL deleteItemOfSystemKeychain(NSArray *accountList)
{
OSStatus retVal;
SecKeychainRef systemKeychainRef;
SecKeychainItemRef kcItem;
AuthorizationRef authRef;
AuthorizationItem right = { "system.keychain.modify", 0, NULL, 0 };
AuthorizationRights rightSet = { 1, &right };

/* Create authorization to access the system.keychain */
retVal = AuthorizationCreate(&rightSet, kAuthorizationEmptyEnvironment, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, &authRef);

if (retVal != errSecSuccess) {
    NSLog(@"Failed to get right to modify system keychain %@", SecCopyErrorMessageString(retVal, NULL));
    return FALSE;
}

SecKeychainSetUserInteractionAllowed(TRUE);
retVal = SecKeychainOpen("/Library/Keychains/System.keychain", &systemKeychainRef);
if (retVal != errSecSuccess) {
    NSLog(@"Failed to open System keychain %@", SecCopyErrorMessageString(retVal, NULL));
    return FALSE;
}

retVal = SecKeychainUnlock(systemKeychainRef, 0, NULL, FALSE);
    if (retVal != errSecSuccess) {
    NSLog(@"Failed to unlock System keychain %@", SecCopyErrorMessageString(retVal, NULL));
    return FALSE;
}

//  retVal = SecKeychainSetSearchList(CFArrayRef searchList);

/* Search the item we wanna to delete */
CFArrayRef arrayRef;
SecKeychainCopySearchList(&arrayRef);
SecKeychainSetSearchList(arrayRef);
CFRelease(arrayRef);

SecKeychainSearchRef searchRef;
SecKeychainSearchCreateFromAttributes(NULL,
                                      kSecGenericPasswordItemClass,
                                      NULL,
                                      &searchRef);  

while (errSecItemNotFound != SecKeychainSearchCopyNext(searchRef, &kcItem))
{
    static int iCount = 1;
    SecKeychainAttributeInfo *info;
    SecKeychainAttributeInfoForItemID(systemKeychainRef, 
                                      CSSM_DL_DB_RECORD_GENERIC_PASSWORD,
                                      &info);
    SecKeychainAttributeList *attributes;
    SecKeychainItemCopyAttributesAndData(kcItem, info, NULL, &attributes, 0, NULL);


    for (int i = 0; i < attributes->count; i ++)
    {
        SecKeychainAttribute attr = attributes->attr[i];

        char attr_tag[5] = {0};
        attr_tag[0] = ((char *)&attr.tag)[3];
        attr_tag[1] = ((char *)&attr.tag)[2];
        attr_tag[2] = ((char *)&attr.tag)[1];
        attr_tag[3] = ((char *)&attr.tag)[0];

        NSString *attrTag = [NSString stringWithCString:attr_tag encoding:NSUTF8StringEncoding];
        NSString *attrValue = [[[NSString alloc] initWithData:[NSData dataWithBytes:attr.data
                                                                             length:attr.length]
                                                     encoding:NSUTF8StringEncoding] autorelease];

        if ([attrTag isEqualToString:@"acct"])
        {
            NSLog(@"Check Item %d:%@:%@", iCount++, attrTag, attrValue);
            for (NSString *str in accountList)  
            {
                if ([attrValue isEqualToString:str])
                {
                    NSLog(@"delete %@...", str);
                    retVal = SecKeychainItemDelete(kcItem);
                    if (retVal != errSecSuccess)
                    {
                        NSLog(@"delete %@ failed...", str);
                    }
                }
            }
        }
    }
}

return TRUE;

}

注意:以 root/admin 身份运行。

:)

I'v got the solution with Objective-C:

BOOL deleteItemOfSystemKeychain(NSArray *accountList)
{
OSStatus retVal;
SecKeychainRef systemKeychainRef;
SecKeychainItemRef kcItem;
AuthorizationRef authRef;
AuthorizationItem right = { "system.keychain.modify", 0, NULL, 0 };
AuthorizationRights rightSet = { 1, &right };

/* Create authorization to access the system.keychain */
retVal = AuthorizationCreate(&rightSet, kAuthorizationEmptyEnvironment, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, &authRef);

if (retVal != errSecSuccess) {
    NSLog(@"Failed to get right to modify system keychain %@", SecCopyErrorMessageString(retVal, NULL));
    return FALSE;
}

SecKeychainSetUserInteractionAllowed(TRUE);
retVal = SecKeychainOpen("/Library/Keychains/System.keychain", &systemKeychainRef);
if (retVal != errSecSuccess) {
    NSLog(@"Failed to open System keychain %@", SecCopyErrorMessageString(retVal, NULL));
    return FALSE;
}

retVal = SecKeychainUnlock(systemKeychainRef, 0, NULL, FALSE);
    if (retVal != errSecSuccess) {
    NSLog(@"Failed to unlock System keychain %@", SecCopyErrorMessageString(retVal, NULL));
    return FALSE;
}

//  retVal = SecKeychainSetSearchList(CFArrayRef searchList);

/* Search the item we wanna to delete */
CFArrayRef arrayRef;
SecKeychainCopySearchList(&arrayRef);
SecKeychainSetSearchList(arrayRef);
CFRelease(arrayRef);

SecKeychainSearchRef searchRef;
SecKeychainSearchCreateFromAttributes(NULL,
                                      kSecGenericPasswordItemClass,
                                      NULL,
                                      &searchRef);  

while (errSecItemNotFound != SecKeychainSearchCopyNext(searchRef, &kcItem))
{
    static int iCount = 1;
    SecKeychainAttributeInfo *info;
    SecKeychainAttributeInfoForItemID(systemKeychainRef, 
                                      CSSM_DL_DB_RECORD_GENERIC_PASSWORD,
                                      &info);
    SecKeychainAttributeList *attributes;
    SecKeychainItemCopyAttributesAndData(kcItem, info, NULL, &attributes, 0, NULL);


    for (int i = 0; i < attributes->count; i ++)
    {
        SecKeychainAttribute attr = attributes->attr[i];

        char attr_tag[5] = {0};
        attr_tag[0] = ((char *)&attr.tag)[3];
        attr_tag[1] = ((char *)&attr.tag)[2];
        attr_tag[2] = ((char *)&attr.tag)[1];
        attr_tag[3] = ((char *)&attr.tag)[0];

        NSString *attrTag = [NSString stringWithCString:attr_tag encoding:NSUTF8StringEncoding];
        NSString *attrValue = [[[NSString alloc] initWithData:[NSData dataWithBytes:attr.data
                                                                             length:attr.length]
                                                     encoding:NSUTF8StringEncoding] autorelease];

        if ([attrTag isEqualToString:@"acct"])
        {
            NSLog(@"Check Item %d:%@:%@", iCount++, attrTag, attrValue);
            for (NSString *str in accountList)  
            {
                if ([attrValue isEqualToString:str])
                {
                    NSLog(@"delete %@...", str);
                    retVal = SecKeychainItemDelete(kcItem);
                    if (retVal != errSecSuccess)
                    {
                        NSLog(@"delete %@ failed...", str);
                    }
                }
            }
        }
    }
}

return TRUE;

}

Note: run this as root/admin.

:)

零度℉ 2024-10-12 20:08:27

您需要以写入权限打开文件:请参阅 books_google_com 来自 AppleScript:Mac OS X 上的脚本和自动化综合指南

You need to open the file with writing permissions: see books_google_com from AppleScript: the comprehensive guide to scripting and automation on Mac OS X

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文