/*
 * mod_authz_svn.c: an Apache mod_dav_svn sub-module to provide path
 *                  based authorization for a Subversion repository.
 *
 * ====================================================================
 *    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 <httpd.h>
#include <http_config.h>
#include <http_core.h>
#include <http_request.h>
#include <http_protocol.h>
#include <http_log.h>
#include <http_config.h>
#include <ap_config.h>
#include <ap_provider.h>
#include <ap_mmn.h>
#include <apr_uri.h>
#include <apr_lib.h>
#include <mod_dav.h>

#include "mod_dav_svn.h"
#include "mod_authz_svn.h"
#include "svn_path.h"
#include "svn_config.h"
#include "svn_string.h"
#include "svn_repos.h"
#include "svn_pools.h"
#include "svn_dirent_uri.h"
#include "private/svn_fspath.h"

/* The apache headers define these and they conflict with our definitions. */
#ifdef PACKAGE_BUGREPORT
#undef PACKAGE_BUGREPORT
#endif
#ifdef PACKAGE_NAME
#undef PACKAGE_NAME
#endif
#ifdef PACKAGE_STRING
#undef PACKAGE_STRING
#endif
#ifdef PACKAGE_TARNAME
#undef PACKAGE_TARNAME
#endif
#ifdef PACKAGE_VERSION
#undef PACKAGE_VERSION
#endif
#include "svn_private_config.h"

#ifdef APLOG_USE_MODULE
APLOG_USE_MODULE(authz_svn);
#else
/* This is part of the APLOG_USE_MODULE() macro in httpd-2.3 */
extern module AP_MODULE_DECLARE_DATA authz_svn_module;
#endif

typedef struct authz_svn_config_rec {
  int authoritative;
  int anonymous;
  int no_auth_when_anon_ok;
  const char *base_path;
  const char *access_file;
  const char *repo_relative_access_file;
  const char *groups_file;
  const char *force_username_case;
} authz_svn_config_rec;

/* version where ap_some_auth_required breaks */
#if AP_MODULE_MAGIC_AT_LEAST(20060110,0)
/* first version with force_authn hook and ap_some_authn_required()
   which allows us to work without ap_some_auth_required() */
#  if AP_MODULE_MAGIC_AT_LEAST(20120211,47) || defined(SVN_USE_FORCE_AUTHN)
#    define USE_FORCE_AUTHN 1
#    define IN_SOME_AUTHN_NOTE "authz_svn-in-some-authn"
#    define FORCE_AUTHN_NOTE "authz_svn-force-authn"
#  else
     /* ap_some_auth_required() is busted and no viable alternative exists */
#    ifndef SVN_ALLOW_BROKEN_HTTPD_AUTH
#      error This Apache httpd has broken auth (CVE-2015-3184)
#    else
       /* user wants to build anyway */
#      define USE_FORCE_AUTHN 0
#    endif
#  endif
#else
   /* old enough that ap_some_auth_required() still works */
#  define USE_FORCE_AUTHN 0
#endif

/*
 * Configuration
 */

/* Implements the #create_dir_config method of Apache's #module vtable. */
static void *
create_authz_svn_dir_config(apr_pool_t *p, char *d)
{
  authz_svn_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
  conf->base_path = d;

  if (d)
    conf->base_path = svn_urlpath__canonicalize(d, p);

  /* By default keep the fortress secure */
  conf->authoritative = 1;
  conf->anonymous = 1;

  return conf;
}

/* canonicalize ACCESS_FILE based on the type of argument.
 * If SERVER_RELATIVE is true, ACCESS_FILE is a relative
 * path then ACCESS_FILE is converted to an absolute
 * path rooted at the server root.
 * Returns NULL if path is not valid.*/
static const char *
canonicalize_access_file(const char *access_file,
                         svn_boolean_t server_relative,
                         apr_pool_t *pool)
{
  if (svn_path_is_url(access_file))
    {
      access_file = svn_uri_canonicalize(access_file, pool);
    }
  else if (!svn_path_is_repos_relative_url(access_file))
    {
      if (server_relative)
        {
          access_file = ap_server_root_relative(pool, access_file);
          if (access_file == NULL)
            return NULL;
        }

      access_file = svn_dirent_internal_style(access_file, pool);
    }

  /* We don't canonicalize repos relative urls since they get
   * canonicalized before calling svn_repos_authz_read3() when they
   * are resolved. */

  return access_file;
}

static const char *
AuthzSVNAccessFile_cmd(cmd_parms *cmd, void *config, const char *arg1)
{
  authz_svn_config_rec *conf = config;

  if (conf->repo_relative_access_file != NULL)
    return "AuthzSVNAccessFile and AuthzSVNReposRelativeAccessFile "
           "directives are mutually exclusive.";

  conf->access_file = canonicalize_access_file(arg1, TRUE, cmd->pool);
  if (!conf->access_file)
    return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, SVN_VA_NULL);

  return NULL;
}


