/* Implementation of OSXKeychain.addInternetPassword(). See the Java docs for
 * explanation of the parameters.
 */
JNIEXPORT void JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1addInternetPassword(JNIEnv* env, jobject obj, jstring serverName, jstring securityDomain, jstring accountName, jstring path, jint port, jint protocol, jint authenticationType, jstring password) {
	OSStatus status;
	jstring_unpacked server_name;
	jstring_unpacked security_domain;
	jstring_unpacked account_name;
	jstring_unpacked server_path;
	jstring_unpacked server_password;

	/* Unpack the string params. */
	jstring_unpack(env, serverName, &server_name);
	jstring_unpack(env, securityDomain, &security_domain);
	jstring_unpack(env, accountName, &account_name);
	jstring_unpack(env, path, &server_path);
	jstring_unpack(env, password, &server_password);
	/* check for allocation failures */
	if (server_name.str == NULL || 
	    security_domain.str == NULL ||
		account_name.str == NULL || 
		server_path.str == NULL ||
		server_password.str == NULL) {
		jstring_unpacked_free(env, serverName, &server_name);
		jstring_unpacked_free(env, securityDomain, &security_domain);
		jstring_unpacked_free(env, accountName, &account_name);
		jstring_unpacked_free(env, path, &server_path);
		jstring_unpacked_free(env, password, &server_password);
		return;
	}

	/* Add the details to the keychain. */
	status = SecKeychainAddInternetPassword(
		NULL,
		server_name.len,
		server_name.str,
		security_domain.len,
		security_domain.str,
		account_name.len,
		account_name.str,
		server_path.len,
		server_path.str,
		port,
		protocol,
		authenticationType,
		server_password.len,
		server_password.str,
		NULL
	);
	if (status != errSecSuccess) {
		throw_osxkeychainexception(env, status);
	}

	/* Clean up. */
	jstring_unpacked_free(env, serverName, &server_name);
	jstring_unpacked_free(env, securityDomain, &security_domain);
	jstring_unpacked_free(env, accountName, &account_name);
	jstring_unpacked_free(env, path, &server_path);
	jstring_unpacked_free(env, password, &server_password);
}
Пример #2
0
void gnc_keyring_set_password (const gchar *access_method,
                               const gchar *server,
                               guint32 port,
                               const gchar *service,
                               const gchar *user,
                               const gchar* password)
{

#ifdef HAVE_GNOME_KEYRING
    GnomeKeyringResult  gkr_result;
    guint32 item_id = 0;

    gkr_result = gnome_keyring_set_network_password_sync
                 (NULL, user, NULL, server, service,
                  access_method, NULL, port, password, &item_id);

    if (gkr_result != GNOME_KEYRING_RESULT_OK)
    {
        PWARN ("Gnome-keyring error: %s",
               gnome_keyring_result_to_message(gkr_result));
        PWARN ("The user will be prompted for a password again next time.");
    }
#endif /* HAVE_GNOME_KEYRING */
#ifdef HAVE_OSX_KEYCHAIN
    OSStatus status;
    SecKeychainItemRef *itemRef = NULL;

    /* mysql and postgres aren't valid protocols on Mac OS X.
     * So we use the security domain parameter to allow us to
     * distinguish between these two.
     */
    // FIXME I'm not sure this works if a password was already in the keychain
    //       I may have to do a lookup first and if it exists, run some update
    //       update function instead
    status = SecKeychainAddInternetPassword ( NULL, /* keychain */
             strlen(server), server,                /* servername */
             strlen(access_method), access_method,  /* securitydomain */
             strlen(user), user,                    /* acountname */
             strlen(service), service,              /* path */
             port,                                  /* port */
             kSecProtocolTypeAny,                   /* protocol */
             kSecAuthenticationTypeDefault,         /* auth type */
             strlen(password), password,            /* passworddata */
             itemRef );

    if ( status != noErr )
    {
        CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL );
        const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring,
                                    GetApplicationTextEncoding());
        PWARN ( "OS X keychain error: %s", resultstring );
        PWARN ( "The user will be prompted for a password again next time." );
        CFRelease ( osx_resultstring );
    }
