Из этого вопроса я знаю, что вы можете использовать SecKeychainFindGenericPassword
без значения имени пользователя.Это все еще возвратит элемент цепочки для ключей для данной услуги.Но как мне тогда получить имя пользователя? Получить имена пользователей, хранящиеся в связке ключей, используя только ServiceName?ИЛИ: Где вы должны хранить имя пользователя?
//SecKeychainFindGenericPassword
//Finds the first generic password based on the attributes passed.
OSStatus SecKeychainFindGenericPassword (
CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char *serviceName,
UInt32 accountNameLength,
const char *accountName,
UInt32 *passwordLength,
void **passwordData,
SecKeychainItemRef *itemRef
);
Мой код выглядит следующим образом:
UInt32 passwordLength = 0;
char *password = nil;
SecKeychainItemRef item = nil;
OSStatus returnStatus = SecKeychainFindGenericPassword(NULL, 9, @"MyAppName", 0, NULL, &passwordLength, (void **)&password, &item);
//Get password
NSString *passwordString = [[[NSString alloc] initWithData:[NSData dataWithBytes:password length:passwordLength] encoding:NSUTF8StringEncoding] autorelease];
SecKeychainItemFreeContent(NULL, password);
//Get username (not yet working)
UInt32 attributeTags[1];
*attributeTags = 'acct';// TODO: populate with the kSecAttrAccount constant (NOT a string cast to a UInt32)
//kSecAccountItemAttr = 'acct',
UInt32 formatConstants[1];
*formatConstants = 0; // TODO: populate with a format constant found in "cssmtype.h". I'm picking "0" = "string" in list below...
//SecKeychainAttributeInfo doc says: "A pointer to the first attribute format in the array. Attribute formats are of type CSSM_DB_ATTRIBUTE_FORMAT."
/* //found in "cssmtype.h"
typedef uint32 CSSM_DB_ATTRIBUTE_FORMAT, *CSSM_DB_ATTRIBUTE_FORMAT_PTR;
enum {
CSSM_DB_ATTRIBUTE_FORMAT_STRING = 0,
CSSM_DB_ATTRIBUTE_FORMAT_SINT32 = 1,
CSSM_DB_ATTRIBUTE_FORMAT_UINT32 = 2,
CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM = 3,
CSSM_DB_ATTRIBUTE_FORMAT_REAL = 4,
CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE = 5,
CSSM_DB_ATTRIBUTE_FORMAT_BLOB = 6,
CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32 = 7,
CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX = 8
};
*/
struct SecKeychainAttributeInfo attributeInfo, 1, *attributeTags, *formatConstants; //ERROR: "Expected ';' at end of declaration list.
//OR:
/*
struct SecKeychainAttributeInfo
{
UInt32 1; //ERROR: "Expected ';' at end of declaration list.
UInt32 *attributeTags;
UInt32 *formatConstants;
}attributeInfo;
*/
/*
SecKeychainAttributeInfo *attributeInfo; //TODO: "change it to hold the structure directly"
attributeInfo->count = 1;
attributeInfo->tag = attributeTags;
attributeInfo->format = formatConstants;
*/
SecKeychainAttributeList *attributeList = nil;
OSStatus attributeStatus = SecKeychainItemCopyAttributesAndData(item, &attributeInfo, NULL, &attributeList, 0, NULL);
if (attributeStatus != noErr)
{
if (_logsErrors)
NSLog(@"Error (%@) - %s", NSStringFromSelector(_cmd), GetMacOSStatusErrorString(attributeStatus));
return nil;
}
for (int i = 0; i < attributeList->count; i ++)
{
SecKeychainAttribute attr = attributeList->attr[i];
NSLog(@"%08x %@", attr.tag, [NSData dataWithBytes:attr.data length:attr.length]);
}
Как получить значение NSString имени пользователя, содержащегося вчто SecKeychainItemRef
?