static const char *
AuthzSVNReposRelativeAccessFile_cmd(cmd_parms *cmd,
                                    void *config,
                                    const char *arg1)
{
  authz_svn_config_rec *conf = config;

  if (conf->access_file != NULL)
    return "AuthzSVNAccessFile and AuthzSVNReposRelativeAccessFile "
           "directives are mutually exclusive.";

  conf->repo_relative_access_file = canonicalize_access_file(arg1, FALSE,
                                                             cmd->pool);

  if (!conf->repo_relative_access_file)
    return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, SVN_VA_NULL);

  return NULL;
}

static const char *
AuthzSVNGroupsFile_cmd(cmd_parms *cmd, void *config, const char *arg1)
{
  authz_svn_config_rec *conf = config;

  conf->groups_file = canonicalize_access_file(arg1, TRUE, cmd->pool);

  if (!conf->groups_file)
    return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, SVN_VA_NULL);

  return NULL;
}

/* Implements the #cmds member of Apache's #module vtable. */
static const command_rec authz_svn_cmds[] =
{
  AP_INIT_FLAG("AuthzSVNAuthoritative", ap_set_flag_slot,
               (void *)APR_OFFSETOF(authz_svn_config_rec, authoritative),
               OR_AUTHCFG,
               "Set to 'Off' to allow access control to be passed along to "
               "lower modules. (default is On.)"),
  AP_INIT_TAKE1("AuthzSVNAccessFile", AuthzSVNAccessFile_cmd,
                NULL,
                OR_AUTHCFG,
                "Path to text file containing permissions of repository "
                "paths.  Path may be an repository relative URL (^/) or "
                "absolute file:// URL to a text file in a Subversion "
                "repository."),
  AP_INIT_TAKE1("AuthzSVNReposRelativeAccessFile",
                AuthzSVNReposRelativeAccessFile_cmd,
                NULL,
                OR_AUTHCFG,
                "Path (relative to repository 'conf' directory) to text "
                "file containing permissions of repository paths. Path may "
                "be an repository relative URL (^/) or absolute file:// URL "
                "to a text file in a Subversion repository."),
  AP_INIT_TAKE1("AuthzSVNGroupsFile",
                AuthzSVNGroupsFile_cmd,
                NULL,
                OR_AUTHCFG,
                "Path to text file containing group definitions for all "
                "repositories.  Path may be an repository relative URL (^/) "
                "or absolute file:// URL to a text file in a Subversion "
                "repository."),
  AP_INIT_FLAG("AuthzSVNAnonymous", ap_set_flag_slot,
               (void *)APR_OFFSETOF(authz_svn_config_rec, anonymous),
               OR_AUTHCFG,
               "Set to 'Off' to disable two special-case behaviours of "
               "this module: (1) interaction with the 'Satisfy Any' "
               "directive, and (2) enforcement of the authorization "
               "policy even when no 'Require' directives are present. "
               "(default is On.)"),
  AP_INIT_FLAG("AuthzSVNNoAuthWhenAnonymousAllowed", ap_set_flag_slot,
               (void *)APR_OFFSETOF(authz_svn_config_rec,
                                    no_auth_when_anon_ok),
               OR_AUTHCFG,
               "Set to 'On' to suppress authentication and authorization "
               "for requests which anonymous users are allowed to perform. "
               "(default is Off.)"),
  AP_INIT_TAKE1("AuthzForceUsernameCase", ap_set_string_slot,
                (void *)APR_OFFSETOF(authz_svn_config_rec,
                                     force_username_case),
                OR_AUTHCFG,
                "Set to 'Upper' or 'Lower' to convert the username before "
                "checking for authorization."),
  { NULL }
};


/* The macros LOG_ARGS_SIGNATURE and LOG_ARGS_CASCADE are expanded as formal
 * and actual parameters to log_access_verdict with respect to HTTPD version.
 */
#if AP_MODULE_MAGIC_AT_LEAST(20100606,0)
#define LOG_ARGS_SIGNATURE const char *file, int line, int module_index
#define LOG_ARGS_CASCADE file, line, module_index
#else
#define LOG_ARGS_SIGNATURE const char *file, int line
#define LOG_ARGS_CASCADE file, line
#endif

/* Log a message indicating the access control decision made about a
 * request.  The macro LOG_ARGS_SIGNATURE expands to FILE, LINE and
 * MODULE_INDEX in HTTPD 2.3 as APLOG_MARK macro has been changed for
 * per-module loglevel configuration.  It expands to FILE and LINE
 * in older server versions.  ALLOWED is boolean.
 * REPOS_PATH and DEST_REPOS_PATH are information
 * about the request.  DEST_REPOS_PATH may be NULL.
 * Non-zero IS_SUBREQ_BYPASS means that this authorization check was
 * implicitly requested using 'subrequest bypass' callback from
 * mod_dav_svn.
 */
