/*
 * cyrus_auth.c :  functions for Cyrus SASL-based authentication
 *
 * ====================================================================
 *    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 "svn_private_config.h"
#ifdef SVN_HAVE_SASL

#define APR_WANT_STRFUNC
#include <apr_want.h>
#include <apr_general.h>
#include <apr_strings.h>
#include <apr_version.h>

#include "svn_types.h"
#include "svn_string.h"
#include "svn_error.h"
#include "svn_pools.h"
#include "svn_ra.h"
#include "svn_ra_svn.h"
#include "svn_base64.h"

#include "private/svn_atomic.h"
#include "private/ra_svn_sasl.h"
#include "private/svn_mutex.h"

#include "ra_svn.h"

/* Note: In addition to being used via svn_atomic__init_once to control
 *       initialization of the SASL code this will also be referenced in
 *       the various functions that work with sasl mutexes to determine
 *       if the sasl pool has been destroyed.  This should be safe, since
 *       it is only set back to zero in the sasl pool's cleanups, which
 *       only happens during apr_terminate, which we assume is occurring
 *       in atexit processing, at which point we are already running in
 *       single threaded mode.
 */
volatile svn_atomic_t svn_ra_svn__sasl_status = 0;

/* Initialized by svn_ra_svn__sasl_common_init(). */
static volatile svn_atomic_t sasl_ctx_count;

static apr_pool_t *sasl_pool = NULL;


/* Pool cleanup called when sasl_pool is destroyed. */
static apr_status_t sasl_done_cb(void *data)
{
  /* Reset svn_ra_svn__sasl_status, in case the client calls
     apr_initialize()/apr_terminate() more than once. */
  svn_ra_svn__sasl_status = 0;
  if (svn_atomic_dec(&sasl_ctx_count) == 0)
    svn_sasl__done();
  return APR_SUCCESS;
}

#if APR_HAS_THREADS
/* Cyrus SASL is thread-safe only if we supply it with mutex functions
 * (with sasl_set_mutex()).  To make this work with APR, we need to use the
 * global sasl_pool for the mutex allocations.  Freeing a mutex actually
 * returns it to a global array.  We allocate mutexes from this
 * array if it is non-empty, or directly from the pool otherwise.
 * We also need a mutex to serialize accesses to the array itself.
 */

/* An array of allocated, but unused, apr_thread_mutex_t's. */
static apr_array_header_t *free_mutexes = NULL;

/* A mutex to serialize access to the array. */
static svn_mutex__t *array_mutex = NULL;

/* Callbacks we pass to sasl_set_mutex(). */

static svn_error_t *
sasl_mutex_alloc_cb_internal(svn_mutex__t **mutex)
{
  if (apr_is_empty_array(free_mutexes))
    return svn_mutex__init(mutex, TRUE, sasl_pool);
  else
    *mutex = *((svn_mutex__t**)apr_array_pop(free_mutexes));

  return SVN_NO_ERROR;
}

static void *sasl_mutex_alloc_cb(void)
{
  svn_mutex__t *mutex = NULL;
  svn_error_t *err;

  if (!svn_ra_svn__sasl_status)
    return NULL;

  err = svn_mutex__lock(array_mutex);
  if (err)
    svn_error_clear(err);
  else
    svn_error_clear(svn_mutex__unlock(array_mutex,
                                      sasl_mutex_alloc_cb_internal(&mutex)));

  return mutex;
}

static int check_result(svn_error_t *err)
{
  if (err)
    {
      svn_error_clear(err);
      return -1;
    }

  return 0;
}

static int sasl_mutex_lock_cb(void *mutex)
{
  if (!svn_ra_svn__sasl_status)
    return 0;
  return check_result(svn_mutex__lock(mutex));
}

static int sasl_mutex_unlock_cb(void *mutex)
{
  if (!svn_ra_svn__sasl_status)
    return 0;
  return check_result(svn_mutex__unlock(mutex, SVN_NO_ERROR));
}

static svn_error_t *
sasl_mutex_free_cb_internal(void *mutex)
{
  APR_ARRAY_PUSH(free_mutexes, svn_mutex__t*) = mutex;
  return SVN_NO_ERROR;
}

