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

结束告诉

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

任何想法?

4

3 回答 3

0

我有 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 身份运行。

:)

于 2010-12-10T06:18:17.387 回答
0

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

于 2010-12-09T14:51:39.963 回答
0

编辑:这不起作用。嗯,反正也只是猜测。我将答案留给后人。


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

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

这个想法是在需要时首先解锁钥匙串,然后确保在完成后重新锁定它。让我知道这是否有效——就像我说的那样,我没有什么想要测试的。

于 2010-12-09T16:44:24.323 回答