int keyring_erase(struct credential *c)
{
	char  *object = NULL;
	GList *entries;
	GnomeKeyringNetworkPasswordData *password_data;
	GnomeKeyringResult result;

	/*
	 * Sanity check that we actually have something to match
	 * against. The input we get is a restrictive pattern,
	 * so technically a blank credential means "erase everything".
	 * But it is too easy to accidentally send this, since it is equivalent
	 * to empty input. So explicitly disallow it, and require that the
	 * pattern have some actual content to match.
	 */
	if (!c->protocol && !c->host && !c->path && !c->username)
		return EXIT_FAILURE;

	object = keyring_object(c);

	result = gnome_keyring_find_network_password_sync(
				c->username,
				NULL /* domain */,
				c->host,
				object,
				c->protocol,
				NULL /* authtype */,
				c->port,
				&entries);

	free(object);

	if (result == GNOME_KEYRING_RESULT_NO_MATCH)
		return EXIT_SUCCESS;

	if (result == GNOME_KEYRING_RESULT_CANCELLED)
		return EXIT_SUCCESS;

	if (result != GNOME_KEYRING_RESULT_OK)
	{
		error("%s",gnome_keyring_result_to_message(result));
		return EXIT_FAILURE;
	}

	/* pick the first one from the list (delete all matches?) */
	password_data = (GnomeKeyringNetworkPasswordData *) entries->data;

	result = gnome_keyring_item_delete_sync(
		password_data->keyring, password_data->item_id);

	gnome_keyring_network_password_list_free(entries);

	if (result != GNOME_KEYRING_RESULT_OK)
	{
		error("%s",gnome_keyring_result_to_message(result));
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
int
main (int argc, char **argv)
{
	GnomeKeyringResult res;

	g_test_init (&argc, &argv, NULL);
	g_set_prgname ("frob-unlock-keyring");

	if (argc < 2) {
		g_printerr ("specify keyring to unlock\n");
		return 2;
	}

	res = gnome_keyring_unlock_sync (argv[1], NULL);
	if (res == GNOME_KEYRING_RESULT_OK) {
		g_printerr ("ok\n");
		return 0;
	} else if (res == GNOME_KEYRING_RESULT_CANCELLED) {
		g_printerr ("cancel\n");
		return 0;
	} else {
		g_printerr ("failed: %s\n", gnome_keyring_result_to_message (res));
		return 1;
	}
}
static int
store_password(jaro_credential_t *cred)
{
    gchar desc[1024];
    GnomeKeyringResult keyres;

    /* Only store complete credentials */
    if (!cred->protocol || !cred->host ||
       	!cred->username || !cred->password)
      return 1;

    g_snprintf(desc, sizeof(desc), "%s %s", cred->protocol, cred->host);
    keyres = gnome_keyring_store_password_sync(&jaro_schema,
					       GNOME_KEYRING_DEFAULT,
					       desc,
					       cred->password,
					       "protocol", cred->protocol,
					       "host", cred->host,
					       "path", cred->path,
					       "username", cred->username,
					       NULL);
    if (keyres != GNOME_KEYRING_RESULT_OK) {
	error("failed to store password: %s", gnome_keyring_result_to_message(keyres));
	return 1;
    }
    return 0;
}
Beispiel #4
0
/*
 * Callback from the keyring lookup in refresh_credentials.
 */
static void
found_password_cb (GnomeKeyringResult  result,
                   GList              *list,
                   gpointer            user_data)
{
  SwService *service = SW_SERVICE (user_data);
  SwServiceLastfm *lastfm = SW_SERVICE_LASTFM (service);
  SwServiceLastfmPrivate *priv = lastfm->priv;

  if (result == GNOME_KEYRING_RESULT_OK && list != NULL) {
    GnomeKeyringNetworkPasswordData *data = list->data;

    g_free (priv->username);
    priv->username = g_strdup (data->user);
  } else {
    g_free (priv->username);
    priv->username = NULL;

    if (result != GNOME_KEYRING_RESULT_NO_MATCH) {
      g_warning (G_STRLOC ": Error getting password: %s", gnome_keyring_result_to_message (result));
    }
  }

  sw_service_emit_user_changed (service);
  sw_service_emit_capabilities_changed (service, get_dynamic_caps (service));
}
Beispiel #5
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 */
}
static GnomeKeyringOperationGetIntCallback
stored_password (GnomeKeyringResult res, guint32 val, widgets *data)
{
    /* user_data will be the same as was passed to gnome_keyring_store_password() */

    if (res != GNOME_KEYRING_RESULT_OK)
    {
        gtk_image_set_from_stock(GTK_IMAGE(data->image_credentials), "gtk-stop", GTK_ICON_SIZE_BUTTON);
        gtk_label_set_label(GTK_LABEL(data->label_credentials), gnome_keyring_result_to_message (res));
    }
}
int keyring_get(struct credential *c)
{
	char* object = NULL;
	GList *entries;
	GnomeKeyringNetworkPasswordData *password_data;
	GnomeKeyringResult result;

	if (!c->protocol || !(c->host || c->path))
		return EXIT_FAILURE;

	object = keyring_object(c);

	result = gnome_keyring_find_network_password_sync(
				c->username,
				NULL /* domain */,
				c->host,
				object,
				c->protocol,
				NULL /* authtype */,
				c->port,
				&entries);

	free(object);

	if (result == GNOME_KEYRING_RESULT_NO_MATCH)
		return EXIT_SUCCESS;

	if (result == GNOME_KEYRING_RESULT_CANCELLED)
		return EXIT_SUCCESS;

	if (result != GNOME_KEYRING_RESULT_OK) {
		error("%s",gnome_keyring_result_to_message(result));
		return EXIT_FAILURE;
	}

	/* pick the first one from the list */
	password_data = (GnomeKeyringNetworkPasswordData *) entries->data;

	free_password(c->password);
	c->password = xstrdup(password_data->password);

	if (!c->username)
		c->username = xstrdup(password_data->user);

	gnome_keyring_network_password_list_free(entries);

	return EXIT_SUCCESS;
}
Beispiel #8
0
// static
bool OTKeyring::Gnome_StoreSecret(const OTString& strUser,
                                  const OTPassword& thePassword,
                                  const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());
    OT_ASSERT(thePassword.getMemorySize() > 0);

    OTData theData(thePassword.getMemory(), thePassword.getMemorySize());
    OTASCIIArmor ascData(theData);
    theData.zeroMemory(); // security reasons.

    OTString strOutput;
    const bool bSuccess =
        ascData.Exists() &&
        ascData.WriteArmoredString(strOutput, "DERIVED KEY"); // There's no
                                                              // default, to
                                                              // force you to
                                                              // enter the right
                                                              // string.
    ascData.zeroMemory();

    GnomeKeyringResult theResult = GNOME_KEYRING_RESULT_IO_ERROR;

    if (bSuccess && strOutput.Exists()) {
        theResult = gnome_keyring_store_password_sync(
            GNOME_KEYRING_NETWORK_PASSWORD,
            GNOME_KEYRING_DEFAULT, // GNOME_KEYRING_SESSION,
            str_display.c_str(), strOutput.Get(), "user", strUser.Get(),
            "protocol", "opentxs", // todo: hardcoding.
            nullptr);
        strOutput.zeroMemory();

        bool bResult = false;

        if (theResult == GNOME_KEYRING_RESULT_OK)
            bResult = true;
        else
            otErr << "OTKeyring::Gnome_StoreSecret: "
                  << "Failure in gnome_keyring_store_password_sync: "
                  << gnome_keyring_result_to_message(theResult) << '\n';

        return bResult;
    }

    otOut << "OTKeyring::Gnome_StoreSecret: No secret to store.\n";

    return false;
}
static void
on_change_password_done (GnomeKeyringResult result, gpointer user_data)
{
	SeahorseCommands *self = SEAHORSE_COMMANDS (user_data);
	SeahorseView *view;

	if (result != GNOME_KEYRING_RESULT_OK &&
	    result != GNOME_KEYRING_RESULT_DENIED &&
	    result != GNOME_KEYRING_RESULT_CANCELLED) {
		view = seahorse_commands_get_view (self);
		seahorse_util_show_error (GTK_WIDGET (seahorse_view_get_window (view)),
		                          _("Couldn't change keyring password"),
		                          gnome_keyring_result_to_message (result));
	}
	
	refresh_all_keyrings (self);
}
Beispiel #10
0
static int
erase_password(jaro_credential_t *cred)
{
    GnomeKeyringResult keyres;

    keyres = gnome_keyring_delete_password_sync(&jaro_schema,
						"protocol", cred->protocol,
						"host", cred->host,
						"path", cred->path,
						"username", cred->username,
						NULL);
    if (keyres != GNOME_KEYRING_RESULT_OK) {
	error("failed to erase password: %s", gnome_keyring_result_to_message(keyres));
	return 1;
    }
    return 0;
}
static gboolean
ep_keyring_insert_password (const gchar *user,
                            const gchar *server,
                            const gchar *protocol,
                            const gchar *display_name,
                            const gchar *password,
                            GError **error)
{
	GnomeKeyringAttributeList *attributes;
	GnomeKeyringResult result;
	guint32 item_id;

	g_return_val_if_fail (user != NULL, FALSE);
	g_return_val_if_fail (server != NULL, FALSE);
	g_return_val_if_fail (protocol != NULL, FALSE);
	g_return_val_if_fail (display_name != NULL, FALSE);
	g_return_val_if_fail (password != NULL, FALSE);

	attributes = gnome_keyring_attribute_list_new ();
	gnome_keyring_attribute_list_append_string (
		attributes, "application", "Evolution");
	gnome_keyring_attribute_list_append_string (
		attributes, "user", user);
	gnome_keyring_attribute_list_append_string (
		attributes, "server", server);
	gnome_keyring_attribute_list_append_string (
		attributes, "protocol", protocol);

	/* XXX We don't use item_id but gnome-keyring doesn't allow
	 *     for a NULL pointer.  In fact it doesn't even check! */
	result = gnome_keyring_item_create_sync (
		NULL, GNOME_KEYRING_ITEM_NETWORK_PASSWORD,
		display_name, attributes, password, TRUE, &item_id);
	if (result != GNOME_KEYRING_RESULT_OK) {
		g_set_error (
			error, EP_KEYRING_ERROR, result,
			"Unable to create password in "
			"keyring (Keyring reports: %s)",
			gnome_keyring_result_to_message (result));
	}

	gnome_keyring_attribute_list_free (attributes);

	return (result == GNOME_KEYRING_RESULT_OK);
}
Beispiel #12
0
static int
check_password(jaro_credential_t *cred)
{
    GnomeKeyringResult keyres;
    gchar *pass = NULL;
    
    keyres = gnome_keyring_find_password_sync(&jaro_schema,
					      &pass,
					      "protocol", cred->protocol,
					      "host", cred->host,
					      "path", cred->path,
					      "username", cred->username,
					      NULL);
    if (keyres != GNOME_KEYRING_RESULT_OK) {
	error("failed to check password: %s", gnome_keyring_result_to_message(keyres));
	return 1;
    }
    gnome_keyring_free_password(pass);
    return 0;
}
Beispiel #13
0
// static
bool OTKeyring::Gnome_DeleteSecret(const OTString& strUser,
                                   const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());

    GnomeKeyringResult theResult = gnome_keyring_delete_password_sync(
        GNOME_KEYRING_NETWORK_PASSWORD, "user", strUser.Get(), "protocol",
        "opentxs", // todo: hardcoding.
        nullptr);  // Always end with nullptr

    if (theResult == GNOME_KEYRING_RESULT_OK) {
        return true;
    }
    else {
        otErr << "OTKeyring::Gnome_DeleteSecret: "
              << "Failure in gnome_keyring_delete_password_sync: "
              << gnome_keyring_result_to_message(theResult) << '\n';
    }

    return false;
}
Beispiel #14
0
/*
 * Callback from the keyring lookup in refresh_credentials.
 */