static void sasl_mutex_free_cb(void *mutex)
{
  svn_error_t *err;

  if (!svn_ra_svn__sasl_status)
    return;

  err = svn_mutex__lock(array_mutex);
  if (err)
    svn_error_clear(err);
  else
    svn_error_clear(svn_mutex__unlock(array_mutex,
                                      sasl_mutex_free_cb_internal(mutex)));
}
#endif /* APR_HAS_THREADS */

svn_error_t *
svn_ra_svn__sasl_common_init(apr_pool_t *pool)
{
  sasl_pool = svn_pool_create(pool);
  sasl_ctx_count = 1;
  apr_pool_cleanup_register(sasl_pool, NULL, sasl_done_cb,
                            apr_pool_cleanup_null);
#if APR_HAS_THREADS
  svn_sasl__set_mutex(sasl_mutex_alloc_cb,
                      sasl_mutex_lock_cb,
                      sasl_mutex_unlock_cb,
                      sasl_mutex_free_cb);
  free_mutexes = apr_array_make(sasl_pool, 0, sizeof(svn_mutex__t *));
  SVN_ERR(svn_mutex__init(&array_mutex, TRUE, sasl_pool));

#endif /* APR_HAS_THREADS */

  return SVN_NO_ERROR;
}

/* We are going to look at errno when we get SASL_FAIL but we don't
   know for sure whether SASL always sets errno.  Clearing errno
   before calling SASL functions helps in cases where SASL does
   nothing to set errno. */
#ifdef apr_set_os_error
#define clear_sasl_errno() apr_set_os_error(APR_SUCCESS)
#else
#define clear_sasl_errno() (void)0
#endif

/* Sometimes SASL returns SASL_FAIL as RESULT and sets errno.
 * SASL_FAIL translates to "generic error" which is quite unhelpful.
 * Try to append a more informative error message based on errno so
 * should be called before doing anything that may change errno. */
static const char *
get_sasl_errno_msg(int result, apr_pool_t *result_pool)
{
#ifdef apr_get_os_error
  char buf[1024];

  if (result == SASL_FAIL && apr_get_os_error() != 0)
    return apr_psprintf(result_pool, ": %s",
                        svn_strerror(apr_get_os_error(), buf, sizeof(buf)));
#endif
  return "";
}

/* Wrap an error message from SASL with a prefix that allows users
 * to tell that the error message came from SASL.  Queries errno and
 * so should be called before doing anything that may change errno. */
static const char *
get_sasl_error(sasl_conn_t *sasl_ctx, int result, apr_pool_t *result_pool)
{
  const char *sasl_errno_msg = get_sasl_errno_msg(result, result_pool);

  return apr_psprintf(result_pool,
                      _("SASL authentication error: %s%s"),
                      svn_sasl__errdetail(sasl_ctx), sasl_errno_msg);
}

static svn_error_t *sasl_init_cb(void *baton, apr_pool_t *pool)
{
  int result;

  SVN_ERR(svn_ra_svn__sasl_common_init(pool));
  clear_sasl_errno();
  result = svn_sasl__client_init(NULL);
  if (result != SASL_OK)
    {
      const char *sasl_errno_msg = get_sasl_errno_msg(result, pool);

      return svn_error_createf
        (SVN_ERR_RA_NOT_AUTHORIZED, NULL,
         _("Could not initialized the SASL library: %s%s"),
         svn_sasl__errstring(result, NULL, NULL),
         sasl_errno_msg);
    }

  return SVN_NO_ERROR;
}

svn_error_t *svn_ra_svn__sasl_init(void)
{
  SVN_ERR(svn_atomic__init_once(&svn_ra_svn__sasl_status,
                                sasl_init_cb, NULL, NULL));
  return SVN_NO_ERROR;
}

static apr_status_t sasl_dispose_cb(void *data)
{
  sasl_conn_t *sasl_ctx = data;
  svn_sasl__dispose(&sasl_ctx);
  if (svn_atomic_dec(&sasl_ctx_count) == 0)
    svn_sasl__done();
  return APR_SUCCESS;
}

