You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Tony Finch <do...@dotat.at> on 1999/02/01 16:41:20 UTC

[PATCH] , was Re: [STATUS] (apache-1.3) Sun Jan 31 23:45:15 EST 1999

Greg Stein <gs...@lyra.org> wrote:
>On Sun, 31 Jan 1999, Rodent of Unusual Size wrote:
>>     * A mechanism is needed for applying access control to methods
>>       that are not known by the server core, either using a Limit __unknown__
>>       as in <<8...@RED-MSG-45>,
>>       or via a LimitExcept directive.
>
>I'd like to reiterate a request for this functionality :-)

Here's a patch providing <LimitExcept> that seems to work. I dislike
the idea of <Limit __unknown__> for a whole lot of fairly ill-defined
reasons. One point is that allowing what you know is OK is more secure
than disallowing what you know isn't OK.

(I shan't mention the name of a security-sensitive web application
that by default uses <Limit GET POST> when it shouldn't use a <Limit>
section at all.)

Tony.
-- 
f.a.n.finch  dot@dotat.at  fanf@demon.net

--- src/main/http_core.c.old	Tue Jan 12 16:26:52 1999
+++ src/main/http_core.c.limitexcept	Mon Feb  1 14:56:58 1999
@@ -1087,8 +1087,8 @@
         return err;
     }
 
-    /* XXX: NB: Currently, we have no way of checking
-     * whether <Limit> sections are closed properly.
+    /* XXX: NB: Currently, we have no way of checking whether
+     * <Limit> or <LimitExcept> sections are closed properly.
      * (If we would add a srm_command_loop() here we might...)
      */
     
@@ -1112,10 +1112,43 @@
     return NULL;
 }
 
+static const char *ap_limit_except(cmd_parms *cmd, void *dummy,
+						  const char *arg)
+{
+    const char *limited_methods = ap_getword(cmd->pool, &arg, '>');
+    int limited;
+  
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
+    if (err != NULL) {
+        return err;
+    }
+
+    /* XXX: NB: see the comment in ap_limit_section. */
+
+    /* initially limit everything except TRACE */
+    limited = ~(1 << M_TRACE);
+
+    while (limited_methods[0]) {
+        char *method = ap_getword_conf(cmd->pool, &limited_methods);
+        int  methnum = ap_method_number_of(method);
+
+        if (methnum == M_INVALID) {
+            return ap_pstrcat(cmd->pool, "unknown method \"",
+                              method, "\" in <LimitExcept>", NULL);
+        }
+        else {
+            limited &= ~(1 << methnum);
+        }
+    }
+
+    cmd->limited = limited;
+    return NULL;
+}
+
 static const char *endlimit_section(cmd_parms *cmd, void *dummy, void *dummy2)
 {
     if (cmd->limited == -1) {
-        return "</Limit> unexpected";
+        return "</Limit> or </LimitExcept> unexpected";
     }
     
     cmd->limited = -1;
@@ -2515,7 +2548,12 @@
 { "<Limit", ap_limit_section, NULL, OR_ALL, RAW_ARGS, "Container for "
   "authentication directives when accessed using specified HTTP methods" },
 { "</Limit>", endlimit_section, NULL, OR_ALL, NO_ARGS,
-  "Marks end of <Limit>" },
+  "Marks end of <Limit>" }, /* or <LimitExcept> */
+{ "<LimitExcept", ap_limit_except, NULL, OR_ALL, RAW_ARGS, "Container for "
+  "authentication directives when accessed using other than the specified "
+  "HTTP methods" },
+{ "</LimitExcept>", endlimit_section, NULL, OR_ALL, NO_ARGS,
+  "Marks end of <LimitExcept>" }, /* actually a synonym for </Limit> */
 { "<IfModule", start_ifmod, NULL, OR_ALL, TAKE1,
   "Container for directives based on existance of specified modules" },
 { end_ifmodule_section, end_ifmod, NULL, OR_ALL, NO_ARGS,
--- htdocs/manual/mod/core.html	Tue Jan 12 16:02:48 1999
+++ htdocs/manual/mod/core.html.limitexcept	Mon Feb  1 15:34:46 1999
@@ -55,6 +55,7 @@
 <LI><A HREF="#keepalive">KeepAlive</A>
 <LI><A HREF="#keepalivetimeout">KeepAliveTimeout</A>
 <LI><A HREF="#limit">&lt;Limit&gt;</A>
+<LI><A HREF="#limitexcept">&lt;LimitExcept&gt;</A>
 <LI><A HREF="#limitrequestbody">LimitRequestBody</A>
 <LI><A HREF="#limitrequestfields">LimitRequestFields</A>
 <LI><A HREF="#limitrequestfieldsize">LimitRequestFieldsize</A>
@@ -664,7 +665,8 @@
 
 The directory sections typically occur in the access.conf file, but they
 may appear in any configuration file. &lt;Directory&gt; directives cannot
-nest, and cannot appear in a <A HREF="#limit">&lt;Limit&gt;</A> section.
+nest, and cannot appear in a <A HREF="#limit">&lt;Limit&gt;</A> or
+<A HREF="#limitexcept">&lt;LimitExcept&gt;</A> section.
 <P>
 
 <STRONG>See also</STRONG>: <A HREF="../sections.html">How Directory,
@@ -1337,6 +1339,30 @@
 If GET is used it will also restrict HEAD requests.
 <STRONG>If you wish to limit all methods, do not include any
 &lt;Limit&gt; directive at all.</STRONG>
+
+<P><HR>
+
+<H2><A NAME="limitexcept">&lt;LimitExcept&gt; directive</A></H2>
+<!--%plaintext &lt;?INDEX {\tt LimitExcept} section directive&gt; -->
+<A
+ HREF="directive-dict.html#Syntax"
+ REL="Help"
+><STRONG>Syntax:</STRONG></A>
+ &lt;LimitExcept <EM>method method</EM> ... &gt; ... &lt;/Limit&gt;<BR>
+<A
+ HREF="directive-dict.html#Context"
+ REL="Help"
+><STRONG>Context:</STRONG></A> any<BR>
+<A
+ HREF="directive-dict.html#Status"
+ REL="Help"
+><STRONG>Status:</STRONG></A> core<P>
+
+&lt;LimitExcept&gt; and &lt;/LimitExcept&gt; are used to enclose a group of
+access control directives which will then apply to any access method
+<STRONG>not</STRONG> listed in the arguments, i.e. it is the opposite of a
+<A HREF="#limit">&lt;Limit&gt;</A> section. See the documentation for 
+<A HREF="#limit">&lt;Limit&gt;</A> for more details.
 
 <P><HR>