Hi,
I would like to get some review from full committers on this patch, which will
enable me to start further work on CryptAPI for this enhancement.
In order to setup the apache environment to use a client certificate you can
feel free to use this link
http://www.stylesen.org/subversion_client_authentication_using_pkcs_12_based_certificates_howto
This patch partially fixes http://subversion.tigris.org/issues/show_bug.cgi?id=2489
Thank You.
Senthil Kumaran S wrote:
> Hi Arfrever,
>
> Arfrever Frehtes Taifersar Arahesis wrote:
>>> Index: subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
>>> ===================================================================
>>> --- subversion/libsvn_auth_gnome_keyring/gnome_keyring.c (revision
>>> 31507)
>>> +++ subversion/libsvn_auth_gnome_keyring/gnome_keyring.c (working copy)
>>> @@ -189,3 +189,60 @@
>>>
>>> gnome_keyring_init();
>>> }
>>> +
>>> +/* Get cached encrypted credentials from the ssl client cert password
>>> + * provider's cache. */
>>> +static svn_error_t *
>>> +gnome_keyring_ssl_client_cert_pw_first_creds(void **credentials,
>>> + void **iter_baton,
>>> + void *provider_baton,
>>> + apr_hash_t *parameters,
>>> + const char *realmstring,
>>> + apr_pool_t *pool)
>>> +{
>>> + return svn_auth__ssl_client_cert_pw_file_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 ssl client cert password
>>> provider's
>>> + * cache. */
>>> +static svn_error_t *
>>> +gnome_keyring_ssl_client_cert_pw_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__ssl_client_cert_pw_file_save_creds_helper
>>> + (saved, credentials,
>>> + provider_baton, parameters,
>>> + realmstring,
>>> + gnome_keyring_password_set,
>>> + SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
>>> + pool);
>>> +}
>>
>> You use gnome_keyring_password_get() and gnome_keyring_password_set().
>> Won't it cause collision with passwords stored by GNOME Keyring simple
>> provider?
>
> No it wont't cause a collision since we have realmstring to
> differentiate. I verified it.
>
> Updated patch attached as per your other comments.
>
>
> ------------------------------------------------------------------------
>
> [[[
> Cache ssl client certificate passphrase.
>
> * subversion/libsvn_ra/ra_loader.c
> (svn_ra_open3): Load config options for storing passphrase from servers
> config file.
>
> * subversion/libsvn_subr/config_file.c
> (ensure_auth_dirs): Create new auth dir to store ssl client cert passphrase.
> (svn_config_ensure): Add doc for the new options in the servers file string.
>
> * subversion/libsvn_subr/cmdline.c
> (get_auth_simple_provider): Rename ...
> (get_auth_provider): ... Return providers based on the provider_type.
> (svn_cmdline_setup_auth_baton): If we have gnome keyring support get the
> corresponding ssl client cert passphrase provider.
>
> * subversion/libsvn_subr/ssl_client_cert_pw_providers.c
> (): Include some private headers. Define SVN_AUTH__AUTHFILE_PASSPHRASE_KEY,
> SVN_AUTH__AUTHFILE_PASSTYPE_KEY.
> (ssl_client_cert_pw_file_provider_baton_t): New baton for ssl client cert
> passphrase provider.
> (simple_passphrase_get): New function to get plaintext passphrase.
> (simple_passphrase_set): New function to store plaintext passphrase.
> (ssl_client_cert_pw_file_first_credentials): Move logic to new helper.
> (ssl_client_cert_pw_file_save_credentials): Move logic to new helper.
> (svn_auth__ssl_client_cert_pw_file_first_creds_helper): New helper function
> for ssl_client_cert_pw_file_first_credentials.
> (svn_auth__ssl_client_cert_pw_file_save_creds_helper): New helper function
> for ssl_client_cert_pw_file_save_credentials.
> (ssl_client_cert_pw_file_provider): Add provision for saving credentials.
> (svn_auth_get_ssl_client_cert_pw_file_provider2): New public API which has
> a prompt function now.
> (svn_auth_get_ssl_client_cert_pw_file_provider): Update API for the above.
>
> * subversion/libsvn_subr/prompt.c
> (plaintext_prompt_helper): New function which has the logic for plaintext
> promting functions.
> (svn_cmdline_auth_plaintext_prompt): Move logic to above function.
> (svn_cmdline_auth_plaintext_passphrase_prompt): New prompt function for
> plaintext passphrase prompt.
>
> * subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
> (gnome_keyring_ssl_client_cert_pw_first_creds): New function to get ssl
> client cert passphrase from encrypted credentials.
> (gnome_keyring_ssl_client_cert_pw_save_creds): New function to save
> encrypted ssl client cert passphrase.
> (gnome_keyring_ssl_client_cert_pw_provider): New baton.
> (svn_auth_get_gnome_keyring_ssl_client_cert_pw_provider): New public API for
> gnome keyring based ssl client cert passphrase storage and retrieval.
>
> * subversion/include/svn_config.h
> (SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP): New option to store ssl client
> cert passphrase.
> (SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSPHRASE): New option to store plaintext
> passphrase.
> (SVN_CONFIG_DEFAULT_OPTION_STORE_PASSPHRASE): New default option for storing
> passphrase set to 'yes'.
> (SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSPHRASE): New default option to
> store plaintext passphrase set to 'ask'.
>
> * subversion/include/svn_auth_dso.h
> (svn_auth_get_gnome_keyring_ssl_client_cert_pw_provider): New public API.
>
> * subversion/include/svn_cmdline.h
> (svn_cmdline_auth_plaintext_passphrase_prompt): New public API added to
> prompt for storing plaintext passphrases.
>
> * subversion/include/private/svn_auth_private.h
> (svn_auth__ssl_client_cert_pw_file_first_creds_helper): New private function.
> (svn_auth__ssl_client_cert_pw_file_save_creds_helper): New private function.
>
> * subversion/include/svn_auth.h
> (svn_auth_ssl_client_cert_pw_provider_func_t): Define function type for the
> provider.
> (svn_auth_plaintext_passphrase_prompt_func_t): New function prototype.
> (SVN_AUTH_PARAM_DONT_STORE_PASSPHRASE): New constant.
> (SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSPHRASE): New constant.
> (svn_auth_get_ssl_client_cert_pw_file_provider2): New public API.
>
> * subversion/libsvn_ra_neon/session.c
> (client_ssl_decrypt_cert): Call svn_auth_save_credentials to save the ssl
> client certificate passphrase.
>
> Patch by: stylesen
> ]]]
> Index: subversion/libsvn_ra/ra_loader.c
> ===================================================================
> --- subversion/libsvn_ra/ra_loader.c (revision 31532)
> +++ subversion/libsvn_ra/ra_loader.c (working copy)
> @@ -401,6 +401,9 @@
> svn_boolean_t store_auth_creds = SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS;
> const char *store_plaintext_passwords
> = SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS;
> + const char *store_plaintext_passphrase
> + = SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSPHRASE;
> + svn_boolean_t store_passphrase = SVN_CONFIG_DEFAULT_OPTION_STORE_PASSPHRASE;
>
> if (callbacks->auth_baton)
> {
> @@ -447,6 +450,16 @@
> SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS));
>
> SVN_ERR(svn_config_get_bool
> + (servers, &store_passphrase, SVN_CONFIG_SECTION_GLOBAL,
> + SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
> + store_passphrase));
> +
> + SVN_ERR(svn_config_get_yes_no_ask
> + (servers, &store_plaintext_passphrase, SVN_CONFIG_SECTION_GLOBAL,
> + SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSPHRASE,
> + SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSPHRASE));
> +
> + SVN_ERR(svn_config_get_bool
> (servers, &store_auth_creds, SVN_CONFIG_SECTION_GLOBAL,
> SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
> store_auth_creds));
> @@ -483,6 +496,16 @@
> (servers, &store_plaintext_passwords, server_group,
> SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
> store_plaintext_passwords));
> +
> + SVN_ERR(svn_config_get_bool
> + (servers, &store_passphrase,
> + server_group, SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
> + store_passphrase));
> +
> + SVN_ERR(svn_config_get_yes_no_ask
> + (servers, &store_plaintext_passphrase, server_group,
> + SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSPHRASE,
> + store_plaintext_passphrase));
> }
> #ifdef MUST_CHOOSE_DAV
> /* Now, which DAV-based RA method do we want to use today? */
> @@ -513,6 +536,14 @@
> SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS,
> store_plaintext_passwords);
>
> + if (! store_passphrase)
> + svn_auth_set_parameter(callbacks->auth_baton,
> + SVN_AUTH_PARAM_DONT_STORE_PASSPHRASE, "");
> +
> + svn_auth_set_parameter(callbacks->auth_baton,
> + SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSPHRASE,
> + store_plaintext_passphrase);
> +
> if (! store_auth_creds)
> svn_auth_set_parameter(callbacks->auth_baton,
> SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
> Index: subversion/libsvn_subr/config_file.c
> ===================================================================
> --- subversion/libsvn_subr/config_file.c (revision 31532)
> +++ subversion/libsvn_subr/config_file.c (working copy)
> @@ -497,6 +497,15 @@
> svn_error_clear(err);
> svn_error_clear(svn_io_dir_make(auth_subdir, APR_OS_DEFAULT, pool));
> }
> +
> + auth_subdir = svn_path_join_many(pool, auth_dir,
> + SVN_AUTH_CRED_SSL_CLIENT_CERT_PW, NULL);
> + err = svn_io_check_path(auth_subdir, &kind, pool);
> + if (err || kind == svn_node_none)
> + {
> + svn_error_clear(err);
> + svn_error_clear(svn_io_dir_make(auth_subdir, APR_OS_DEFAULT, pool));
> + }
> }
>
>
> @@ -757,7 +766,12 @@
> "### to disk in any way." NL
> "### store-plaintext-passwords Specifies whether passwords may" NL
> "### be cached on disk unencrypted." NL
> - "###" NL
> + "### store-ssl-client-cert-pp Specifies whether passphrase used" NL
> + "### to authenticate against a client" NL
> + "### certificate may be cached to disk" NL
> + "### in any way" NL
> + "### store-plaintext-passphrase Specifies whether passphrases may" NL
> + "### be cached on disk unencrypted." NL
> "### store-auth-creds Specifies whether any auth info" NL
> "### (passwords as well as server certs)"
> NL
> @@ -780,6 +794,24 @@
> "### this option has no effect if either 'store-passwords' or " NL
> "### 'store-auth-creds' is set to 'no'." NL
> "###" NL
> + "### Set store-ssl-client-cert-pp to 'no' to avoid storing ssl" NL
> + "### client certificate passphrase in the auth/ area of your" NL
> + "### config directory. It defaults to 'yes', but Subversion will" NL
> + "### never save your passphrase to disk in plaintext unless you tell"NL
> + "### it to." NL
> + "### Note that this option only prevents saving of *new* passphrase;"NL
> + "### it doesn't invalidate existing passphrase. (To do that, remove" NL
> + "### the cache files by hand as described in the Subversion book.)" NL
> + "###" NL
> + "### Set store-plaintext-passphrase to 'no' to avoid storing" NL
> + "### passphrase in unencrypted form in the auth/ area of your config"NL
> + "### directory. Set it to 'yes' to allow Subversion to store" NL
> + "### unencrypted passphrase in the auth/ area. The default is" NL
> + "### 'ask', which means that Subversion will ask you before" NL
> + "### saving a passphrase to disk in unencrypted form. Note that" NL
> + "### this option has no effect if either 'store-passphrase' or " NL
> + "### 'store-auth-creds' is set to 'no'." NL
> + "###" NL
> "### Set store-auth-creds to 'no' to avoid storing any Subversion" NL
> "### credentials in the auth/ area of your config directory." NL
> "### Note that this includes SSL server certificates." NL
> Index: subversion/libsvn_subr/cmdline.c
> ===================================================================
> --- subversion/libsvn_subr/cmdline.c (revision 31532)
> +++ subversion/libsvn_subr/cmdline.c (working copy)
> @@ -355,11 +355,12 @@
> }
>
> #if defined(SVN_HAVE_KWALLET) || defined(SVN_HAVE_GNOME_KEYRING)
> -/* Dynamically load authentication simple provider. */
> +/* Dynamically load authentication provider. */
> static svn_boolean_t
> -get_auth_simple_provider(svn_auth_provider_object_t **provider,
> - const char *provider_name,
> - apr_pool_t *pool)
> +get_auth_provider(svn_auth_provider_object_t **provider,
> + const char *provider_name,
> + const char *provider_type,
> + apr_pool_t *pool)
> {
> apr_dso_handle_t *dso;
> apr_dso_handle_sym_t symbol;
> @@ -372,8 +373,9 @@
> provider_name,
> SVN_VER_MAJOR);
> funcname = apr_psprintf(pool,
> - "svn_auth_get_%s_simple_provider",
> - provider_name);
> + "svn_auth_get_%s_%s_provider",
> + provider_name, provider_type);
> +
> err = svn_dso_load(&dso, libname);
> if (err == SVN_NO_ERROR)
> {
> @@ -381,10 +383,20 @@
> {
> if (! apr_dso_sym(&symbol, dso, funcname))
> {
> - svn_auth_simple_provider_func_t func;
> - func = (svn_auth_simple_provider_func_t) symbol;
> - func(provider, pool);
> - ret = TRUE;
> + if (strcmp(provider_type, "simple") == 0)
> + {
> + svn_auth_simple_provider_func_t func;
> + func = (svn_auth_simple_provider_func_t) symbol;
> + func(provider, pool);
> + ret = TRUE;
> + }
> + else if (strcmp(provider_type, "ssl_client_cert_pw") == 0)
> + {
> + svn_auth_ssl_client_cert_pw_provider_func_t func;
> + func = (svn_auth_ssl_client_cert_pw_provider_func_t) symbol;
> + func(provider, pool);
> + ret = TRUE;
> + }
> }
> }
> }
> @@ -464,10 +476,16 @@
> if (apr_strnatcmp(password_store, "gnome-keyring") == 0)
> {
> #ifdef SVN_HAVE_GNOME_KEYRING
> - if (get_auth_simple_provider(&provider, "gnome_keyring", pool))
> + if (get_auth_provider(&provider, "gnome_keyring", "simple", pool))
> {
> APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
> }
> + if (get_auth_provider(&provider, "gnome_keyring",
> + "ssl_client_cert_pw", pool))
> + {
> + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *)
> + = provider;
> + }
> #endif
> continue;
> }
> @@ -475,7 +493,7 @@
> if (apr_strnatcmp(password_store, "kwallet") == 0)
> {
> #ifdef SVN_HAVE_KWALLET
> - if (get_auth_simple_provider(&provider, "kwallet", pool))
> + if (get_auth_provider(&provider, "kwallet", pool))
> {
> APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
> }
> @@ -490,10 +508,8 @@
>
> if (non_interactive == FALSE)
> {
> - /* This provider is odd in that it isn't a prompting provider in
> - the classic sense. That is, it doesn't need to prompt in
> - order to get creds, but it *does* need to prompt the user
> - regarding the *cache storage* of creds. */
> + /* This provider doesn't prompt the user in order to get creds.
> + * It prompts the user regarding the caching of creds. */
> svn_auth_get_simple_provider2(&provider,
> svn_cmdline_auth_plaintext_prompt,
> pb, pool);
> @@ -515,7 +531,20 @@
> APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
> svn_auth_get_ssl_client_cert_file_provider(&provider, pool);
> APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
> - svn_auth_get_ssl_client_cert_pw_file_provider(&provider, pool);
> +
> + if (non_interactive == FALSE)
> + {
> + /* This provider doesn't prompt the user in order to get creds.
> + * It prompts the user regarding the caching of creds. */
> + svn_auth_get_ssl_client_cert_pw_file_provider2
> + (&provider, svn_cmdline_auth_plaintext_passphrase_prompt,
> + pb, pool);
> + }
> + else
> + {
> + svn_auth_get_ssl_client_cert_pw_file_provider2(&provider, NULL, NULL,
> + pool);
> + }
> APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
>
> if (non_interactive == FALSE)
> Index: subversion/libsvn_subr/ssl_client_cert_pw_providers.c
> ===================================================================
> --- subversion/libsvn_subr/ssl_client_cert_pw_providers.c (revision 31532)
> +++ subversion/libsvn_subr/ssl_client_cert_pw_providers.c (working copy)
> @@ -28,31 +28,112 @@
> #include "svn_error.h"
> #include "svn_config.h"
>
> +#include "private/svn_auth_private.h"
> +
> +#include "svn_private_config.h"
>
> /*-----------------------------------------------------------------------*/
> /* File provider */
> /*-----------------------------------------------------------------------*/
>
> -/* retrieve and load a password for a client certificate from servers file */
> -static svn_error_t *
> -ssl_client_cert_pw_file_first_credentials(void **credentials_p,
> - void **iter_baton,
> - void *provider_baton,
> - apr_hash_t *parameters,
> - const char *realmstring,
> - apr_pool_t *pool)
> +/* The keys that will be stored on disk */
> +#define SVN_AUTH__AUTHFILE_PASSPHRASE_KEY "passphrase"
> +#define SVN_AUTH__AUTHFILE_PASSTYPE_KEY "passtype"
> +
> +/* Baton type for the ssl client cert passphrase provider. */
> +typedef struct
> {
> + svn_auth_plaintext_passphrase_prompt_func_t plaintext_passphrase_prompt_func;
> + void *prompt_baton;
> + /* We cache the user's answer to the plaintext prompt, keyed
> + * by realm, in case we'll be called multiple times for the
> + * same realm. */
> + apr_hash_t *plaintext_answers;
> +} ssl_client_cert_pw_file_provider_baton_t;
> +
> +/* Implementation of svn_auth__password_get_t that retrieves
> + the plaintext passphrase from CREDS. */
> +static svn_boolean_t
> +simple_passphrase_get(const char **passphrase,
> + apr_hash_t *creds,
> + const char *realmstring,
> + const char *username,
> + svn_boolean_t non_interactive,
> + apr_pool_t *pool)
> +{
> + svn_string_t *str;
> + str = apr_hash_get(creds, SVN_AUTH__AUTHFILE_PASSPHRASE_KEY,
> + APR_HASH_KEY_STRING);
> + if (str && str->data)
> + {
> + *passphrase = str->data;
> + return TRUE;
> + }
> + return FALSE;
> +}
> +
> +/* Implementation of svn_auth__password_set_t that stores
> + the plaintext passphrase in CREDS. */
> +static svn_boolean_t
> +simple_passphrase_set(apr_hash_t *creds,
> + const char *realmstring,
> + const char *username,
> + const char *passphrase,
> + svn_boolean_t non_interactive,
> + apr_pool_t *pool)
> +{
> + apr_hash_set(creds, SVN_AUTH__AUTHFILE_PASSPHRASE_KEY, APR_HASH_KEY_STRING,
> + svn_string_create(passphrase, pool));
> + return TRUE;
> +}
> +
> +/* retrieve and load a password for a client certificate from servers file,
> + * else from the auth/ cache. */
> +svn_error_t *
> +svn_auth__ssl_client_cert_pw_file_first_creds_helper
> + (void **credentials_p,
> + void **iter_baton,
> + void *provider_baton,
> + apr_hash_t *parameters,
> + const char *realmstring,
> + svn_auth__password_get_t passphrase_get,
> + const char *passtype,
> + apr_pool_t *pool)
> +{
> svn_config_t *cfg = apr_hash_get(parameters,
> SVN_AUTH_PARAM_CONFIG,
> APR_HASH_KEY_STRING);
> const char *server_group = apr_hash_get(parameters,
> SVN_AUTH_PARAM_SERVER_GROUP,
> APR_HASH_KEY_STRING);
> -
> + svn_boolean_t non_interactive = apr_hash_get(parameters,
> + SVN_AUTH_PARAM_NON_INTERACTIVE,
> + APR_HASH_KEY_STRING) != NULL;
> const char *password =
> svn_config_get_server_setting(cfg, server_group,
> SVN_CONFIG_OPTION_SSL_CLIENT_CERT_PASSWORD,
> NULL);
> + if (! password)
> + {
> + svn_error_t *err;
> + apr_hash_t *creds_hash = NULL;
> + const char *config_dir = apr_hash_get(parameters,
> + SVN_AUTH_PARAM_CONFIG_DIR,
> + APR_HASH_KEY_STRING);
> +
> + /* Try to load passphrase from the auth/ cache. */
> + err = svn_config_read_auth_data(&creds_hash,
> + SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
> + realmstring, config_dir, pool);
> + svn_error_clear(err);
> + if (! err && creds_hash)
> + {
> + if (!passphrase_get(&password, creds_hash, realmstring,
> + NULL, non_interactive, pool))
> + password = NULL;
> + }
> + }
> +
> if (password)
> {
> svn_auth_cred_ssl_client_cert_pw_t *cred
> @@ -67,23 +148,244 @@
> }
>
>
> +/* Save passphrase for a client certificate in auth/ cache */
> +svn_error_t *
> +svn_auth__ssl_client_cert_pw_file_save_creds_helper
> + (svn_boolean_t *saved,
> + void *credentials,
> + void *provider_baton,
> + apr_hash_t *parameters,
> + const char *realmstring,
> + svn_auth__password_set_t passphrase_set,
> + const char *passtype,
> + apr_pool_t *pool)
> +{
> + svn_auth_cred_ssl_client_cert_pw_t *creds = credentials;
> + apr_hash_t *creds_hash = NULL;
> + const char *config_dir;
> + svn_error_t *err;
> + svn_boolean_t dont_store_passphrase =
> + apr_hash_get(parameters,
> + SVN_AUTH_PARAM_DONT_STORE_PASSPHRASE,
> + APR_HASH_KEY_STRING) != NULL;
> + const char *store_plaintext_passphrase =
> + apr_hash_get(parameters,
> + SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSPHRASE,
> + APR_HASH_KEY_STRING);
> + svn_boolean_t non_interactive = apr_hash_get(parameters,
> + SVN_AUTH_PARAM_NON_INTERACTIVE,
> + APR_HASH_KEY_STRING) != NULL;
> + ssl_client_cert_pw_file_provider_baton_t *b =
> + (ssl_client_cert_pw_file_provider_baton_t *)provider_baton;
> +
> + svn_boolean_t no_auth_cache =
> + (! creds->may_save) || (apr_hash_get(parameters,
> + SVN_AUTH_PARAM_NO_AUTH_CACHE,
> + APR_HASH_KEY_STRING) != NULL);
> +
> + *saved = FALSE;
> +
> + if (no_auth_cache)
> + return SVN_NO_ERROR;
> +
> + config_dir = apr_hash_get(parameters,
> + SVN_AUTH_PARAM_CONFIG_DIR,
> + APR_HASH_KEY_STRING);
> + creds_hash = apr_hash_make(pool);
> +
> + /* Don't store passphrase in any form if the user has told
> + * us not to do so. */
> + if (! dont_store_passphrase)
> + {
> + svn_boolean_t may_save_passphrase = FALSE;
> +
> + /* If the passphrase is going to be stored encrypted, go right
> + * ahead and store it to disk. Else determine whether saving
> + * in plaintext is OK. */
> + if (strcmp(passtype, SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE) == 0)
> + {
> + may_save_passphrase = TRUE;
> + }
> + else
> + {
> + if (svn_cstring_casecmp(store_plaintext_passphrase,
> + SVN_CONFIG_ASK) == 0)
> + {
> + if (non_interactive)
> + /* In non-interactive mode, the default behaviour is
> + * to not store the passphrase */
> + may_save_passphrase = FALSE;
> + else if (b->plaintext_passphrase_prompt_func)
> + {
> + /* We're interactive, and the client provided a
> + * prompt callback. So we can ask the user.
> + *
> + * Check for a cached answer before prompting. */
> + svn_boolean_t *cached_answer;
> + cached_answer = apr_hash_get(b->plaintext_answers,
> + realmstring,
> + APR_HASH_KEY_STRING);
> + if (cached_answer)
> + may_save_passphrase = *cached_answer;
> + else
> + {
> + /* Nothing cached for this realm, prompt the user. */
> + SVN_ERR((*b->plaintext_passphrase_prompt_func)
> + (&may_save_passphrase,
> + realmstring,
> + b->prompt_baton,
> + pool));
> +
> + /* Cache the user's answer in case we're called again
> + * for the same realm.
> + *
> + * XXX: Hopefully, our caller has passed us
> + * a pool that survives across RA sessions!
> + * We use that pool to cache user answers, and
> + * we may be called again for the same realm when the
> + * current RA session is reparented, or when a different
> + * RA session using the same realm is opened.
> + * If the pool does not survive until then, caching
> + * won't work, and for some reason the call to
> + * apr_hash_set() below may even end up crashing in
> + * apr_palloc().
> + */
> + cached_answer = apr_palloc(pool, sizeof(svn_boolean_t));
> + *cached_answer = may_save_passphrase;
> + apr_hash_set(b->plaintext_answers, realmstring,
> + APR_HASH_KEY_STRING, cached_answer);
> + }
> + }
> + else
> + {
> + may_save_passphrase = FALSE;
> + }
> + }
> + else if (svn_cstring_casecmp(store_plaintext_passphrase,
> + SVN_CONFIG_FALSE) == 0)
> + {
> + may_save_passphrase = FALSE;
> + }
> + else if (svn_cstring_casecmp(store_plaintext_passphrase,
> + SVN_CONFIG_TRUE) == 0)
> + {
> + may_save_passphrase = TRUE;
> + }
> + else
> + {
> + return svn_error_createf
> + (SVN_ERR_RA_DAV_INVALID_CONFIG_VALUE, NULL,
> + _("Config error: invalid value '%s' for option '%s'"),
> + store_plaintext_passphrase,
> + SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSPHRASE);
> + }
> + }
> +
> + if (may_save_passphrase)
> + {
> + *saved = passphrase_set(creds_hash, realmstring,
> + NULL, creds->password,
> + non_interactive, pool);
> +
> + if (*saved && passtype)
> + /* Store the passphrase type with the auth data, so that we
> + know which provider owns the password. */
> + apr_hash_set(creds_hash, SVN_AUTH__AUTHFILE_PASSTYPE_KEY,
> + APR_HASH_KEY_STRING,
> + svn_string_create(passtype, pool));
> +
> + /* Save credentials to disk. */
> + err = svn_config_write_auth_data(creds_hash,
> + SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
> + realmstring, config_dir, pool);
> + svn_error_clear(err);
> + *saved = ! err;
> + }
> + }
> +
> + return SVN_NO_ERROR;
> +}
> +
> +
> +/* Get cached (unencrypted) credentials from the ssl client cert password
> + * provider's cache. */
> +static svn_error_t *
> +ssl_client_cert_pw_file_first_credentials(void **credentials,
> + void **iter_baton,
> + void *provider_baton,
> + apr_hash_t *parameters,
> + const char *realmstring,
> + apr_pool_t *pool)
> +{
> + return svn_auth__ssl_client_cert_pw_file_first_creds_helper
> + (credentials,
> + iter_baton,
> + provider_baton,
> + parameters,
> + realmstring,
> + simple_passphrase_get,
> + SVN_AUTH__SIMPLE_PASSWORD_TYPE,
> + pool);
> +}
> +
> +
> +/* Save (unencrypted) credentials to the ssl client cert password provider's
> + * cache. */
> +static svn_error_t *
> +ssl_client_cert_pw_file_save_credentials(svn_boolean_t *saved,
> + void *credentials,
> + void *provider_baton,
> + apr_hash_t *parameters,
> + const char *realmstring,
> + apr_pool_t *pool)
> +{
> + return svn_auth__ssl_client_cert_pw_file_save_creds_helper
> + (saved, credentials,
> + provider_baton,
> + parameters,
> + realmstring,
> + simple_passphrase_set,
> + SVN_AUTH__SIMPLE_PASSWORD_TYPE,
> + pool);
> +}
> +
> static const svn_auth_provider_t ssl_client_cert_pw_file_provider = {
> SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
> ssl_client_cert_pw_file_first_credentials,
> NULL,
> - NULL
> + ssl_client_cert_pw_file_save_credentials
> };
>
>
> /*** Public API to SSL file providers. ***/
> -void svn_auth_get_ssl_client_cert_pw_file_provider
> - (svn_auth_provider_object_t **provider, apr_pool_t *pool)
> +void
> +svn_auth_get_ssl_client_cert_pw_file_provider2
> + (svn_auth_provider_object_t **provider,
> + svn_auth_plaintext_passphrase_prompt_func_t plaintext_passphrase_prompt_func,
> + void* prompt_baton,
> + apr_pool_t *pool)
> {
> svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
> + ssl_client_cert_pw_file_provider_baton_t *pb = apr_pcalloc(pool,
> + sizeof(*pb));
> +
> + pb->plaintext_passphrase_prompt_func = plaintext_passphrase_prompt_func;
> + pb->prompt_baton = prompt_baton;
> + pb->plaintext_answers = apr_hash_make(pool);
> +
> po->vtable = &ssl_client_cert_pw_file_provider;
> + po->provider_baton = pb;
> *provider = po;
> }
>
> +void
> +svn_auth_get_ssl_client_cert_pw_file_provider
> + (svn_auth_provider_object_t **provider,
> + apr_pool_t *pool)
> +{
> + svn_auth_get_ssl_client_cert_pw_file_provider2(provider, NULL, NULL, pool);
> +}
> +
>
> /*-----------------------------------------------------------------------*/
> /* Prompt provider */
> Index: subversion/libsvn_subr/prompt.c
> ===================================================================
> --- subversion/libsvn_subr/prompt.c (revision 31532)
> +++ subversion/libsvn_subr/prompt.c (working copy)
> @@ -379,37 +379,25 @@
> return SVN_NO_ERROR;
> }
>
> -/* This implements 'svn_auth_plaintext_prompt_func_t'. */
> -svn_error_t *
> -svn_cmdline_auth_plaintext_prompt(svn_boolean_t *may_save_plaintext,
> - const char *realmstring,
> - void *baton,
> - apr_pool_t *pool)
> +/* This is a helper for plaintext prompt functions. */
> +static svn_error_t *
> +plaintext_prompt_helper(svn_boolean_t *may_save_plaintext,
> + const char *realmstring,
> + const char *prompt_string,
> + const char *prompt_text,
> + void *baton,
> + apr_pool_t *pool)
> {
> const char *answer = NULL;
> svn_boolean_t answered = FALSE;
> - const char *prompt_string = _("Store password unencrypted (yes/no)? ");
> svn_cmdline_prompt_baton2_t *pb = baton;
> const char *config_path;
>
> SVN_ERR(svn_config_get_user_config_path(&config_path, pb->config_dir,
> SVN_CONFIG_CATEGORY_SERVERS, pool));
>
> - SVN_ERR(svn_cmdline_fprintf(stderr, pool,
> - _("-----------------------------------------------------------------------\n"
> - "ATTENTION! Your password for authentication realm:\n"
> - "\n"
> - " %s\n"
> - "\n"
> - "can only be stored to disk unencrypted! You are advised to configure\n"
> - "your system so that Subversion can store passwords encrypted, if\n"
> - "possible. See the documentation for details.\n"
> - "\n"
> - "You can avoid future appearances of this warning by setting the value\n"
> - "of the 'store-plaintext-passwords' option to either 'yes' or 'no' in\n"
> - "'%s'.\n"
> - "-----------------------------------------------------------------------\n"
> - ), realmstring, config_path));
> + SVN_ERR(svn_cmdline_fprintf(stderr, pool, prompt_text, realmstring,
> + config_path));
>
> do
> {
> @@ -443,6 +431,66 @@
> return SVN_NO_ERROR;
> }
>
> +/* This implements 'svn_auth_plaintext_prompt_func_t'. */
> +svn_error_t *
> +svn_cmdline_auth_plaintext_prompt(svn_boolean_t *may_save_plaintext,
> + const char *realmstring,
> + void *baton,
> + apr_pool_t *pool)
> +{
> + const char *prompt_string = _("Store password unencrypted (yes/no)? ");
> + const char *prompt_text =
> + _("-----------------------------------------------------------------------\n"
> + "ATTENTION! Your password for authentication realm:\n"
> + "\n"
> + " %s\n"
> + "\n"
> + "can only be stored to disk unencrypted! You are advised to configure\n"
> + "your system so that Subversion can store passwords encrypted, if\n"
> + "possible. See the documentation for details.\n"
> + "\n"
> + "You can avoid future appearances of this warning by setting the value\n"
> + "of the 'store-plaintext-passwords' option to either 'yes' or 'no' in\n"
> + "'%s'.\n"
> + "-----------------------------------------------------------------------\n"
> + );
> +
> + SVN_ERR(plaintext_prompt_helper(may_save_plaintext, realmstring,
> + prompt_string, prompt_text, baton,
> + pool));
> + return SVN_NO_ERROR;
> +}
> +
> +/* This implements 'svn_auth_plaintext_passphrase_prompt_func_t'. */
> +svn_error_t *
> +svn_cmdline_auth_plaintext_passphrase_prompt(svn_boolean_t *may_save_plaintext,
> + const char *realmstring,
> + void *baton,
> + apr_pool_t *pool)
> +{
> + const char *prompt_string = _("Store passphrase unencrypted (yes/no)? ");
> + const char *prompt_text =
> + _("-----------------------------------------------------------------------\n"
> + "ATTENTION! Your passphrase for client certificate:\n"
> + "\n"
> + " %s\n"
> + "\n"
> + "can only be stored to disk unencrypted! You are advised to configure\n"
> + "your system so that Subversion can store passphrase encrypted, if\n"
> + "possible. See the documentation for details.\n"
> + "\n"
> + "You can avoid future appearances of this warning by setting the value\n"
> + "of the 'store-plaintext-passphrase' option to either 'yes' or 'no' in\n"
> + "'%s'.\n"
> + "-----------------------------------------------------------------------\n"
> + );
> +
> + SVN_ERR(plaintext_prompt_helper(may_save_plaintext, realmstring,
> + prompt_string, prompt_text, baton,
> + pool));
> + return SVN_NO_ERROR;
> +}
> +
>
> /** Generic prompting. **/
>
> Index: subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
> ===================================================================
> --- subversion/libsvn_auth_gnome_keyring/gnome_keyring.c (revision 31532)
> +++ subversion/libsvn_auth_gnome_keyring/gnome_keyring.c (working copy)
> @@ -192,3 +192,60 @@
>
> gnome_keyring_init();
> }
> +
> +/* Get cached encrypted credentials from the ssl client cert password
> + * provider's cache. */
> +static svn_error_t *
> +gnome_keyring_ssl_client_cert_pw_first_creds(void **credentials,
> + void **iter_baton,
> + void *provider_baton,
> + apr_hash_t *parameters,
> + const char *realmstring,
> + apr_pool_t *pool)
> +{
> + return svn_auth__ssl_client_cert_pw_file_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 ssl client cert password provider's
> + * cache. */
> +static svn_error_t *
> +gnome_keyring_ssl_client_cert_pw_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__ssl_client_cert_pw_file_save_creds_helper
> + (saved, credentials,
> + provider_baton, parameters,
> + realmstring,
> + gnome_keyring_password_set,
> + SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
> + pool);
> +}
> +
> +static const svn_auth_provider_t gnome_keyring_ssl_client_cert_pw_provider = {
> + SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
> + gnome_keyring_ssl_client_cert_pw_first_creds,
> + NULL,
> + gnome_keyring_ssl_client_cert_pw_save_creds
> +};
> +
> +/* Public API */
> +void
> +svn_auth_get_gnome_keyring_ssl_client_cert_pw_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_ssl_client_cert_pw_provider;
> + *provider = po;
> +}
> Index: subversion/include/svn_config.h
> ===================================================================
> --- subversion/include/svn_config.h (revision 31532)
> +++ subversion/include/svn_config.h (working copy)
> @@ -77,6 +77,9 @@
> #define SVN_CONFIG_OPTION_STORE_PASSWORDS "store-passwords"
> #define SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS "store-plaintext-passwords"
> #define SVN_CONFIG_OPTION_STORE_AUTH_CREDS "store-auth-creds"
> +#define SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP "store-ssl-client-cert-pp"
> +#define SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSPHRASE \
> + "store-plaintext-passphrase"
>
> #define SVN_CONFIG_CATEGORY_CONFIG "config"
> #define SVN_CONFIG_SECTION_AUTH "auth"
> @@ -146,9 +149,11 @@
> /* Default values for some options. Should be passed as default values
> * to svn_config_get and friends, instead of hard-coding the defaults in
> * multiple places. */
> -#define SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS TRUE
> -#define SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS SVN_CONFIG_ASK
> -#define SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS TRUE
> +#define SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS TRUE
> +#define SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS SVN_CONFIG_ASK
> +#define SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS TRUE
> +#define SVN_CONFIG_DEFAULT_OPTION_STORE_PASSPHRASE TRUE
> +#define SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSPHRASE SVN_CONFIG_ASK
>
> /** Read configuration information from the standard sources and merge it
> * into the hash @a *cfg_hash. If @a config_dir is not NULL it specifies a
> Index: subversion/include/svn_auth_dso.h
> ===================================================================
> --- subversion/include/svn_auth_dso.h (revision 31532)
> +++ subversion/include/svn_auth_dso.h (working copy)
> @@ -51,6 +51,25 @@
>
> /**
> * Create and return @a *provider, an authentication provider of type @c
> + * svn_auth_cred_ssl_client_cert_pw_t that gets/sets information from the
> + * user's ~/.subversion configuration directory. Allocate @a *provider in
> + * @a pool.
> + *
> + * This is like svn_client_get_ssl_client_cert_pw_file_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_ssl_client_cert_pw_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.
> Index: subversion/include/svn_cmdline.h
> ===================================================================
> --- subversion/include/svn_cmdline.h (revision 31532)
> +++ subversion/include/svn_cmdline.h (working copy)
> @@ -277,6 +277,17 @@
> void *baton,
> apr_pool_t *pool);
>
> +/** An implementation of @c svn_auth_plaintext_passphrase_prompt_func_t that
> + * prompts the user whether storing unencypted passphrase to disk is OK.
> + *
> + * @since New in 1.6.
> + */
> +svn_error_t *
> +svn_cmdline_auth_plaintext_passphrase_prompt(svn_boolean_t *may_save_plaintext,
> + const char *realmstring,
> + void *baton,
> + apr_pool_t *pool);
> +
> /** Initialize auth baton @a ab with the standard set of authentication
> * providers used by the command line client. @a non_interactive,
> * @a username, @a password, @a config_dir, and @a no_auth_cache are the
> Index: subversion/include/private/svn_auth_private.h
> ===================================================================
> --- subversion/include/private/svn_auth_private.h (revision 31532)
> +++ subversion/include/private/svn_auth_private.h (working copy)
> @@ -93,6 +93,38 @@
> const char *passtype,
> apr_pool_t *pool);
>
> +/* Common implementation for ssl_client_cert_pw_file_first_credentials.
> + Uses PARAMETERS, REALMSTRING and the ssl client passphrase auth provider's
> + passphrase cache to fill the CREDENTIALS. PASSPHRASE_GET is used to obtain
> + the passphrase value. PASSTYPE identifies the type of the cached passphrase.
> + CREDENTIALS are allocated from POOL. */
> +svn_error_t *
> +svn_auth__ssl_client_cert_pw_file_first_creds_helper
> + (void **credentials,
> + void **iter_baton,
> + void *provider_baton,
> + apr_hash_t *parameters,
> + const char *realmstring,
> + svn_auth__password_get_t passphrase_get,
> + const char *passtype,
> + apr_pool_t *pool);
> +
> +/* Common implementation for ssl_client_cert_pw_file_save_credentials and
> + Uses PARAMETERS and REALMSTRING to save a set of CREDENTIALS to the ssl
> + client cert auth provider's passphrase cache. PASSPHRASE_SET is used to
> + store the passphrase. PASSTYPE identifies the type of the cached passphrase.
> + Allocates from POOL. */
> +svn_error_t *
> +svn_auth__ssl_client_cert_pw_file_save_creds_helper
> + (svn_boolean_t *saved,
> + void *credentials,
> + void *provider_baton,
> + apr_hash_t *parameters,
> + const char *realmstring,
> + svn_auth__password_set_t passphrase_set,
> + const char *passtype,
> + apr_pool_t *pool);
> +
> #ifdef __cplusplus
> }
> #endif /* __cplusplus */
> Index: subversion/include/svn_auth.h
> ===================================================================
> --- subversion/include/svn_auth.h (revision 31532)
> +++ subversion/include/svn_auth.h (working copy)
> @@ -238,6 +238,11 @@
> } svn_auth_cred_ssl_client_cert_t;
>
>
> +/** A function returning an SSL client certificate passphrase provider. */
> +typedef void (*svn_auth_ssl_client_cert_pw_provider_func_t)
> + (svn_auth_provider_object_t **provider,
> + apr_pool_t *pool);
> +
> /** SSL client certificate passphrase credential type.
> *
> * @note The realmstring used with this credential type must be a name that
> @@ -500,6 +505,38 @@
> void *baton,
> apr_pool_t *pool);
>
> +/** Called only by providers which save passphrase unencrypted.
> + * In this callback, clients should ask the user whether storing
> + * a passphrase for the realm identified by @a realmstring to disk
> + * in plaintext is allowed.
> + *
> + * The answer is returned in @a *may_save_plaintext.
> + * @a baton is an implementation-specific closure.
> + * All allocations should be done in @a pool.
> + *
> + * This callback is called only once per authentication realm,
> + * not once per RA session. This means that clients implementing
> + * this callback must make sure that the pool passed to any
> + * implementation of save_credentials (part of svn_auth_provider_t)
> + * survives across RA sessions.
> + *
> + * If this callback is NULL it is not called.
> + * Client developers are highly encouraged to provide this callback
> + * to ensure their users are made aware of the fact that their passphrase
> + * is going to be stored unencrypted.
> + *
> + * Clients can however set the callback to NULL and set
> + * SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSPHRASE to SVN_CONFIG_FALSE or
> + * SVN_CONFIG_TRUE to enforce a certain behaviour.
> + *
> + * @since New in 1.6
> + */
> +typedef svn_error_t *(*svn_auth_plaintext_passphrase_prompt_func_t)
> + (svn_boolean_t *may_save_plaintext,
> + const char *realmstring,
> + void *baton,
> + apr_pool_t *pool);
> +
>
> /** Initialize an authentication system.
> *
> @@ -572,6 +609,18 @@
> #define SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS SVN_AUTH_PARAM_PREFIX \
> "store-plaintext-passwords"
>
> +/** @brief The application doesn't want any providers to save passphrase
> + * to disk. Property value is irrelevant; only property's existence
> + * matters. */
> +#define SVN_AUTH_PARAM_DONT_STORE_PASSPHRASE SVN_AUTH_PARAM_PREFIX \
> + "dont-store-passphrase"
> +
> +/** @brief Indicates whether providers may save passphrase to disk in
> + * plaintext. Property value can be either SVN_CONFIG_TRUE,
> + * SVN_CONFIG_FALSE, or SVN_CONFIG_ASK. */
> +#define SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSPHRASE SVN_AUTH_PARAM_PREFIX \
> + "store-plaintext-passphrase"
> +
> /** @brief The application doesn't want any providers to save credentials
> * to disk. Property value is irrelevant; only property's existence
> * matters. */
> @@ -832,12 +881,29 @@
>
>
> /** Create and return @a *provider, an authentication provider of type @c
> - * svn_auth_cred_ssl_client_cert_pw_t, allocated in @a pool.
> + * svn_auth_cred_ssl_client_cert_pw_t that gets/sets information from the user's
> + * ~/.subversion configuration directory.
> *
> - * @a *provider retrieves its credentials from the configuration
> - * mechanism. The returned credential is used when a loaded client
> - * certificate is protected by a passphrase.
> + * If the provider is going to save the passphrase unencrypted,
> + * it calls @a plaintext_passphrase_prompt_func before saving the
> + * passphrase.
> *
> + * @a prompt_baton is passed to @a plaintext_passphrase_prompt_func.
> + *
> + * Allocate @a *provider in @a pool.
> + *
> + * @since New in 1.6.
> + */
> +void svn_auth_get_ssl_client_cert_pw_file_provider2
> + (svn_auth_provider_object_t **provider,
> + svn_auth_plaintext_passphrase_prompt_func_t plaintext_passphrase_prompt_func,
> + void* prompt_baton,
> + apr_pool_t *pool);
> +
> +/** Like svn_auth_get_simple_provider2, but without the ability to
> + * call the svn_auth_plaintext_passphrase_prompt_func_t callback.
> + *
> + * @deprecated Provided for backwards compatibility with the 1.5 API.
> * @since New in 1.4.
> */
> void svn_auth_get_ssl_client_cert_pw_file_provider
> Index: subversion/libsvn_ra_neon/session.c
> ===================================================================
> --- subversion/libsvn_ra_neon/session.c (revision 31532)
> +++ subversion/libsvn_ra_neon/session.c (working copy)
> @@ -290,6 +290,10 @@
>
> if (ne_ssl_clicert_decrypt(clicert, pw_creds->password) == 0)
> {
> + error = svn_auth_save_credentials(state, pool);
> + if (error)
> + svn_error_clear(error);
> +
> /* Success */
> ok = TRUE;
> break;
>
>
>
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
> For additional commands, e-mail: dev-help_at_subversion.tigris.org
--
Senthil Kumaran S
http://www.stylesen.org/
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-06-17 13:17:41 CEST