void svn_ra_svn__default_secprops(sasl_security_properties_t *secprops)
{
  /* The minimum and maximum security strength factors that the chosen
     SASL mechanism should provide.  0 means 'no encryption', 256 means
     '256-bit encryption', which is about the best that any SASL
     mechanism can provide.  Using these values effectively means 'use
     whatever encryption the other side wants'.  Note that SASL will try
     to use better encryption whenever possible, so if both the server and
     the client use these values the highest possible encryption strength
     will be used. */
  secprops->min_ssf = 0;
  secprops->max_ssf = 256;

  /* Set maxbufsize to the maximum amount of data we can read at any one time.
     This value needs to be communicated to the peer if a security layer
     is negotiated. */
  secprops->maxbufsize = SVN_RA_SVN__READBUF_SIZE;

  secprops->security_flags = 0;
  secprops->property_names = secprops->property_values = NULL;
}

/* A baton type used by the SASL username and password callbacks. */
typedef struct cred_baton {
  svn_auth_baton_t *auth_baton;
  svn_auth_iterstate_t *iterstate;
  const char *realmstring;

  /* Unfortunately SASL uses two separate callbacks for the username and
     password, but we must fetch both of them at the same time. So we cache
     their values in the baton, set them to NULL individually when SASL
     demands them, and fetch the next pair when both are NULL. */
  const char *username;
  const char *password;

  /* Any errors we receive from svn_auth_{first,next}_credentials
     are saved here. */
  svn_error_t *err;

  /* This flag is set when we run out of credential providers. */
  svn_boolean_t no_more_creds;

  /* Were the auth callbacks ever called? */
  svn_boolean_t was_used;

  apr_pool_t *pool;
} cred_baton_t;

/* Call svn_auth_{first,next}_credentials. If successful, set BATON->username
   and BATON->password to the new username and password and return TRUE,
   otherwise return FALSE. If there are no more credentials, set
   BATON->no_more_creds to TRUE. Any errors are saved in BATON->err. */
static svn_boolean_t
get_credentials(cred_baton_t *baton)
{
  void *creds;

  if (baton->iterstate)
    baton->err = svn_auth_next_credentials(&creds, baton->iterstate,
                                           baton->pool);
  else
    baton->err = svn_auth_first_credentials(&creds, &baton->iterstate,
                                            SVN_AUTH_CRED_SIMPLE,
                                            baton->realmstring,
                                            baton->auth_baton, baton->pool);
  if (baton->err)
    return FALSE;

  if (! creds)
    {
      baton->no_more_creds = TRUE;
      return FALSE;
    }

  baton->username = ((svn_auth_cred_simple_t *)creds)->username;
  baton->password = ((svn_auth_cred_simple_t *)creds)->password;
  baton->was_used = TRUE;

  return TRUE;
}

/* The username callback. Implements the sasl_getsimple_t interface. */
static int
get_username_cb(void *b, int id, const char **username, size_t *len)
{
  cred_baton_t *baton = b;

  if (baton->username || get_credentials(baton))
    {
      *username = baton->username;
      if (len)
        *len = strlen(baton->username);
      baton->username = NULL;

      return SASL_OK;
    }

  return SASL_FAIL;
}

/* The password callback. Implements the sasl_getsecret_t interface. */
static int
get_password_cb(sasl_conn_t *conn, void *b, int id, sasl_secret_t **psecret)
{
  cred_baton_t *baton = b;

  if (baton->password || get_credentials(baton))
    {
      sasl_secret_t *secret;
      size_t len = strlen(baton->password);

      /* sasl_secret_t is a struct with a variable-sized array as a final
         member, which means we need to allocate len-1 supplementary bytes
         (one byte is part of sasl_secret_t, and we don't need a NULL
         terminator). */
      secret = apr_palloc(baton->pool, sizeof(*secret) + len - 1);
      secret->len = len;
      memcpy(secret->data, baton->password, len);
      baton->password = NULL;
      *psecret = secret;

      return SASL_OK;
    }

  return SASL_FAIL;
}

