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>
+ <!--#if expr="-A /private" --><br />
+ <indent>
+ Click <a href="/private">here</a> to access private
+ information.<br />
+ </indent>
+ <!--#endif -->
+ </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><!--#if expr="-A /foo"--> 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><!--#if expr="-A /foo"--> 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 ? ¤t->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}
};