You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2012/11/07 14:27:54 UTC

svn commit: r1406617 - in /httpd/httpd/trunk: CHANGES docs/log-message-tags/next-number docs/manual/mod/mod_allowhandlers.xml modules/aaa/config.m4 modules/aaa/mod_allowhandlers.c

Author: sf
Date: Wed Nov  7 13:27:54 2012
New Revision: 1406617

URL: http://svn.apache.org/viewvc?rev=1406617&view=rev
Log:
mod_allowhandlers: New module to forbid specific handlers for specific
directories.

Added:
    httpd/httpd/trunk/docs/manual/mod/mod_allowhandlers.xml
    httpd/httpd/trunk/modules/aaa/mod_allowhandlers.c
Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/log-message-tags/next-number
    httpd/httpd/trunk/modules/aaa/config.m4

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1406617&r1=1406616&r2=1406617&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Wed Nov  7 13:27:54 2012
@@ -1,7 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
-  *) Be more correct about rejecting directives that cannot work in <If>
+  *) mod_allowhandlers: New module to forbid specific handlers for specific
+     directories. [Stefan Fritsch]
+
+  *) core: Be more correct about rejecting directives that cannot work in <If>
      sections. [Stefan Fritsch]
 
   *) core: Fix directives like LogLevel that need to know if they are invoked

Modified: httpd/httpd/trunk/docs/log-message-tags/next-number
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/log-message-tags/next-number?rev=1406617&r1=1406616&r2=1406617&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/log-message-tags/next-number (original)
+++ httpd/httpd/trunk/docs/log-message-tags/next-number Wed Nov  7 13:27:54 2012
@@ -1 +1 @@
-2398
+2401

Added: httpd/httpd/trunk/docs/manual/mod/mod_allowhandlers.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_allowhandlers.xml?rev=1406617&view=auto
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_allowhandlers.xml (added)
+++ httpd/httpd/trunk/docs/manual/mod/mod_allowhandlers.xml Wed Nov  7 13:27:54 2012
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
+<?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
+<!-- $LastChangedRevision$ -->
+
+<!--
+Upon adding a new module XML doc, you will need to:
+
+svn ps svn:eol-style native <alltextfiles>
+svn ps svn:keywords LastChangedRevision mod_allowhandlers.xml
+
+in order for it to rebuild correctly.
+
+-->
+
+<!--
+ 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.
+-->
+
+<modulesynopsis metafile="mod_allowhandlers.xml.meta">
+<name>mod_allowhandlers</name>
+<description>Easily restrict what HTTP handlers can be used on the server</description>
+<status>Experimental</status>
+<sourcefile>mod_allowhandlers.c</sourcefile>
+<identifier>allowhandlers_module</identifier>
+
+
+<summary>
+<p>This module makes it easy to restrict which handlers may be used for a
+request. A possible configuration would be:</p>
+
+<highlight language="config">
+&lt;Location /&gt;
+  AllowHandlers not server-info server-status balancer-manager ldap-status
+&lt;/Location&gt;
+</highlight>
+
+<p>It also registers a handler named <code>forbidden</code> that simply
+returns 403 FORBIDDEN to the client. This can be used with directives like
+<directive module="mod_mime">AddHandler</directive>.</p>
+
+</summary>
+
+<seealso><directive module="core">SetHandler</directive></seealso>
+<seealso><directive module="mime">AddHandler</directive></seealso>
+
+<directivesynopsis>
+<name>AllowHandlers</name>
+<description>Restrict access to the listed handlers</description>
+<syntax>AllowHandlers [not] none|<em>handler-name</em>
+[none|<em>handler-name</em>]...</syntax>
+<default>AllowHandlers all</default>
+<contextlist><context>directory</context></contextlist>
+<status>Experimental</status>
+
+<usage>
+
+<p>The handler names are case sensitive. The special name
+<code>none</code> can be used to match the case where no handler has been
+set. The special vallue <code>all</code> can be used to allow all
+handlers again in a later config section, even if some headers were denied
+earlier in the configuration merge order:</p>
+
+<highlight language="config">
+&lt;Location /server-status&gt;
+  AllowHandlers all
+  SetHandler server-status
+&lt;/Location&gt;
+</highlight>
+
+</usage>
+</directivesynopsis>
+
+</modulesynopsis>

Modified: httpd/httpd/trunk/modules/aaa/config.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/config.m4?rev=1406617&r1=1406616&r2=1406617&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/aaa/config.m4 (original)
+++ httpd/httpd/trunk/modules/aaa/config.m4 Wed Nov  7 13:27:54 2012
@@ -74,6 +74,7 @@ APACHE_MODULE(auth_digest, RFC2617 Diges
 ])
 
 APACHE_MODULE(allowmethods, restrict allowed HTTP methods, , , most)