/* Create a new SASL context. */
static svn_error_t *new_sasl_ctx(sasl_conn_t **sasl_ctx,
                                 svn_boolean_t is_tunneled,
                                 const char *hostname,
                                 const char *local_addrport,
                                 const char *remote_addrport,
                                 sasl_callback_t *callbacks,
                                 apr_pool_t *pool)
{
  sasl_security_properties_t secprops;
  int result;

  clear_sasl_errno();
  result = svn_sasl__client_new(SVN_RA_SVN_SASL_NAME,
                                hostname, local_addrport, remote_addrport,
                                callbacks, SASL_SUCCESS_DATA,
                                sasl_ctx);
  if (result != SASL_OK)
    {
      const char *sasl_errno_msg = get_sasl_errno_msg(result, pool);

      return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                               _("Could not create SASL context: %s%s"),
                               svn_sasl__errstring(result, NULL, NULL),
                               sasl_errno_msg);
    }
  svn_atomic_inc(&sasl_ctx_count);
  apr_pool_cleanup_register(pool, *sasl_ctx, sasl_dispose_cb,
                            apr_pool_cleanup_null);

  if (is_tunneled)
    {
      /* We need to tell SASL that this connection is tunneled,
         otherwise it will ignore EXTERNAL. The third parameter
         should be the username, but since SASL doesn't seem
         to use it on the client side, any non-empty string will do. */
      clear_sasl_errno();
      result = svn_sasl__setprop(*sasl_ctx,
                                 SASL_AUTH_EXTERNAL, " ");
      if (result != SASL_OK)
        return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                get_sasl_error(*sasl_ctx, result, pool));
    }

  /* Set security properties. */
  svn_ra_svn__default_secprops(&secprops);
  svn_sasl__setprop(*sasl_ctx, SASL_SEC_PROPS, &secprops);

  return SVN_NO_ERROR;
}

