Author: cmpilato Date: Fri Apr 5 20:14:01 2013 New Revision: 1465112 URL: http://svn.apache.org/r1465112 Log: Allow credentials cleanup even when the 'no-auth-cache' option is set. If someone doesn't want to fiddle with their auth cache, they shouldn't call this function. Also, don't send credentials through the cleanup callback which are not ultimately managed by Subversion (because they live in a third-party security provider).
* subversion/libsvn_subr/simple_providers.c (svn_auth__simple_cleanup_walk): Allow cleanup even when 'no-auth-cache' flag is set. Don't allow cleanup of credentials which are housed in third-party providers. Finally, stop passing a cred kind value as a provider. Strictly speaking, we don't even have a name for our proprietary Subversion caching provider, but there's at least some degree of precedent for using the "simple" password type string, so run with that for now. Modified: subversion/trunk/subversion/libsvn_subr/simple_providers.c Modified: subversion/trunk/subversion/libsvn_subr/simple_providers.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/simple_providers.c?rev=1465112&r1=1465111&r2=1465112&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_subr/simple_providers.c (original) +++ subversion/trunk/subversion/libsvn_subr/simple_providers.c Fri Apr 5 20:14:01 2013 @@ -519,7 +519,6 @@ svn_auth__simple_cleanup_walk(svn_auth_b apr_pool_t *scratch_pool) { const char *config_dir; - svn_boolean_t no_auth_cache; int i; apr_pool_t *iterpool; @@ -534,15 +533,13 @@ svn_auth__simple_cleanup_walk(svn_auth_b }; config_dir = svn_auth_get_parameter(baton, SVN_AUTH_PARAM_CONFIG_DIR); - no_auth_cache = (svn_auth_get_parameter(baton, SVN_AUTH_PARAM_NO_AUTH_CACHE) - != NULL); - - if ((! config_dir) || no_auth_cache) + if (! config_dir) { /* Can't locate the cache to clear */ return SVN_NO_ERROR; } + iterpool = svn_pool_create(scratch_pool); for (i = 0; cred_kinds[i]; i++) { @@ -561,7 +558,6 @@ svn_auth__simple_cleanup_walk(svn_auth_b dir_path = svn_dirent_dirname(item_path, iterpool); err = svn_io_get_dirents3(&nodes, dir_path, TRUE, iterpool, iterpool); - if (err) { if (!APR_STATUS_IS_ENOENT(err->apr_err) @@ -577,7 +573,9 @@ svn_auth__simple_cleanup_walk(svn_auth_b { svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi); svn_stream_t *stream; - apr_hash_t *file_data; + apr_hash_t *creds_hash; + const svn_string_t *realm, *passtype; + svn_boolean_t delete_file = FALSE; if (dirent->kind != svn_node_file) continue; @@ -595,8 +593,8 @@ svn_auth__simple_cleanup_walk(svn_auth_b continue; } - file_data = apr_hash_make(itempool); - err = svn_hash_read2(file_data, stream, SVN_HASH_TERMINATOR, itempool); + creds_hash = apr_hash_make(itempool); + err = svn_hash_read2(creds_hash, stream, SVN_HASH_TERMINATOR, itempool); err = svn_error_compose_create(err, svn_stream_close(stream)); if (err) { @@ -605,32 +603,41 @@ svn_auth__simple_cleanup_walk(svn_auth_b continue; } - { - const svn_string_t *realm = svn_hash_gets(file_data, - SVN_CONFIG_REALMSTRING_KEY); - svn_boolean_t delete_file = FALSE; - - if (! realm) - continue; /* Not an auth file */ - - SVN_ERR(cleanup_func(&delete_file, cleanup_baton, cred_kinds[i], - realm->data, SVN_AUTH_CRED_SIMPLE, itempool)); - - if (delete_file) - { - /* Delete from the credential hash */ - const char *cache_key = apr_pstrcat(itempool, - cred_kinds[0], - ":", - realm->data, - (char *)NULL); - - svn_hash_sets(creds_cache, cache_key, NULL); - - /* And the file on disk */ - SVN_ERR(svn_io_remove_file2(item_path, TRUE, itempool)); - } - } + realm = svn_hash_gets(creds_hash, SVN_CONFIG_REALMSTRING_KEY); + if (! realm) + continue; /* Not an auth file */ + + /* With the exception of the "windows" and "simple" password + types, a non-empty "passtype" value means that this + record is just metadata for credentials cached elsewhere. + In order to avoid giving the impression that we're able + to clear cached data that we really aren't, we'll skip + such records. */ + passtype = svn_hash_gets(creds_hash, AUTHN_PASSTYPE_KEY); + if (passtype && passtype->data + && (! ((strcmp(passtype->data, + SVN_AUTH__WINCRYPT_PASSWORD_TYPE) == 0) + || (strcmp(passtype->data, + SVN_AUTH__SIMPLE_PASSWORD_TYPE) == 0)))) + continue; + + SVN_ERR(cleanup_func(&delete_file, cleanup_baton, cred_kinds[i], + realm->data, + passtype ? passtype->data + : SVN_AUTH__SIMPLE_PASSWORD_TYPE, + itempool)); + + if (delete_file) + { + /* Delete from the credential hash */ + const char *cache_key = apr_pstrcat(itempool, cred_kinds[0], ":", + realm->data, (char *)NULL); + + svn_hash_sets(creds_cache, cache_key, NULL); + + /* And the file on disk */ + SVN_ERR(svn_io_remove_file2(item_path, TRUE, itempool)); + } } }