#endif /* HAVE_OSX_KEYCHAIN */
}
Пример #3
0
static void add_internet_password(void)
{
	/* Only store complete credentials */
	if (!protocol || !host || !username || !password)
		return;

	if (SecKeychainAddInternetPassword(
	      KEYCHAIN_ARGS,
	      KEYCHAIN_ITEM(password),
	      NULL))
		return;
}
Пример #4
0
bool OsxWallet::setCredentials(const QString &realm, const QString &user, const QString &password)
{
    const QByteArray realm_data = realm.toUtf8();
    const QByteArray user_data = user.toUtf8();
    const QByteArray password_data = password.toUtf8();

    /* check whether the entry already exists */
    SecKeychainItemRef itemRef = NULL;
    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)
    {
        // FIXME: we should not update username!
        SecKeychainAttribute attr;
        SecKeychainAttributeList attrList;
        attr.tag = kSecAccountItemAttr;
        attr.length = user_data.size();
        attr.data = (void*)user_data.constData();
        attrList.count = 1;
        attrList.attr = &attr;

        rc = SecKeychainItemModifyAttributesAndData(itemRef, &attrList, password_data.size(), password_data.constData());
        CFRelease(itemRef);
    } else {
        rc = SecKeychainAddInternetPassword(keychain,
            realm_data.size(), realm_data.constData(),
            0, NULL,
            user_data.size(), user_data.constData(),
            0, NULL,
            0, kSecProtocolTypeAny, kSecAuthenticationTypeAny,
            password_data.size(), password_data.constData(), NULL);
    }

    return (rc == errSecSuccess);
}
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 SG_password__set(
	SG_context *pCtx,
	const char *szRepoSpec,
	SG_string *pUserName,
	SG_string *pPassword)
{
	const char *username, *password;
	SG_string *path = NULL;
	SG_string *server = NULL;
	SecProtocolType proto;
	SG_uint32 port;
	SG_bool isValid = SG_FALSE;

	OSStatus saveRes, findRes;
	SecKeychainItemRef item = NULL;

	SG_NULLARGCHECK(pUserName);
	SG_NULLARGCHECK(pPassword);
	SG_NULLARGCHECK(szRepoSpec);

	username = SG_string__sz(pUserName);
	password = SG_string__sz(pPassword);

	SG_ERR_CHECK(  _sg_password__parse_url(pCtx, szRepoSpec,
		&isValid, &proto, &server, &path, &port)  );

	if (! isValid)
		SG_ERR_THROW(SG_ERR_NOTIMPLEMENTED);

	findRes = SecKeychainFindInternetPassword(
		NULL,
		SG_STRLEN( SG_string__sz(server) ), SG_string__sz(server),
		0, NULL,
		SG_STRLEN(username), username,
		SG_STRLEN( SG_string__sz(path) ), SG_string__sz(path),
		port, proto, kSecAuthenticationTypeDefault,
		NULL, NULL,
		&item);

	if (findRes == errSecSuccess)
	{
		saveRes = SecKeychainItemModifyAttributesAndData(item, NULL, SG_STRLEN(password), password);
	}
	else
	{
		saveRes = SecKeychainAddInternetPassword(
			NULL,
			SG_STRLEN( SG_string__sz(server) ), SG_string__sz(server),
			0, NULL,
			SG_STRLEN(username), username,
			SG_STRLEN( SG_string__sz(path) ), SG_string__sz(path),
			port, proto, kSecAuthenticationTypeDefault,
			SG_STRLEN(password), password,
			NULL);
	}

	if (saveRes != errSecSuccess)
		_SG_THROW_MAC_SEC_ERROR(saveRes);

fail:
	if (item)
		CFRelease(item);

	SG_STRING_NULLFREE(pCtx, path);
	SG_STRING_NULLFREE(pCtx, server);
}
Пример #7
0
VALUE set_internet_password_for(VALUE self, VALUE data) {
    VALUE ret = Qfalse;

    CHECK_FETCH_HASH_KEY(account)
    CHECK_FETCH_HASH_KEY(protocol)
    CHECK_FETCH_HASH_KEY(server)
    CHECK_FETCH_HASH_KEY(password)

    VALUE sym_auth = rb_eval_string(":auth");
    VALUE auth;

    if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_auth)) {
        auth = kSecAuthenticationTypeDefault;
    } else {
        auth = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_auth), rb_intern("to_s"), 0);
        auth = String2FourChar(StringValuePtr(auth));
    }

    VALUE sym_port = rb_eval_string(":port");
    VALUE port;

    if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_port)) {
        port = 0;
    } else {
        port = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_port), rb_intern("to_i"), 0);
        port = NUM2INT(port);
    }

    VALUE sym_path = rb_eval_string(":path");
    VALUE path;

    if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_path)) {
        path = rb_str_new2("");
    } else {
        path = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_path), rb_intern("to_s"), 0);
    }

    OSStatus status = SecKeychainAddInternetPassword (
                          NULL,                                       // default keychain
                          strlen(StringValuePtr(server)),             // length of serverName
                          StringValuePtr(server),                     // serverName
                          0,                                          // length of domain
                          NULL,                                       // no domain
                          strlen(StringValuePtr(account)),            // length of account name
                          StringValuePtr(account),                    // account name
                          strlen(StringValuePtr(path)),               // length of path
                          StringValuePtr(path),                       // path
                          port,                                       // ignore port
                          String2FourChar(StringValuePtr(protocol)),  // protocol
                          auth,                                       // auth type
                          strlen(StringValuePtr(password)),
                          StringValuePtr(password),
                          NULL
                      );

    if (status == noErr) {
        ret = Qtrue;
    } else if (status == errSecDuplicateItem) {
        // Try updating instead
        SecKeychainItemRef itemRef = nil;

        status = SecKeychainFindInternetPassword (
                     NULL,                                       // default keychain
                     strlen(StringValuePtr(server)),             // length of serverName
                     StringValuePtr(server),                     // serverName
                     0,                                          // length of domain
                     NULL,                                       // no domain
                     strlen(StringValuePtr(account)),            // length of account name
                     StringValuePtr(account),                    // account name
                     strlen(StringValuePtr(path)),               // length of path
                     StringValuePtr(path),                       // path
                     port,                                       // ignore port
                     String2FourChar(StringValuePtr(protocol)),  // protocol
                     auth,
                     nil,
                     nil,
                     &itemRef
                 );

        if (status != noErr)
            rb_raise(rb_eStandardError, getStatusString(status));

        status = SecKeychainItemModifyAttributesAndData (
                     itemRef,                             // the item reference
                     NULL,                                // no change to attributes
                     strlen(StringValuePtr(password)),    // length of password
                     StringValuePtr(password)             // pointer to password data
                 );
        if (status != noErr)
            rb_raise(rb_eStandardError, getStatusString(status));

        ret = Qtrue;
    } else {
        rb_raise(rb_eStandardError, getStatusString(status));
    }

    return ret;
}