static void
log_access_verdict(LOG_ARGS_SIGNATURE,
                   const request_rec *r, int allowed, int is_subreq_bypass,
                   const char *repos_path, const char *dest_repos_path)
{
  int level = allowed ? APLOG_INFO : APLOG_ERR;
  const char *verdict = allowed ? "granted" : "denied";

  /* Use less important log level for implicit sub-request authorization
     checks. */
  if (is_subreq_bypass)
    level = APLOG_INFO;
  else if (r->main && r->method_number == M_GET)
    level = APLOG_INFO;

  if (r->user)
    {
      if (dest_repos_path)
        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
                      "Access %s: '%s' %s %s %s", verdict, r->user,
                      r->method, repos_path, dest_repos_path);
      else
        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
                      "Access %s: '%s' %s %s", verdict, r->user,
                      r->method, repos_path);
    }
  else
    {
      if (dest_repos_path)
        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
                      "Access %s: - %s %s %s", verdict,
                      r->method, repos_path, dest_repos_path);
      else
        ap_log_rerror(LOG_ARGS_CASCADE, level, 0, r,
                      "Access %s: - %s %s", verdict,
                      r->method, repos_path);
    }
}

/* Log a message at LOG_LEVEL indicating the ERR encountered during
 * the request R.
 * LOG_ARGS_SIGNATURE expands as in log_access_verdict() above.
 * PREFIX is inserted at the start of the message.  The rest of the
 * message is generated by combining the message for each error in the
 * chain of ERR, excluding for trace errors.  ERR will be cleared
 * when finished. */
static void
log_svn_message(LOG_ARGS_SIGNATURE, int log_level,
                request_rec *r, const char *prefix,
                svn_error_t *err, apr_pool_t *scratch_pool)
{
  svn_error_t *err_pos = svn_error_purge_tracing(err);
  svn_stringbuf_t *buff = svn_stringbuf_create(prefix, scratch_pool);

  /* Build the error chain into a space separated stringbuf. */
  while (err_pos)
    {
      svn_stringbuf_appendbyte(buff, ' ');
      if (err_pos->message)
        {
          svn_stringbuf_appendcstr(buff, err_pos->message);
        }
      else
        {
          char strerr[256];

          svn_stringbuf_appendcstr(buff, svn_strerror(err->apr_err, strerr,
                                                       sizeof(strerr)));
        }

      err_pos = err_pos->child;
    }

  ap_log_rerror(LOG_ARGS_CASCADE, log_level,
                /* If it is an error code that APR can make sense of, then
                   show it, otherwise, pass zero to avoid putting "APR does
                   not understand this error code" in the error log. */
                ((err->apr_err >= APR_OS_START_USERERR &&
                  err->apr_err < APR_OS_START_CANONERR) ?
                 0 : err->apr_err),
                r, "%s", buff->data);

  svn_error_clear(err);
}

/* Log the error error ERR encountered during the request R.
 * LOG_ARGS_SIGNATURE expands as in log_access_verdict() above.
 * PREFIX is inserted at the start of the message.  The rest of the
 * message is generated by combining the message for each error in the
 * chain of ERR, excluding for trace errors.  ERR will be cleared
 * when finished. */
static APR_INLINE void
log_svn_error(LOG_ARGS_SIGNATURE,
              request_rec *r, const char *prefix,
              svn_error_t *err, apr_pool_t *scratch_pool)
{
  log_svn_message(LOG_ARGS_CASCADE, APLOG_ERR,
                  r, prefix, err, scratch_pool);
}

/* Baton for log_authz_warning. */
typedef struct authz_warning_baton_t
{
  request_rec *r;
  const char *prefix;
} authz_warning_baton_t;

/* Handle an authz parser warning. ERR will *not* be cleared.*/
static APR_INLINE void
log_authz_warning(void *baton,
                  const svn_error_t *err,
                  apr_pool_t *scratch_pool)
{
  const authz_warning_baton_t *const warning_baton = baton;
  log_svn_message(APLOG_MARK, APLOG_WARNING,
                  warning_baton->r, warning_baton->prefix,
                  svn_error_dup(err), scratch_pool);
}

/* Resolve *PATH into an absolute canonical URL iff *PATH is a repos-relative
 * URL.  If *REPOS_URL is NULL convert REPOS_PATH into a file URL stored
 * in *REPOS_URL, if *REPOS_URL is not null REPOS_PATH is ignored.  The
 * resulting *REPOS_URL will be used as the root of the repos-relative URL.
 * The result will be stored in *PATH. */
