/*
 * mod_dontdothat.c: an Apache filter that allows you to return arbitrary
 *                   errors for various types of Subversion requests.
 *
 * ====================================================================
 *    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_protocol.h>
#include <http_request.h>
#include <http_log.h>
#include <util_filter.h>
#include <ap_config.h>
#include <apr_strings.h>
#include <apr_uri.h>

#include "mod_dav_svn.h"
#include "svn_string.h"
#include "svn_config.h"
#include "svn_path.h"
#include "svn_xml.h"
#include "private/svn_fspath.h"

extern module AP_MODULE_DECLARE_DATA dontdothat_module;

typedef struct dontdothat_config_rec {
  const char *config_file;
  const char *base_path;
  int no_replay;
} dontdothat_config_rec;

static void *create_dontdothat_dir_config(apr_pool_t *pool, char *dir)
{
  dontdothat_config_rec *cfg = apr_pcalloc(pool, sizeof(*cfg));

  cfg->base_path = dir;
  cfg->no_replay = 1;

  return cfg;
}

static const command_rec dontdothat_cmds[] =
{
  AP_INIT_TAKE1("DontDoThatConfigFile", ap_set_file_slot,
                (void *) APR_OFFSETOF(dontdothat_config_rec, config_file),
                OR_ALL,
                "Text file containing actions to take for specific requests"),
  AP_INIT_FLAG("DontDoThatDisallowReplay",  ap_set_flag_slot,
                (void *) APR_OFFSETOF(dontdothat_config_rec, no_replay),
                OR_ALL, "Disallow replay requests as if they are other recursive requests."),
  { NULL }
};

typedef enum parse_state_t {
  STATE_BEGINNING,
  STATE_IN_UPDATE,
  STATE_IN_SRC_PATH,
  STATE_IN_DST_PATH,
  STATE_IN_RECURSIVE
} parse_state_t;

typedef struct dontdothat_filter_ctx {
  /* Set to TRUE when we determine that the request is safe and should be
   * allowed to continue. */
  svn_boolean_t let_it_go;

  /* Set to TRUE when we determine that the request is unsafe and should be
   * stopped in its tracks. */
  svn_boolean_t no_soup_for_you;

  svn_xml_parser_t *xmlp;

  /* The current location in the REPORT body. */
  parse_state_t state;

  /* A buffer to hold CDATA we encounter. */
  svn_stringbuf_t *buffer;

  dontdothat_config_rec *cfg;

  /* An array of wildcards that are special cased to be allowed. */
  apr_array_header_t *allow_recursive_ops;

  /* An array of wildcards where recursive operations are not allowed. */
  apr_array_header_t *no_recursive_ops;

  /* TRUE if a path has failed a test already. */
  svn_boolean_t path_failed;

  /* An error for when we're using this as a baton while parsing config
   * files. */
  svn_error_t *err;

  /* The current request. */
  request_rec *r;
} dontdothat_filter_ctx;

/* Return TRUE if wildcard WC matches path P, FALSE otherwise. */
static svn_boolean_t
matches(const char *wc, const char *p)
{
  for (;;)
    {
      switch (*wc)
        {
          case '*':
            if (wc[1] != '/' && wc[1] != '\0')
              abort(); /* This was checked for during parsing of the config. */

            /* It's a wild card, so eat up until the next / in p. */
            while (*p && p[1] != '/')
              ++p;

            /* If we ran out of p and we're out of wc then it matched. */
            if (! *p)
              {
                if (wc[1] == '\0')
                  return TRUE;
                else
                  return FALSE;
              }
            break;

          case '\0':
            if (*p != '\0')
              /* This means we hit the end of wc without running out of p. */
              return FALSE;
            else
              /* Or they were exactly the same length, so it's not lower. */
              return TRUE;

          default:
            if (*wc != *p)
              return FALSE; /* If we don't match, then move on to the next
                             * case. */
            else
              break;
        }

      ++wc;
      ++p;

      if (! *p && *wc)
        return FALSE;
    }
}

/* duplicate of dav_svn__log_err() from mod_dav_svn/util.c */
static void
log_dav_err(request_rec *r,
            dav_error *err,
            int level)
{
    dav_error *errscan;

    /* Log the errors */
    /* ### should have a directive to log the first or all */
    for (errscan = err; errscan != NULL; errscan = errscan->prev) {
        apr_status_t status;

        if (errscan->desc == NULL)
            continue;

#if AP_MODULE_MAGIC_AT_LEAST(20091119,0)
        status = errscan->aprerr;
#else
        status = errscan->save_errno;
#endif

        ap_log_rerror(APLOG_MARK, level, status, r,
                      "%s  [%d, #%d]",
                      errscan->desc, errscan->status, errscan->error_id);
    }
}

