/*
  This file is part of libmicrohttpd
  Copyright (C) 2022 Evgeny Grin (Karlson2k)

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.
  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * @file microhttpd/gen_auth.c
 * @brief  HTTP authorisation general functions
 * @author Karlson2k (Evgeny Grin)
 */

#include "gen_auth.h"
#include "internal.h"
#include "connection.h"
#include "mhd_str.h"
#include "mhd_assert.h"

#ifdef BAUTH_SUPPORT
#include "basicauth.h"
#endif /* BAUTH_SUPPORT */
#ifdef DAUTH_SUPPORT
#include "digestauth.h"
#endif /* DAUTH_SUPPORT */

#if ! defined(BAUTH_SUPPORT) && ! defined(DAUTH_SUPPORT)
#error This file requires Basic or Digest authentication support
#endif

/**
 * Type of authorisation
 */
enum MHD_AuthType
{
  MHD_AUTHTYPE_NONE = 0,/**< No authorisation, unused */
  MHD_AUTHTYPE_BASIC,   /**< Basic Authorisation, RFC 7617  */
  MHD_AUTHTYPE_DIGEST,  /**< Digest Authorisation, RFC 7616 */
  MHD_AUTHTYPE_UNKNOWN, /**< Unknown/Unsupported authorisation type, unused */
  MHD_AUTHTYPE_INVALID  /**< Wrong/broken authorisation header, unused */
};

/**
 * Find required "Authorization" request header
 * @param c the connection with request
 * @param type the type of the authorisation: basic or digest
 * @param[out] auth_value will be set to the remaining of header value after
 *                        authorisation token (after "Basic " or "Digest ")
 * @return true if requested header is found,
 *         false otherwise
 */
static bool
find_auth_rq_header_ (const struct MHD_Connection *c, enum MHD_AuthType type,
                      struct _MHD_str_w_len *auth_value)
{
  const struct MHD_HTTP_Req_Header *h;
  const char *token;
  size_t token_len;

  mhd_assert (MHD_CONNECTION_HEADERS_PROCESSED <= c->state);
  if (MHD_CONNECTION_HEADERS_PROCESSED > c->state)
    return false;

#ifdef DAUTH_SUPPORT
  if (MHD_AUTHTYPE_DIGEST == type)
  {
    token = _MHD_AUTH_DIGEST_BASE;
    token_len = MHD_STATICSTR_LEN_ (_MHD_AUTH_DIGEST_BASE);
  }
  else /* combined with the next line */
#endif /* DAUTH_SUPPORT */
#ifdef BAUTH_SUPPORT
  if (MHD_AUTHTYPE_BASIC == type)
  {
    token = _MHD_AUTH_BASIC_BASE;
    token_len = MHD_STATICSTR_LEN_ (_MHD_AUTH_BASIC_BASE);
  }
  else /* combined with the next line */
#endif /* BAUTH_SUPPORT */
  {
    mhd_assert (0);
    return false;
  }

  for (h = c->rq.headers_received; NULL != h; h = h->next)
  {
    if (MHD_HEADER_KIND != h->kind)
      continue;
    if (MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_AUTHORIZATION) != h->header_size)
      continue;
    if (token_len > h->value_size)
      continue;
    if (! MHD_str_equal_caseless_bin_n_ (MHD_HTTP_HEADER_AUTHORIZATION,
                                         h->header,
                                         MHD_STATICSTR_LEN_ ( \
                                           MHD_HTTP_HEADER_AUTHORIZATION)))
      continue;
    if (! MHD_str_equal_caseless_bin_n_ (h->value, token, token_len))
      continue;
    /* Match only if token string is full header value or token is
     * followed by space or tab
     * Note: RFC 9110 (and RFC 7234) allows only space character, but
     * tab is supported here as well for additional flexibility and uniformity
     * as tabs are supported as separators between parameters.
     */
    if ((token_len == h->value_size) ||
        (' ' == h->value[token_len]) || ('\t'  == h->value[token_len]))
    {
      if (token_len != h->value_size)
      { /* Skip whitespace */
        auth_value->str = h->value + token_len + 1;
        auth_value->len = h->value_size - (token_len + 1);
      }
      else
      { /* No whitespace to skip */
        auth_value->str = h->value + token_len;
        auth_value->len = h->value_size - token_len;
      }
      return true; /* Found a match */
    }
  }
  return false; /* No matching header has been found */
}


#ifdef BAUTH_SUPPORT


/**
 * Parse request Authorization header parameters for Basic Authentication
 * @param str the header string, everything after "Basic " substring
 * @param str_len the length of @a str in characters
 * @param[out] pbauth the pointer to the structure with Basic Authentication
 *               parameters
 * @return true if parameters has been successfully parsed,
 *         false if format of the @a str is invalid
 */
