/*
 * auth.c: authentication support functions for Subversion
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */


#include <apr_pools.h>
#include <apr_tables.h>
#include <apr_strings.h>

#include "svn_hash.h"
#include "svn_types.h"
#include "svn_string.h"
#include "svn_error.h"
#include "svn_auth.h"
#include "svn_config.h"
#include "svn_private_config.h"
#include "svn_dso.h"
#include "svn_version.h"
#include "private/svn_auth_private.h"
#include "private/svn_dep_compat.h"

#include "auth.h"

/* AN OVERVIEW
   ===========

   A good way to think of this machinery is as a set of tables.

     - Each type of credentials selects a single table.

     - In a given table, each row is a 'provider' capable of returning
       the same type of credentials.  Each column represents a
       provider's repeated attempts to provide credentials.


   Fetching Credentials from Providers
   -----------------------------------

   When the caller asks for a particular type of credentials, the
   machinery in this file walks over the appropriate table.  It starts
   with the first provider (first row), and calls first_credentials()
   to get the first set of credentials (first column).  If the caller
   is unhappy with the credentials, then each subsequent call to
   next_credentials() traverses the row from left to right.  If the
   provider returns error at any point, then we go to the next provider
   (row).  We continue this way until every provider fails, or
   until the client is happy with the returned credentials.

   Note that the caller cannot see the table traversal, and thus has
   no idea when we switch providers.


   Storing Credentials with Providers
   ----------------------------------

   When the server has validated a set of credentials, and when
   credential caching is enabled, we have the chance to store those
   credentials for later use.  The provider which provided the working
   credentials is the first one given the opportunity to (re)cache
   those credentials.  Its save_credentials() function is invoked with
   the working credentials.  If that provider reports that it
   successfully stored the credentials, we're done.  Otherwise, we
   walk the providers (rows) for that type of credentials in order
   from the top of the table, allowing each in turn the opportunity to
   store the credentials.  When one reports that it has done so
   successfully -- or when we run out of providers (rows) to try --
   the table walk ends.
*/



/* This effectively defines a single table.  Every provider in this
   array returns the same kind of credentials. */
typedef struct provider_set_t
{
  /* ordered array of svn_auth_provider_object_t */
  apr_array_header_t *providers;

} provider_set_t;


/* The main auth baton. */
struct svn_auth_baton_t
{
  /* a collection of tables.  maps cred_kind -> provider_set */
  apr_hash_t *tables;

  /* the pool I'm allocated in. */
  apr_pool_t *pool;

  /* run-time parameters needed by providers. */
  apr_hash_t *parameters;
  apr_hash_t *slave_parameters;

  /* run-time credentials cache. */
  apr_hash_t *creds_cache;
};

/* Abstracted iteration baton */
struct svn_auth_iterstate_t
{
  provider_set_t *table;        /* the table being searched */
  int provider_idx;             /* the current provider (row) */
  svn_boolean_t got_first;      /* did we get the provider's first creds? */
  void *provider_iter_baton;    /* the provider's own iteration context */
  const char *realmstring;      /* The original realmstring passed in */
  const char *cache_key;        /* key to use in auth_baton's creds_cache */
  svn_auth_baton_t *auth_baton; /* the original auth_baton. */
  apr_hash_t *parameters;
};



void
svn_auth_open(svn_auth_baton_t **auth_baton,
              const apr_array_header_t *providers,
              apr_pool_t *pool)
{
  svn_auth_baton_t *ab;
  svn_auth_provider_object_t *provider;
  int i;

  /* Build the auth_baton. */
  ab = apr_pcalloc(pool, sizeof(*ab));
  ab->tables = apr_hash_make(pool);
  ab->parameters = apr_hash_make(pool);
  /* ab->slave_parameters = NULL; */
  ab->creds_cache = apr_hash_make(pool);
  ab->pool = pool;

  /* Register each provider in order.  Providers of different
     credentials will be automatically sorted into different tables by
     register_provider(). */
  for (i = 0; i < providers->nelts; i++)
    {
      provider_set_t *table;
      provider = APR_ARRAY_IDX(providers, i, svn_auth_provider_object_t *);

      /* Add it to the appropriate table in the auth_baton */
      table = svn_hash_gets(ab->tables, provider->vtable->cred_kind);
      if (! table)
        {
          table = apr_pcalloc(pool, sizeof(*table));
          table->providers
            = apr_array_make(pool, 1, sizeof(svn_auth_provider_object_t *));

          svn_hash_sets(ab->tables, provider->vtable->cred_kind, table);
        }
      APR_ARRAY_PUSH(table->providers, svn_auth_provider_object_t *)
        = provider;
    }

  *auth_baton = ab;
}

