Permalink
Browse files

mod_allowhandlers: New module to forbid specific handlers for specific

directories.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1406617 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent cd2e3c9 commit 5be4ad321e94dcbfb2d0170332382c4c6662d489 Stefan Fritsch committed Nov 7, 2012
Showing with 236 additions and 2 deletions.
  1. +4 −1 CHANGES
  2. +1 −1 docs/log-message-tags/next-number
  3. +87 −0 docs/manual/mod/mod_allowhandlers.xml
  4. +1 −0 modules/aaa/config.m4
  5. +143 −0 modules/aaa/mod_allowhandlers.c
View
@@ -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
@@ -1 +1 @@
-2398
+2401
@@ -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>
View
@@ -74,6 +74,7 @@ APACHE_MODULE(auth_digest, RFC2617 Digest authentication, , , most, [
])
APACHE_MODULE(allowmethods, restrict allowed HTTP methods, , , most)
+APACHE_MODULE(allowhandlers, restrict allowed handlers, , , most)
APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
@@ -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,
+};
+

0 comments on commit 5be4ad3

Please sign in to comment.