static bool
parse_bauth_params (const char *str,
                    size_t str_len,
                    struct MHD_RqBAuth *pbauth)
{
  size_t i;

  i = 0;

  /* Skip all whitespaces at start */
  while (i < str_len && (' ' == str[i] || '\t' == str[i]))
    i++;

  if (str_len > i)
  {
    size_t token68_start;
    size_t token68_len;

    /* 'i' points to the first non-whitespace char after scheme token */
    token68_start = i;
    /* Find end of the token. Token cannot contain whitespace. */
    while (i < str_len && ' ' != str[i] && '\t' != str[i])
    {
      if (0 == str[i])
        return false;  /* Binary zero is not allowed */
      if ((',' == str[i]) || (';' == str[i]))
        return false;  /* Only single token68 is allowed */
      i++;
    }
    token68_len = i - token68_start;
    mhd_assert (0 != token68_len);

    /* Skip all whitespaces */
    while (i < str_len && (' ' == str[i] || '\t' == str[i]))
      i++;
    /* Check whether any garbage is present at the end of the string */
    if (str_len != i)
      return false;
    else
    {
      /* No more data in the string, only single token68. */
      pbauth->token68.str = str + token68_start;
      pbauth->token68.len = token68_len;
    }
  }
  return true;
}


/**
 * Return request's Basic Authorisation parameters.
 *
 * Function return result of parsing of the request's "Authorization" header or
 * returns cached parsing result if the header was already parsed for
 * the current request.
 * @param connection the connection to process
 * @return the pointer to structure with Authentication parameters,
 *         NULL if no memory in memory pool, if called too early (before
 *         header has been received) or if no valid Basic Authorisation header
 *         found.
 */
const struct MHD_RqBAuth *
MHD_get_rq_bauth_params_ (struct MHD_Connection *connection)
{
  struct _MHD_str_w_len h_auth_value;
  struct MHD_RqBAuth *bauth;

  mhd_assert (MHD_CONNECTION_HEADERS_PROCESSED <= connection->state);

  if (connection->rq.bauth_tried)
    return connection->rq.bauth;

  if (MHD_CONNECTION_HEADERS_PROCESSED > connection->state)
    return NULL;

  if (! find_auth_rq_header_ (connection, MHD_AUTHTYPE_BASIC, &h_auth_value))
  {
    connection->rq.bauth_tried = true;
    connection->rq.bauth = NULL;
    return NULL;
  }

  bauth =
    (struct MHD_RqBAuth *)
    MHD_connection_alloc_memory_ (connection, sizeof (struct MHD_RqBAuth));

  if (NULL == bauth)
  {
#ifdef HAVE_MESSAGES
    MHD_DLOG (connection->daemon,
              _ ("Not enough memory in the connection's pool to allocate " \
                 "for Basic Authorization header parsing.\n"));
#endif /* HAVE_MESSAGES */
    return NULL;
  }

  memset (bauth, 0, sizeof(struct MHD_RqBAuth));
  if (parse_bauth_params (h_auth_value.str, h_auth_value.len, bauth))
    connection->rq.bauth = bauth;
  else
  {
#ifdef HAVE_MESSAGES
    MHD_DLOG (connection->daemon,
              _ ("The Basic Authorization client's header has "
                 "incorrect format.\n"));
#endif /* HAVE_MESSAGES */
    connection->rq.bauth = NULL;
    /* Memory in the pool remains allocated until next request */
  }
  connection->rq.bauth_tried = true;
  return connection->rq.bauth;
}


#endif /* BAUTH_SUPPORT */

#ifdef DAUTH_SUPPORT

/**
 * Helper structure to map token name to position where to put token's value
 */
struct dauth_token_param
{
  const struct _MHD_cstr_w_len *const tk_name;
  struct MHD_RqDAuthParam *const param;
};


/**
 * Get client's Digest Authorization algorithm type.
 * If no algorithm is specified by client, MD5 is assumed.
 * @param params the Digest Authorization 'algorithm' parameter
 * @return the algorithm type
 */