/* Magic pointer value to allow storing 'NULL' in an apr_hash_t */
static const void *auth_NULL = NULL;

void
svn_auth_set_parameter(svn_auth_baton_t *auth_baton,
                       const char *name,
                       const void *value)
{
  if (auth_baton)
    {
      if (auth_baton->slave_parameters)
        {
          if (!value)
            value = &auth_NULL;

          svn_hash_sets(auth_baton->slave_parameters, name, value);
        }
      else
        svn_hash_sets(auth_baton->parameters, name, value);
    }
}

const void *
svn_auth_get_parameter(svn_auth_baton_t *auth_baton,
                       const char *name)
{
  const void *value;
  if (!auth_baton)
    return NULL;
  else if (!auth_baton->slave_parameters)
    return svn_hash_gets(auth_baton->parameters, name);

  value = svn_hash_gets(auth_baton->slave_parameters, name);

  if (value)
    return (value == &auth_NULL ? NULL : value);

  return svn_hash_gets(auth_baton->parameters, name);
}


/* Return the key used to address the in-memory cache of auth
   credentials of type CRED_KIND and associated with REALMSTRING. */
static const char *
make_cache_key(const char *cred_kind,
               const char *realmstring,
               apr_pool_t *pool)
{
  return apr_pstrcat(pool, cred_kind, ":", realmstring, SVN_VA_NULL);
}