static svn_error_t *
resolve_repos_relative_url(const char **path, const char **repos_url,
                           const char *repos_path, apr_pool_t *pool)
{
  if (svn_path_is_repos_relative_url(*path))
    {
      if (!*repos_url)
        SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, repos_path, pool));

      SVN_ERR(svn_path_resolve_repos_relative_url(path, *path,
                                                  *repos_url, pool));
      *path = svn_uri_canonicalize(*path, pool);
    }

  return SVN_NO_ERROR;
}

/*
 * Get the, possibly cached, svn_authz_t for this request.
 */
static svn_authz_t *
get_access_conf(request_rec *r, authz_svn_config_rec *conf,
                apr_pool_t *scratch_pool)
{
  const char *cache_key = NULL;
  const char *access_file;
  const char *groups_file;
  const char *repos_path;
  const char *repos_url = NULL;
  void *user_data = NULL;
  svn_authz_t *access_conf = NULL;
  svn_error_t *svn_err = SVN_NO_ERROR;
  dav_error *dav_err;

  dav_err = dav_svn_get_repos_path2(r, conf->base_path, &repos_path, scratch_pool);
  if (dav_err)
    {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "%s", dav_err->desc);
      return NULL;
    }

  if (conf->repo_relative_access_file)
    {
      access_file = conf->repo_relative_access_file;
      if (!svn_path_is_repos_relative_url(access_file) &&
          !svn_path_is_url(access_file))
        {
          access_file = svn_dirent_join_many(scratch_pool, repos_path, "conf",
                                             conf->repo_relative_access_file,
                                             SVN_VA_NULL);
        }
    }
  else
    {
      access_file = conf->access_file;
    }
  groups_file = conf->groups_file;

  svn_err = resolve_repos_relative_url(&access_file, &repos_url, repos_path,
                                       scratch_pool);
  if (svn_err)
    {
      log_svn_error(APLOG_MARK, r,
                    conf->repo_relative_access_file ?
                    "Failed to load the AuthzSVNReposRelativeAccessFile:" :
                    "Failed to load the AuthzSVNAccessFile:",
                    svn_err, scratch_pool);
      return NULL;
    }

  ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                "Path to authz file is %s", access_file);

  if (groups_file)
    {
      svn_err = resolve_repos_relative_url(&groups_file, &repos_url, repos_path,
                                           scratch_pool);
      if (svn_err)
        {
          log_svn_error(APLOG_MARK, r,
                        "Failed to load the AuthzSVNGroupsFile:",
                        svn_err, scratch_pool);
          return NULL;
        }

      ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                    "Path to groups file is %s", groups_file);
    }

  cache_key = apr_pstrcat(scratch_pool, "mod_authz_svn:",
                          access_file, groups_file, SVN_VA_NULL);
  apr_pool_userdata_get(&user_data, cache_key, r->connection->pool);
  access_conf = user_data;
  if (access_conf == NULL)
    {
      authz_warning_baton_t warning_baton;
      warning_baton.r = r;
      warning_baton.prefix = "mod_authz_svn: warning:";

      svn_err = svn_repos_authz_read4(&access_conf, access_file,
                                      groups_file, TRUE, NULL,
                                      log_authz_warning, &warning_baton,
                                      r->connection->pool,
                                      scratch_pool);

      if (svn_err)
        {
          log_svn_error(APLOG_MARK, r,
                        "Failed to load the mod_authz_svn config:",
                        svn_err, scratch_pool);
          access_conf = NULL;
        }
      else
        {
          /* Cache the open repos for the next request on this connection */
          apr_pool_userdata_set(access_conf, cache_key,
                                NULL, r->connection->pool);
        }
    }
  return access_conf;
}

/* Convert TEXT to upper case if TO_UPPERCASE is TRUE, else
   converts it to lower case. */
static void
convert_case(char *text, svn_boolean_t to_uppercase)
{
  char *c = text;
  while (*c)
    {
      *c = (char)(to_uppercase ? apr_toupper(*c) : apr_tolower(*c));
      ++c;
    }
}

/* Return the username to authorize, with case-conversion performed if
   CONF->force_username_case is set. */
static char *
get_username_to_authorize(request_rec *r, authz_svn_config_rec *conf,
                          apr_pool_t *pool)
{
  char *username_to_authorize = r->user;
  if (username_to_authorize && conf->force_username_case)
    {
      username_to_authorize = apr_pstrdup(pool, r->user);
      convert_case(username_to_authorize,
                   strcasecmp(conf->force_username_case, "upper") == 0);
    }
  return username_to_authorize;
}

