Beispiel #1
0
static CFStringRef rb_copy_item_class(SecKeychainItemRef item){
  SecItemClass secItemClass;
  SecKeychainItemCopyContent(item, &secItemClass, NULL, NULL, NULL);
  secItemClass = CFSwapInt32HostToBig(secItemClass);
  CFStringRef cfclass = CFStringCreateWithBytes(NULL, (UInt8*)&secItemClass, sizeof(secItemClass), kCFStringEncodingUTF8, false);
  return cfclass;
}
void CertificateAttributeCoder::decode(TokenContext *tokenContext,
                                       const MetaAttribute &metaAttribute,
                                       Record &record)
{
	// Get the SecCertificateAdornment off record using a pointer to ourself as
	// the key
	SecCertificateAdornment &sca =
		record.adornment<SecCertificateAdornment>(this, tokenContext,
			metaAttribute, record);

	// Get the keychain item for the certificate from the record's adornment.
	SecKeychainItemRef certificate = sca.certificateItem();
	// Read the attribute with the requested attributeId from the item.
	SecKeychainAttribute ska = { metaAttribute.attributeId() };
	SecKeychainAttributeList skal = { 1, &ska };
	OSStatus status = SecKeychainItemCopyContent(certificate, NULL, &skal,
		NULL, NULL);
	if (status)
		MacOSError::throwMe(status);
	// Add the retrieved attribute as an attribute to the record.
	record.attributeAtIndex(metaAttribute.attributeIndex(),
		new Attribute(ska.data, ska.length));
	// Free the retrieved attribute.
	status = SecKeychainItemFreeContent(&skal, NULL);
	if (status)
		MacOSError::throwMe(status);

	// @@@ The code above only returns one email address.  Fix this.
}
static void find_username_in_item(SecKeychainItemRef item)
{
	SecKeychainAttributeList list;
	SecKeychainAttribute attr;

	list.count = 1;
	list.attr = &attr;
	attr.tag = kSecAccountItemAttr;

	if (SecKeychainItemCopyContent(item, NULL, &list, NULL, NULL))
		return;

	write_item("username", attr.data, attr.length);
	SecKeychainItemFreeContent(&list, NULL);
}
Beispiel #4
0
bool OsxWallet::getCredentials(const QString &realm, QString &user, QString &password)
{
    const QByteArray realm_data = realm.toUtf8();
    const QByteArray user_data = user.toUtf8();
    SecKeychainItemRef itemRef = NULL;

    /* get password */
    int rc = SecKeychainFindInternetPassword(keychain,
        realm_data.size(), realm_data.constData(),
        0, NULL,
        user_data.size(), user_data.constData(),
        0, NULL,
        0, kSecProtocolTypeAny, kSecAuthenticationTypeAny,
        0, NULL,
        &itemRef);
    if (rc != errSecSuccess)
        return false;

    /* get username */
    SecKeychainAttribute attr;
    SecKeychainAttributeList attrList;
    attr.tag = kSecAccountItemAttr;
    attr.length = 0;
    attr.data = NULL;
    attrList.count = 1;
    attrList.attr = &attr;

    UInt32 password_length = 0;
    void *password_data = NULL;

    if (SecKeychainItemCopyContent(itemRef, NULL, &attrList, &password_length, &password_data) != errSecSuccess)
    {
        CFRelease(itemRef);
        return false;
    }

    /* store results */
    user = QString::fromUtf8(QByteArray((char*)attr.data, attr.length));
    password = QString::fromUtf8(QByteArray((char*)password_data, password_length));
    SecKeychainItemFreeContent(&attrList, password_data);
    CFRelease(itemRef);
    return true;
}
static void checkContent(SecKeychainItemRef itemRef)
{
	SecItemClass itemClass;

	SecKeychainAttribute attrs[] =
	{
		{ kSecLabelItemAttr, 0, NULL },
		{ kSecAccountItemAttr, 0, NULL },
		{ kSecServiceItemAttr, 0, NULL }
	};

	SecKeychainAttributeList attrList =
		{ sizeof(attrs) / sizeof(*attrs), attrs };
	UInt32 length;
	void *data;

#if 1
	ok_status(SecKeychainItemCopyContent(itemRef, &itemClass, &attrList,
		&length, &data), "get item data in callback");
	SKIP: {
		skip("length mismatch", 1,
			is(length, sizeof(password), "<rdar://problem/3867900> "
				"SecKeychainItemCopyContent() returns bad data on items "
				"from notifications"));

		ok(!memcmp(password, data, length), "password data matches.");
	}
#else
	if (length != sizeof(password) || memcmp(password, data, length))
	{
		fprintf(stderr, "password '%.*s' not same as '%.*s'\n",
			(int)sizeof(password), password,
			(int)length, (char *)data);
	}
#endif

	ok_status(SecKeychainItemFreeContent(&attrList, data),
		"free item data in callback");
}
static OSStatus
do_password_item_printing(	SecKeychainItemRef itemRef,
                          Boolean get_password,
                          Boolean password_stdout)
{
    OSStatus result = noErr;
    void *passwordData = NULL;
    UInt32 passwordLength = 0;

    if(get_password) {
		result = SecKeychainItemCopyContent(itemRef, NULL, NULL, &passwordLength, &passwordData);
		if(result != noErr) return result;
    }
    if(!password_stdout) {
        print_keychain_item_attributes(stdout, itemRef, FALSE, FALSE, FALSE, FALSE);
		if(get_password) {
			fputs("password: "******"%02x", password[i]);
        } else {
            for(int i=0; i<passwordLength; i++) putchar(password[i]);
        }
        putchar('\n');
    }

    if (passwordData) SecKeychainItemFreeContent(NULL, passwordData);
    return noErr;

}
void tests(int dont_skip)
{
	SecKeychainRef source, dest;
	ok_status(SecKeychainCreate("source", 4, "test", FALSE, NULL, &source),
		"create source keychain");
	ok_status(SecKeychainCreate("dest", 4, "test", FALSE, NULL, &dest),
		"create dest keychain");
	SecKeychainItemRef original = NULL;
	ok_status(SecKeychainAddInternetPassword(source,
		19, "members.spamcop.net",
		0, NULL,
		5, "smith",
		0, NULL,
		80, kSecProtocolTypeHTTP,
		kSecAuthenticationTypeDefault,
		4, "test", &original), "add internet password");
	SecKeychainAttribute origAttrs[] = 
	{
		{ kSecCreationDateItemAttr },
		{ kSecModDateItemAttr }
	};
	SecKeychainAttributeList origAttrList =
	{
		sizeof(origAttrs) / sizeof(*origAttrs),
		origAttrs
	};
	ok_status(SecKeychainItemCopyContent(original, NULL, &origAttrList,
		NULL, NULL), "SecKeychainItemCopyContent");

	/* Must sleep 1 second to trigger mod date bug. */
	sleep(1);
	SecKeychainItemRef copy;
	ok_status(SecKeychainItemCreateCopy(original, dest, NULL, &copy),
		"copy item");

	SecKeychainAttribute copyAttrs[] = 
	{
		{ kSecCreationDateItemAttr },
		{ kSecModDateItemAttr }
	};
	SecKeychainAttributeList copyAttrList =
	{
		sizeof(copyAttrs) / sizeof(*copyAttrs),
		copyAttrs
	};
	ok_status(SecKeychainItemCopyContent(copy, NULL, &copyAttrList,
		NULL, NULL), "SecKeychainItemCopyContent");

	is(origAttrs[0].length, 16, "creation date length 16");
	is(origAttrs[1].length, 16, "mod date length 16");
	is(origAttrs[0].length, copyAttrs[0].length, "creation date length same");
	is(origAttrs[1].length, copyAttrs[1].length, "mod date length same");

	TODO: {
		todo("<rdar://problem/3731664> Moving/copying a keychain item "
			"between keychains erroneously updates dates");

		diag("original creation: %.*s copy creation: %.*s",
			(int)origAttrs[0].length, (const char *)origAttrs[0].data,
			(int)copyAttrs[0].length, (const char *)copyAttrs[0].data);
		ok(!memcmp(origAttrs[0].data, copyAttrs[0].data, origAttrs[0].length),
			"creation date same");

		diag("original mod: %.*s copy mod: %.*s",
			(int)origAttrs[1].length, (const char *)origAttrs[1].data,
			(int)copyAttrs[1].length, (const char *)copyAttrs[1].data);
		ok(!memcmp(origAttrs[1].data, copyAttrs[1].data, origAttrs[1].length),
			"mod date same");
	}

	ok_status(SecKeychainItemFreeContent(&origAttrList, NULL),
		"SecKeychainItemCopyContent");
	ok_status(SecKeychainItemFreeContent(&copyAttrList, NULL),
		"SecKeychainItemCopyContent");

	is(CFGetRetainCount(original), 1, "original retaincount is 1");
	CFRelease(original);
	is(CFGetRetainCount(copy), 1, "copy retaincount is 1");
	CFRelease(copy);
	is(CFGetRetainCount(source), 1, "source retaincount is 1");
	ok_status(SecKeychainDelete(source), "delete keychain source");
	CFRelease(source);
	ok_status(SecKeychainDelete(dest), "delete keychain dest");
	is(CFGetRetainCount(dest), 1, "dest retaincount is 1");
	CFRelease(dest);

	ok(tests_end(1), "cleanup");
}
void tests(void)
{
	SecKeychainRef keychain = NULL;
	ok_status(SecKeychainCreate("test", 4, "test", FALSE, NULL, &keychain),
		"create keychain");
	ok_status(test_sec_event_register(kSecEveryEventMask),
		"register for all events");
	int item_num;
	int item_count = 9;
	for (item_num = 0; item_num < item_count; ++item_num)
	{
		char account[64];
		sprintf(account, "account-%d", item_num);
		ok_status(SecKeychainAddGenericPassword(keychain, 7, "service",
			strlen(account), account, 4, "test", NULL),
			"add generic password");
	}
	SecKeychainAttribute attrs[] =
	{ { kSecAccountItemAttr } };
	SecKeychainAttributeList attrList =
	{ sizeof(attrs) / sizeof(*attrs), attrs };

	for (item_num = 0; item_num < item_count - 2; ++item_num)
	{
		char account[64];
		sprintf(account, "account-%d", item_num);
		SecKeychainItemRef item = NULL;
		is_sec_event(kSecAddEvent, NULL, &item, NULL, "got add event");

		SKIP: {
			skip("no item", 3, item != NULL);

			ok_status(SecKeychainItemCopyContent(item, NULL, &attrList, NULL,
				NULL), "get content");
			
			eq_stringn(account, strlen(account), attrs[0].data, attrs[0].length,
				"account name in notification matches");
			ok_status(SecKeychainItemFreeContent(&attrList, NULL),
				"free content");
		}
	}

	for (; item_num < item_count; ++item_num)
	{
		char account[64];
		sprintf(account, "account-%d", item_num);
		SecKeychainItemRef item = NULL;
		is_sec_event(kSecAddEvent, NULL, &item, NULL, "got add event");

		SKIP: {
			skip("no item", 3, item != NULL);

			ok_status(SecKeychainItemCopyContent(item, NULL, &attrList, NULL,
				NULL), "get content");
			eq_stringn(account, strlen(account), attrs[0].data, attrs[0].length,
				"account name in notification matches");
			ok_status(SecKeychainItemFreeContent(&attrList, NULL),
				"free content");
		}
	}
	
	ok(tests_end(1), "cleanup");
}