mirror of
https://github.com/git/git.git
synced 2024-10-28 04:49:43 +01:00
osxkeychain: erase matching passwords only
Other credential helpers support deleting credentials that match a specified password. See7144dee3ec
(credential/libsecret: erase matching creds only, 2023-07-26) andcb626f8e5c
(credential/wincred: erase matching creds only, 2023-07-26). Support this in osxkeychain too by extracting, decrypting and comparing the stored password before deleting. Fixes the following test failure with osxkeychain: 11 - helper (osxkeychain) does not erase a password distinct from input Signed-off-by: Bo Anderson <mail@boanderson.me> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
9032bcad82
commit
e3cef40db8
1 changed files with 55 additions and 1 deletions
|
@ -169,9 +169,55 @@ static OSStatus find_internet_password(void)
|
|||
return result;
|
||||
}
|
||||
|
||||
static OSStatus delete_ref(const void *itemRef)
|
||||
{
|
||||
CFArrayRef item_ref_list;
|
||||
CFDictionaryRef delete_query;
|
||||
OSStatus result;
|
||||
|
||||
item_ref_list = CFArrayCreate(kCFAllocatorDefault,
|
||||
&itemRef,
|
||||
1,
|
||||
&kCFTypeArrayCallBacks);
|
||||
delete_query = create_dictionary(kCFAllocatorDefault,
|
||||
kSecClass, kSecClassInternetPassword,
|
||||
kSecMatchItemList, item_ref_list,
|
||||
NULL);
|
||||
|
||||
if (password) {
|
||||
/* We only want to delete items with a matching password */
|
||||
CFIndex capacity;
|
||||
CFMutableDictionaryRef query;
|
||||
CFDataRef data;
|
||||
|
||||
capacity = CFDictionaryGetCount(delete_query) + 1;
|
||||
query = CFDictionaryCreateMutableCopy(kCFAllocatorDefault,
|
||||
capacity,
|
||||
delete_query);
|
||||
CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
|
||||
result = SecItemCopyMatching(query, (CFTypeRef *)&data);
|
||||
if (!result) {
|
||||
if (CFEqual(data, password))
|
||||
result = SecItemDelete(delete_query);
|
||||
|
||||
CFRelease(data);
|
||||
}
|
||||
|
||||
CFRelease(query);
|
||||
} else {
|
||||
result = SecItemDelete(delete_query);
|
||||
}
|
||||
|
||||
CFRelease(delete_query);
|
||||
CFRelease(item_ref_list);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static OSStatus delete_internet_password(void)
|
||||
{
|
||||
CFDictionaryRef attrs;
|
||||
CFArrayRef refs;
|
||||
OSStatus result;
|
||||
|
||||
/*
|
||||
|
@ -183,10 +229,18 @@ static OSStatus delete_internet_password(void)
|
|||
return -1;
|
||||
|
||||
attrs = CREATE_SEC_ATTRIBUTES(kSecMatchLimit, kSecMatchLimitAll,
|
||||
kSecReturnRef, kCFBooleanTrue,
|
||||
NULL);
|
||||
result = SecItemDelete(attrs);
|
||||
result = SecItemCopyMatching(attrs, (CFTypeRef *)&refs);
|
||||
CFRelease(attrs);
|
||||
|
||||
if (!result) {
|
||||
for (CFIndex i = 0; !result && i < CFArrayGetCount(refs); i++)
|
||||
result = delete_ref(CFArrayGetValueAtIndex(refs, i));
|
||||
|
||||
CFRelease(refs);
|
||||
}
|
||||
|
||||
/* We consider not found to not be an error */
|
||||
if (result == errSecItemNotFound)
|
||||
result = errSecSuccess;
|
||||
|
|
Loading…
Reference in a new issue