/* Perform an authentication exchange */
static svn_error_t *try_auth(svn_ra_svn__session_baton_t *sess,
                             sasl_conn_t *sasl_ctx,
                             svn_boolean_t *success,
                             const char **last_err,
                             const char *mechstring,
                             apr_pool_t *pool)
{
  sasl_interact_t *client_interact = NULL;
  const char *out, *mech, *status = NULL;
  const svn_string_t *arg = NULL, *in;
  int result;
  unsigned int outlen;
  svn_boolean_t again;

  do
    {
      again = FALSE;
      clear_sasl_errno();
      result = svn_sasl__client_start(sasl_ctx,
                                      mechstring,
                                      &client_interact,
                                      &out,
                                      &outlen,
                                      &mech);
      switch (result)
        {
          case SASL_OK:
          case SASL_CONTINUE:
            /* Success. */
            break;
          case SASL_NOMECH:
            return svn_error_create(SVN_ERR_RA_SVN_NO_MECHANISMS, NULL, NULL);
          case SASL_BADPARAM:
          case SASL_NOMEM:
            /* Fatal error.  Fail the authentication. */
            return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                    get_sasl_error(sasl_ctx, result, pool));
          default:
            /* For anything else, delete the mech from the list
               and try again. */
            {
              const char *pmech = strstr(mechstring, mech);
              const char *head = apr_pstrndup(pool, mechstring,
                                              pmech - mechstring);
              const char *tail = pmech + strlen(mech);

              mechstring = apr_pstrcat(pool, head, tail, SVN_VA_NULL);
              again = TRUE;
            }
        }
    }
  while (again);

  /* Prepare the initial authentication token. */
  if (outlen > 0 || strcmp(mech, "EXTERNAL") == 0)
    arg = svn_base64_encode_string2(svn_string_ncreate(out, outlen, pool),
                                    TRUE, pool);

  /* Send the initial client response */
  SVN_ERR(svn_ra_svn__auth_response(sess->conn, pool, mech,
                                    arg ? arg->data : NULL));

  while (result == SASL_CONTINUE)
    {
      /* Read the server response */
      SVN_ERR(svn_ra_svn__read_tuple(sess->conn, pool, "w(?s)",
                                     &status, &in));

      if (strcmp(status, "failure") == 0)
        {
          /* Authentication failed.  Use the next set of credentials */
          *success = FALSE;
          /* Remember the message sent by the server because we'll want to
             return a meaningful error if we run out of auth providers. */
          *last_err = in ? in->data : "";
          return SVN_NO_ERROR;
        }

      if ((strcmp(status, "success") != 0 && strcmp(status, "step") != 0)
          || in == NULL)
        return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                _("Unexpected server response"
                                " to authentication"));

      /* If the mech is CRAM-MD5 we don't base64-decode the server response. */
      if (strcmp(mech, "CRAM-MD5") != 0)
        in = svn_base64_decode_string(in, pool);

      clear_sasl_errno();
      result = svn_sasl__client_step(sasl_ctx,
                                     in->data,
                                     (const unsigned int) in->len,
                                     &client_interact,
                                     &out, /* Filled in by SASL. */
                                     &outlen);

      if (result != SASL_OK && result != SASL_CONTINUE)
        return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                get_sasl_error(sasl_ctx, result, pool));

      /* If the server thinks we're done, then don't send any response. */
      if (strcmp(status, "success") == 0)
        break;

      if (outlen > 0)
        {
          arg = svn_string_ncreate(out, outlen, pool);
          /* Write our response. */
          /* For CRAM-MD5, we don't use base64-encoding. */
          if (strcmp(mech, "CRAM-MD5") != 0)
            arg = svn_base64_encode_string2(arg, TRUE, pool);
          SVN_ERR(svn_ra_svn__write_cstring(sess->conn, pool, arg->data));
        }
      else
        {
          SVN_ERR(svn_ra_svn__write_cstring(sess->conn, pool, ""));
        }
    }

  if (!status || strcmp(status, "step") == 0)
    {
      /* This is a client-send-last mech.  Read the last server response. */
      SVN_ERR(svn_ra_svn__read_tuple(sess->conn, pool, "w(?s)",
              &status, &in));

      if (strcmp(status, "failure") == 0)
        {
          *success = FALSE;
          *last_err = in ? in->data : "";
        }
      else if (strcmp(status, "success") == 0)
        {
          /* We're done */
          *success = TRUE;
        }
      else
        return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                _("Unexpected server response"
                                " to authentication"));
    }
  else
    *success = TRUE;
  return SVN_NO_ERROR;
}

/* Baton for a SASL encrypted svn_ra_svn__stream_t. */
typedef struct sasl_baton {
  svn_ra_svn__stream_t *stream; /* Inherited stream. */
  sasl_conn_t *ctx;             /* The SASL context for this connection. */
  unsigned int maxsize;         /* The maximum amount of data we can encode. */
  const char *read_buf;         /* The buffer returned by sasl_decode. */
  unsigned int read_len;        /* Its current length. */
  const char *write_buf;        /* The buffer returned by sasl_encode. */
  unsigned int write_len;       /* Its length. */
  apr_pool_t *scratch_pool;
} sasl_baton_t;

/* Functions to implement a SASL encrypted svn_ra_svn__stream_t. */

/* Implements svn_read_fn_t. */
static svn_error_t *sasl_read_cb(void *baton, char *buffer, apr_size_t *len)
{
  sasl_baton_t *sasl_baton = baton;
  int result;
  /* A copy of *len, used by the wrapped stream. */
  apr_size_t len2 = *len;

  /* sasl_decode might need more data than a single read can provide,
     hence the need to put a loop around the decoding. */
  while (! sasl_baton->read_buf || sasl_baton->read_len == 0)
    {
      SVN_ERR(svn_ra_svn__stream_read(sasl_baton->stream, buffer, &len2));
      if (len2 == 0)
        {
          *len = 0;
          return SVN_NO_ERROR;
        }
      clear_sasl_errno();
      result = svn_sasl__decode(sasl_baton->ctx, buffer, (unsigned int) len2,
                                &sasl_baton->read_buf,
                                &sasl_baton->read_len);
      if (result != SASL_OK)
        return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                get_sasl_error(sasl_baton->ctx, result,
                                               sasl_baton->scratch_pool));
    }

  /* The buffer returned by sasl_decode might be larger than what the
     caller wants.  If this is the case, we only copy back *len bytes now
     (the rest will be returned by subsequent calls to this function).
     If not, we just copy back the whole thing. */
  if (*len >= sasl_baton->read_len)
    {
      memcpy(buffer, sasl_baton->read_buf, sasl_baton->read_len);
      *len = sasl_baton->read_len;
      sasl_baton->read_buf = NULL;
      sasl_baton->read_len = 0;
    }
  else
    {
      memcpy(buffer, sasl_baton->read_buf, *len);
      sasl_baton->read_len -= *len;
      sasl_baton->read_buf += *len;
    }

  return SVN_NO_ERROR;
}

