[evolution-activesync/wip/port-to-libsecret] eas-connection: Port to libsecret
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-activesync/wip/port-to-libsecret] eas-connection: Port to libsecret
- Date: Thu, 10 Mar 2022 09:42:20 +0000 (UTC)
commit 90d957d7d61dc5ea41ec1cd9beeb10950b13cb1f
Author: Milan Crha <mcrha redhat com>
Date: Wed Mar 9 12:56:14 2022 +0100
eas-connection: Port to libsecret
The gnome-keyring dependency is ancient, some distributions do not
provide it anymore, thus port to a modern libsecret.
configure.ac | 2 +-
eas-daemon/libeas/Makefile.am | 4 +-
eas-daemon/libeas/eas-connection.c | 180 +++++++++++++++++++++----------------
3 files changed, 107 insertions(+), 79 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 7430abd..387ed2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,7 +54,7 @@ AC_PROG_LIBTOOL
privincludedir='${includedir}'/eas-daemon
AC_SUBST(privincludedir)
-PKG_CHECK_MODULES(GNOMEKEYRING, gnome-keyring-1)
+PKG_CHECK_MODULES(LIBSECRET, libsecret-1)
PKG_CHECK_MODULES(EDATASERVER, libedataserver-1.2)
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1)
PKG_CHECK_MODULES(LIBXML, libxml-2.0)
diff --git a/eas-daemon/libeas/Makefile.am b/eas-daemon/libeas/Makefile.am
index d55e664..3500e3f 100644
--- a/eas-daemon/libeas/Makefile.am
+++ b/eas-daemon/libeas/Makefile.am
@@ -15,7 +15,7 @@ libeas_la_CPPFLAGS = \
$(LIBICAL_CFLAGS) \
$(GIO_CFLAGS) \
$(LIBEBOOK_CFLAGS) \
- $(GNOMEKEYRING_CFLAGS) \
+ $(LIBSECRET_CFLAGS) \
-DG_LOG_DOMAIN=\"libeas\" \
-I$(top_srcdir)/libeasclient \
-DASKPASS=\"@ASKPASS@\" \
@@ -31,7 +31,7 @@ libeas_la_LDFLAGS = \
$(LIBICAL_LIBS) \
$(GIO_LIBS) \
$(LIBEBOOK_LIBS) \
- $(GNOMEKEYRING_LIBS) \
+ $(LIBSECRET_LIBS) \
$(NULL)
diff --git a/eas-daemon/libeas/eas-connection.c b/eas-daemon/libeas/eas-connection.c
index 006cab7..05a0aa6 100644
--- a/eas-daemon/libeas/eas-connection.c
+++ b/eas-daemon/libeas/eas-connection.c
@@ -68,7 +68,7 @@
#include <libxml/xmlreader.h> // xmlDoc
#include <time.h>
#include <unistd.h>
-#include <gnome-keyring.h>
+#include <libsecret/secret.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
@@ -129,13 +129,27 @@ struct _EasConnectionPrivate {
#define EAS_CONNECTION_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EAS_TYPE_CONNECTION,
EasConnectionPrivate))
-typedef struct _EasGnomeKeyringResponse {
- GnomeKeyringResult result;
+#define KEYRING_ITEM_ATTRIBUTE_USER "eas-user"
+#define KEYRING_ITEM_ATTRIBUTE_SERVER "eas-server"
+
+static SecretSchema password_schema = {
+ "org.gnome.Evolution.ActiveSync",
+ SECRET_SCHEMA_DONT_MATCH_NAME,
+ {
+ { KEYRING_ITEM_ATTRIBUTE_USER, SECRET_SCHEMA_ATTRIBUTE_STRING },
+ { KEYRING_ITEM_ATTRIBUTE_SERVER, SECRET_SCHEMA_ATTRIBUTE_STRING },
+ { NULL, 0 }
+ }
+};
+
+typedef struct _EasLibsecretResponse {
+ gboolean success;
+ guint error_code; /* from SECRET_ERROR domain */
gchar* password;
EFlag *semaphore;
const gchar* username;
const gchar* serverUri;
-} EasGnomeKeyringResponse;
+} EasLibsecretResponse;
typedef struct _EasNode EasNode;
@@ -374,25 +388,31 @@ eas_connection_class_init (EasConnectionClass *klass)
}
static void
-storePasswordCallback (GnomeKeyringResult result, gpointer data)
+storePasswordCallback (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- EasGnomeKeyringResponse *response = data;
+ EasLibsecretResponse *response = user_data;
+ GError *local_error = NULL;
g_assert (response);
- g_debug ("storePasswordCallback++ [%d]", response->result);
+ g_debug ("storePasswordCallback++");
g_assert (response->semaphore);
- response->result = result;
+ response->success = secret_password_store_finish (result, &local_error);
+ response->error_code = (local_error && local_error->domain == SECRET_ERROR) ? local_error->code : ~0;
e_flag_set (response->semaphore);
- g_debug ("storePasswordCallback--");
+ g_debug ("storePasswordCallback--%s%s", local_error ? " Failed: " : "", local_error ?
local_error->message : "");
+
+ g_clear_error (&local_error);
}
static gboolean
mainloop_password_store (gpointer data)
{
- EasGnomeKeyringResponse *response = data;
+ EasLibsecretResponse *response = data;
gchar * description = g_strdup_printf ("ActiveSync Server Password for %s@%s",
response->username,
response->serverUri);
@@ -401,16 +421,16 @@ mainloop_password_store (gpointer data)
g_assert (response->password);
- gnome_keyring_store_password (GNOME_KEYRING_NETWORK_PASSWORD,
- NULL,
- description,
- response->password,
- storePasswordCallback,
- response,
- NULL,
- "user", response->username,
- "server", response->serverUri,
- NULL);
+ secret_password_store (&password_schema,
+ SECRET_COLLECTION_DEFAULT,
+ description,
+ response->password,
+ NULL,
+ storePasswordCallback,
+ response,
+ KEYRING_ITEM_ATTRIBUTE_USER, response->username,
+ KEYRING_ITEM_ATTRIBUTE_SERVER, response->serverUri,
+ NULL);
g_free (description);
g_debug ("mainloop_password_store--");
@@ -418,11 +438,11 @@ mainloop_password_store (gpointer data)
}
// nb: can't be called from the main thread or will hang
-static GnomeKeyringResult
+static gboolean
writePasswordToKeyring (const gchar *password, const gchar* username, const gchar* serverUri)
{
- GnomeKeyringResult result = GNOME_KEYRING_RESULT_DENIED;
- EasGnomeKeyringResponse *response = g_malloc0 (sizeof (EasGnomeKeyringResponse));
+ gboolean success = FALSE;
+ EasLibsecretResponse *response = g_malloc0 (sizeof (EasLibsecretResponse));
GSource *source = NULL;
g_debug ("writePasswordToKeyring++");
@@ -441,28 +461,34 @@ writePasswordToKeyring (const gchar *password, const gchar* username, const gcha
e_flag_wait (response->semaphore);
e_flag_free (response->semaphore);
- result = response->result;
+ success = response->success;
g_free (response);
g_debug ("writePasswordToKeyring--");
- return result;
+ return success;
}
static void
-getPasswordCallback (GnomeKeyringResult result, const char* password, gpointer data)
+getPasswordCallback (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- EasGnomeKeyringResponse *response = data;
+ EasLibsecretResponse *response = user_data;
+ GError *local_error = NULL;
g_debug ("getPasswordCallback++");
g_assert (response);
g_assert (response->semaphore);
- response->result = result;
- response->password = g_strdup (password);
+ response->password = secret_password_lookup_finish (result, &local_error);
+ response->success = local_error == NULL && response->password != NULL;
+ response->error_code = (local_error && local_error->domain == SECRET_ERROR) ? local_error->code :
SECRET_ERROR_NO_SUCH_OBJECT;
e_flag_set (response->semaphore);
- g_debug ("getPasswordCallback--");
+ g_debug ("getPasswordCallback--%s%s", local_error ? " Failed: " : "", local_error ?
local_error->message : "");
+
+ g_clear_error (&local_error);
}
static gboolean
@@ -471,7 +497,7 @@ fetch_and_store_password (const gchar *account_id, const gchar *username, const
gchar *argv[3];
gchar * password = NULL;
GError * error = NULL;
- GnomeKeyringResult result = GNOME_KEYRING_RESULT_DENIED;
+ gboolean success;
gint exit_status = 0;
g_debug ("fetch_and_store_password++");
@@ -494,7 +520,7 @@ fetch_and_store_password (const gchar *account_id, const gchar *username, const
}
g_strchomp (password);
- result = writePasswordToKeyring (password, username, serverUri);
+ success = writePasswordToKeyring (password, username, serverUri);
memset (password, 0, strlen (password));
g_free (password);
@@ -503,36 +529,37 @@ fetch_and_store_password (const gchar *account_id, const gchar *username, const
g_free (argv[1]);
g_debug ("fetch_and_store_password--");
- return (result == GNOME_KEYRING_RESULT_OK);
+ return success;
}
static gboolean
mainloop_password_fetch (gpointer data)
{
- EasGnomeKeyringResponse *response = data;
+ EasLibsecretResponse *response = data;
g_debug ("mainloop_password_fetch++");
- gnome_keyring_find_password (GNOME_KEYRING_NETWORK_PASSWORD,
- getPasswordCallback,
- response,
- NULL,
- "user", response->username,
- "server", response->serverUri,
- NULL);
+ secret_password_lookup (&password_schema,
+ NULL,
+ getPasswordCallback,
+ response,
+ KEYRING_ITEM_ATTRIBUTE_USER, response->username,
+ KEYRING_ITEM_ATTRIBUTE_SERVER, response->serverUri,
+ NULL);
g_debug ("mainloop_password_fetch--");
return FALSE;
}
-static GnomeKeyringResult
-getPasswordFromKeyring (const gchar* username, const gchar* serverUri, char** password)
+/* error_code is from SECRET_ERROR domain */
+static gboolean
+getPasswordFromKeyring (const gchar* username, const gchar* serverUri, char** password, guint
*out_error_code)
{
- GnomeKeyringResult result = GNOME_KEYRING_RESULT_DENIED;
+ gboolean success;
EFlag *semaphore = NULL;
- EasGnomeKeyringResponse *response = g_malloc0 (sizeof (EasGnomeKeyringResponse));
+ EasLibsecretResponse *response = g_malloc0 (sizeof (EasLibsecretResponse));
GSource *source = NULL;
g_debug ("getPasswordFromKeyring++");
@@ -550,12 +577,13 @@ getPasswordFromKeyring (const gchar* username, const gchar* serverUri, char** pa
e_flag_wait (response->semaphore);
e_flag_free (response->semaphore);
- result = response->result;
+ success = response->success;
+ *out_error_code = response->error_code;
*password = response->password;
g_free (response);
g_debug ("getPasswordFromKeyring--");
- return result;
+ return success;
}
static void
@@ -569,7 +597,7 @@ connection_authenticate (SoupSession *sess,
const gchar * username = eas_account_get_username (cnc->priv->account);
const gchar * serverUri = eas_account_get_uri (cnc->priv->account);
const gchar * account_id = eas_account_get_uid (cnc->priv->account);
- GnomeKeyringResult result = GNOME_KEYRING_RESULT_DENIED;
+ guint error_code = ~0;
gchar* password = NULL;
g_debug (" eas_connection - connection_authenticate++");
@@ -581,41 +609,41 @@ connection_authenticate (SoupSession *sess,
g_debug("Password = \'%s\'", password);
if (password && password[0]) {
- g_warning ("Found password in GSettings, writing it to Gnome Keyring");
+ g_warning ("Found password in GSettings, writing it to libsecret");
- if (GNOME_KEYRING_RESULT_OK != writePasswordToKeyring (password, username, serverUri)) {
- g_warning ("Failed to store GSettings password in Gnome Keyring");
+ if (!writePasswordToKeyring (password, username, serverUri)) {
+ g_warning ("Failed to store GSettings password in libsecret");
}
}
password = NULL;
- result = getPasswordFromKeyring (username, serverUri, &password);
-
- if (GNOME_KEYRING_RESULT_NO_MATCH == result) {
- g_warning ("Failed to find password in Gnome Keyring");
+ if (!getPasswordFromKeyring (username, serverUri, &password, &error_code)) {
+ if (error_code == SECRET_ERROR_NO_SUCH_OBJECT) {
+ g_warning ("Failed to find password in libsecret");
- if (fetch_and_store_password (account_id, username, serverUri)) {
- if (GNOME_KEYRING_RESULT_OK == getPasswordFromKeyring (username, serverUri,
&password)) {
- g_debug ("First authentication attempt with newly set password");
- cnc->priv->retrying_asked = FALSE;
- soup_auth_authenticate (auth,
- username,
- password);
- } else {
- g_critical ("Failed to fetch and store password to gnome keyring [%d]",
result);
- }
+ if (fetch_and_store_password (account_id, username, serverUri)) {
+ if (getPasswordFromKeyring (username, serverUri, &password, &error_code)) {
+ g_debug ("First authentication attempt with newly set password");
+ cnc->priv->retrying_asked = FALSE;
+ soup_auth_authenticate (auth,
+ username,
+ password);
+ } else {
+ g_critical ("Failed to fetch and store password to libsecret [%d]",
error_code);
+ }
- if (password) {
- memset (password, 0 , strlen (password));
- g_free (password);
- password = NULL;
+ if (password) {
+ memset (password, 0 , strlen (password));
+ g_free (password);
+ password = NULL;
+ }
}
+ } else {
+ g_warning ("libsecret failed to find password [%d]", error_code);
}
- } else if (result != GNOME_KEYRING_RESULT_OK) {
- g_warning ("GnomeKeyring failed to find password [%d]", result);
} else {
- g_debug ("Found password in Gnome Keyring");
+ g_debug ("Found password in libsecret");
if (!retrying) {
g_debug ("First authentication attempt");
@@ -640,13 +668,13 @@ connection_authenticate (SoupSession *sess,
}
if (fetch_and_store_password (account_id, username, serverUri)) {
- if (GNOME_KEYRING_RESULT_OK == getPasswordFromKeyring (username, serverUri,
&password)) {
+ if (getPasswordFromKeyring (username, serverUri, &password, &error_code)) {
g_debug ("Second authentication with newly set password");
soup_auth_authenticate (auth,
username,
password);
} else {
- g_critical ("Failed to store password to gnome keyring [%d]", result);
+ g_critical ("Failed to store password to libsecret [%d]", error_code);
}
if (password) {
@@ -2569,13 +2597,13 @@ options_connection_authenticate (SoupSession *sess,
/*
TODO - this isn't the right way to do this:
currently uses a temporary authenticate callback
- to avoid using the asynchronous gnome keyring functions
+ to avoid using the asynchronous libsecret functions
It will be necessary to add an equivalent function to the client libraries
rather than providing this 'shortcut' straight to easconnection.
If we connect to the authenticate signal, then connection_authenticate will
hang since soup_session_send_message is being called from (and blocking)
- the same thread that the gnome keyring stuff uses the idle loop of.
+ the same thread that the libsecret stuff uses the idle loop of.
use the HTTP OPTIONS command to ask server for a list of protocols
store results in GSettings
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]