/dev/qulogic/masterpassword: efe6019c9e91: Add a Secret Service ...
Elliott Sales de Andrade
qulogic at pidgin.im
Thu Aug 23 02:12:32 EDT 2012
Changeset: efe6019c9e91e1b36cd7a5bc68caa4a179124b56
Author: Elliott Sales de Andrade <qulogic at pidgin.im>
Date: 2012-08-23 01:27 -0400
Branch: soc.2008.masterpassword
URL: http://hg.pidgin.im/dev/qulogic/masterpassword/rev/efe6019c9e91
Description:
Add a Secret Service password plugin.
No, not *that* Secret Service... The password storing one:
http://developer.gnome.org/libsecret/
diffstat:
configure.ac | 24 +
libpurple/plugins/keyrings/Makefile.am | 14 +
libpurple/plugins/keyrings/secretservice.c | 360 +++++++++++++++++++++++++++++
3 files changed, 398 insertions(+), 0 deletions(-)
diffs (truncated from 437 to 300 lines):
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1447,6 +1447,29 @@ else
fi
dnl #######################################################################
+dnl # Check for Secret Service headers
+dnl #######################################################################
+
+AC_ARG_ENABLE(libsecret, [AC_HELP_STRING([--disable-secret-service], [disable Secret Service support])], enable_secret_service=$enableval, enable_secret_service=yes)
+
+dnl Check for libsecret; if we don't have it, oh well
+if test "x$enable_secret_service" = "xyes" ; then
+ PKG_CHECK_MODULES(SECRETSERVICE, [libsecret-1], [
+ AC_SUBST(SECRETSERVICE_CFLAGS)
+ AC_SUBST(SECRETSERVICE_LIBS)
+ AC_DEFINE(HAVE_SECRETSERVICE, 1, [Define if we have Secret Service.])
+ ], [
+ if test "x$force_deps" = "xyes" ; then
+ AC_MSG_ERROR([
+Secret Service development headers not found.
+Use --disable-secret-service if you do not need Secret Service support.
+])
+ fi])
+fi
+
+AM_CONDITIONAL(ENABLE_SECRETSERVICE, test "x$enable_secret_service" = "xyes")
+
+dnl #######################################################################
dnl # Check for GNOME Keyring headers
dnl #######################################################################
@@ -2806,6 +2829,7 @@ if test "x$enable_dbus" = "xyes" ; then
fi
echo Build with GNU Libidn......... : $enable_idn
echo Build with NetworkManager..... : $enable_nm
+echo Build with Secret Service..... : $enable_secret_service
echo Build with GNOME Keyring...... : $enable_gnome_keyring
echo Build with KWallet............ : $enable_kwallet
echo SSL Library/Libraries......... : $msg_ssl
diff --git a/libpurple/plugins/keyrings/Makefile.am b/libpurple/plugins/keyrings/Makefile.am
--- a/libpurple/plugins/keyrings/Makefile.am
+++ b/libpurple/plugins/keyrings/Makefile.am
@@ -8,6 +8,15 @@ internalkeyring_la_LDFLAGS = -module -av
internalkeyring_la_SOURCES = internalkeyring.c
internalkeyring_la_LIBADD = $(GLIB_LIBS)
+if ENABLE_SECRETSERVICE
+
+secretservice_la_CFLAGS = $(AM_CPPFLAGS) $(SECRETSERVICE_CFLAGS)
+secretservice_la_LDFLAGS = -module -avoid-version
+secretservice_la_SOURCES = secretservice.c
+secretservice_la_LIBADD = $(GLIB_LIBS) $(SECRETSERVICE_LIBS)
+
+endif
+
if ENABLE_GNOMEKEYRING
gnomekeyring_la_CFLAGS = $(AM_CPPFLAGS) $(GNOMEKEYRING_CFLAGS)
@@ -35,6 +44,11 @@ if PLUGINS
plugin_LTLIBRARIES = \
internalkeyring.la
+if ENABLE_SECRETSERVICE
+plugin_LTLIBRARIES += \
+ secretservice.la
+endif
+
if ENABLE_GNOMEKEYRING
plugin_LTLIBRARIES += \
gnomekeyring.la
diff --git a/libpurple/plugins/keyrings/secretservice.c b/libpurple/plugins/keyrings/secretservice.c
new file mode 100644
--- /dev/null
+++ b/libpurple/plugins/keyrings/secretservice.c
@@ -0,0 +1,360 @@
+/* purple
+ * @file secretservice.c Secret Service password storage
+ * @ingroup plugins
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program ; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "account.h"
+#include "debug.h"
+#include "keyring.h"
+#include "plugin.h"
+#include "version.h"
+
+#include <libsecret/secret.h>
+
+#define SECRETSERVICE_NAME N_("Secret Service")
+#define SECRETSERVICE_ID "keyring-libsecret"
+
+#define ERR_SECRETSERVICEPLUGIN (ss_error_domain())
+
+static PurpleKeyring *keyring_handler = NULL;
+
+static const SecretSchema purple_schema = {
+ "im.pidgin.Purple", SECRET_SCHEMA_NONE,
+ {
+ {"user", SECRET_SCHEMA_ATTRIBUTE_STRING},
+ {"protocol", SECRET_SCHEMA_ATTRIBUTE_STRING},
+ {"NULL", 0}
+ },
+ /* Reserved fields */
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+typedef struct _InfoStorage InfoStorage;
+
+struct _InfoStorage
+{
+ PurpleAccount *account;
+ gpointer cb;
+ gpointer user_data;
+};
+
+static GQuark
+ss_error_domain(void)
+{
+ return g_quark_from_static_string("SecretService plugin");
+}
+
+
+/***********************************************/
+/* Keyring interface */
+/***********************************************/
+static void
+ss_read_continue(GObject *object, GAsyncResult *result, gpointer data)
+{
+ InfoStorage *storage = data;
+ PurpleAccount *account = storage->account;
+ PurpleKeyringReadCallback cb = storage->cb;
+ char *password;
+ GError *error = NULL;
+
+ password = secret_password_lookup_finish(result, &error);
+
+ if (error != NULL) {
+ int code = error->code;
+ g_error_free(error);
+
+ switch (code) {
+ case G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND:
+ case G_DBUS_ERROR_IO_ERROR:
+ error = g_error_new(ERR_SECRETSERVICEPLUGIN,
+ PURPLE_KEYRING_ERROR_NOCHANNEL,
+ "Failed to communicate with Secret Service (account : %s).",
+ purple_account_get_username(account));
+ if (cb != NULL)
+ cb(account, NULL, error, storage->user_data);
+ g_error_free(error);
+ break;
+
+ default:
+ error = g_error_new(ERR_SECRETSERVICEPLUGIN,
+ PURPLE_KEYRING_ERROR_NOCHANNEL,
+ "Unknown error (account : %s).",
+ purple_account_get_username(account));
+ if (cb != NULL)
+ cb(account, NULL, error, storage->user_data);
+ g_error_free(error);
+ break;
+ }
+
+ } else if (password == NULL) {
+ error = g_error_new(ERR_SECRETSERVICEPLUGIN,
+ PURPLE_KEYRING_ERROR_NOPASSWD,
+ "No password found for account: %s",
+ purple_account_get_username(account));
+ if (cb != NULL)
+ cb(account, NULL, error, storage->user_data);
+ g_error_free(error);
+
+ } else {
+ if (cb != NULL)
+ cb(account, password, NULL, storage->user_data);
+ }
+
+ g_free(storage);
+}
+
+static void
+ss_read(PurpleAccount *account, PurpleKeyringReadCallback cb, gpointer data)
+{
+ InfoStorage *storage = g_new0(InfoStorage, 1);
+
+ storage->account = account;
+ storage->cb = cb;
+ storage->user_data = data;
+
+ secret_password_lookup(&purple_schema,
+ NULL, ss_read_continue, storage,
+ "user", purple_account_get_username(account),
+ "protocol", purple_account_get_protocol_id(account),
+ NULL);
+}
+
+static void
+ss_save_continue(GObject *object, GAsyncResult *result, gpointer data)
+{
+ InfoStorage *storage = data;
+ PurpleKeyringSaveCallback cb;
+ GError *error = NULL;
+ PurpleAccount *account;
+
+ account = storage->account;
+ cb = storage->cb;
+
+ secret_password_store_finish(result, &error);
+
+ if (error != NULL) {
+ int code = error->code;
+ g_error_free(error);
+
+ switch (code) {
+ case G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND:
+ case G_DBUS_ERROR_IO_ERROR:
+ purple_debug_info("keyring-libsecret",
+ "Failed to communicate with Secret Service (account : %s (%s)).\n",
+ purple_account_get_username(account),
+ purple_account_get_protocol_id(account));
+ error = g_error_new(ERR_SECRETSERVICEPLUGIN,
+ PURPLE_KEYRING_ERROR_NOCHANNEL,
+ "Failed to communicate with Secret Service (account : %s).",
+ purple_account_get_username(account));
+ if (cb != NULL)
+ cb(account, error, storage->user_data);
+ g_error_free(error);
+ break;
+
+ default:
+ purple_debug_info("keyring-libsecret",
+ "Unknown error (account : %s (%s)).\n",
+ purple_account_get_username(account),
+ purple_account_get_protocol_id(account));
+ error = g_error_new(ERR_SECRETSERVICEPLUGIN,
+ PURPLE_KEYRING_ERROR_NOCHANNEL,
+ "Unknown error (account : %s).",
+ purple_account_get_username(account));
+ if (cb != NULL)
+ cb(account, error, storage->user_data);
+ g_error_free(error);
+ break;
+ }
+
+ } else {
+ purple_debug_info("keyring-libsecret", "Password for %s updated.\n",
+ purple_account_get_username(account));
+
+ if (cb != NULL)
+ cb(account, NULL, storage->user_data);
+ }
+
+ g_free(storage);
+}
+
+static void
+ss_save(PurpleAccount *account,
+ const gchar *password,
+ PurpleKeyringSaveCallback cb,
+ gpointer data)
+{
+ InfoStorage *storage = g_new0(InfoStorage, 1);
+
+ storage->account = account;
+ storage->cb = cb;
+ storage->user_data = data;
+
+ if (password != NULL && *password != '\0') {
+ const char *username = purple_account_get_username(account);
+ char *label;
+
+ purple_debug_info("keyring-libsecret",
+ "Updating password for account %s (%s).\n",
+ username, purple_account_get_protocol_id(account));
+
+ label = g_strdup_printf(_("Pidgin IM password for account %s"), username);
+ secret_password_store(&purple_schema, SECRET_COLLECTION_DEFAULT,
+ label, password,
+ NULL, ss_save_continue, storage,
More information about the Commits
mailing list