/* Check if the current request R is allowed.  Upon exit *REPOS_PATH_REF
 * will contain the path and repository name that an operation was requested
 * on in the form 'name:path'.  *DEST_REPOS_PATH_REF will contain the
 * destination path if the requested operation was a MOVE or a COPY.
 * Returns OK when access is allowed, DECLINED when it isn't, or an HTTP_
 * error code when an error occurred.
 */
static int
req_check_access(request_rec *r,
                 authz_svn_config_rec *conf,
                 const char **repos_path_ref,
                 const char **dest_repos_path_ref)
{
  const char *dest_uri;
  apr_uri_t parsed_dest_uri;
  const char *cleaned_uri;
  int trailing_slash;
  const char *repos_name;
  const char *dest_repos_name;
  const char *relative_path;
  const char *repos_path;
  const char *dest_repos_path = NULL;
  dav_error *dav_err;
  svn_repos_authz_access_t authz_svn_type = svn_authz_none;
  svn_boolean_t authz_access_granted = FALSE;
  svn_authz_t *access_conf = NULL;
  svn_error_t *svn_err;
  const char *username_to_authorize = get_username_to_authorize(r, conf,
                                                                r->pool);

  switch (r->method_number)
    {
      /* All methods requiring read access to all subtrees of r->uri */
      case M_COPY:
        authz_svn_type |= svn_authz_recursive;

      /* All methods requiring read access to r->uri */
      case M_OPTIONS:
      case M_GET:
      case M_PROPFIND:
      case M_REPORT:
        authz_svn_type |= svn_authz_read;
        break;

      /* All methods requiring write access to all subtrees of r->uri */
      case M_MOVE:
      case M_DELETE:
        authz_svn_type |= svn_authz_recursive;

      /* All methods requiring write access to r->uri */
      case M_MKCOL:
      case M_PUT:
      case M_PROPPATCH:
      case M_CHECKOUT:
      case M_MERGE:
      case M_MKACTIVITY:
      case M_LOCK:
      case M_UNLOCK:
        authz_svn_type |= svn_authz_write;
        break;

      default:
        /* Require most strict access for unknown methods */
        authz_svn_type |= svn_authz_write | svn_authz_recursive;
        break;
    }

  if (strcmp(svn_urlpath__canonicalize(r->uri, r->pool), conf->base_path) == 0)
    {
      /* Do no access control when conf->base_path(as configured in <Location>)
       * and given uri are same. The reason for such relaxation of access
       * control is "This module is meant to control access inside the
       * repository path, in this case inside PATH is empty and hence
       * dav_svn_split_uri fails saying no repository name present".
       * One may ask it will allow access to '/' inside the repository if
       * repository is served via SVNPath instead of SVNParentPath.
       * It does not, The other methods(PROPFIND, MKACTIVITY) for
       * accomplishing the operation takes care of making a request to
       * proper URL */
      return OK;
    }

  dav_err = dav_svn_split_uri(r,
                              r->uri,
                              conf->base_path,
                              &cleaned_uri,
                              &trailing_slash,
                              &repos_name,
                              &relative_path,
                              &repos_path);
  if (dav_err)
    {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "%s  [%d, #%d]",
                    dav_err->desc, dav_err->status, dav_err->error_id);
      /* Ensure that we never allow access by dav_err->status */
      return (dav_err->status != OK && dav_err->status != DECLINED) ?
              dav_err->status : HTTP_INTERNAL_SERVER_ERROR;
    }

  /* Ignore the URI passed to MERGE, like mod_dav_svn does.
   * See issue #1821.
   * XXX: When we start accepting a broader range of DeltaV MERGE
   * XXX: requests, this should be revisited.
   */
  if (r->method_number == M_MERGE)
    repos_path = NULL;

  if (repos_path)
    repos_path = svn_fspath__canonicalize(repos_path, r->pool);

  *repos_path_ref = apr_pstrcat(r->pool, repos_name, ":", repos_path,
                                SVN_VA_NULL);

  if (r->method_number == M_MOVE || r->method_number == M_COPY)
    {
      apr_status_t status;

      dest_uri = apr_table_get(r->headers_in, "Destination");

      /* Decline MOVE or COPY when there is no Destination uri, this will
       * cause failure.
       */
      if (!dest_uri)
        return DECLINED;

      status = apr_uri_parse(r->pool, dest_uri, &parsed_dest_uri);
      if (status)
        {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                        "Invalid URI in Destination header");
          return HTTP_BAD_REQUEST;
        }
      if (!parsed_dest_uri.path)
        {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                        "Invalid URI in Destination header");
          return HTTP_BAD_REQUEST;
        }

      ap_unescape_url(parsed_dest_uri.path);
      dest_uri = parsed_dest_uri.path;
      if (strncmp(dest_uri, conf->base_path, strlen(conf->base_path)))
        {
          /* If it is not the same location, then we don't allow it.
           * XXX: Instead we could compare repository uuids, but that
           * XXX: seems a bit over the top.
           */
          return HTTP_BAD_REQUEST;
        }

      dav_err = dav_svn_split_uri(r,
                                  dest_uri,
                                  conf->base_path,
                                  &cleaned_uri,
                                  &trailing_slash,
                                  &dest_repos_name,
                                  &relative_path,
                                  &dest_repos_path);

      if (dav_err)
        {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                        "%s  [%d, #%d]",
                        dav_err->desc, dav_err->status, dav_err->error_id);
          /* Ensure that we never allow access by dav_err->status */
          return (dav_err->status != OK && dav_err->status != DECLINED) ?
                  dav_err->status : HTTP_INTERNAL_SERVER_ERROR;
        }

      if (dest_repos_path)
        dest_repos_path = svn_fspath__canonicalize(dest_repos_path, r->pool);

      *dest_repos_path_ref = apr_pstrcat(r->pool, dest_repos_name, ":",
                                         dest_repos_path, SVN_VA_NULL);
    }

  /* Retrieve/cache authorization file */
  access_conf = get_access_conf(r,conf, r->pool);
  if (access_conf == NULL)
    return DECLINED;

  /* Perform authz access control.
   *
   * First test the special case where repos_path == NULL, and skip
   * calling the authz routines in that case.  This is an oddity of
   * the DAV RA method: some requests have no repos_path, but apache
   * still triggers an authz lookup for the URI.
   *
   * However, if repos_path == NULL and the request requires write
   * access, then perform a global authz lookup.  The request is
   * denied if the user committing isn't granted any access anywhere
   * in the repository.  This is to avoid operations that involve no
   * paths (committing an empty revision, leaving a dangling
   * transaction in the FS) being granted by default, letting
   * unauthenticated users write some changes to the repository.
   * This was issue #2388.
   *
   * XXX: For now, requesting access to the entire repository always
   * XXX: succeeds, until we come up with a good way of figuring
   * XXX: this out.
   */
  if (repos_path
      || (!repos_path && (authz_svn_type & svn_authz_write)))
    {
      svn_err = svn_repos_authz_check_access(access_conf, repos_name,
                                             repos_path,
                                             username_to_authorize,
                                             authz_svn_type,
                                             &authz_access_granted,
                                             r->pool);
      if (svn_err)
        {
          log_svn_error(APLOG_MARK, r,
                        "Failed to perform access control:",
                        svn_err, r->pool);

          return DECLINED;
        }
        if (!authz_access_granted)
          return DECLINED;
    }

  /* XXX: MKCOL, MOVE, DELETE
   * XXX: Require write access to the parent dir of repos_path.
   */

  /* XXX: PUT
   * XXX: If the path doesn't exist, require write access to the
   * XXX: parent dir of repos_path.
   */

  /* Only MOVE and COPY have a second uri we have to check access to. */
  if (r->method_number != M_MOVE && r->method_number != M_COPY)
    return OK;

  /* Check access on the destination repos_path.  Again, skip this if
     repos_path == NULL (see above for explanations) */
  if (repos_path)
    {
      svn_err = svn_repos_authz_check_access(access_conf,
                                             dest_repos_name,
                                             dest_repos_path,
                                             username_to_authorize,
                                             svn_authz_write
                                             |svn_authz_recursive,
                                             &authz_access_granted,
                                             r->pool);
      if (svn_err)
        {
          log_svn_error(APLOG_MARK, r,
                        "Failed to perform access control:",
                        svn_err, r->pool);

          return DECLINED;
        }
      if (!authz_access_granted)
        return DECLINED;
    }

  /* XXX: MOVE and COPY, if the path doesn't exist yet, also
   * XXX: require write access to the parent dir of dest_repos_path.
   */

  return OK;
}