static svn_boolean_t
is_this_legal(dontdothat_filter_ctx *ctx, const char *uri)
{
  const char *relative_path;
  const char *cleaned_uri;
  const char *repos_name;
  const char *uri_path;
  int trailing_slash;
  dav_error *derr;

  /* uri can be an absolute uri or just a path, we only want the path to match
   * against */
  if (uri && svn_path_is_url(uri))
    {
      apr_uri_t parsed_uri;
      apr_status_t rv = apr_uri_parse(ctx->r->pool, uri, &parsed_uri);
      if (APR_SUCCESS != rv)
        {
          /* Error parsing the URI, log and reject request. */
          ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, ctx->r,
                        "mod_dontdothat: blocked request after failing "
                        "to parse uri: '%s'", uri);
          return FALSE;
        }
      uri_path = parsed_uri.path;
    }
  else
    {
      uri_path = uri;
    }

  if (uri_path)
    {
      const char *repos_path;

      derr = dav_svn_split_uri(ctx->r,
                               uri_path,
                               ctx->cfg->base_path,
                               &cleaned_uri,
                               &trailing_slash,
                               &repos_name,
                               &relative_path,
                               &repos_path);
      if (! derr)
        {
          int idx;

          if (! repos_path)
            repos_path = "";

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

          /* First check the special cases that are always legal... */
          for (idx = 0; idx < ctx->allow_recursive_ops->nelts; ++idx)
            {
              const char *wc = APR_ARRAY_IDX(ctx->allow_recursive_ops,
                                             idx,
                                             const char *);

              if (matches(wc, repos_path))
                {
                  ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->r,
                                "mod_dontdothat: rule %s allows %s",
                                wc, repos_path);
                  return TRUE;
                }
            }

          /* Then look for stuff we explicitly don't allow. */
          for (idx = 0; idx < ctx->no_recursive_ops->nelts; ++idx)
            {
              const char *wc = APR_ARRAY_IDX(ctx->no_recursive_ops,
                                             idx,
                                             const char *);

              if (matches(wc, repos_path))
                {
                  ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->r,
                                "mod_dontdothat: rule %s forbids %s",
                                wc, repos_path);
                  return FALSE;
                }
            }
        }
      else
        {
          log_dav_err(ctx->r, derr, APLOG_ERR);
          return FALSE;
        }

    }
  else
    {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r,
                    "mod_dontdothat: empty uri passed to is_this_legal(), "
                    "module bug?");
      return FALSE;
    }

  return TRUE;
}

static apr_status_t
dontdothat_filter(ap_filter_t *f,
                  apr_bucket_brigade *bb,
                  ap_input_mode_t mode,
                  apr_read_type_e block,
                  apr_off_t readbytes)
{
  dontdothat_filter_ctx *ctx = f->ctx;
  apr_status_t rv;
  apr_bucket *e;

  if (mode != AP_MODE_READBYTES)
    return ap_get_brigade(f->next, bb, mode, block, readbytes);

  rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
  if (rv)
    return rv;

  for (e = APR_BRIGADE_FIRST(bb);
       e != APR_BRIGADE_SENTINEL(bb);
       e = APR_BUCKET_NEXT(e))
    {
      svn_boolean_t last = APR_BUCKET_IS_EOS(e);
      const char *str;
      apr_size_t len;
      svn_error_t *err;

      if (last)
        {
          str = "";
          len = 0;
        }
      else
        {
          rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
          if (rv)
            return rv;
        }

      err = svn_xml_parse(ctx->xmlp, str, len, last);
      if (err)
        {
          /* let_it_go so we clean up our parser, no_soup_for_you so that we
           * bail out before bothering to parse this stuff a second time. */
          ctx->let_it_go = TRUE;
          ctx->no_soup_for_you = TRUE;
          svn_error_clear(err);
        }

      /* If we found something that isn't allowed, set the correct status
       * and return an error so it'll bail out before it gets anywhere it
       * can do real damage. */
      if (ctx->no_soup_for_you)
        {
          /* XXX maybe set up the SVN-ACTION env var so that it'll show up
           *     in the Subversion operational logs? */

          ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
                        "mod_dontdothat: client broke the rules, "
                        "returning error");

          /* Ok, pass an error bucket and an eos bucket back to the client.
           *
           * NOTE: The custom error string passed here doesn't seem to be
           *       used anywhere by httpd.  This is quite possibly a bug.
           *
           * TODO: Try and pass back a custom document body containing a
           *       serialized svn_error_t so the client displays a better
           *       error message. */
          bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
          e = ap_bucket_error_create(403, "No Soup For You!",
                                     f->r->pool, f->c->bucket_alloc);
          APR_BRIGADE_INSERT_TAIL(bb, e);
          e = apr_bucket_eos_create(f->c->bucket_alloc);
          APR_BRIGADE_INSERT_TAIL(bb, e);

          /* Don't forget to remove us, otherwise recursion blows the stack. */
          ap_remove_input_filter(f);

          return ap_pass_brigade(f->r->output_filters, bb);
        }
      else if (ctx->let_it_go || last)
        {
          ap_remove_input_filter(f);

          ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
                        "mod_dontdothat: letting request go through");

          return rv;
        }
    }

  return rv;
}

