On the 'gnome-keyring' branch:
Merge r31297:31335 from trunk.
git-svn-id: https://svn.apache.org/repos/asf/subversion/branches/gnome-keyring@871410 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/Makefile.in b/Makefile.in
index fcdb920..8acbeab 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -41,6 +41,7 @@
SVN_APR_LIBS = @SVN_APR_LIBS@
SVN_APRUTIL_LIBS = @SVN_APRUTIL_LIBS@
SVN_DB_LIBS =
+SVN_GNOME_KEYRING_LIBS = @SVN_GNOME_KEYRING_LIBS@
SVN_KWALLET_LIBS = @SVN_KWALLET_LIBS@
SVN_SERF_LIBS = @SVN_SERF_LIBS@
SVN_SASL_LIBS = @SVN_SASL_LIBS@
@@ -54,6 +55,7 @@
fsmod_libdir = @libdir@
ramod_libdir = @libdir@
bdb_libdir = @libdir@
+gnome_keyring_libdir = @libdir@
kwallet_libdir = @libdir@
neon_libdir = @libdir@
serf_libdir = @libdir@
@@ -104,7 +106,7 @@
LT_CXX_LIBADD = @LT_CXX_LIBADD@
INCLUDES = -I$(top_srcdir)/subversion/include -I$(top_builddir)/subversion \
- @SVN_APR_INCLUDES@ @SVN_APRUTIL_INCLUDES@ \
+ @SVN_APR_INCLUDES@ @SVN_APRUTIL_INCLUDES@ @SVN_GNOME_KEYRING_INCLUDES@ \
@SVN_KWALLET_INCLUDES@ @SVN_NEON_INCLUDES@ @SVN_SASL_INCLUDES@ \
@SVN_SERF_INCLUDES@ @SVN_ZLIB_INCLUDES@
@@ -190,6 +192,7 @@
INSTALL_FSMOD_LIB = $(INSTALL_LIB)
INSTALL_RAMOD_LIB = $(INSTALL_LIB)
INSTALL_BDB_LIB = $(INSTALL_LIB)
+INSTALL_GNOME_KEYRING_LIB = $(INSTALL_LIB)
INSTALL_KWALLET_LIB = $(INSTALL_LIB)
INSTALL_NEON_LIB = $(INSTALL_LIB)
INSTALL_SERF_LIB = $(INSTALL_LIB)
diff --git a/build.conf b/build.conf
index 4df3e1f..3c8a2b5 100644
--- a/build.conf
+++ b/build.conf
@@ -201,6 +201,14 @@
install = bin
manpages = subversion/svnversion/svnversion.1
+# Support for GNOME Keyring
+[libsvn_auth_gnome_keyring]
+description = Subversion GNOME Keyring Library
+type = lib
+install = gnome-keyring-lib
+path = subversion/libsvn_auth_gnome_keyring
+libs = apr gnome-keyring libsvn_subr
+
# Support for KWallet
[libsvn_auth_kwallet]
description = Subversion KWallet Library
@@ -836,6 +844,10 @@
type = lib
external-lib = $(SVN_DB_LIBS)
+[gnome-keyring]
+type = lib
+external-lib = $(SVN_GNOME_KEYRING_LIBS)
+
[kwallet]
type = lib
external-lib = $(SVN_KWALLET_LIBS)
diff --git a/configure.ac b/configure.ac
index 7c62532..30b817f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -303,6 +303,58 @@
AC_CHECK_PROG(HAVE_PKG_CONFIG, pkg-config, yes)
+dnl GNOME Keyring -------------------
+
+AC_ARG_WITH(gnome_keyring,
+ AS_HELP_STRING([--with-gnome-keyring],
+ [Enable use of GNOME Keyring for auth credentials]),
+ [with_gnome_keyring="$withval"],
+ [with_gnome_keyring=no])
+
+AC_MSG_CHECKING([whether to look for GNOME Keyring])
+if test "$with_gnome_keyring" != "no"; then
+ AC_MSG_RESULT([yes])
+ if test "$enable_shared" = "yes"; then
+ if test "$APR_HAS_DSO" = "yes"; then
+ if test "$HAVE_PKG_CONFIG" = "yes"; then
+ AC_MSG_CHECKING([for GLib, D-Bus and GNOME Keyring .pc files])
+ if pkg-config --exists glib-2.0 dbus-1 gnome-keyring-1; then
+ AC_MSG_RESULT([yes])
+ old_CPPFLAGS="$CPPFLAGS"
+ SVN_GNOME_KEYRING_INCLUDES="`pkg-config --cflags glib-2.0 dbus-1 gnome-keyring-1`"
+ CPPFLAGS="$CPPFLAGS $SVN_GNOME_KEYRING_INCLUDES"
+ AC_CHECK_HEADER(gnome-keyring.h, with_gnome_keyring=yes, with_gnome_keyring=no)
+ AC_MSG_CHECKING([for GNOME Keyring])
+ if test "$with_gnome_keyring" = "yes"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([SVN_HAVE_GNOME_KEYRING], [1],
+ [Is GNOME Keyring support enabled?])
+ CPPFLAGS="$old_CPPFLAGS"
+ SVN_GNOME_KEYRING_LIBS="`pkg-config --libs glib-2.0 dbus-1 gnome-keyring-1`"
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([cannot find GNOME Keyring])
+ fi
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([cannot find GLib, D-Bus and GNOME Keyring .pc files])
+ fi
+ else
+ AC_MSG_ERROR([cannot find pkg-config])
+ fi
+ else
+ AC_MSG_ERROR([APR does not have support for DSOs])
+ fi
+ else
+ AC_MSG_ERROR([--with-gnome-keyring conflicts with --disable-shared])
+ fi
+else
+ AC_MSG_RESULT([no])
+fi
+AC_SUBST(SVN_GNOME_KEYRING_INCLUDES)
+AC_SUBST(SVN_GNOME_KEYRING_LIBS)
+
+
dnl I18n -------------------
AC_ARG_ENABLE(nls,
@@ -498,6 +550,12 @@
INSTALL_STATIC_RULES="$INSTALL_STATIC_RULES install-kwallet-lib"
fi
+if test "$with_gnome_keyring" = "yes"; then
+ BUILD_RULES="$BUILD_RULES gnome-keyring-lib"
+ INSTALL_RULES="`echo $INSTALL_RULES | sed 's/install-lib/install-lib install-gnome-keyring-lib/'`"
+ INSTALL_STATIC_RULES="$INSTALL_STATIC_RULES install-gnome-keyring-lib"
+fi
+
if test "$USE_NLS" = "yes"; then
BUILD_RULES="$BUILD_RULES locale"
INSTALL_RULES="$INSTALL_RULES install-locale"
diff --git a/subversion/bindings/javahl/native/SVNClient.cpp b/subversion/bindings/javahl/native/SVNClient.cpp
index aa12df4..aa95953 100644
--- a/subversion/bindings/javahl/native/SVNClient.cpp
+++ b/subversion/bindings/javahl/native/SVNClient.cpp
@@ -1213,6 +1213,12 @@
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
}
#endif
+#ifdef SVN_HAVE_GNOME_KEYRING
+ if (get_auth_simple_provider(&provider, "gnome_keyring", pool))
+ {
+ APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
+ }
+#endif
svn_auth_get_simple_provider(&provider, pool);
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
svn_auth_get_username_provider(&provider, pool);
diff --git a/subversion/include/private/svn_auth_private.h b/subversion/include/private/svn_auth_private.h
index 528b1a8..186e525 100644
--- a/subversion/include/private/svn_auth_private.h
+++ b/subversion/include/private/svn_auth_private.h
@@ -34,6 +34,7 @@
#define SVN_AUTH__WINCRYPT_PASSWORD_TYPE "wincrypt"
#define SVN_AUTH__KEYCHAIN_PASSWORD_TYPE "keychain"
#define SVN_AUTH__KWALLET_PASSWORD_TYPE "kwallet"
+#define SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE "gnome-keyring"
/* A function that stores in *PASSWORD (potentially after decrypting it)
the user's password. It might be obtained directly from CREDS, or
diff --git a/subversion/include/svn_auth_dso.h b/subversion/include/svn_auth_dso.h
index 90d8a0b..ae36e48 100644
--- a/subversion/include/svn_auth_dso.h
+++ b/subversion/include/svn_auth_dso.h
@@ -37,6 +37,25 @@
* @a pool.
*
* This is like svn_client_get_simple_provider(), except that the
+ * password is stored in GNOME Keyring.
+ *
+ * @since New in 1.6
+ * @note This function actually works only on systems with
+ * libsvn_auth_gnome_keyring and GNOME Keyring installed.
+ */
+void
+svn_auth_get_gnome_keyring_simple_provider
+ (svn_auth_provider_object_t **provider,
+ apr_pool_t *pool);
+
+
+/**
+ * Create and return @a *provider, an authentication provider of type @c
+ * svn_auth_cred_simple_t that gets/sets information from the user's
+ * ~/.subversion configuration directory. Allocate @a *provider in
+ * @a pool.
+ *
+ * This is like svn_client_get_simple_provider(), except that the
* password is stored in KWallet.
*
* @since New in 1.6
diff --git a/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c b/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
new file mode 100644
index 0000000..f473482
--- /dev/null
+++ b/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
@@ -0,0 +1,191 @@
+/*
+ * gnome_keyring.c: GNOME Keyring provider for SVN_AUTH_CRED_SIMPLE
+ *
+ * ====================================================================
+ * Copyright (c) 2008 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+
+#include <apr_pools.h>
+#include "svn_auth.h"
+#include "svn_auth_dso.h"
+#include "svn_error.h"
+
+#include "private/svn_auth_private.h"
+
+#include "svn_private_config.h"
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gnome-keyring.h>
+
+
+/*-----------------------------------------------------------------------*/
+/* GNOME Keyring simple provider, puts passwords in GNOME Keyring */
+/*-----------------------------------------------------------------------*/
+
+/* Implementation of password_get_t that retrieves the password
+ from GNOME Keyring. */
+static svn_boolean_t
+gnome_keyring_password_get(const char **password,
+ apr_hash_t *creds,
+ const char *realmstring,
+ const char *username,
+ svn_boolean_t non_interactive,
+ apr_pool_t *pool)
+{
+ if (non_interactive)
+ {
+ return FALSE;
+ }
+
+ if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
+ {
+ return FALSE;
+ }
+
+ if (! gnome_keyring_is_available())
+ {
+ return FALSE;
+ }
+
+ GnomeKeyringResult result;
+ GList *items;
+ svn_boolean_t ret = FALSE;
+
+ result = gnome_keyring_find_network_password_sync(username, realmstring,
+ NULL, NULL, NULL, NULL, 0,
+ &items);
+
+ if (result == GNOME_KEYRING_RESULT_OK && items && items->data)
+ {
+ GnomeKeyringNetworkPasswordData *item;
+ item = (GnomeKeyringNetworkPasswordData *)items->data;
+ if (item->password)
+ {
+ size_t len = strlen(item->password);
+ if (len > 0)
+ {
+ *password = apr_pstrmemdup(pool, item->password, len);
+ ret = TRUE;
+ }
+ }
+ gnome_keyring_network_password_list_free(items);
+ }
+
+ return ret;
+}
+
+/* Implementation of password_set_t that stores the password in
+ GNOME Keyring. */
+static svn_boolean_t
+gnome_keyring_password_set(apr_hash_t *creds,
+ const char *realmstring,
+ const char *username,
+ const char *password,
+ svn_boolean_t non_interactive,
+ apr_pool_t *pool)
+{
+ if (non_interactive)
+ {
+ return FALSE;
+ }
+
+ if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
+ {
+ return FALSE;
+ }
+
+ if (! gnome_keyring_is_available())
+ {
+ return FALSE;
+ }
+
+ GnomeKeyringResult result;
+ guint32 item_id;
+
+ result = gnome_keyring_set_network_password_sync(NULL, /* default keyring */
+ username, realmstring,
+ NULL, NULL, NULL, NULL, 0,
+ password,
+ &item_id);
+
+ return result == GNOME_KEYRING_RESULT_OK;
+}
+
+/* Get cached encrypted credentials from the simple provider's cache. */
+static svn_error_t *
+gnome_keyring_simple_first_creds(void **credentials,
+ void **iter_baton,
+ void *provider_baton,
+ apr_hash_t *parameters,
+ const char *realmstring,
+ apr_pool_t *pool)
+{
+ return svn_auth__simple_first_creds_helper(credentials,
+ iter_baton, provider_baton,
+ parameters, realmstring,
+ gnome_keyring_password_get,
+ SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
+ pool);
+}
+
+/* Save encrypted credentials to the simple provider's cache. */
+static svn_error_t *
+gnome_keyring_simple_save_creds(svn_boolean_t *saved,
+ void *credentials,
+ void *provider_baton,
+ apr_hash_t *parameters,
+ const char *realmstring,
+ apr_pool_t *pool)
+{
+ return svn_auth__simple_save_creds_helper(saved, credentials,
+ provider_baton, parameters,
+ realmstring,
+ gnome_keyring_password_set,
+ SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
+ pool);
+}
+
+static void
+gnome_keyring_init()
+{
+ g_set_application_name("Subversion");
+}
+
+static const svn_auth_provider_t gnome_keyring_simple_provider = {
+ SVN_AUTH_CRED_SIMPLE,
+ gnome_keyring_simple_first_creds,
+ NULL,
+ gnome_keyring_simple_save_creds
+};
+
+/* Public API */
+void
+svn_auth_get_gnome_keyring_simple_provider
+ (svn_auth_provider_object_t **provider,
+ apr_pool_t *pool)
+{
+ svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
+
+ po->vtable = &gnome_keyring_simple_provider;
+ *provider = po;
+
+ gnome_keyring_init();
+}
diff --git a/subversion/libsvn_subr/cmdline.c b/subversion/libsvn_subr/cmdline.c
index 04a7c60..be91633 100644
--- a/subversion/libsvn_subr/cmdline.c
+++ b/subversion/libsvn_subr/cmdline.c
@@ -436,6 +436,12 @@
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
}
#endif
+#ifdef SVN_HAVE_GNOME_KEYRING
+ if (get_auth_simple_provider(&provider, "gnome_keyring", pool))
+ {
+ APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
+ }
+#endif
if (non_interactive == FALSE)
{
/* This provider is odd in that it isn't a prompting provider in
diff --git a/subversion/libsvn_subr/simple_providers.c b/subversion/libsvn_subr/simple_providers.c
index d4e0443..0323876 100644
--- a/subversion/libsvn_subr/simple_providers.c
+++ b/subversion/libsvn_subr/simple_providers.c
@@ -261,7 +261,8 @@
* in plaintext is OK. */
if (strcmp(passtype, SVN_AUTH__WINCRYPT_PASSWORD_TYPE) == 0
|| strcmp(passtype, SVN_AUTH__KEYCHAIN_PASSWORD_TYPE) == 0
- || strcmp(passtype, SVN_AUTH__KWALLET_PASSWORD_TYPE) == 0)
+ || strcmp(passtype, SVN_AUTH__KWALLET_PASSWORD_TYPE) == 0
+ || strcmp(passtype, SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE) == 0)
{
may_save_password = TRUE;
}