static enum MHD_DigestAuthAlgo3
get_rq_dauth_algo (const struct MHD_RqDAuthParam *const algo_param)
{
  if (NULL == algo_param->value.str)
    return MHD_DIGEST_AUTH_ALGO3_MD5; /* Assume MD5 by default */

  if (algo_param->quoted)
  {
    if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
                                               algo_param->value.len, \
                                               _MHD_MD5_TOKEN))
      return MHD_DIGEST_AUTH_ALGO3_MD5;
    if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
                                               algo_param->value.len, \
                                               _MHD_SHA256_TOKEN))
      return MHD_DIGEST_AUTH_ALGO3_SHA256;
    if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
                                               algo_param->value.len, \
                                               _MHD_MD5_TOKEN _MHD_SESS_TOKEN))
      return MHD_DIGEST_AUTH_ALGO3_SHA512_256;
    if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
                                               algo_param->value.len, \
                                               _MHD_SHA512_256_TOKEN \
                                               _MHD_SESS_TOKEN))

      /* Algorithms below are not supported by MHD for authentication */

      return MHD_DIGEST_AUTH_ALGO3_MD5_SESSION;
    if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
                                               algo_param->value.len, \
                                               _MHD_SHA256_TOKEN \
                                               _MHD_SESS_TOKEN))
      return MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION;
    if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
                                               algo_param->value.len, \
                                               _MHD_SHA512_256_TOKEN))
      return MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION;

    /* No known algorithm has been detected */
    return MHD_DIGEST_AUTH_ALGO3_INVALID;
  }
  /* The algorithm value is not quoted */
  if (MHD_str_equal_caseless_s_bin_n_ (_MHD_MD5_TOKEN, \
                                       algo_param->value.str, \
                                       algo_param->value.len))
    return MHD_DIGEST_AUTH_ALGO3_MD5;
  if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA256_TOKEN, \
                                       algo_param->value.str, \
                                       algo_param->value.len))
    return MHD_DIGEST_AUTH_ALGO3_SHA256;
  if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA512_256_TOKEN, \
                                       algo_param->value.str, \
                                       algo_param->value.len))
    return MHD_DIGEST_AUTH_ALGO3_SHA512_256;

  /* Algorithms below are not supported by MHD for authentication */

  if (MHD_str_equal_caseless_s_bin_n_ (_MHD_MD5_TOKEN _MHD_SESS_TOKEN, \
                                       algo_param->value.str, \
                                       algo_param->value.len))
    return MHD_DIGEST_AUTH_ALGO3_MD5_SESSION;
  if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA256_TOKEN _MHD_SESS_TOKEN, \
                                       algo_param->value.str, \
                                       algo_param->value.len))
    return MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION;
  if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA512_256_TOKEN _MHD_SESS_TOKEN, \
                                       algo_param->value.str, \
                                       algo_param->value.len))
    return MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION;

  /* No known algorithm has been detected */
  return MHD_DIGEST_AUTH_ALGO3_INVALID;
}


/**
 * Get QOP ('quality of protection') type.
 * @param qop_param the Digest Authorization 'QOP' parameter
 * @return detected QOP ('quality of protection') type.
 */
static enum MHD_DigestAuthQOP
get_rq_dauth_qop (const struct MHD_RqDAuthParam *const qop_param)
{
  if (NULL == qop_param->value.str)
    return MHD_DIGEST_AUTH_QOP_NONE;
  if (qop_param->quoted)
  {
    if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \
                                               qop_param->value.len, \
                                               MHD_TOKEN_AUTH_))
      return MHD_DIGEST_AUTH_QOP_AUTH;
    if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \
                                               qop_param->value.len, \
                                               MHD_TOKEN_AUTH_INT_))
      return MHD_DIGEST_AUTH_QOP_AUTH_INT;
  }
  else
  {
    if (MHD_str_equal_caseless_s_bin_n_ (MHD_TOKEN_AUTH_, \
                                         qop_param->value.str, \
                                         qop_param->value.len))
      return MHD_DIGEST_AUTH_QOP_AUTH;
    if (MHD_str_equal_caseless_s_bin_n_ (MHD_TOKEN_AUTH_INT_, \
                                         qop_param->value.str, \
                                         qop_param->value.len))
      return MHD_DIGEST_AUTH_QOP_AUTH_INT;
  }
  /* No know QOP has been detected */
  return MHD_DIGEST_AUTH_QOP_INVALID;
}


/**
 * Parse request Authorization header parameters for Digest Authentication
 * @param str the header string, everything after "Digest " substring
 * @param str_len the length of @a str in characters
 * @param[out] pdauth the pointer to the structure with Digest Authentication
 *               parameters
 * @return true if parameters has been successfully parsed,
 *         false if format of the @a str is invalid
 */
