You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2012/08/03 20:42:46 UTC
svn commit: r1369161 - in /subversion/branches/master-passphrase/subversion:
include/private/svn_auth_private.h include/svn_auth.h libsvn_subr/auth.c
libsvn_subr/cmdline.c libsvn_subr/masterpass_providers.c
Author: cmpilato
Date: Fri Aug 3 18:42:46 2012
New Revision: 1369161
URL: http://svn.apache.org/viewvc?rev=1369161&view=rev
Log:
On the 'master-passphrase' branch: Add the framework for supporting
the obvious additional platform-specific master passphrase providers.
* subversion/include/private/svn_auth_private.h
(SVN_AUTH__DEFAULT_PROVIDER_LIST): New #define.
* subversion/include/svn_auth.h
(svn_auth_master_passphrase_provider_func_t): New function type.
(svn_auth_get_platform_specific_master_passphrase_providers): New function.
* subversion/libsvn_subr/auth.c
(SVN__DEFAULT_AUTH_PROVIDER_LIST): Remove.
(svn_auth_get_platform_specific_client_providers): Use
SVN_AUTH__DEFAULT_PROVIDER_LIST instead of SVN__DEFAULT_AUTH_PROVIDER_LIST.
* subversion/libsvn_subr/cmdline.c
(open_auth_store): Add 'cfg' parameter, and now call
svn_auth_get_platform_specific_master_passphrase_providers() instead
of explicitly referencing the gpg-agent master passphrase provider.
(svn_cmdline_create_auth_baton): Update call to open_auth_store().
* subversion/libsvn_subr/masterpass_providers.c
(get_provider, svn_auth_get_platform_specific_master_passphrase_providers):
New functions.
Modified:
subversion/branches/master-passphrase/subversion/include/private/svn_auth_private.h
subversion/branches/master-passphrase/subversion/include/svn_auth.h
subversion/branches/master-passphrase/subversion/libsvn_subr/auth.c
subversion/branches/master-passphrase/subversion/libsvn_subr/cmdline.c
subversion/branches/master-passphrase/subversion/libsvn_subr/masterpass_providers.c
Modified: subversion/branches/master-passphrase/subversion/include/private/svn_auth_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/private/svn_auth_private.h?rev=1369161&r1=1369160&r2=1369161&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/private/svn_auth_private.h (original)
+++ subversion/branches/master-passphrase/subversion/include/private/svn_auth_private.h Fri Aug 3 18:42:46 2012
@@ -48,6 +48,13 @@ extern "C" {
#define SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE "gnome-keyring"
#define SVN_AUTH__GPG_AGENT_PASSWORD_TYPE "gpg-agent"
+/* Default ordered list of available third-party password storage
+ * providers.
+ */
+#define SVN_AUTH__DEFAULT_PROVIDER_LIST \
+ "gnome-keyring,kwallet,keychain,gpg-agent,windows-cryptoapi"
+
+
/* A function that stores in *PASSWORD (potentially after decrypting it)
the user's password. It might be obtained directly from CREDS, or
from an external store, using REALMSTRING and USERNAME as keys.
Modified: subversion/branches/master-passphrase/subversion/include/svn_auth.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/svn_auth.h?rev=1369161&r1=1369160&r2=1369161&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/svn_auth.h (original)
+++ subversion/branches/master-passphrase/subversion/include/svn_auth.h Fri Aug 3 18:42:46 2012
@@ -900,6 +900,7 @@ svn_auth_get_platform_specific_client_pr
svn_config_t *config,
apr_pool_t *pool);
+
#if (defined(WIN32) && !defined(__MINGW32__)) || defined(DOXYGEN)
/**
* Set @a *provider to an authentication provider of type @c
@@ -1310,6 +1311,34 @@ svn_auth_get_ssl_client_cert_pw_prompt_p
apr_pool_t *pool);
+
+/*** Master Passphrase Providers ***/
+
+/** Master passphrase providers are unique in Subversion in that they
+ * are used with a unique svn_auth_baton_t which is not the same auth
+ * baton used for other provider types ("simple", "username", etc.).
+ */
+
+/** A function returning a master passphrase provider. */
+typedef void (*svn_auth_master_passphrase_provider_func_t)(
+ svn_auth_provider_object_t **provider,
+ apr_pool_t *pool);
+
+/** Set @a *providers to an array of @c svn_auth_provider_object_t
+ * master passphrase providers appropriate for the client platform and
+ * which honor the allowed, ordered providers specified via the
+ * 'password-stores' option @a config. Allocate providers from @a
+ * pool.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_auth_get_platform_specific_master_passphrase_providers(
+ apr_array_header_t **providers,
+ svn_config_t *config,
+ apr_pool_t *pool);
+
+
/** Set @a *provider to an authentication provider of type @c
* svn_auth_cred_master_passphrase_t, allocated in @a pool.
*
Modified: subversion/branches/master-passphrase/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_subr/auth.c?rev=1369161&r1=1369160&r2=1369161&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_subr/auth.c Fri Aug 3 18:42:46 2012
@@ -34,6 +34,7 @@
#include "svn_private_config.h"
#include "svn_dso.h"
#include "svn_version.h"
+#include "private/svn_auth_private.h"
/* AN OVERVIEW
===========
@@ -523,9 +524,6 @@ svn_auth_get_platform_specific_client_pr
apr_array_header_t *password_stores;
int i;
-#define SVN__DEFAULT_AUTH_PROVIDER_LIST \
- "gnome-keyring,kwallet,keychain,gpg-agent,windows-cryptoapi"
-
if (config)
{
svn_config_get
@@ -533,11 +531,11 @@ svn_auth_get_platform_specific_client_pr
&password_stores_config_option,
SVN_CONFIG_SECTION_AUTH,
SVN_CONFIG_OPTION_PASSWORD_STORES,
- SVN__DEFAULT_AUTH_PROVIDER_LIST);
+ SVN_AUTH__DEFAULT_PROVIDER_LIST);
}
else
{
- password_stores_config_option = SVN__DEFAULT_AUTH_PROVIDER_LIST;
+ password_stores_config_option = SVN_AUTH__DEFAULT_PROVIDER_LIST;
}
*providers = apr_array_make(pool, 12, sizeof(svn_auth_provider_object_t *));
Modified: subversion/branches/master-passphrase/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_subr/cmdline.c?rev=1369161&r1=1369160&r2=1369161&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_subr/cmdline.c Fri Aug 3 18:42:46 2012
@@ -450,6 +450,7 @@ ssl_trust_unknown_server_cert
/* Instantiate and open an auth store. */
static svn_error_t *
open_auth_store(svn_auth__store_t **auth_store_p,
+ svn_config_t *cfg,
const char *config_dir,
svn_boolean_t use_master_password,
svn_boolean_t no_auth_cache,
@@ -473,16 +474,10 @@ open_auth_store(svn_auth__store_t **auth
/* Build an authentication baton with the relevant master
passphrase providers. */
- mp_providers = apr_array_make(pool, 1,
- sizeof(svn_auth_provider_object_t *));
if (! non_interactive)
{
-#if !defined(WIN32) || defined(DOXYGEN)
- /* ### FIXME!! This should be done by code that inspects
- and honors the 'password-stores' configuration setting! */
- svn_auth_get_gpg_agent_master_passphrase_provider(&provider, pool);
- APR_ARRAY_PUSH(mp_providers, svn_auth_provider_object_t *) = provider;
-#endif /* !defined(WIN32) || defined(DOXYGEN) */
+ SVN_ERR(svn_auth_get_platform_specific_master_passphrase_providers(
+ &mp_providers, cfg, pool));
svn_auth_get_master_passphrase_prompt_provider(
&provider, svn_cmdline_auth_master_passphrase_prompt,
pb, 3, pool);
@@ -689,7 +684,7 @@ svn_cmdline_create_auth_baton(svn_auth_b
#endif /* SVN_HAVE_GNOME_KEYRING */
/* Open the appropriate auth store, and cache it in the auth baton. */
- SVN_ERR(open_auth_store(&auth_store, config_dir, use_master_password,
+ SVN_ERR(open_auth_store(&auth_store, cfg, config_dir, use_master_password,
(no_auth_cache || ! store_auth_creds_val),
non_interactive, pb, pool));
svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_AUTH_STORE, auth_store);
Modified: subversion/branches/master-passphrase/subversion/libsvn_subr/masterpass_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_subr/masterpass_providers.c?rev=1369161&r1=1369160&r2=1369161&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_subr/masterpass_providers.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_subr/masterpass_providers.c Fri Aug 3 18:42:46 2012
@@ -28,6 +28,8 @@
#include "svn_error.h"
#include "svn_config.h"
#include "svn_string.h"
+#include "svn_dso.h"
+#include "svn_version.h"
#include "auth_store.h"
#include "private/svn_auth_private.h"
@@ -149,3 +151,163 @@ void svn_auth_get_master_passphrase_prom
po->provider_baton = pb;
*provider = po;
}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Platform-specific providers */
+/*-----------------------------------------------------------------------*/
+
+/* Set *PROVIDER to the master passphrase provider known by
+ PROVIDER_NAME, if available for the plaform; set it to NULL
+ otherwise. */
+static svn_error_t *
+get_provider(svn_auth_provider_object_t **provider,
+ const char *provider_name,
+ apr_pool_t *pool)
+{
+ *provider = NULL;
+
+ if (apr_strnatcmp(provider_name, "gnome_keyring") == 0 ||
+ apr_strnatcmp(provider_name, "kwallet") == 0)
+ {
+#if (defined(SVN_HAVE_GNOME_KEYRING) || defined(SVN_HAVE_KWALLET))
+ apr_dso_handle_t *dso;
+ apr_dso_handle_sym_t provider_func_symbol, version_func_symbol;
+ const char *provider_func_name, *version_func_name;
+ const char *library_label, *library_name;
+
+ library_name = apr_psprintf(pool, "libsvn_auth_%s-%d.so.0",
+ provider_name, SVN_VER_MAJOR);
+ library_label = apr_psprintf(pool, "svn_%s", provider_name);
+ provider_func_name =
+ apr_psprintf(pool,
+ "svn_auth__get_%s_master_passphrase_provider",
+ provider_name);
+ version_func_name =
+ apr_psprintf(pool, "svn_auth_%s_version", provider_name);
+ SVN_ERR(svn_dso_load(&dso, library_name));
+ if (dso)
+ {
+ if (apr_dso_sym(&version_func_symbol, dso, version_func_name) == 0)
+ {
+ svn_version_func_t version_func = version_func_symbol;
+ svn_version_checklist_t check_list[2];
+
+ check_list[0].label = library_label;
+ check_list[0].version_query = version_func;
+ check_list[1].label = NULL;
+ check_list[1].version_query = NULL;
+ SVN_ERR(svn_ver_check_list(svn_subr_version(), check_list));
+ }
+ if (apr_dso_sym(&provider_func_symbol, dso, provider_func_name) == 0)
+ {
+ svn_auth_master_passphrase_provider_func_t provider_func =
+ provider_func_symbol;
+ provider_func(provider, pool);
+ }
+ }
+#endif /* defined(SVN_HAVE_GNOME_KEYRING) || defined(SVN_HAVE_KWALLET) */
+ }
+ else if (strcmp(provider_name, "gpg_agent") == 0)
+ {
+#if defined(SVN_HAVE_GPG_AGENT)
+ svn_auth_get_gpg_agent_master_passphrase_provider(provider, pool);
+#endif /* defined(SVN_HAVE_GPG_AGENT) */
+ }
+ else if (strcmp(provider_name, "keychain") == 0)
+ {
+#ifdef SVN_HAVE_KEYCHAIN_SERVICES
+ svn_auth_get_keychain_master_passphrase_provider(provider, pool);
+#endif /* SVN_HAVE_KEYCHAIN_SERVICES */
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+/* If provider P is non-NULL, add it to the providers LIST. */
+#define SVN__MAYBE_ADD_PROVIDER(list,p) \
+ { if (p) APR_ARRAY_PUSH(list, \
+ svn_auth_provider_object_t *) = p; }
+
+svn_error_t *
+svn_auth_get_platform_specific_master_passphrase_providers(
+ apr_array_header_t **providers,
+ svn_config_t *config,
+ apr_pool_t *pool)
+{
+ svn_auth_provider_object_t *provider;
+ const char *password_stores_config_option = SVN_AUTH__DEFAULT_PROVIDER_LIST;
+ apr_array_header_t *password_stores;
+ int i;
+
+ /* Initialize our output. */
+ *providers = apr_array_make(pool, 12, sizeof(svn_auth_provider_object_t *));
+
+ if (config)
+ {
+ svn_config_get(config, &password_stores_config_option,
+ SVN_CONFIG_SECTION_AUTH,
+ SVN_CONFIG_OPTION_PASSWORD_STORES,
+ SVN_AUTH__DEFAULT_PROVIDER_LIST);
+ }
+
+ password_stores = svn_cstring_split(password_stores_config_option,
+ " ,", TRUE, pool);
+ for (i = 0; i < password_stores->nelts; i++)
+ {
+ const char *password_store = APR_ARRAY_IDX(password_stores, i,
+ const char *);
+
+ /* GNOME Keyring */
+ if (apr_strnatcmp(password_store, "gnome-keyring") == 0)
+ {
+#if 0
+ SVN_ERR(get_provider(&provider, "gnome_keyring", pool));
+ SVN__MAYBE_ADD_PROVIDER(*providers, provider);
+#endif
+ continue;
+ }
+
+ /* GPG-Agent */
+ if (apr_strnatcmp(password_store, "gpg-agent") == 0)
+ {
+ SVN_ERR(get_provider(&provider, "gpg_agent", pool));
+ SVN__MAYBE_ADD_PROVIDER(*providers, provider);
+ continue;
+ }
+
+ /* KWallet */
+ if (apr_strnatcmp(password_store, "kwallet") == 0)
+ {
+#if 0
+ SVN_ERR(get_provider(&provider, "kwallet", pool));
+ SVN__MAYBE_ADD_PROVIDER(*providers, provider);
+#endif
+ continue;
+ }
+
+ /* Keychain */
+ if (apr_strnatcmp(password_store, "keychain") == 0)
+ {
+#if 0
+ SVN_ERR(get_provider(&provider, "keychain", pool));
+ SVN__MAYBE_ADD_PROVIDER(*providers, provider);
+#endif
+ continue;
+ }
+
+ /* Windows (no master passphrase provider for this platform) */
+ if (apr_strnatcmp(password_store, "windows-cryptoapi") == 0)
+ continue;
+
+ return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
+ _("Invalid config: unknown password store '%s'"),
+ password_store);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+#undef SVN__MAYBE_ADD_PROVIDER