static void
found_password_cb (GnomeKeyringResult  result,
                   GList              *list,
                   gpointer            user_data)
{
  SwService *service = SW_SERVICE (user_data);
  SwServicePlurk *plurk = SW_SERVICE_PLURK (service);
  SwServicePlurkPrivate *priv = plurk->priv;

  if (result == GNOME_KEYRING_RESULT_OK && list != NULL) {
    GnomeKeyringNetworkPasswordData *data = list->data;

    g_free (priv->username);
    g_free (priv->password);

    priv->username = g_strdup (data->user);
    priv->password = g_strdup (data->password);

    /* If we're online, force a reconnect to fetch new credentials */
    if (sw_is_online ()) {
      online_notify (FALSE, service);
      online_notify (TRUE, service);
    }
  } else {
    g_free (priv->username);
    g_free (priv->password);
    priv->username = NULL;
    priv->password = NULL;
    priv->credentials = OFFLINE;

    if (result != GNOME_KEYRING_RESULT_NO_MATCH) {
      g_warning (G_STRLOC ": Error getting password: %s", gnome_keyring_result_to_message (result));
    }
  }

  sw_service_emit_user_changed (service);
  sw_service_emit_capabilities_changed (service, get_dynamic_caps (service));
}
static gboolean
ep_keyring_delete_passwords (const gchar *user,
                             const gchar *server,
                             const gchar *protocol,
                             GList *passwords,
                             GError **error)
{
	while (passwords != NULL) {
		GnomeKeyringFound *found = passwords->data;
		GnomeKeyringResult result;

		/* Validate the item before deleting it. */
		if (!ep_keyring_validate (user, server, protocol, found->attributes)) {
			/* XXX We didn't always store protocols in the
			 *     keyring, so for backward-compatibility
			 *     try validating by user and server only. */
			if (!ep_keyring_validate (user, server, NULL, found->attributes)) {
				passwords = g_list_next (passwords);
				continue;
			}
		}

		result = gnome_keyring_item_delete_sync (NULL, found->item_id);
		if (result != GNOME_KEYRING_RESULT_OK) {
			g_set_error (
				error, EP_KEYRING_ERROR, result,
				"Unable to delete password in "
				"keyring (Keyring reports: %s)",
				gnome_keyring_result_to_message (result));
			return FALSE;
		}

		passwords = g_list_next (passwords);
	}

	return TRUE;
}
static GList *
ep_keyring_lookup_passwords (const gchar *user,
                             const gchar *server,
                             const gchar *protocol,
                             GError **error)
{
	GnomeKeyringAttributeList *attributes;
	GnomeKeyringResult result;
	GList *passwords = NULL;

	attributes = gnome_keyring_attribute_list_new ();
	gnome_keyring_attribute_list_append_string (
		attributes, "application", "Evolution");
	if (user != NULL)
		gnome_keyring_attribute_list_append_string (
			attributes, "user", user);
	if (server != NULL)
		gnome_keyring_attribute_list_append_string (
			attributes, "server", server);
	if (protocol != NULL)
		gnome_keyring_attribute_list_append_string (
			attributes, "protocol", protocol);

	result = gnome_keyring_find_items_sync (
		GNOME_KEYRING_ITEM_NETWORK_PASSWORD, attributes, &passwords);
	if (result != GNOME_KEYRING_RESULT_OK) {
		g_set_error (
			error, EP_KEYRING_ERROR, result,
			"Unable to find password(s) in "
			"keyring (Keyring reports: %s)",
			gnome_keyring_result_to_message (result));
	}

	gnome_keyring_attribute_list_free (attributes);

	return passwords;
}
Beispiel #17
0
// static
bool OTKeyring::Gnome_RetrieveSecret(const OTString& strUser,
                                     OTPassword& thePassword,
                                     const std::string& str_display)
{
    OT_ASSERT(strUser.Exists());

    GnomeKeyringResult theResult = GNOME_KEYRING_RESULT_IO_ERROR;
    gchar* gchar_p_password = nullptr;

    // if the password exists in the keyring, set it in
    // thePassword (output argument.)
    //
    int32_t nCount = -1;
    int64_t lSleep = 1;

    while ((GNOME_KEYRING_RESULT_OK != theResult)) {
        ++nCount; // 0 on first iteration.

        theResult = gnome_keyring_find_password_sync(
            GNOME_KEYRING_NETWORK_PASSWORD, &gchar_p_password, "user",
            strUser.Get(), "protocol", "opentxs", // todo: hardcoding.
            nullptr);

        if (GNOME_KEYRING_RESULT_OK == theResult) break;

        if (nCount > 2) // todo hardcoding.
            break;      // we try a few times -- not infinite times!

        OTString strGnomeError(gnome_keyring_result_to_message(theResult));

        //        OTString strGnomeError;
        //        switch (theResult) {
        //            case GNOME_KEYRING_RESULT_OK: strGnomeError
        // = "GNOME_KEYRING_RESULT_OK"; break;
        //            case GNOME_KEYRING_RESULT_DENIED: strGnomeError
        // = "GNOME_KEYRING_RESULT_DENIED"; break;
        //            case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON: strGnomeError
        // = "GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON"; break;
        //            case GNOME_KEYRING_RESULT_ALREADY_UNLOCKED: strGnomeError
        // = "GNOME_KEYRING_RESULT_ALREADY_UNLOCKED"; break;
        //            case GNOME_KEYRING_RESULT_NO_SUCH_KEYRING: strGnomeError
        // = "GNOME_KEYRING_RESULT_NO_SUCH_KEYRING"; break;
        //            case GNOME_KEYRING_RESULT_BAD_ARGUMENTS: strGnomeError
        // = "GNOME_KEYRING_RESULT_BAD_ARGUMENTS"; break;
        //            case GNOME_KEYRING_RESULT_IO_ERROR: strGnomeError
        // = "GNOME_KEYRING_RESULT_IO_ERROR"; break;
        //            case GNOME_KEYRING_RESULT_CANCELLED: strGnomeError
        // = "GNOME_KEYRING_RESULT_CANCELLED"; break;
        //            case GNOME_KEYRING_RESULT_KEYRING_ALREADY_EXISTS:
        // strGnomeError = "GNOME_KEYRING_RESULT_KEYRING_ALREADY_EXISTS"; break;
        //            case GNOME_KEYRING_RESULT_NO_MATCH: strGnomeError
        // = "GNOME_KEYRING_RESULT_NO_MATCH"; break;
        //
        //            default:
        //                strGnomeError = "Unknown! Very strange!";
        //                break;
        //        }

        otErr << __FUNCTION__ << ": gnome_keyring_find_password_sync returned "
              << strGnomeError.Get() << '\n';
        otErr << "Remedy: Sleeping for " << lSleep
              << " seconds and then retrying (attempt " << (nCount + 2) << '\n';
        // on first iteration, nCount is 0, and this will say "attempt 2" aka
        // "second attempt," which is correct.

        sleep(lSleep);
        lSleep *= 2; // double it each time
    }

    if ((theResult == GNOME_KEYRING_RESULT_OK) &&
        (nullptr != gchar_p_password)) {
        size_t sizePassword =
            OTString::safe_strlen(gchar_p_password, MAX_STRING_LENGTH);

        if (sizePassword > 0) {
            OTString strData(gchar_p_password, sizePassword);

            gnome_keyring_free_password(gchar_p_password);
            gchar_p_password = nullptr;

            OTASCIIArmor ascData;
            const bool bLoaded =
                strData.Exists() && ascData.LoadFromString(strData);
            strData.zeroMemory();

            if (!bLoaded)
                otErr << __FUNCTION__ << ": Failed trying to decode secret "
                                         "from Gnome Keyring contents:\n\n"
                      << strData.Get() << "\n\n";
            else {
                OTData thePayload(ascData);
                ascData.zeroMemory();
                if (thePayload.IsEmpty())
                    otErr << __FUNCTION__ << ": Failed trying to decode secret "
                                             "OTData from OTASCIIArmor "
                          << "from Gnome Keyring contents:\n\n" << strData.Get()
                          << "\n\n";
                else {
                    thePassword.setMemory(thePayload.GetPayloadPointer(),
                                          thePayload.GetSize());
                    thePayload.zeroMemory(); // for security.
                    return true;
                }
                return false;
            }
        }
    }

    // Not an error: what if it just hasn't been set there yet?
    //
    otOut << "OTKeyring::Gnome_RetrieveSecret: "
          << "No secret found: gnome_keyring_find_password_sync: "
          << gnome_keyring_result_to_message(theResult) << '\n';

    return false;
}
Beispiel #18
0
gboolean gnc_keyring_get_password ( GtkWidget *parent,
                                    const gchar *access_method,
                                    const gchar *server,
                                    guint32 port,
                                    const gchar *service,
                                    gchar **user,
                                    gchar **password)
{
    gboolean password_found = FALSE;
#ifdef HAVE_GNOME_KEYRING
    GnomeKeyringResult  gkr_result;
    GList *found_list = NULL;
    GnomeKeyringNetworkPasswordData *found;
#endif
#ifdef HAVE_OSX_KEYCHAIN
    void *password_data;
    UInt32 password_length;
    OSStatus status;
#endif

    g_return_val_if_fail (user != NULL, FALSE);
    g_return_val_if_fail (password != NULL, FALSE);

    *password = NULL;

#ifdef HAVE_GNOME_KEYRING
    gkr_result = gnome_keyring_find_network_password_sync
                 ( *user, NULL, server, service,
                   access_method, NULL, port, &found_list );

    if (gkr_result == GNOME_KEYRING_RESULT_OK)
    {
        found = (GnomeKeyringNetworkPasswordData *) found_list->data;
        if (found->password)
            *password = g_strdup(found->password);
        password_found = TRUE;
    }
    else
        PWARN ("Gnome-keyring access failed: %s.",
               gnome_keyring_result_to_message(gkr_result));

    gnome_keyring_network_password_list_free(found_list);
#endif /* HAVE_GNOME_KEYRING */

#ifdef HAVE_OSX_KEYCHAIN
    /* 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.
     */
    if (*user != NULL)
    {
        status = SecKeychainFindInternetPassword( NULL,
                 strlen(server), server,
                 strlen(access_method), access_method,
                 strlen(*user), *user,
                 strlen(service), service,
                 port,
                 kSecProtocolTypeAny,
                 kSecAuthenticationTypeDefault,
                 &password_length, &password_data,
                 NULL);

        if ( status == noErr )
        {
            *password = g_strndup(password_data, password_length);
            password_found = TRUE;
            SecKeychainItemFreeContent(NULL, password_data);
        }
        else
        {
            CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL );
            const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring,
                                        GetApplicationTextEncoding());
            PWARN ( "OS X keychain error: %s", resultstring );
            CFRelease ( osx_resultstring );
        }
    }