svn_error_t *
svn_auth_first_credentials(void **credentials,
                           svn_auth_iterstate_t **state,
                           const char *cred_kind,
                           const char *realmstring,
                           svn_auth_baton_t *auth_baton,
                           apr_pool_t *pool)
{
  int i = 0;
  provider_set_t *table;
  svn_auth_provider_object_t *provider = NULL;
  void *creds = NULL;
  void *iter_baton = NULL;
  svn_boolean_t got_first = FALSE;
  svn_auth_iterstate_t *iterstate;
  const char *cache_key;
  apr_hash_t *parameters;

  if (! auth_baton)
    return svn_error_create(SVN_ERR_AUTHN_NO_PROVIDER, NULL,
                            _("No authentication providers registered"));

  /* Get the appropriate table of providers for CRED_KIND. */
  table = svn_hash_gets(auth_baton->tables, cred_kind);
  if (! table)
    return svn_error_createf(SVN_ERR_AUTHN_NO_PROVIDER, NULL,
                             _("No provider registered for '%s' credentials"),
                             cred_kind);

  if (auth_baton->slave_parameters)
    {
      apr_hash_index_t *hi;
      parameters = apr_hash_copy(pool, auth_baton->parameters);

      for (hi = apr_hash_first(pool, auth_baton->slave_parameters);
            hi;
            hi = apr_hash_next(hi))
        {
          const void *value = apr_hash_this_val(hi);

          if (value == &auth_NULL)
            value = NULL;

          svn_hash_sets(parameters, apr_hash_this_key(hi), value);
        }
    }
  else
    parameters = auth_baton->parameters;

  /* First, see if we have cached creds in the auth_baton. */
  cache_key = make_cache_key(cred_kind, realmstring, pool);
  creds = svn_hash_gets(auth_baton->creds_cache, cache_key);
  if (creds)
    {
       got_first = FALSE;
    }
  else
    /* If not, find a provider that can give "first" credentials. */
    {
      /* Find a provider that can give "first" credentials. */
      for (i = 0; i < table->providers->nelts; i++)
        {
          provider = APR_ARRAY_IDX(table->providers, i,
                                   svn_auth_provider_object_t *);
          SVN_ERR(provider->vtable->first_credentials(&creds, &iter_baton,
                                                      provider->provider_baton,
                                                      parameters,
                                                      realmstring,
                                                      auth_baton->pool));

          if (creds != NULL)
            {
              got_first = TRUE;
              break;
            }
        }
    }

  if (! creds)
    {
      *state = NULL;
    }
  else
    {
      /* Build an abstract iteration state. */
      iterstate = apr_pcalloc(pool, sizeof(*iterstate));
      iterstate->table = table;
      iterstate->provider_idx = i;
      iterstate->got_first = got_first;
      iterstate->provider_iter_baton = iter_baton;
      iterstate->realmstring = apr_pstrdup(pool, realmstring);
      iterstate->cache_key = cache_key;
      iterstate->auth_baton = auth_baton;
      iterstate->parameters = parameters;
      *state = iterstate;

      /* Put the creds in the cache */
      svn_hash_sets(auth_baton->creds_cache,
                    apr_pstrdup(auth_baton->pool, cache_key),
                    creds);
    }

  *credentials = creds;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_auth_next_credentials(void **credentials,
                          svn_auth_iterstate_t *state,
                          apr_pool_t *pool)
{
  svn_auth_baton_t *auth_baton = state->auth_baton;
  svn_auth_provider_object_t *provider;
  provider_set_t *table = state->table;
  void *creds = NULL;

  /* Continue traversing the table from where we left off. */
  for (/* no init */;
       state->provider_idx < table->providers->nelts;
       state->provider_idx++)
    {
      provider = APR_ARRAY_IDX(table->providers,
                               state->provider_idx,
                               svn_auth_provider_object_t *);
      if (! state->got_first)
        {
          SVN_ERR(provider->vtable->first_credentials(
                      &creds, &(state->provider_iter_baton),
                      provider->provider_baton, state->parameters,
                      state->realmstring, auth_baton->pool));
          state->got_first = TRUE;
        }
      else if (provider->vtable->next_credentials)
        {
          SVN_ERR(provider->vtable->next_credentials(&creds,
                                                     state->provider_iter_baton,
                                                     provider->provider_baton,
                                                     state->parameters,
                                                     state->realmstring,
                                                     auth_baton->pool));
        }

      if (creds != NULL)
        {
          /* Put the creds in the cache */
          svn_hash_sets(auth_baton->creds_cache,
                        apr_pstrdup(auth_baton->pool, state->cache_key),
                        creds);
          break;
        }

      state->got_first = FALSE;
    }

  *credentials = creds;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_auth_save_credentials(svn_auth_iterstate_t *state,
                          apr_pool_t *pool)
{
  int i;
  svn_auth_provider_object_t *provider;
  svn_boolean_t save_succeeded = FALSE;
  const char *no_auth_cache;
  void *creds;

  if (! state || state->table->providers->nelts <= state->provider_idx)
    return SVN_NO_ERROR;

  creds = svn_hash_gets(state->auth_baton->creds_cache, state->cache_key);
  if (! creds)
    return SVN_NO_ERROR;

  /* Do not save the creds if SVN_AUTH_PARAM_NO_AUTH_CACHE is set */
  no_auth_cache = svn_hash_gets(state->parameters,
                                SVN_AUTH_PARAM_NO_AUTH_CACHE);
  if (no_auth_cache)
    return SVN_NO_ERROR;

  /* First, try to save the creds using the provider that produced them. */
  provider = APR_ARRAY_IDX(state->table->providers,
                           state->provider_idx,
                           svn_auth_provider_object_t *);
  if (provider->vtable->save_credentials)
    SVN_ERR(provider->vtable->save_credentials(&save_succeeded,
                                               creds,
                                               provider->provider_baton,
                                               state->parameters,
                                               state->realmstring,
                                               pool));
  if (save_succeeded)
    return SVN_NO_ERROR;

  /* Otherwise, loop from the top of the list, asking every provider
     to attempt a save.  ### todo: someday optimize so we don't
     necessarily start from the top of the list. */
  for (i = 0; i < state->table->providers->nelts; i++)
    {
      provider = APR_ARRAY_IDX(state->table->providers, i,
                               svn_auth_provider_object_t *);
      if (provider->vtable->save_credentials)
        SVN_ERR(provider->vtable->save_credentials(&save_succeeded, creds,
                                                   provider->provider_baton,
                                                   state->parameters,
                                                   state->realmstring,
                                                   pool));

      if (save_succeeded)
        break;
    }

  /* ### notice that at the moment, if no provider can save, there's
     no way the caller will know. */

  return SVN_NO_ERROR;
}


svn_error_t *
svn_auth_forget_credentials(svn_auth_baton_t *auth_baton,
                            const char *cred_kind,
                            const char *realmstring,
                            apr_pool_t *scratch_pool)
{
  SVN_ERR_ASSERT((cred_kind && realmstring) || (!cred_kind && !realmstring));

  /* If we have a CRED_KIND and REALMSTRING, we clear out just the
     cached item (if any).  Otherwise, empty the whole hash. */
  if (cred_kind)
    {
      svn_hash_sets(auth_baton->creds_cache,
                    make_cache_key(cred_kind, realmstring, scratch_pool),
                    NULL);
    }
  else
    {
      apr_hash_clear(auth_baton->creds_cache);
    }

  return SVN_NO_ERROR;
}


svn_auth_ssl_server_cert_info_t *
svn_auth_ssl_server_cert_info_dup
  (const svn_auth_ssl_server_cert_info_t *info, apr_pool_t *pool)
{
  svn_auth_ssl_server_cert_info_t *new_info
    = apr_palloc(pool, sizeof(*new_info));

  *new_info = *info;

  new_info->hostname = apr_pstrdup(pool, new_info->hostname);
  new_info->fingerprint = apr_pstrdup(pool, new_info->fingerprint);
  new_info->valid_from = apr_pstrdup(pool, new_info->valid_from);
  new_info->valid_until = apr_pstrdup(pool, new_info->valid_until);
  new_info->issuer_dname = apr_pstrdup(pool, new_info->issuer_dname);
  new_info->ascii_cert = apr_pstrdup(pool, new_info->ascii_cert);

  return new_info;
}

svn_error_t *
svn_auth_get_platform_specific_provider(svn_auth_provider_object_t **provider,
                                        const char *provider_name,
                                        const char *provider_type,
                                        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_function_symbol, version_function_symbol;
      const char *library_label, *library_name;
      const char *provider_function_name, *version_function_name;
      library_name = apr_psprintf(pool,
                                  "libsvn_auth_%s-%d.so.%d",
                                  provider_name,
                                  SVN_VER_MAJOR, SVN_SOVERSION);
      library_label = apr_psprintf(pool, "svn_%s", provider_name);
      provider_function_name = apr_psprintf(pool,
                                            "svn_auth_get_%s_%s_provider",
                                            provider_name, provider_type);
      version_function_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_function_symbol,
                          dso,
                          version_function_name) == 0)
            {
              svn_version_func_t version_function
                = version_function_symbol;
              svn_version_checklist_t check_list[2];

              check_list[0].label = library_label;
              check_list[0].version_query = version_function;
              check_list[1].label = NULL;
              check_list[1].version_query = NULL;
              SVN_ERR(svn_ver_check_list2(svn_subr_version(), check_list,
                                          svn_ver_equal));
            }
          if (apr_dso_sym(&provider_function_symbol,
                          dso,
                          provider_function_name) == 0)
            {
              if (strcmp(provider_type, "simple") == 0)
                {
                  svn_auth_simple_provider_func_t provider_function
                    = provider_function_symbol;
                  provider_function(provider, pool);
                }
              else if (strcmp(provider_type, "ssl_client_cert_pw") == 0)
                {
                  svn_auth_ssl_client_cert_pw_provider_func_t provider_function
                    = provider_function_symbol;
                  provider_function(provider, pool);
                }
            }
        }