+APACHE_MODULE(allowhandlers, restrict allowed handlers, , , most)
 
 APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
 

Added: httpd/httpd/trunk/modules/aaa/mod_allowhandlers.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_allowhandlers.c?rev=1406617&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/aaa/mod_allowhandlers.c (added)
+++ httpd/httpd/trunk/modules/aaa/mod_allowhandlers.c Wed Nov  7 13:27:54 2012
@@ -0,0 +1,143 @@
+/* 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_request.h"
+#include "http_log.h"
+
+module AP_MODULE_DECLARE_DATA allowhandlers_module;
+
+typedef enum {
+    AH_ALLOW = 0,
+    AH_DENY = 1,
+} ah_op_e;
+typedef struct {
+    apr_table_t *handlers;
+    ah_op_e     op;
+} ah_conf_t;
+
+static const char * const forbidden_handler = "forbidden";
+static const char * const no_handler        = "none";
+
+static int ah_fixups(request_rec *r)
+{
+    ah_conf_t *conf = ap_get_module_config(r->per_dir_config,
+                                         &allowhandlers_module);
+    int match = 0;
+    const char *handler_name;
+    if (!r->handler || r->handler[0] == '\0') {
+        handler_name = no_handler;
+    }
+    else if (strcasecmp(r->handler, forbidden_handler) == 0) {
+        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+                      APLOGNO(02398) "Handler 'forbidden' denied by "
+                      "server configuration: URI %s (file %s)",
+                      r->uri, r->filename);
+        return HTTP_FORBIDDEN;
+    }
+    else {
+        handler_name = r->handler;
+    }
+
+    if (!conf)
+        return DECLINED;
+    if (conf->handlers && apr_table_get(conf->handlers, handler_name))
+        match = 1;
+
+    if ((match && conf->op == AH_ALLOW) || (!match && conf->op == AH_DENY)) {
+        return DECLINED;
+    }
+    else {
+        if (handler_name != no_handler) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+                          APLOGNO(02399) "Handler '%s' denied by "
+                          "server configuration: URI %s (file %s)",
+                          r->handler, r->uri, r->filename);
+        }
+        else {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+                          APLOGNO(02400) "Handler denied by server "
+                          "configuration: No handler set for URI %s (file %s)",
+                          r->uri, r->filename);
+        }
+        return HTTP_FORBIDDEN;
+    }
+}
+
+static void *ah_create_conf(apr_pool_t * p, char *dummy)
+{
+  ah_conf_t *conf = apr_pcalloc(p, sizeof(ah_conf_t));
+  conf->op = AH_DENY;
+  return conf;
+}
+
+static const char *set_allowed_handlers(cmd_parms *cmd, void *d, int argc, char *const argv[])
+{
+    int i;
+    ah_conf_t* conf = (ah_conf_t*) d;
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
+    if (err)
+        return err;
+    if (argc == 0)
+        return "AllowHandlers: No handler name given";
+    conf->op = AH_ALLOW;
+    if (conf->handlers)
+        apr_table_clear(conf->handlers);
+    for (i = 0; i < argc; i++) {
+        if (strcasecmp(argv[i], forbidden_handler) == 0 && conf->op != AH_DENY)
+            return "Handler name 'forbidden' cannot be changed.";
+        if (strcasecmp(argv[i], "all") == 0) {
+            if (argc != 1)
+                return "'all' not possible with specific handler names";
+            conf->op = AH_DENY;
+            return NULL;
+        }
+        else if (strcasecmp(argv[i], "not") == 0) {
+            if (i != 0 || argc == 1)
+                return "'not' must come before specific handler names";
+            conf->op = AH_DENY;
+        }
+        else {
+            if (!conf->handlers)
+                conf->handlers = apr_table_make(cmd->pool, 4);
+            apr_table_setn(conf->handlers, argv[i], "1");
+        }
+    }
+    return NULL;
+}
+
+static void ah_register_hooks(apr_pool_t * p)
+{
+    ap_hook_fixups(ah_fixups, NULL, NULL, APR_HOOK_REALLY_LAST);
+}
+
+static const command_rec ah_cmds[] = {
+    AP_INIT_TAKE_ARGV("AllowHandlers", set_allowed_handlers, NULL, ACCESS_CONF,
+                      "only allow specific handlers (use 'not' to negate)"),
+  {NULL}
+};
+
+AP_DECLARE_MODULE(allowhandlers) = {
+  STANDARD20_MODULE_STUFF,
+  ah_create_conf,
+  NULL,
+  NULL,
+  NULL,
+  ah_cmds,
+  ah_register_hooks,
+};
+