/*
 * cram.c :  Minimal standalone CRAM-MD5 implementation
 *
 * ====================================================================
 *    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.
 * ====================================================================
 */



#define APR_WANT_STRFUNC
#define APR_WANT_STDIO
#include <apr_want.h>
#include <apr_general.h>
#include <apr_strings.h>
#include <apr_network_io.h>
#include <apr_time.h>
#include <apr_md5.h>

#include "svn_types.h"
#include "svn_string.h"
#include "svn_error.h"
#include "svn_ra_svn.h"
#include "svn_config.h"
#include "svn_private_config.h"

#include "ra_svn.h"

static int hex_to_int(char c)
{
  return (c >= '0' && c <= '9') ? c - '0'
    : (c >= 'a' && c <= 'f') ? c - 'a' + 10
    : -1;
}

static char int_to_hex(int v)
{
  return (char)((v < 10) ? '0' + v : 'a' + (v - 10));
}

static svn_boolean_t hex_decode(unsigned char *hashval, const char *hexval)
{
  int i, h1, h2;

  for (i = 0; i < APR_MD5_DIGESTSIZE; i++)
    {
      h1 = hex_to_int(hexval[2 * i]);
      h2 = hex_to_int(hexval[2 * i + 1]);
      if (h1 == -1 || h2 == -1)
        return FALSE;
      hashval[i] = (unsigned char)((h1 << 4) | h2);
    }
  return TRUE;
}

static void hex_encode(char *hexval, const unsigned char *hashval)
{
  int i;

  for (i = 0; i < APR_MD5_DIGESTSIZE; i++)
    {
      hexval[2 * i] = int_to_hex((hashval[i] >> 4) & 0xf);
      hexval[2 * i + 1] = int_to_hex(hashval[i] & 0xf);
    }
}

static void compute_digest(unsigned char *digest, const char *challenge,
                           const char *password)
{
  unsigned char secret[64];
  apr_size_t len = strlen(password), i;
  apr_md5_ctx_t ctx;

  /* Munge the password into a 64-byte secret. */
  memset(secret, 0, sizeof(secret));
  if (len <= sizeof(secret))
    memcpy(secret, password, len);
  else
    apr_md5(secret, password, len);

  /* Compute MD5(secret XOR opad, MD5(secret XOR ipad, challenge)),
   * where ipad is a string of 0x36 and opad is a string of 0x5c. */
  for (i = 0; i < sizeof(secret); i++)
    secret[i] ^= 0x36;
  apr_md5_init(&ctx);
  apr_md5_update(&ctx, secret, sizeof(secret));
  apr_md5_update(&ctx, challenge, strlen(challenge));
  apr_md5_final(digest, &ctx);
  for (i = 0; i < sizeof(secret); i++)
    secret[i] ^= (0x36 ^ 0x5c);
  apr_md5_init(&ctx);
  apr_md5_update(&ctx, secret, sizeof(secret));
  apr_md5_update(&ctx, digest, APR_MD5_DIGESTSIZE);
  apr_md5_final(digest, &ctx);
}

/* Fail the authentication, from the server's perspective. */
static svn_error_t *fail(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                         const char *msg)
{
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(c)", "failure", msg));
  return svn_ra_svn__flush(conn, pool);
}

/* If we can, make the nonce with random bytes.  If we can't... well,
 * it just has to be different each time.  The current time isn't
 * absolutely guaranteed to be different for each connection, but it
 * should prevent replay attacks in practice. */
static apr_status_t make_nonce(apr_uint64_t *nonce)
{
#if APR_HAS_RANDOM
  return apr_generate_random_bytes((unsigned char *) nonce, sizeof(*nonce));
#else
  *nonce = apr_time_now();
  return APR_SUCCESS;
#endif
}

svn_error_t *svn_ra_svn_cram_server(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                    svn_config_t *pwdb, const char **user,
                                    svn_boolean_t *success)
{
  apr_status_t status;
  apr_uint64_t nonce;
  char hostbuf[APRMAXHOSTLEN + 1];
  unsigned char cdigest[APR_MD5_DIGESTSIZE], sdigest[APR_MD5_DIGESTSIZE];
  const char *challenge, *sep, *password;
  svn_ra_svn_item_t *item;
  svn_string_t *resp;

  *success = FALSE;

  /* Send a challenge. */
  status = make_nonce(&nonce);
  if (!status)
    status = apr_gethostname(hostbuf, sizeof(hostbuf), pool);
  if (status)
    return fail(conn, pool, "Internal server error in authentication");
  challenge = apr_psprintf(pool,
                           "<%" APR_UINT64_T_FMT ".%" APR_TIME_T_FMT "@%s>",
                           nonce, apr_time_now(), hostbuf);
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(c)", "step", challenge));

  /* Read the client's response and decode it into *user and cdigest. */
  SVN_ERR(svn_ra_svn__read_item(conn, pool, &item));
  if (item->kind != SVN_RA_SVN_STRING)  /* Very wrong; don't report failure */
    return SVN_NO_ERROR;
  resp = item->u.string;
  sep = strrchr(resp->data, ' ');
  if (!sep || resp->len - (sep + 1 - resp->data) != APR_MD5_DIGESTSIZE * 2
      || !hex_decode(cdigest, sep + 1))
    return fail(conn, pool, "Malformed client response in authentication");
  *user = apr_pstrmemdup(pool, resp->data, sep - resp->data);

  /* Verify the digest against the password in pwfile. */
  svn_config_get(pwdb, &password, SVN_CONFIG_SECTION_USERS, *user, NULL);
  if (!password)
    return fail(conn, pool, "Username not found");
  compute_digest(sdigest, challenge, password);
  if (memcmp(cdigest, sdigest, sizeof(sdigest)) != 0)
    return fail(conn, pool, "Password incorrect");

  *success = TRUE;
  return svn_ra_svn__write_tuple(conn, pool, "w()", "success");
}

svn_error_t *svn_ra_svn__cram_client(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                     const char *user, const char *password,
                                     const char **message)
{
  const char *status, *str, *reply;
  unsigned char digest[APR_MD5_DIGESTSIZE];
  char hex[2 * APR_MD5_DIGESTSIZE + 1];

  /* Read the server challenge. */
  SVN_ERR(svn_ra_svn__read_tuple(conn, pool, "w(?c)", &status, &str));
  if (strcmp(status, "failure") == 0 && str)
    {
      *message = str;
      return SVN_NO_ERROR;
    }
  else if (strcmp(status, "step") != 0 || !str)
    return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                            _("Unexpected server response to authentication"));

  /* Write our response. */
  compute_digest(digest, str, password);
  hex_encode(hex, digest);
  hex[sizeof(hex) - 1] = '\0';
  reply = apr_psprintf(pool, "%s %s", user, hex);
  SVN_ERR(svn_ra_svn__write_cstring(conn, pool, reply));

  /* Read the success or failure response from the server. */
  SVN_ERR(svn_ra_svn__read_tuple(conn, pool, "w(?c)", &status, &str));
  if (strcmp(status, "failure") == 0 && str)
    {
      *message = str;
      return SVN_NO_ERROR;
    }
  else if (strcmp(status, "success") != 0 || str)
    return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                            _("Unexpected server response to authentication"));

  *message = NULL;
  return SVN_NO_ERROR;
}