/* Implements svn_write_fn_t. */
static svn_error_t *
sasl_write_cb(void *baton, const char *buffer, apr_size_t *len)
{
  sasl_baton_t *sasl_baton = baton;
  int result;

  if (! sasl_baton->write_buf || sasl_baton->write_len == 0)
    {
      /* Make sure we don't write too much. */
      *len = (*len > sasl_baton->maxsize) ? sasl_baton->maxsize : *len;
      clear_sasl_errno();
      result = svn_sasl__encode(sasl_baton->ctx, buffer, (unsigned int) *len,
                                &sasl_baton->write_buf,
                                &sasl_baton->write_len);

      if (result != SASL_OK)
        return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                get_sasl_error(sasl_baton->ctx, result,
                                               sasl_baton->scratch_pool));
    }

  do
    {
      apr_size_t tmplen = sasl_baton->write_len;
      SVN_ERR(svn_ra_svn__stream_write(sasl_baton->stream,
                                       sasl_baton->write_buf,
                                       &tmplen));
      if (tmplen == 0)
      {
        /* The output buffer and its length will be preserved in sasl_baton
           and will be written out during the next call to this function
           (which will have the same arguments). */
        *len = 0;
        return SVN_NO_ERROR;
      }
      sasl_baton->write_len -= (unsigned int) tmplen;
      sasl_baton->write_buf += tmplen;
    }
  while (sasl_baton->write_len > 0);

  sasl_baton->write_buf = NULL;
  sasl_baton->write_len = 0;

  return SVN_NO_ERROR;
}

/* Implements ra_svn_timeout_fn_t. */
static void sasl_timeout_cb(void *baton, apr_interval_time_t interval)
{
  sasl_baton_t *sasl_baton = baton;
  svn_ra_svn__stream_timeout(sasl_baton->stream, interval);
}

/* Implements svn_stream_data_available_fn_t. */
static svn_error_t *
sasl_data_available_cb(void *baton, svn_boolean_t *data_available)
{
  sasl_baton_t *sasl_baton = baton;
  return svn_error_trace(svn_ra_svn__stream_data_available(sasl_baton->stream,
                                                         data_available));
}

