You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ni...@apache.org on 2007/12/02 23:24:02 UTC

svn commit: r600393 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS docs/manual/mod/mod_include.xml modules/filters/mod_include.c

Author: niq
Date: Sun Dec  2 14:24:02 2007
New Revision: 600393

URL: http://svn.apache.org/viewvc?rev=600393&view=rev
Log:
Backport mod_include access checking (r571872,571927,572136)

Modified:
    httpd/httpd/branches/2.2.x/CHANGES
    httpd/httpd/branches/2.2.x/STATUS
    httpd/httpd/branches/2.2.x/docs/manual/mod/mod_include.xml
    httpd/httpd/branches/2.2.x/modules/filters/mod_include.c

Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=600393&r1=600392&r2=600393&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Sun Dec  2 14:24:02 2007
@@ -1,6 +1,11 @@
                                                         -*- coding: utf-8 -*-
 Changes with Apache 2.2.7
 
+  *) mod_include: Add an "if" directive syntax to test whether an URL
+     is accessible, and if so, conditionally display content. This
+     allows a webmaster to hide a link to a private page when the user
+     has no access to that page. [Graham Leggett]
+
   *) Various code cleanups. PR 38699, 39518, 42005, 42006, 42007, 42008, 42009
      [Christophe Jaillet <christophe.jaillet wanadoo.fr>]
 

Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=600393&r1=600392&r2=600393&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Sun Dec  2 14:24:02 2007
@@ -79,15 +79,6 @@
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-   * mod_include: Add an "if" directive syntax to test whether an URL
-     is accessible, and if so, conditionally display content. This
-     allows a webmaster to hide a link to a private page when the user
-     has no access to that page.
-     http://svn.apache.org/viewvc?view=rev&revision=571872
-     http://svn.apache.org/viewvc?view=rev&revision=571927
-     http://svn.apache.org/viewvc?view=rev&revision=572136
-     +1: minfrin, jim, niq
-
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
   [ New proposals should be added at the end of the list ]
 

Modified: httpd/httpd/branches/2.2.x/docs/manual/mod/mod_include.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/docs/manual/mod/mod_include.xml?rev=600393&r1=600392&r2=600393&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/docs/manual/mod/mod_include.xml (original)
+++ httpd/httpd/branches/2.2.x/docs/manual/mod/mod_include.xml Sun Dec  2 14:24:02 2007
@@ -501,6 +501,25 @@
       <dt><code><var>string</var></code></dt>
       <dd>true if <var>string</var> is not empty</dd>
 
+      <dt><code><var>-A string</var></code></dt>
+      <dd><p>true if the URL represented by the string is accessible by
+      configuration, false otherwise. This test only has an effect if
+      <directive>SSIEnableAccess</directive> is on. This is useful
+      where content on a page is to be hidden from users who are not
+      authorized to view the URL, such as a link to that URL. Note
+      that the URL is only tested for whether access would be granted,
+      not whether the URL exists.</p>
+
+      <example><title>Example</title>
+        &lt;!--#if expr="-A /private" --&gt;<br />
+        <indent>
+          Click &lt;a href="/private"&gt;here&lt;/a&gt; to access private
+          information.<br />
+        </indent>
+        &lt;!--#endif --&gt;
+      </example>
+      </dd>
+
       <dt><code><var>string1</var> = <var>string2</var><br />
       <var>string1</var> == <var>string2</var><br />
       <var>string1</var> != <var>string2</var></code></dt>
@@ -745,6 +764,34 @@
 </directivesynopsis>
 
 <directivesynopsis>
+<name>SSIEnableAccess</name>
+<description>Enable the -A flag during conditional flow control processing.</description>
+<syntax>SSIEnableAccess on|off</syntax>
+<default>SSIEnableAccess off</default>
+<contextlist><context>directory</context><context>.htaccess</context></contextlist>
+
+<usage>
+    <p>The <directive>SSIEnableAccess</directive> directive controls whether
+    the -A test is enabled during conditional flow control processing.
+    <directive>SSIEnableAccess</directive> can take on the following values:</p>
+
+    <dl>
+
+      <dt><code>off</code></dt>
+      <dd>&lt;!--#if expr="-A /foo"--&gt; will be interpreted as a series
+      of string and regular expression tokens, the -A has no special
+      meaning.</dd>
+
+      <dt><code>on</code></dt>
+      <dd>&lt;!--#if expr="-A /foo"--&gt; will evaluate to false if the
+      URL /foo is inaccessible by configuration, or true otherwise.</dd>
+
+    </dl>
+
+</usage>
+</directivesynopsis>
+
+<directivesynopsis>
 <name>XBitHack</name>
 <description>Parse SSI directives in files with the execute bit
 set</description>
@@ -785,7 +832,7 @@
       </dd>
     </dl>
 
-    </usage>
+</usage>
 </directivesynopsis>
 
 </modulesynopsis>

Modified: httpd/httpd/branches/2.2.x/modules/filters/mod_include.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/filters/mod_include.c?rev=600393&r1=600392&r2=600393&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/filters/mod_include.c (original)
+++ httpd/httpd/branches/2.2.x/modules/filters/mod_include.c Sun Dec  2 14:24:02 2007
@@ -80,7 +80,8 @@
     TOKEN_GE,
     TOKEN_LE,
     TOKEN_GT,