/* Implements svn_xml_char_data callback */
static void
cdata(void *baton, const char *data, apr_size_t len)
{
  dontdothat_filter_ctx *ctx = baton;

  if (ctx->no_soup_for_you || ctx->let_it_go)
    return;

  switch (ctx->state)
    {
      case STATE_IN_SRC_PATH:
        /* FALLTHROUGH */

      case STATE_IN_DST_PATH:
        /* FALLTHROUGH */

      case STATE_IN_RECURSIVE:
        if (! ctx->buffer)
          ctx->buffer = svn_stringbuf_ncreate(data, len, ctx->r->pool);
        else
          svn_stringbuf_appendbytes(ctx->buffer, data, len);
        break;

      default:
        break;
    }
}

/* Implements svn_xml_start_elem callback */
static void
start_element(void *baton, const char *name, const char **attrs)
{
  dontdothat_filter_ctx *ctx = baton;
  const char *sep;

  if (ctx->no_soup_for_you || ctx->let_it_go)
    return;

  /* XXX Hack.  We should be doing real namespace support, but for now we
   *     just skip ahead of any namespace prefix.  If someone's sending us
   *     an update-report element outside of the SVN namespace they'll get
   *     what they deserve... */
  sep = ap_strchr_c(name, ':');
  if (sep)
    name = sep + 1;

  switch (ctx->state)
    {
      case STATE_BEGINNING:
        if (strcmp(name, "update-report") == 0)
          ctx->state = STATE_IN_UPDATE;
        else if (strcmp(name, "replay-report") == 0 && ctx->cfg->no_replay)
          {
            /* XXX it would be useful if there was a way to override this
             *     on a per-user basis... */
            if (! is_this_legal(ctx, ctx->r->unparsed_uri))
              ctx->no_soup_for_you = TRUE;
            else
              ctx->let_it_go = TRUE;
          }
        else
          ctx->let_it_go = TRUE;
        break;

      case STATE_IN_UPDATE:
        if (strcmp(name, "src-path") == 0)
          {
            ctx->state = STATE_IN_SRC_PATH;
            if (ctx->buffer)
              ctx->buffer->len = 0;
          }
        else if (strcmp(name, "dst-path") == 0)
          {
            ctx->state = STATE_IN_DST_PATH;
            if (ctx->buffer)
              ctx->buffer->len = 0;
          }
        else if (strcmp(name, "recursive") == 0)
          {
            ctx->state = STATE_IN_RECURSIVE;
            if (ctx->buffer)
              ctx->buffer->len = 0;
          }
        else
          ; /* XXX Figure out what else we need to deal with...  Switch
             *     has that link-path thing we probably need to look out
             *     for... */
        break;

      default:
        break;
    }
}

/* Implements svn_xml_end_elem callback */
static void
end_element(void *baton, const char *name)
{
  dontdothat_filter_ctx *ctx = baton;
  const char *sep;

  if (ctx->no_soup_for_you || ctx->let_it_go)
    return;

  /* XXX Hack.  We should be doing real namespace support, but for now we
   *     just skip ahead of any namespace prefix.  If someone's sending us
   *     an update-report element outside of the SVN namespace they'll get
   *     what they deserve... */
  sep = ap_strchr_c(name, ':');
  if (sep)
    name = sep + 1;

  switch (ctx->state)
    {
      case STATE_IN_SRC_PATH:
        ctx->state = STATE_IN_UPDATE;

        svn_stringbuf_strip_whitespace(ctx->buffer);

        if (! ctx->path_failed && ! is_this_legal(ctx, ctx->buffer->data))
          ctx->path_failed = TRUE;
        break;

      case STATE_IN_DST_PATH:
        ctx->state = STATE_IN_UPDATE;

        svn_stringbuf_strip_whitespace(ctx->buffer);

        if (! ctx->path_failed && ! is_this_legal(ctx, ctx->buffer->data))
          ctx->path_failed = TRUE;
        break;

      case STATE_IN_RECURSIVE:
        ctx->state = STATE_IN_UPDATE;

        svn_stringbuf_strip_whitespace(ctx->buffer);

        /* If this isn't recursive we let it go. */
        if (strcmp(ctx->buffer->data, "no") == 0)
          {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->r,
                          "mod_dontdothat: letting nonrecursive request go");
            ctx->let_it_go = TRUE;
          }
        break;

      case STATE_IN_UPDATE:
        if (strcmp(name, "update-report") == 0)
          {
            /* If we made it here without figuring out that this is
             * nonrecursive, then the path check is our final word
             * on the subject. */

            if (ctx->path_failed)
              ctx->no_soup_for_you = TRUE;
            else
              ctx->let_it_go = TRUE;
          }
        else
          ; /* XXX Is there other stuff we care about? */
        break;

      default:
        abort();
    }
}

