httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From minf...@apache.org
Subject svn commit: r571872 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_include.xml modules/filters/mod_include.c modules/filters/mod_include.h
Date Sat, 01 Sep 2007 21:27:27 GMT
Author: minfrin
Date: Sat Sep  1 14:27:26 2007
New Revision: 571872

URL: http://svn.apache.org/viewvc?rev=571872&view=rev
Log:
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.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_include.xml
    httpd/httpd/trunk/modules/filters/mod_include.c
    httpd/httpd/trunk/modules/filters/mod_include.h

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=571872&r1=571871&r2=571872&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sat Sep  1 14:27:26 2007
@@ -2,6 +2,11 @@
 Changes with Apache 2.3.0
 [ When backported to 2.2.x, remove entry from this file ]
 
+  *) 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]
+
   *) mod_authnz_ldap, mod_authn_dbd: Tidy up the code to expose authn
      parameters to the environment. Improve portability to
      EBCDIC machines by using apr_toupper(). [Martin Kraemer]

Modified: httpd/httpd/trunk/docs/manual/mod/mod_include.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_include.xml?rev=571872&r1=571871&r2=571872&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_include.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_include.xml Sat Sep  1 14:27:26 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>location</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/trunk/modules/filters/mod_include.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_include.c?rev=571872&r1=571871&r2=571872&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_include.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_include.c Sat Sep  1 14:27:26 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 {
@@ -941,7 +943,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 +992,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 +1029,13 @@
         }
         TYPE_TOKEN(token, TOKEN_LT);
         return 0;
+    case '-':
+        if (**parse == 'A' && (ctx->accessenable)) {
+            TYPE_TOKEN(token, TOKEN_ACCESS);
+            ++*parse;
+            return 0;
+        }
+        break;
     }
 
     /* It's a string or regex token
@@ -1079,11 +1092,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 +1124,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 +1144,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 +1157,7 @@
             switch (new->token.type) {
             case TOKEN_STRING:
             case TOKEN_NOT:
+            case TOKEN_ACCESS:
             case TOKEN_LBRACE:
                 root = current = new;
                 continue;
@@ -1276,6 +1292,7 @@
             break;
 
         case TOKEN_NOT:
+        case TOKEN_ACCESS:
         case TOKEN_LBRACE:
             switch (current->token.type) {
             case TOKEN_STRING:
@@ -1462,6 +1479,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 +3571,7 @@
         if (ap_allow_options(r) & OPT_INCNOEXEC) {
             ctx->flags |= SSI_FLAG_NO_EXEC;
         }
+        ctx->accessenable = conf->accessenable;
 
         ctx->if_nesting_level = 0;
         intern->re = NULL;
@@ -3808,6 +3854,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}
 };
 

Modified: httpd/httpd/trunk/modules/filters/mod_include.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_include.h?rev=571872&r1=571871&r2=571872&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_include.h (original)
+++ httpd/httpd/trunk/modules/filters/mod_include.h Sat Sep  1 14:27:26 2007
@@ -96,6 +96,9 @@
 
     /* pointer to internal (non-public) data, don't touch */
     struct ssi_internal_ctx *intern;
+
+    /* is using the access tests allowed? */
+    int         accessenable;
 } include_ctx_t;
 
 typedef apr_status_t (include_handler_fn_t)(include_ctx_t *, ap_filter_t *,



Mime
View raw message