/*
 * Implementation of subreq_bypass with scratch_pool parameter.
 */
static int
subreq_bypass2(request_rec *r,
               const char *repos_path,
               const char *repos_name,
               apr_pool_t *scratch_pool)
{
  svn_error_t *svn_err = NULL;
  svn_authz_t *access_conf = NULL;
  authz_svn_config_rec *conf = NULL;
  svn_boolean_t authz_access_granted = FALSE;
  const char *username_to_authorize;

  conf = ap_get_module_config(r->per_dir_config,
                              &authz_svn_module);
  username_to_authorize = get_username_to_authorize(r, conf, scratch_pool);

  /* If configured properly, this should never be true, but just in case. */
  if (!conf->anonymous
      || (! (conf->access_file || conf->repo_relative_access_file)))
    {
      log_access_verdict(APLOG_MARK, r, 0, TRUE, repos_path, NULL);
      return HTTP_FORBIDDEN;
    }

  /* Retrieve authorization file */
  access_conf = get_access_conf(r, conf, scratch_pool);
  if (access_conf == NULL)
    return HTTP_FORBIDDEN;

  /* Perform authz access control.
   * See similarly labeled comment in req_check_access.
   */
  if (repos_path)
    {
      svn_err = svn_repos_authz_check_access(access_conf, repos_name,
                                             repos_path,
                                             username_to_authorize,
                                             svn_authz_none|svn_authz_read,
                                             &authz_access_granted,
                                             scratch_pool);
      if (svn_err)
        {
          log_svn_error(APLOG_MARK, r,
                        "Failed to perform access control:",
                        svn_err, scratch_pool);
          return HTTP_FORBIDDEN;
        }
      if (!authz_access_granted)
        {
          log_access_verdict(APLOG_MARK, r, 0, TRUE, repos_path, NULL);
          return HTTP_FORBIDDEN;
        }
    }

  log_access_verdict(APLOG_MARK, r, 1, TRUE, repos_path, NULL);

  return OK;
}