-    TOKEN_LT
+    TOKEN_LT,
+    TOKEN_ACCESS
 } token_type_t;
 
 typedef struct {
@@ -114,6 +115,7 @@
     const char *default_time_fmt;
     const char *undefined_echo;
     xbithack_t  xbithack;
+    const int accessenable;
 } include_dir_config;
 
 typedef struct {
@@ -190,6 +192,8 @@
     const char   *undefined_echo;
     apr_size_t    undefined_echo_len;
 
+    int         accessenable;    /* is using the access tests allowed? */
+
 #ifdef DEBUG_INCLUDE
     struct {
         ap_filter_t *f;
@@ -941,7 +945,7 @@
     return rc;
 }
 
-static int get_ptoken(apr_pool_t *pool, const char **parse, token_t *token)
+static int get_ptoken(include_ctx_t *ctx, const char **parse, token_t *token, token_t *previous)
 {
     const char *p;
     apr_size_t shift;
@@ -990,6 +994,10 @@
         unmatched = '\'';
         break;
     case '/':
+        /* if last token was ACCESS, this token is STRING */
+        if (previous != NULL && TOKEN_ACCESS == previous->type) {
+            break;
+        }
         TYPE_TOKEN(token, TOKEN_RE);
         unmatched = '/';
         break;
@@ -1023,6 +1031,13 @@
         }
         TYPE_TOKEN(token, TOKEN_LT);
         return 0;
+    case '-':
+        if (**parse == 'A' && (ctx->intern->accessenable)) {
+            TYPE_TOKEN(token, TOKEN_ACCESS);
+            ++*parse;
+            return 0;
+        }
+        break;
     }
 
     /* It's a string or regex token
@@ -1079,11 +1094,11 @@
     }
 
     if (unmatched) {
-        token->value = apr_pstrdup(pool, "");
+        token->value = apr_pstrdup(ctx->dpool, "");
     }
     else {
         apr_size_t len = p - token->value - shift;
-        char *c = apr_palloc(pool, len + 1);
+        char *c = apr_palloc(ctx->dpool, len + 1);
 
         p = token->value;
         token->value = c;
@@ -1111,6 +1126,7 @@
 {
     parse_node_t *new, *root = NULL, *current = NULL;
     request_rec *r = ctx->intern->r;
+    request_rec *rr = NULL;
     const char *error = "Invalid expression \"%s\" in file %s";
     const char *parse = expr;
     int was_unmatched = 0;
@@ -1130,7 +1146,8 @@
          */
         CREATE_NODE(ctx, new);
 
-        was_unmatched = get_ptoken(ctx->dpool, &parse, &new->token);
+        was_unmatched = get_ptoken(ctx, &parse, &new->token,
+                         (current != NULL ? &current->token : NULL));
         if (!parse) {
             break;
         }
@@ -1142,6 +1159,7 @@
             switch (new->token.type) {
             case TOKEN_STRING:
             case TOKEN_NOT:
+            case TOKEN_ACCESS:
             case TOKEN_LBRACE:
                 root = current = new;
                 continue;
@@ -1276,6 +1294,7 @@
             break;
 
         case TOKEN_NOT:
+        case TOKEN_ACCESS:
         case TOKEN_LBRACE:
             switch (current->token.type) {
             case TOKEN_STRING:
@@ -1462,6 +1481,34 @@
             }
             break;
 
+        case TOKEN_ACCESS:
+            if (current->left || !current->right ||
+                (current->right->token.type != TOKEN_STRING &&
+                 current->right->token.type != TOKEN_RE)) {
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                            "Invalid expression \"%s\" in file %s: Token '-A' must be followed by a URI string.",
+                            expr, r->filename);
+                *was_error = 1;
+                return 0;
+            }
+            current->right->token.value =
+                ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0,
+                                    SSI_EXPAND_DROP_NAME);
+            rr = ap_sub_req_lookup_uri(current->right->token.value, r, NULL);
+            /* 400 and higher are considered access denied */
+            if (rr->status < HTTP_BAD_REQUEST) {
+                current->value = 1;
+            }
+            else {
+                current->value = 0;
+                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rr->status, r, 
+                              "mod_include: The tested "
+                              "subrequest -A \"%s\" returned an error code.",
+                              current->right->token.value);
+            }
+            ap_destroy_sub_req(rr);
+            break;
+
         case TOKEN_RE:
             if (!error) {
                 error = "No operator before regex in expr \"%s\" in file %s";
@@ -3526,6 +3573,7 @@
         if (ap_allow_options(r) & OPT_INCNOEXEC) {
             ctx->flags |= SSI_FLAG_NO_EXEC;
         }
+        intern->accessenable = conf->accessenable;
 
         ctx->if_nesting_level = 0;
         intern->re = NULL;
@@ -3808,6 +3856,9 @@
                   "SSI End String Tag"),
     AP_INIT_TAKE1("SSIUndefinedEcho", set_undefined_echo, NULL, OR_ALL,
                   "String to be displayed if an echoed variable is undefined"),
+    AP_INIT_FLAG("SSIAccessEnable", ap_set_flag_slot,
+                  (void *)APR_OFFSETOF(include_dir_config, accessenable),
+                  OR_LIMIT, "Whether testing access is enabled. Limited to 'on' or 'off'"),
     {NULL}
 };