#endif /* HAVE_OSX_KEYCHAIN */

    if ( !password_found )
    {
        /* If we got here, either no proper password store is
         * available on this system, or we couldn't retrieve
         * a password from it. In both cases, just ask the user
         * to enter one
         */
        gchar *db_path, *heading;

        if ( port == 0 )
            db_path = g_strdup_printf ( "%s://%s/%s", access_method, server, service );
        else
            db_path = g_strdup_printf ( "%s://%s:%d/%s", access_method, server, port, service );
        heading = g_strdup_printf ( /* Translators: %s is a path to a database or any other url,
                 like mysql://[email protected]/somedb, http://www.somequotes.com/thequotes */
                      _("Enter a user name and password to connect to: %s"),
                      db_path );

        password_found = gnc_get_username_password ( parent, heading,
                         *user, NULL,
                         user, password );
        g_free ( db_path );
        g_free ( heading );

        if ( password_found )
        {
            /* User entered new user/password information
             * Let's try to add it to a password store.
             */
            gchar *newuser = g_strdup( *user );
            gchar *newpassword = g_strdup( *password );
            gnc_keyring_set_password ( access_method,
                                       server,
                                       port,
                                       service,
                                       newuser,
                                       newpassword );
            g_free ( newuser );
            g_free ( newpassword );
        }
    }

    return password_found;
}