/*
 * This function is used as a provider to allow mod_dav_svn to bypass the
 * generation of an apache request when checking GET access from
 * "mod_dav_svn/authz.c" .
 */
static int
subreq_bypass(request_rec *r,
              const char *repos_path,
              const char *repos_name)
{
  int status;
  apr_pool_t *scratch_pool;

  scratch_pool = svn_pool_create(r->pool);
  status = subreq_bypass2(r, repos_path, repos_name, scratch_pool);
  svn_pool_destroy(scratch_pool);

  return status;
}

/*
 * Hooks
 */

static int
access_checker(request_rec *r)
{
  authz_svn_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                    &authz_svn_module);
  const char *repos_path = NULL;
  const char *dest_repos_path = NULL;
  int status, authn_required;

#if USE_FORCE_AUTHN
  /* Use the force_authn() hook available in 2.4.x to work securely
   * given that ap_some_auth_required() is no longer functional for our
   * purposes in 2.4.x.
   */
  int authn_configured;

  /* We are not configured to run */
  if (!conf->anonymous || apr_table_get(r->notes, IN_SOME_AUTHN_NOTE)
      || (! (conf->access_file || conf->repo_relative_access_file)))
    return DECLINED;

  /* Authentication is configured */
  authn_configured = ap_auth_type(r) != NULL;
  if (authn_configured)
    {
      /* If the user is trying to authenticate, let him.  It doesn't
       * make much sense to grant anonymous access but deny authenticated
       * users access, even though you can do that with '$anon' in the
       * access file.
       */
      if (apr_table_get(r->headers_in,
                        (PROXYREQ_PROXY == r->proxyreq)
                        ? "Proxy-Authorization" : "Authorization"))
        {
          /* Set the note to force authn regardless of what access_checker_ex
             hook requires */
          apr_table_setn(r->notes, FORCE_AUTHN_NOTE, "1");

          /* provide the proper return so the access_checker hook doesn't
           * prevent the code from continuing on to the other auth hooks */
          if (ap_satisfies(r) != SATISFY_ANY)
            return OK;
          else
            return HTTP_FORBIDDEN;
        }
    }

#else
  /* Support for older versions of httpd that have a working
   * ap_some_auth_required() */

  /* We are not configured to run */
  if (!conf->anonymous
      || (! (conf->access_file || conf->repo_relative_access_file)))
    return DECLINED;

  authn_required = ap_some_auth_required(r);
  if (authn_required)
    {
      /* It makes no sense to check if a location is both accessible
       * anonymous and by an authenticated user (in the same request!).
       */
      if (ap_satisfies(r) != SATISFY_ANY)
        return DECLINED;

      /* If the user is trying to authenticate, let him.  It doesn't
       * make much sense to grant anonymous access but deny authenticated
       * users access, even though you can do that with '$anon' in the
       * access file.
       */
      if (apr_table_get(r->headers_in,
                        (PROXYREQ_PROXY == r->proxyreq)
                        ? "Proxy-Authorization" : "Authorization"))
        {
          /* Given Satisfy Any is in effect, we have to forbid access
           * to let the auth_checker hook have a go at it.
           */
          return HTTP_FORBIDDEN;
        }
    }
