コード例 #1
0
gboolean
goa_utils_delete_credentials_sync (GoaProvider   *provider,
                                   GoaAccount    *object,
                                   GCancellable  *cancellable,
                                   GError       **error)
{
  gboolean ret;
  gchar *password_key;
  const gchar *id;
  GError *sec_error = NULL;

  g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
  g_return_val_if_fail (GOA_IS_ACCOUNT (object), FALSE);
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  ret = FALSE;

  password_key = NULL;

  id = goa_account_get_id (object);

  password_key = g_strdup_printf ("%s:gen%d:%s",
                                  goa_provider_get_provider_type (GOA_PROVIDER (provider)),
                                  goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
                                  id);

  secret_password_clear_sync (&secret_password_schema,
                              cancellable,
                              &sec_error,
                              "goa-identity", password_key,
                              NULL);
  if (sec_error != NULL)
    {
      g_warning ("secret_password_clear_sync() failed: %s", sec_error->message);
      g_set_error_literal (error,
                           GOA_ERROR,
                           GOA_ERROR_FAILED, /* TODO: more specific */
                           _("Failed to delete credentials from the keyring"));
      g_error_free (sec_error);
      goto out;
    }

  g_debug ("Cleared keyring credentials for id: %s", id);
  ret = TRUE;

 out:
  g_free (password_key);
  return ret;
}
コード例 #2
0
static void
get_all_providers_cb (GObject      *source,
                      GAsyncResult *res,
                      gpointer      user_data)
{
  AddAccountData *data = user_data;
  GoaProvider *provider;
  GKeyFile *key_file;
  GError *error;
  GList *providers;
  GList *l;
  gchar *path;
  gchar *id;
  gchar *group;
  gchar *key_file_data;
  gsize length;
  gchar *object_path;
  GVariantIter iter;
  const gchar *key;
  const gchar *value;

  /* TODO: could check for @type */

  provider = NULL;
  key_file = NULL;
  providers = NULL;
  path = NULL;
  id = NULL;
  group = NULL;
  key_file_data = NULL;
  object_path = NULL;

  if (!goa_provider_get_all_finish (&providers, res, NULL))
    goto out;

  for (l = providers; l != NULL; l = l->next)
    {
      GoaProvider *p;
      const gchar *type;

      p = GOA_PROVIDER (l->data);
      type = goa_provider_get_provider_type (p);
      if (g_strcmp0 (type, data->provider_type) == 0)
        {
          provider = p;
          break;
        }
    }

  if (provider == NULL)
    {
      error= NULL;
      g_set_error (&error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific */
                   _("Failed to find a provider for: %s"),
                   data->provider_type);
      g_dbus_method_invocation_return_gerror (data->invocation, error);
      goto out;
    }

  key_file = g_key_file_new ();
  path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
  error = NULL;
  if (!g_file_get_contents (path,
                            &key_file_data,
                            &length,
                            &error))
    {
      if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT)
        {
          g_error_free (error);
        }
      else
        {
          g_prefix_error (&error, "Error loading file %s: ", path);
          g_dbus_method_invocation_return_gerror (data->invocation, error);
          goto out;
        }
    }
  else
    {
      if (length > 0)
        {
          error = NULL;
          if (!g_key_file_load_from_data (key_file, key_file_data, length, G_KEY_FILE_KEEP_COMMENTS, &error))
            {
              g_prefix_error (&error, "Error parsing key-value-file %s: ", path);
              g_dbus_method_invocation_return_gerror (data->invocation, error);
              goto out;
            }
        }
    }

  id = generate_new_id (data->daemon);
  group = g_strdup_printf ("Account %s", id);
  g_key_file_set_string (key_file, group, "Provider", data->provider_type);
  g_key_file_set_string (key_file, group, "Identity", data->identity);
  g_key_file_set_string (key_file, group, "PresentationIdentity", data->presentation_identity);

  g_variant_iter_init (&iter, data->details);
  while (g_variant_iter_next (&iter, "{&s&s}", &key, &value))
    {
      /* We treat IsTemporary special.  If it's true we add in
       * the current session guid, so it can be ignored after
       * the session is over.
       */
      if (g_strcmp0 (key, "IsTemporary") == 0)
        {
          if (g_strcmp0 (value, "true") == 0)
            {
              const char *guid;

              guid = g_dbus_connection_get_guid (data->daemon->connection);
              g_key_file_set_string (key_file, group, "SessionId", guid);
            }
        }

      g_key_file_set_string (key_file, group, key, value);
    }

  g_free (key_file_data);
  error = NULL;
  key_file_data = g_key_file_to_data (key_file,
                                      &length,
                                      &error);
  if (key_file_data == NULL)
    {
      g_prefix_error (&error, "Error generating key-value-file: ");
      g_dbus_method_invocation_return_gerror (data->invocation, error);
      goto out;
    }

  error = NULL;
  if (!g_file_set_contents (path,
                            key_file_data,
                            length,
                            &error))
    {
      g_prefix_error (&error, "Error writing key-value-file %s: ", path);
      g_dbus_method_invocation_return_gerror (data->invocation, error);
      goto out;
    }

  /* We don't want to fail AddAccount if we could not store the
   * credentials in the keyring.
   */
  goa_utils_store_credentials_for_id_sync (provider,
                                           id,
                                           data->credentials,
                                           NULL, /* GCancellable */
                                           NULL);

  goa_daemon_reload_configuration (data->daemon);

  object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", id);
  goa_manager_complete_add_account (data->manager, data->invocation, object_path);

 out:
  g_free (object_path);
  if (providers != NULL)
    g_list_free_full (providers, g_object_unref);
  g_free (key_file_data);
  g_free (group);
  g_free (id);
  g_free (path);
  if (key_file != NULL)
    g_key_file_free (key_file);

  g_object_unref (data->daemon);
  g_object_unref (data->manager);
  g_object_unref (data->invocation);
  g_free (data->provider_type);
  g_free (data->identity);
  g_free (data->presentation_identity);
  g_variant_unref (data->credentials);
  g_variant_unref (data->details);
  g_slice_free (AddAccountData, data);
}
コード例 #3
0
gboolean
goa_utils_store_credentials_for_id_sync (GoaProvider   *provider,
                                         const gchar   *id,
                                         GVariant      *credentials,
                                         GCancellable  *cancellable,
                                         GError       **error)
{
  gboolean ret;
  gchar *credentials_str;
  gchar *password_description;
  gchar *password_key;
  GError *sec_error = NULL;

  g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
  g_return_val_if_fail (id != NULL && id[0] != '\0', FALSE);
  g_return_val_if_fail (credentials != NULL, FALSE);
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  ret = FALSE;

  credentials_str = g_variant_print (credentials, TRUE);
  g_variant_ref_sink (credentials);
  g_variant_unref (credentials);

  password_key = g_strdup_printf ("%s:gen%d:%s",
                                  goa_provider_get_provider_type (GOA_PROVIDER (provider)),
                                  goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
                                  id);
  /* Translators: The %s is the type of the provider, e.g. 'google' or 'yahoo' */
  password_description = g_strdup_printf (_("GOA %s credentials for identity %s"),
                                          goa_provider_get_provider_type (GOA_PROVIDER (provider)),
                                          id);

  if (!secret_password_store_sync (&secret_password_schema,
                                   SECRET_COLLECTION_DEFAULT, /* default keyring */
                                   password_description,
                                   credentials_str,
                                   cancellable,
                                   &sec_error,
                                   "goa-identity", password_key,
                                   NULL))
    {
      g_warning ("secret_password_store_sync() failed: %s", sec_error->message);
      g_set_error_literal (error,
                           GOA_ERROR,
                           GOA_ERROR_FAILED, /* TODO: more specific */
                           _("Failed to store credentials in the keyring"));
      g_error_free (sec_error);
      goto out;
    }

  g_debug ("Stored keyring credentials for identity: %s", id);
  ret = TRUE;

 out:
  g_free (credentials_str);
  g_free (password_key);
  g_free (password_description);
  return ret;
}
コード例 #4
0
GVariant *
goa_utils_lookup_credentials_sync (GoaProvider   *provider,
                                   GoaObject     *object,
                                   GCancellable  *cancellable,
                                   GError       **error)
{
  gchar *password_key;
  GVariant *ret;
  gchar *password;
  const gchar *id;
  GError *sec_error = NULL;

  g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL);
  g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE);
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  ret = NULL;
  password_key = NULL;
  password = NULL;

  id = goa_account_get_id (goa_object_peek_account (object));

  password_key = g_strdup_printf ("%s:gen%d:%s",
                                  goa_provider_get_provider_type (GOA_PROVIDER (provider)),
                                  goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
                                  id);

  password = secret_password_lookup_sync (&secret_password_schema,
                                          cancellable,
                                          &sec_error,
                                          "goa-identity", password_key,
                                          NULL);
  if (sec_error != NULL)
    {
      g_warning ("secret_password_lookup_sync() failed: %s", sec_error->message);
      g_set_error_literal (error,
                           GOA_ERROR,
                           GOA_ERROR_FAILED, /* TODO: more specific */
                           _("Failed to retrieve credentials from the keyring"));
      g_error_free (sec_error);
      goto out;
    }
  else if (password == NULL)
    {
      g_warning ("secret_password_lookup_sync() returned NULL");
      g_set_error_literal (error,
                           GOA_ERROR,
                           GOA_ERROR_FAILED, /* TODO: more specific */
                           _("No credentials found in the keyring"));
      goto out;
    }

  g_debug ("Retrieved keyring credentials for id: %s", id);

  ret = g_variant_parse (NULL, /* GVariantType */
                         password,
                         NULL, /* limit */
                         NULL, /* endptr */
                         error);
  if (ret == NULL)
    {
      g_prefix_error (error, _("Error parsing result obtained from the keyring: "));
      goto out;
    }

  if (g_variant_is_floating (ret))
    g_variant_ref_sink (ret);

 out:
  g_free (password);
  g_free (password_key);
  return ret;
}
コード例 #5
0
static GoaObject *
add_account (GoaProvider    *provider,
             GoaClient      *client,
             GtkDialog      *dialog,
             GtkBox         *vbox,
             GError        **error)
{
  AddAccountData data;
  GVariantBuilder credentials;
  GVariantBuilder details;
  GoaEwsClient *ews_client;
  GoaObject *ret;
  gboolean accept_ssl_errors;
  const gchar *email_address;
  const gchar *server;
  const gchar *password;
  const gchar *username;
  const gchar *provider_type;
  gint response;

  ews_client = NULL;
  accept_ssl_errors = FALSE;

  ret = NULL;

  memset (&data, 0, sizeof (AddAccountData));
  data.loop = g_main_loop_new (NULL, FALSE);
  data.dialog = dialog;
  data.error = NULL;

  create_account_details_ui (provider, dialog, vbox, TRUE, &data);
  gtk_widget_show_all (GTK_WIDGET (vbox));

  ews_client = goa_ews_client_new ();

 ews_again:
  response = gtk_dialog_run (dialog);
  if (response != GTK_RESPONSE_OK)
    {
      g_set_error (&data.error,
                   GOA_ERROR,
                   GOA_ERROR_DIALOG_DISMISSED,
                   _("Dialog was dismissed"));
      goto out;
    }

  email_address = gtk_entry_get_text (GTK_ENTRY (data.email_address));
  password = gtk_entry_get_text (GTK_ENTRY (data.password));
  username = gtk_entry_get_text (GTK_ENTRY (data.username));
  server = gtk_entry_get_text (GTK_ENTRY (data.server));

  /* See if there's already an account of this type with the
   * given identity
   */
  provider_type = goa_provider_get_provider_type (provider);
  if (!goa_utils_check_duplicate (client,
                                  username,
                                  provider_type,
                                  (GoaPeekInterfaceFunc) goa_object_peek_password_based,
                                  &data.error))
    goto out;

  goa_ews_client_autodiscover (ews_client,
                               email_address,
                               password,
                               username,
                               server,
                               accept_ssl_errors,
                               NULL,
                               autodiscover_cb,
                               &data);
  goa_spinner_button_start (GOA_SPINNER_BUTTON (data.spinner_button));
  g_main_loop_run (data.loop);

  if (data.error != NULL)
    {
      gchar *markup;

      if (data.error->code == GOA_ERROR_SSL)
        {
          goa_spinner_button_set_label (GOA_SPINNER_BUTTON (data.spinner_button), _("_Ignore"));
          accept_ssl_errors = TRUE;
        }
      else
        {
          goa_spinner_button_set_label (GOA_SPINNER_BUTTON (data.spinner_button), _("_Try Again"));
          accept_ssl_errors = FALSE;
        }

      markup = g_strdup_printf ("<b>%s:</b> %s",
                                _("Error connecting to Microsoft Exchange server"),
                                data.error->message);
      g_clear_error (&data.error);

      gtk_label_set_markup (GTK_LABEL (data.cluebar_label), markup);
      g_free (markup);

      gtk_expander_set_expanded (GTK_EXPANDER (data.expander), TRUE);
      gtk_widget_set_no_show_all (data.cluebar, FALSE);
      gtk_widget_show_all (data.cluebar);
      goto ews_again;
    }

  gtk_widget_hide (GTK_WIDGET (dialog));

  g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT);
  g_variant_builder_add (&credentials, "{sv}", "password", g_variant_new_string (password));

  g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
  g_variant_builder_add (&details, "{ss}", "MailEnabled", "true");
  g_variant_builder_add (&details, "{ss}", "CalendarEnabled", "true");
  g_variant_builder_add (&details, "{ss}", "ContactsEnabled", "true");
  g_variant_builder_add (&details, "{ss}", "Host", server);
  g_variant_builder_add (&details, "{ss}", "AcceptSslErrors", (accept_ssl_errors) ? "true" : "false");

  /* OK, everything is dandy, add the account */
  /* we want the GoaClient to update before this method returns (so it
   * can create a proxy for the new object) so run the mainloop while
   * waiting for this to complete
   */
  goa_manager_call_add_account (goa_client_get_manager (client),
                                goa_provider_get_provider_type (provider),
                                username,
                                email_address,
                                g_variant_builder_end (&credentials),
                                g_variant_builder_end (&details),
                                NULL, /* GCancellable* */
                                (GAsyncReadyCallback) add_account_cb,
                                &data);
  g_main_loop_run (data.loop);
  if (data.error != NULL)
    goto out;

  ret = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client),
                                                      data.account_object_path));

 out:
  /* We might have an object even when data.error is set.
   * eg., if we failed to store the credentials in the keyring.
   */
  if (data.error != NULL)
    g_propagate_error (error, data.error);
  else
    g_assert (ret != NULL);

  g_free (data.account_object_path);
  if (data.loop != NULL)
    g_main_loop_unref (data.loop);
  if (ews_client != NULL)
    g_object_unref (ews_client);
  return ret;
}