static bool
parse_dauth_params (const char *str,
                    const size_t str_len,
                    struct MHD_RqDAuth *pdauth)
{
  static const struct _MHD_cstr_w_len nonce_tk = _MHD_S_STR_W_LEN ("nonce");
  static const struct _MHD_cstr_w_len opaque_tk = _MHD_S_STR_W_LEN ("opaque");
  static const struct _MHD_cstr_w_len algorithm_tk =
    _MHD_S_STR_W_LEN ("algorithm");
  static const struct _MHD_cstr_w_len response_tk =
    _MHD_S_STR_W_LEN ("response");
  static const struct _MHD_cstr_w_len username_tk =
    _MHD_S_STR_W_LEN ("username");
  static const struct _MHD_cstr_w_len username_ext_tk =
    _MHD_S_STR_W_LEN ("username*");
  static const struct _MHD_cstr_w_len realm_tk = _MHD_S_STR_W_LEN ("realm");
  static const struct _MHD_cstr_w_len uri_tk = _MHD_S_STR_W_LEN ("uri");
  static const struct _MHD_cstr_w_len qop_tk = _MHD_S_STR_W_LEN ("qop");
  static const struct _MHD_cstr_w_len cnonce_tk = _MHD_S_STR_W_LEN ("cnonce");
  static const struct _MHD_cstr_w_len nc_tk = _MHD_S_STR_W_LEN ("nc");
  static const struct _MHD_cstr_w_len userhash_tk =
    _MHD_S_STR_W_LEN ("userhash");
  struct MHD_RqDAuthParam userhash;
  struct MHD_RqDAuthParam algorithm;
  struct dauth_token_param map[] = {
    {&nonce_tk, &(pdauth->nonce)},
    {&opaque_tk, &(pdauth->opaque)},
    {&algorithm_tk, &algorithm},
    {&response_tk, &(pdauth->response)},
    {&username_tk, &(pdauth->username)},
    {&username_ext_tk, &(pdauth->username_ext)},
    {&realm_tk, &(pdauth->realm)},
    {&uri_tk, &(pdauth->uri)},
    {&qop_tk, &(pdauth->qop_raw)},
    {&cnonce_tk, &(pdauth->cnonce)},
    {&nc_tk, &(pdauth->nc)},
    {&userhash_tk, &userhash}
  };
  size_t i;
  size_t p;

  memset (&userhash, 0, sizeof(userhash));
  memset (&algorithm, 0, sizeof(algorithm));
  i = 0;

  /* Skip all whitespaces at start */
  while (i < str_len && (' ' == str[i] || '\t' == str[i]))
    i++;

  while (str_len > i)
  {
    size_t left;
    mhd_assert (' ' != str[i]);
    mhd_assert ('\t' != str[i]);

    left = str_len - i;
    if ('=' == str[i])
      return false; /* The equal sign is not allowed as the first character */
    for (p = 0; p < sizeof(map) / sizeof(map[0]); p++)
    {
      struct dauth_token_param *const aparam = map + p;
      if ( (aparam->tk_name->len <= left) &&
           MHD_str_equal_caseless_bin_n_ (str + i, aparam->tk_name->str,
                                          aparam->tk_name->len) &&
           ((aparam->tk_name->len == left) ||
            ('=' == str[i + aparam->tk_name->len]) ||
            (' ' == str[i + aparam->tk_name->len]) ||
            ('\t' == str[i + aparam->tk_name->len]) ||
            (',' == str[i + aparam->tk_name->len]) ||
            (';' == str[i + aparam->tk_name->len])) )
      {
        size_t value_start;
        size_t value_len;
        bool quoted; /* Only mark as "quoted" if backslash-escape used */

        if (aparam->tk_name->len == left)
          return false; /* No equal sign after parameter name, broken data */

        quoted = false;
        i += aparam->tk_name->len;
        /* Skip all whitespaces before '=' */
        while (str_len > i && (' ' == str[i] || '\t' == str[i]))
          i++;
        if ((i == str_len) || ('=' != str[i]))
          return false; /* No equal sign, broken data */
        i++;
        /* Skip all whitespaces after '=' */
        while (str_len > i && (' ' == str[i] || '\t' == str[i]))
          i++;
        if ((str_len > i) && ('"' == str[i]))
        { /* Value is in quotation marks */
          i++; /* Advance after the opening quote */
          value_start = i;
          while (str_len > i && '"' != str[i])
          {
            if ('\\' == str[i])
            {
              i++;
              quoted = true; /* Have escaped chars */
            }
            if (0 == str[i])
              return false; /* Binary zero in parameter value */
            i++;
          }
          if (str_len <= i)
            return false; /* No closing quote */
          mhd_assert ('"' == str[i]);
          value_len = i - value_start;
          i++; /* Advance after the closing quote */
        }
        else
        {
          value_start = i;
          while (str_len > i && ',' != str[i] &&
                 ' ' != str[i] && '\t' != str[i] && ';' != str[i])
          {
            if (0 == str[i])
              return false;  /* Binary zero in parameter value */
            i++;
          }
          if (';' == str[i])
            return false;  /* Semicolon in parameter value */
          value_len = i - value_start;
        }
        /* Skip all whitespaces after parameter value */
        while (str_len > i && (' ' == str[i] || '\t' == str[i]))
          i++;
        if ((str_len > i) && (',' != str[i]))
          return false; /* Garbage after parameter value */

        /* Have valid parameter name and value */
        mhd_assert (! quoted || 0 != value_len);
        aparam->param->value.str = str + value_start;
        aparam->param->value.len = value_len;
        aparam->param->quoted = quoted;

        break; /* Found matching parameter name */
      }
    }
    if (p == sizeof(map) / sizeof(map[0]))
    {
      /* No matching parameter name */
      while (str_len > i && ',' != str[i])
      {
        if ((0 == str[i]) || (';' == str[i]))
          return false; /* Not allowed characters */
        if ('"' == str[i])
        { /* Skip quoted part */
          i++; /* Advance after the opening quote */
          while (str_len > i && '"' != str[i])
          {
            if (0 == str[i])
              return false;  /* Binary zero is not allowed */
            if ('\\' == str[i])
              i++;           /* Skip escaped char */
            i++;
          }
          if (str_len <= i)
            return false; /* No closing quote */
          mhd_assert ('"' == str[i]);
        }
        i++;
      }
    }
    mhd_assert (str_len == i || ',' == str[i]);
    if (str_len > i)
      i++; /* Advance after ',' */
    /* Skip all whitespaces before next parameter name */
    while (i < str_len && (' ' == str[i] || '\t' == str[i]))
      i++;
  }