#endif

  /* If anon access is allowed, return OK */
  status = req_check_access(r, conf, &repos_path, &dest_repos_path);
  if (status == DECLINED)
    {
      if (!conf->authoritative)
        return DECLINED;

#if USE_FORCE_AUTHN
      if (authn_configured) {
          /* We have to check to see if authn is required because if so we must
           * return DECLINED rather than FORBIDDEN (403) since returning
           * the 403 leaks information about what paths may exist to
           * unauthenticated users.  Returning DECLINED means apache's request
           * handling will continue until the authn module itself generates
           * UNAUTHORIZED (401).

           * We must set a note here in order to use
           * ap_some_authn_rquired() without triggering an infinite
           * loop since the call will trigger this function to be
           * called again. */
          apr_table_setn(r->notes, IN_SOME_AUTHN_NOTE, "1");
          authn_required = ap_some_authn_required(r);
          apr_table_unset(r->notes, IN_SOME_AUTHN_NOTE);
          if (authn_required)
            return DECLINED;
      }
#else
      if (!authn_required)
#endif
        log_access_verdict(APLOG_MARK, r, 0, FALSE, repos_path, dest_repos_path);

      return HTTP_FORBIDDEN;
    }

  if (status != OK)
    return status;

  log_access_verdict(APLOG_MARK, r, 1, FALSE, repos_path, dest_repos_path);

  return OK;
}

static int
check_user_id(request_rec *r)
{
  authz_svn_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                    &authz_svn_module);
  const char *repos_path = NULL;
  const char *dest_repos_path = NULL;
  int status;

  /* We are not configured to run, or, an earlier module has already
   * authenticated this request. */
  if (!conf->no_auth_when_anon_ok || r->user
      || (! (conf->access_file || conf->repo_relative_access_file)))
    return DECLINED;

  /* If anon access is allowed, return OK, preventing later modules
   * from issuing an HTTP_UNAUTHORIZED.  Also pass a note to our
   * auth_checker hook that access has already been checked. */
  status = req_check_access(r, conf, &repos_path, &dest_repos_path);
  if (status == OK)
    {
      apr_table_setn(r->notes, "authz_svn-anon-ok", "1");
      log_access_verdict(APLOG_MARK, r, 1, FALSE, repos_path, dest_repos_path);
      return OK;
    }

  return status;
}

static int
auth_checker(request_rec *r)
{
  authz_svn_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                    &authz_svn_module);
  const char *repos_path = NULL;
  const char *dest_repos_path = NULL;
  int status;

  /* We are not configured to run */
  if (! (conf->access_file || conf->repo_relative_access_file))
    return DECLINED;

  /* Previous hook (check_user_id) already did all the work,
   * and, as a sanity check, r->user hasn't been set since then? */
  if (!r->user && apr_table_get(r->notes, "authz_svn-anon-ok"))
    return OK;

  status = req_check_access(r, conf, &repos_path, &dest_repos_path);
  if (status == DECLINED)
    {
      if (conf->authoritative)
        {
          log_access_verdict(APLOG_MARK, r, 0, FALSE, repos_path, dest_repos_path);
          ap_note_auth_failure(r);
          return HTTP_FORBIDDEN;
        }
      return DECLINED;
    }

  if (status != OK)
    return status;

  log_access_verdict(APLOG_MARK, r, 1, FALSE, repos_path, dest_repos_path);

  return OK;
}

#if USE_FORCE_AUTHN
static int
force_authn(request_rec *r)
{
  if (apr_table_get(r->notes, FORCE_AUTHN_NOTE))
    return OK;

  return DECLINED;
}
#endif

/*
 * Module flesh
 */

/* Implements the #register_hooks method of Apache's #module vtable. */
static void
register_hooks(apr_pool_t *p)
{
  static const char * const mod_ssl[] = { "mod_ssl.c", NULL };

  ap_hook_access_checker(access_checker, NULL, NULL, APR_HOOK_LAST);
  /* Our check_user_id hook must be before any module which will return
   * HTTP_UNAUTHORIZED (mod_auth_basic, etc.), but after mod_ssl, to
   * give SSLOptions +FakeBasicAuth a chance to work. */
  ap_hook_check_user_id(check_user_id, mod_ssl, NULL, APR_HOOK_FIRST);
  ap_hook_auth_checker(auth_checker, NULL, NULL, APR_HOOK_FIRST);
#if USE_FORCE_AUTHN
  ap_hook_force_authn(force_authn, NULL, NULL, APR_HOOK_FIRST);
#endif
  ap_register_provider(p,
                       AUTHZ_SVN__SUBREQ_BYPASS_PROV_GRP,
                       AUTHZ_SVN__SUBREQ_BYPASS_PROV_NAME,
                       AUTHZ_SVN__SUBREQ_BYPASS_PROV_VER,
                       (void*)subreq_bypass);
}

module AP_MODULE_DECLARE_DATA authz_svn_module =
{
  STANDARD20_MODULE_STUFF,
  create_authz_svn_dir_config,     /* dir config creator */
  NULL,                            /* dir merger --- default is to override */
  NULL,                            /* server config */
  NULL,                            /* merge server config */
  authz_svn_cmds,                  /* command apr_table_t */
  register_hooks                   /* register hooks */
};