static svn_boolean_t
is_valid_wildcard(const char *wc)
{
  while (*wc)
    {
      if (*wc == '*')
        {
          if (wc[1] && wc[1] != '/')
            return FALSE;
        }

      ++wc;
    }

  return TRUE;
}

static svn_boolean_t
config_enumerator(const char *wildcard,
                  const char *action,
                  void *baton,
                  apr_pool_t *pool)
{
  dontdothat_filter_ctx *ctx = baton;

  if (strcmp(action, "deny") == 0)
    {
      if (is_valid_wildcard(wildcard))
        APR_ARRAY_PUSH(ctx->no_recursive_ops, const char *) = wildcard;
      else
        ctx->err = svn_error_createf(APR_EINVAL,
                                     NULL,
                                     "'%s' is an invalid wildcard",
                                     wildcard);
    }
  else if (strcmp(action, "allow") == 0)
    {
      if (is_valid_wildcard(wildcard))
        APR_ARRAY_PUSH(ctx->allow_recursive_ops, const char *) = wildcard;
      else
        ctx->err = svn_error_createf(APR_EINVAL,
                                     NULL,
                                     "'%s' is an invalid wildcard",
                                     wildcard);
    }
  else
    {
      ctx->err = svn_error_createf(APR_EINVAL,
                                   NULL,
                                   "'%s' is not a valid action",
                                   action);
    }

  if (ctx->err)
    return FALSE;
  else
    return TRUE;
}

static void
dontdothat_insert_filters(request_rec *r)
{
  dontdothat_config_rec *cfg = ap_get_module_config(r->per_dir_config,
                                                    &dontdothat_module);

  if (! cfg->config_file)
    return;

  if (strcmp("REPORT", r->method) == 0)
    {
      dontdothat_filter_ctx *ctx = apr_pcalloc(r->pool, sizeof(*ctx));
      svn_config_t *config;
      svn_error_t *err;

      ctx->r = r;

      ctx->cfg = cfg;

      ctx->allow_recursive_ops = apr_array_make(r->pool, 5, sizeof(char *));

      ctx->no_recursive_ops = apr_array_make(r->pool, 5, sizeof(char *));

      /* XXX is there a way to error out from this point?  Would be nice... */

      err = svn_config_read3(&config, cfg->config_file, TRUE,
                             FALSE, TRUE, r->pool);
      if (err)
        {
          char buff[256];

          ap_log_rerror(APLOG_MARK, APLOG_ERR,
                        ((err->apr_err >= APR_OS_START_USERERR &&
                          err->apr_err < APR_OS_START_CANONERR) ?
                         0 : err->apr_err),
                        r, "Failed to load DontDoThatConfigFile: %s",
                        svn_err_best_message(err, buff, sizeof(buff)));

          svn_error_clear(err);

          return;
        }

      svn_config_enumerate2(config,
                            "recursive-actions",
                            config_enumerator,
                            ctx,
                            r->pool);
      if (ctx->err)
        {
          char buff[256];

          ap_log_rerror(APLOG_MARK, APLOG_ERR,
                        ((ctx->err->apr_err >= APR_OS_START_USERERR &&
                          ctx->err->apr_err < APR_OS_START_CANONERR) ?
                         0 : ctx->err->apr_err),
                        r, "Failed to parse DontDoThatConfigFile: %s",
                        svn_err_best_message(ctx->err, buff, sizeof(buff)));

          svn_error_clear(ctx->err);

          return;
        }

      ctx->state = STATE_BEGINNING;

      ctx->xmlp = svn_xml_make_parser(ctx, start_element, end_element,
                                      cdata, r->pool);

      ap_add_input_filter("DONTDOTHAT_FILTER", ctx, r, r->connection);
    }
}

static void
dontdothat_register_hooks(apr_pool_t *pool)
{
  ap_hook_insert_filter(dontdothat_insert_filters, NULL, NULL, APR_HOOK_FIRST);

  ap_register_input_filter("DONTDOTHAT_FILTER",
                           dontdothat_filter,
                           NULL,
                           AP_FTYPE_RESOURCE);
}

module AP_MODULE_DECLARE_DATA dontdothat_module =
{
  STANDARD20_MODULE_STUFF,
  create_dontdothat_dir_config,
  NULL,
  NULL,
  NULL,
  dontdothat_cmds,
  dontdothat_register_hooks
};
