kinit: Update SecKeychainFindGenericPassword to SecItemCopyMatching.
Tested on macOS Venture 13.4. Not sure if this requires some compatibility ifdefs for older macOS. fix https://github.com/heimdal/heimdal/issues/1168
This commit is contained in:

committed by
Nico Williams

parent
e3e271ff70
commit
9569ee1a3b
@@ -779,29 +779,81 @@ get_new_tickets(krb5_context context,
|
|||||||
|
|
||||||
#ifdef HAVE_FRAMEWORK_SECURITY
|
#ifdef HAVE_FRAMEWORK_SECURITY
|
||||||
if (passwd[0] == '\0') {
|
if (passwd[0] == '\0') {
|
||||||
|
enum querykey {
|
||||||
|
qk_class, qk_matchlimit, qk_service, qk_account, qk_secreturndata,
|
||||||
|
};
|
||||||
|
const void *querykeys[] = {
|
||||||
|
[qk_class] = kSecClass,
|
||||||
|
[qk_matchlimit] = kSecMatchLimit,
|
||||||
|
[qk_service] = kSecAttrService,
|
||||||
|
[qk_account] = kSecAttrAccount,
|
||||||
|
[qk_secreturndata] = kSecReturnData,
|
||||||
|
};
|
||||||
|
const void *queryargs[] = {
|
||||||
|
[qk_class] = kSecClassGenericPassword,
|
||||||
|
[qk_matchlimit] = kSecMatchLimitOne,
|
||||||
|
[qk_service] = NULL, /* filled in later */
|
||||||
|
[qk_account] = NULL, /* filled in later */
|
||||||
|
[qk_secreturndata] = kCFBooleanTrue,
|
||||||
|
};
|
||||||
|
CFStringRef service_ref = NULL;
|
||||||
|
CFStringRef account_ref = NULL;
|
||||||
|
CFDictionaryRef query_ref = NULL;
|
||||||
const char *realm;
|
const char *realm;
|
||||||
OSStatus osret;
|
OSStatus osret;
|
||||||
UInt32 length;
|
char *name = NULL;
|
||||||
void *buffer;
|
CFTypeRef item_ref = NULL;
|
||||||
char *name;
|
CFDataRef item;
|
||||||
|
CFIndex length;
|
||||||
|
|
||||||
realm = krb5_principal_get_realm(context, principal);
|
realm = krb5_principal_get_realm(context, principal);
|
||||||
|
|
||||||
ret = krb5_unparse_name_flags(context, principal,
|
ret = krb5_unparse_name_flags(context, principal,
|
||||||
KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
|
KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto nopassword;
|
goto fail;
|
||||||
|
|
||||||
osret = SecKeychainFindGenericPassword(NULL, strlen(realm), realm,
|
service_ref = CFStringCreateWithCString(kCFAllocatorDefault, realm,
|
||||||
strlen(name), name,
|
kCFStringEncodingUTF8);
|
||||||
&length, &buffer, NULL);
|
if (service_ref == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
account_ref = CFStringCreateWithCString(kCFAllocatorDefault, name,
|
||||||
|
kCFStringEncodingUTF8);
|
||||||
|
if (account_ref == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
queryargs[qk_service] = service_ref;
|
||||||
|
queryargs[qk_account] = account_ref;
|
||||||
|
query_ref = CFDictionaryCreate(kCFAllocatorDefault,
|
||||||
|
querykeys, queryargs,
|
||||||
|
/*numValues*/sizeof(querykeys)/sizeof(querykeys[0]),
|
||||||
|
/*keyCallbacks*/NULL, /*valueCallbacks*/NULL);
|
||||||
|
if (query_ref == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
osret = SecItemCopyMatching(query_ref, &item_ref);
|
||||||
|
if (osret != noErr)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
item = item_ref;
|
||||||
|
length = CFDataGetLength(item);
|
||||||
|
if (length >= sizeof(passwd) - 1)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
CFDataGetBytes(item, CFRangeMake(0, length), (UInt8 *)passwd);
|
||||||
|
passwd[length] = '\0';
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (item_ref)
|
||||||
|
CFRelease(item_ref);
|
||||||
|
if (query_ref)
|
||||||
|
CFRelease(query_ref);
|
||||||
|
if (account_ref)
|
||||||
|
CFRelease(account_ref);
|
||||||
|
if (service_ref)
|
||||||
|
CFRelease(service_ref);
|
||||||
free(name);
|
free(name);
|
||||||
if (osret == noErr && length < sizeof(passwd) - 1) {
|
|
||||||
memcpy(passwd, buffer, length);
|
|
||||||
passwd[length] = '\0';
|
|
||||||
}
|
|
||||||
nopassword:
|
|
||||||
do { } while(0);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user