#endif
    }
  else
    {
#if defined(SVN_HAVE_GPG_AGENT)
      if (strcmp(provider_name, "gpg_agent") == 0 &&
          strcmp(provider_type, "simple") == 0)
        {
          svn_auth__get_gpg_agent_simple_provider(provider, pool);
        }
#endif
#ifdef SVN_HAVE_KEYCHAIN_SERVICES
      if (strcmp(provider_name, "keychain") == 0 &&
          strcmp(provider_type, "simple") == 0)
        {
          svn_auth__get_keychain_simple_provider(provider, pool);
        }
      else if (strcmp(provider_name, "keychain") == 0 &&
               strcmp(provider_type, "ssl_client_cert_pw") == 0)
        {
          svn_auth__get_keychain_ssl_client_cert_pw_provider(provider, pool);
        }
#endif

#if defined(WIN32) && !defined(__MINGW32__)
      if (strcmp(provider_name, "windows") == 0 &&
          strcmp(provider_type, "simple") == 0)
        {
          svn_auth__get_windows_simple_provider(provider, pool);
        }
      else if (strcmp(provider_name, "windows") == 0 &&
               strcmp(provider_type, "ssl_client_cert_pw") == 0)
        {
          svn_auth__get_windows_ssl_client_cert_pw_provider(provider, pool);
        }
      else if (strcmp(provider_name, "windows") == 0 &&
               strcmp(provider_type, "ssl_server_trust") == 0)
        {
          svn_auth__get_windows_ssl_server_trust_provider(provider, pool);
        }
      else if (strcmp(provider_name, "windows") == 0 &&
               strcmp(provider_type, "ssl_server_authority") == 0)
        {
          svn_auth__get_windows_ssl_server_authority_provider(provider, pool);
        }
#endif
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_auth_get_platform_specific_client_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;
  apr_array_header_t *password_stores;
  int i;

#define SVN__MAYBE_ADD_PROVIDER(list, p) \
  { if (p) APR_ARRAY_PUSH(list, svn_auth_provider_object_t *) = p; }

#define SVN__DEFAULT_AUTH_PROVIDER_LIST \
         "gnome-keyring,kwallet,keychain,gpg-agent,windows-cryptoapi"

  *providers = apr_array_make(pool, 12, sizeof(svn_auth_provider_object_t *));

  /* Fetch the configured list of password stores, and split them into
     an array. */
  svn_config_get(config,
                 &password_stores_config_option,
                 SVN_CONFIG_SECTION_AUTH,
                 SVN_CONFIG_OPTION_PASSWORD_STORES,
                 SVN__DEFAULT_AUTH_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)
        {
          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "gnome_keyring",
                                                          "simple",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);

          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "gnome_keyring",
                                                          "ssl_client_cert_pw",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);
        }
      /* GPG-AGENT */
      else if (apr_strnatcmp(password_store, "gpg-agent") == 0)
        {
          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "gpg_agent",
                                                          "simple",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);
        }
      /* KWallet */
      else if (apr_strnatcmp(password_store, "kwallet") == 0)
        {
          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "kwallet",
                                                          "simple",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);

          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "kwallet",
                                                          "ssl_client_cert_pw",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);
        }
      /* Keychain */
      else if (apr_strnatcmp(password_store, "keychain") == 0)
        {
          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "keychain",
                                                          "simple",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);

          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "keychain",
                                                          "ssl_client_cert_pw",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);
        }
      /* Windows */
      else if (apr_strnatcmp(password_store, "windows-cryptoapi") == 0)
        {
          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "windows",
                                                          "simple",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);

          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                          "windows",
                                                          "ssl_client_cert_pw",
                                                          pool));
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);
        }
    }

  /* Windows has two providers without a store to allow easy access to
     SSL servers. We enable these unconditionally.
     (This behavior was moved here from svn_cmdline_create_auth_baton()) */
  SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                  "windows",
                                                  "ssl_server_trust",
                                                  pool));
  SVN__MAYBE_ADD_PROVIDER(*providers, provider);

  /* The windows ssl authority certificate CRYPTOAPI provider. */
  SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                  "windows",
                                                  "ssl_server_authority",
                                                  pool));

  SVN__MAYBE_ADD_PROVIDER(*providers, provider);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_auth__make_session_auth(svn_auth_baton_t **session_auth_baton,
                            const svn_auth_baton_t *auth_baton,
                            apr_hash_t *config,
                            const char *server_name,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
{
  svn_boolean_t store_passwords = SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS;
  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;
  svn_boolean_t store_pp = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP;
  const char *store_pp_plaintext
    = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT;
  svn_config_t *servers = NULL;
  const char *server_group = NULL;

  struct svn_auth_baton_t *ab;

  ab = apr_pmemdup(result_pool, auth_baton, sizeof(*ab));

  ab->slave_parameters = apr_hash_make(result_pool);

  /* The 'store-passwords' and 'store-auth-creds' parameters used to
  * live in SVN_CONFIG_CATEGORY_CONFIG. For backward compatibility,
  * if values for these parameters have already been set by our
  * callers, we use those values as defaults.
  *
  * Note that we can only catch the case where users explicitly set
  * "store-passwords = no" or 'store-auth-creds = no".
  *
  * However, since the default value for both these options is
  * currently (and has always been) "yes", users won't know
  * the difference if they set "store-passwords = yes" or
  * "store-auth-creds = yes" -- they'll get the expected behaviour.
  */

  if (svn_auth_get_parameter(ab, SVN_AUTH_PARAM_DONT_STORE_PASSWORDS) != NULL)
    store_passwords = FALSE;

  if (svn_auth_get_parameter(ab, SVN_AUTH_PARAM_NO_AUTH_CACHE) != NULL)
    store_auth_creds = FALSE;

  /* All the svn_auth_set_parameter() calls below this not only affect the
     to be created ra session, but also all the ra sessions that are already
     use this auth baton!

     Please try to key things based on the realm string instead of this
     construct.
 */

  if (config)
    {
      /* Grab the 'servers' config. */
      servers = svn_hash_gets(config, SVN_CONFIG_CATEGORY_SERVERS);
      if (servers)
        {
          /* First, look in the global section. */

          SVN_ERR(svn_config_get_bool
            (servers, &store_passwords, SVN_CONFIG_SECTION_GLOBAL,
             SVN_CONFIG_OPTION_STORE_PASSWORDS,
             store_passwords));

          SVN_ERR(svn_config_get_yes_no_ask
            (servers, &store_plaintext_passwords, SVN_CONFIG_SECTION_GLOBAL,
             SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
             SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS));

          SVN_ERR(svn_config_get_bool
            (servers, &store_pp, SVN_CONFIG_SECTION_GLOBAL,
             SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
             store_pp));

          SVN_ERR(svn_config_get_yes_no_ask
            (servers, &store_pp_plaintext,
             SVN_CONFIG_SECTION_GLOBAL,
             SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
             SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT));

          SVN_ERR(svn_config_get_bool
            (servers, &store_auth_creds, SVN_CONFIG_SECTION_GLOBAL,
              SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
              store_auth_creds));

          /* Find out where we're about to connect to, and
           * try to pick a server group based on the destination. */
          server_group = svn_config_find_group(servers, server_name,
                                               SVN_CONFIG_SECTION_GROUPS,
                                               scratch_pool);

          if (server_group)
            {
              /* Override global auth caching parameters with the ones
               * for the server group, if any. */
              SVN_ERR(svn_config_get_bool(servers, &store_auth_creds,
                                          server_group,
                                          SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
                                          store_auth_creds));

              SVN_ERR(svn_config_get_bool(servers, &store_passwords,
                                          server_group,
                                          SVN_CONFIG_OPTION_STORE_PASSWORDS,
                                          store_passwords));

              SVN_ERR(svn_config_get_yes_no_ask
                (servers, &store_plaintext_passwords, server_group,
                 SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
                 store_plaintext_passwords));

              SVN_ERR(svn_config_get_bool
                (servers, &store_pp,
                 server_group, SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
                 store_pp));

              SVN_ERR(svn_config_get_yes_no_ask
                (servers, &store_pp_plaintext, server_group,
                 SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
                 store_pp_plaintext));
            }
        }
    }

  /* Save auth caching parameters in the auth parameter hash. */
  if (! store_passwords)
    svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");

  svn_auth_set_parameter(ab,
                         SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS,
                         store_plaintext_passwords);

  if (! store_pp)
    svn_auth_set_parameter(ab,
                           SVN_AUTH_PARAM_DONT_STORE_SSL_CLIENT_CERT_PP,
                           "");

  svn_auth_set_parameter(ab,
                         SVN_AUTH_PARAM_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
                         store_pp_plaintext);

  if (! store_auth_creds)
    svn_auth_set_parameter(ab, SVN_AUTH_PARAM_NO_AUTH_CACHE, "");

  if (server_group)
    svn_auth_set_parameter(ab,
                           SVN_AUTH_PARAM_SERVER_GROUP,
                           apr_pstrdup(ab->pool, server_group));

  *session_auth_baton = ab;

  return SVN_NO_ERROR;
}


static svn_error_t *
dummy_first_creds(void **credentials,
                  void **iter_baton,
                  void *provider_baton,
                  apr_hash_t *parameters,
                  const char *realmstring,
                  apr_pool_t *pool)
{
  *credentials = NULL;
  *iter_baton = NULL;
  return SVN_NO_ERROR;
}

void
svn_auth__get_dummmy_simple_provider(svn_auth_provider_object_t **provider,
                                     apr_pool_t *pool)
{
  static const svn_auth_provider_t vtable = {
    SVN_AUTH_CRED_SIMPLE,
    dummy_first_creds,
    NULL, NULL
  };

  svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));

  po->vtable = &vtable;
  *provider = po;
}