svn_error_t *svn_ra_svn__enable_sasl_encryption(svn_ra_svn_conn_t *conn,
                                                sasl_conn_t *sasl_ctx,
                                                apr_pool_t *pool)
{
  const sasl_ssf_t *ssfp;

  if (! conn->encrypted)
    {
      int result;

      /* Get the strength of the security layer. */
      clear_sasl_errno();
      result = svn_sasl__getprop(sasl_ctx, SASL_SSF, (void*) &ssfp);
      if (result != SASL_OK)
        return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                get_sasl_error(sasl_ctx, result, pool));

      if (*ssfp > 0)
        {
          sasl_baton_t *sasl_baton;
          const void *maxsize;

          /* Flush the connection, as we're about to replace its stream. */
          SVN_ERR(svn_ra_svn__flush(conn, pool));

          /* Create and initialize the stream baton. */
          sasl_baton = apr_pcalloc(conn->pool, sizeof(*sasl_baton));
          sasl_baton->ctx = sasl_ctx;
          sasl_baton->scratch_pool = conn->pool;

          /* Find out the maximum input size for sasl_encode. */
          clear_sasl_errno();
          result = svn_sasl__getprop(sasl_ctx, SASL_MAXOUTBUF, &maxsize);
          if (result != SASL_OK)
            return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                    get_sasl_error(sasl_ctx, result, pool));
          sasl_baton->maxsize = *((const unsigned int *) maxsize);

          /* If there is any data left in the read buffer at this point,
             we need to decrypt it. */
          if (conn->read_end > conn->read_ptr)
            {
              clear_sasl_errno();
              result = svn_sasl__decode(
                  sasl_ctx, conn->read_ptr,
                  (unsigned int) (conn->read_end - conn->read_ptr),
                  &sasl_baton->read_buf, &sasl_baton->read_len);
              if (result != SASL_OK)
                return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                        get_sasl_error(sasl_ctx, result, pool));
              conn->read_end = conn->read_ptr;
            }

          /* Wrap the existing stream. */
          sasl_baton->stream = conn->stream;

          {
            svn_stream_t *sasl_in = svn_stream_create(sasl_baton, conn->pool);
            svn_stream_t *sasl_out = svn_stream_create(sasl_baton, conn->pool);

            svn_stream_set_read2(sasl_in, sasl_read_cb, NULL /* use default */);
            svn_stream_set_data_available(sasl_in, sasl_data_available_cb);
            svn_stream_set_write(sasl_out, sasl_write_cb);

            conn->stream = svn_ra_svn__stream_create(sasl_in, sasl_out,
                                                     sasl_baton,
                                                     sasl_timeout_cb,
                                                     conn->pool);
          }
          /* Yay, we have a security layer! */
          conn->encrypted = TRUE;
        }
    }
  return SVN_NO_ERROR;
}