  /* Postprocess values */

  if (NULL != userhash.value.str)
  {
    if (userhash.quoted)
      pdauth->userhash =
        MHD_str_equal_caseless_quoted_s_bin_n (userhash.value.str, \
                                               userhash.value.len, \
                                               "true");
    else
      pdauth->userhash =
        MHD_str_equal_caseless_s_bin_n_ ("true", userhash.value.str, \
                                         userhash.value.len);

  }
  else
    pdauth->userhash = false;

  pdauth->algo3 = get_rq_dauth_algo (&algorithm);
  pdauth->qop = get_rq_dauth_qop (&pdauth->qop_raw);

  return true;
}


/**
 * Return request's Digest Authorisation parameters.
 *
 * Function return result of parsing of the request's "Authorization" header or
 * returns cached parsing result if the header was already parsed for
 * the current request.
 * @param connection the connection to process
 * @return the pointer to structure with Authentication parameters,
 *         NULL if no memory in memory pool, if called too early (before
 *         header has been received) or if no valid Basic Authorisation header
 *         found.
 */
const struct MHD_RqDAuth *
MHD_get_rq_dauth_params_ (struct MHD_Connection *connection)
{
  struct _MHD_str_w_len h_auth_value;
  struct MHD_RqDAuth *dauth;

  mhd_assert (MHD_CONNECTION_HEADERS_PROCESSED <= connection->state);

  if (connection->rq.dauth_tried)
    return connection->rq.dauth;

  if (MHD_CONNECTION_HEADERS_PROCESSED > connection->state)
    return NULL;

  if (! find_auth_rq_header_ (connection, MHD_AUTHTYPE_DIGEST, &h_auth_value))
  {
    connection->rq.dauth_tried = true;
    connection->rq.dauth = NULL;
    return NULL;
  }

  dauth =
    (struct MHD_RqDAuth *)
    MHD_connection_alloc_memory_ (connection, sizeof (struct MHD_RqDAuth));

  if (NULL == dauth)
  {
#ifdef HAVE_MESSAGES
    MHD_DLOG (connection->daemon,
              _ ("Not enough memory in the connection's pool to allocate " \
                 "for Digest Authorization header parsing.\n"));
#endif /* HAVE_MESSAGES */
    return NULL;
  }

  memset (dauth, 0, sizeof(struct MHD_RqDAuth));
  if (parse_dauth_params (h_auth_value.str, h_auth_value.len, dauth))
    connection->rq.dauth = dauth;
  else
  {
#ifdef HAVE_MESSAGES
    MHD_DLOG (connection->daemon,
              _ ("The Digest Authorization client's header has "
                 "incorrect format.\n"));
#endif /* HAVE_MESSAGES */
    connection->rq.dauth = NULL;
    /* Memory in the pool remains allocated until next request */
  }
  connection->rq.dauth_tried = true;
  return connection->rq.dauth;
}


#endif /* DAUTH_SUPPORT */