svn_error_t *svn_ra_svn__get_addresses(const char **local_addrport,
                                       const char **remote_addrport,
                                       svn_ra_svn_conn_t *conn,
                                       apr_pool_t *pool)
{
  if (conn->sock)
    {
      apr_status_t apr_err;
      apr_sockaddr_t *local_sa, *remote_sa;
      char *local_addr, *remote_addr;

      apr_err = apr_socket_addr_get(&local_sa, APR_LOCAL, conn->sock);
      if (apr_err)
        return svn_error_wrap_apr(apr_err, NULL);

      apr_err = apr_socket_addr_get(&remote_sa, APR_REMOTE, conn->sock);
      if (apr_err)
        return svn_error_wrap_apr(apr_err, NULL);

      apr_err = apr_sockaddr_ip_get(&local_addr, local_sa);
      if (apr_err)
        return svn_error_wrap_apr(apr_err, NULL);

      apr_err = apr_sockaddr_ip_get(&remote_addr, remote_sa);
      if (apr_err)
        return svn_error_wrap_apr(apr_err, NULL);

      /* Format the IP address and port number like this: a.b.c.d;port */
      *local_addrport = apr_pstrcat(pool, local_addr, ";",
                                    apr_itoa(pool, (int)local_sa->port),
                                    SVN_VA_NULL);
      *remote_addrport = apr_pstrcat(pool, remote_addr, ";",
                                     apr_itoa(pool, (int)remote_sa->port),
                                     SVN_VA_NULL);
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_ra_svn__do_cyrus_auth(svn_ra_svn__session_baton_t *sess,
                          const svn_ra_svn__list_t *mechlist,
                          const char *realm, apr_pool_t *pool)
{
  apr_pool_t *subpool;
  sasl_conn_t *sasl_ctx;
  const char *mechstring = "", *last_err = "", *realmstring;
  const char *local_addrport = NULL, *remote_addrport = NULL;
  svn_boolean_t success;
  sasl_callback_t *callbacks;
  cred_baton_t cred_baton = { 0 };
  int i;

  if (!sess->is_tunneled)
    {
      SVN_ERR(svn_ra_svn__get_addresses(&local_addrport, &remote_addrport,
                                        sess->conn, pool));
    }

  /* Prefer EXTERNAL, then ANONYMOUS, then let SASL decide. */
  if (svn_ra_svn__find_mech(mechlist, "EXTERNAL"))
    mechstring = "EXTERNAL";
  else if (svn_ra_svn__find_mech(mechlist, "ANONYMOUS"))
    mechstring = "ANONYMOUS";
  else
    {
      /* Create a string containing the list of mechanisms, separated by spaces. */
      for (i = 0; i < mechlist->nelts; i++)
        {
          svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(mechlist, i);
          mechstring = apr_pstrcat(pool,
                                   mechstring,
                                   i == 0 ? "" : " ",
                                   elt->u.word.data, SVN_VA_NULL);
        }
    }

  realmstring = apr_psprintf(pool, "%s %s", sess->realm_prefix, realm);

  /* Initialize the credential baton. */
  cred_baton.auth_baton = sess->auth_baton;
  cred_baton.realmstring = realmstring;
  cred_baton.pool = pool;

  /* Reserve space for 3 callbacks (for the username, password and the
     array terminator).  These structures must persist until the
     disposal of the SASL context at pool cleanup, however the
     callback functions will not be invoked outside this function so
     other structures can have a shorter lifetime. */
  callbacks = apr_palloc(sess->conn->pool, sizeof(*callbacks) * 3);

  /* Initialize the callbacks array. */

  /* The username callback. */
  callbacks[0].id = SASL_CB_AUTHNAME;
  callbacks[0].proc = (int (*)(void))get_username_cb;
  callbacks[0].context = &cred_baton;

  /* The password callback. */
  callbacks[1].id = SASL_CB_PASS;
  callbacks[1].proc = (int (*)(void))get_password_cb;
  callbacks[1].context = &cred_baton;

  /* Mark the end of the array. */
  callbacks[2].id = SASL_CB_LIST_END;
  callbacks[2].proc = NULL;
  callbacks[2].context = NULL;

  subpool = svn_pool_create(pool);
  do
    {
      svn_error_t *err;

      /* If last_err was set to a non-empty string, it needs to be duplicated
         to the parent pool before the subpool is cleared. */
      if (*last_err)
        last_err = apr_pstrdup(pool, last_err);
      svn_pool_clear(subpool);

      SVN_ERR(new_sasl_ctx(&sasl_ctx, sess->is_tunneled,
                           sess->hostname, local_addrport, remote_addrport,
                           callbacks, sess->conn->pool));
      err = try_auth(sess, sasl_ctx, &success, &last_err, mechstring,
                     subpool);

      /* If we encountered an error while fetching credentials, that error
         has priority. */
      if (cred_baton.err)
        {
          svn_error_clear(err);
          return cred_baton.err;
        }
      if (cred_baton.no_more_creds
          || (! err && ! success && ! cred_baton.was_used))
        {
          svn_error_clear(err);
          /* If we ran out of authentication providers, or if we got a server
             error and our callbacks were never called, there's no point in
             retrying authentication.  Return the last error sent by the
             server. */
          if (*last_err)
            return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                     _("Authentication error from server: %s"),
                                     last_err);
          /* Hmm, we don't have a server error. Return a generic error. */
          return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                  _("Can't get username or password"));
        }
      if (err)
        {
          if (err->apr_err == SVN_ERR_RA_SVN_NO_MECHANISMS)
            {
              svn_error_clear(err);

              /* We could not find a supported mechanism in the list sent by the
                 server. In many cases this happens because the client is missing
                 the CRAM-MD5 or ANONYMOUS plugins, in which case we can simply use
                 the built-in implementation. In all other cases this call will be
                 useless, but hey, at least we'll get consistent error messages. */
              return svn_error_trace(svn_ra_svn__do_internal_auth(sess, mechlist,
                                                                realm, pool));
            }
          return err;
        }
    }
  while (!success);
  svn_pool_destroy(subpool);

  SVN_ERR(svn_ra_svn__enable_sasl_encryption(sess->conn, sasl_ctx, pool));

  SVN_ERR(svn_auth_save_credentials(cred_baton.iterstate, pool));

  return SVN_NO_ERROR;
}

#endif /* SVN_HAVE_SASL */
