[prev in list] [next in list] [prev in thread] [next in thread]
List: apache-cvs
Subject: svn commit: r1128564 - in /httpd/httpd/trunk: CHANGES docs/manual/expr.xml
From: sf () apache ! org
Date: 2011-05-28 7:01:48
Message-ID: 20110528070148.2B789238896F () eris ! apache ! org
[Download RAW message or body]
Author: sf
Date: Sat May 28 07:01:47 2011
New Revision: 1128564
URL: http://svn.apache.org/viewvc?rev=1128564&view=rev
Log:
Add some features to ap_expr for use by mod_include:
* a restricted mode that does not allow to bypass request access restrictions
* new variables DOCUMENT_URI (alias for REQUEST_URI), LAST_MODIFIED
* -A as an alias for -U
* an additional data entry in ap_expr_eval_ctx_t for use by the consumer
* an extensible ap_expr_exec_ctx() API that allows to use that data entry
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/docs/manual/expr.xml
httpd/httpd/trunk/include/ap_expr.h
httpd/httpd/trunk/include/ap_mmn.h
httpd/httpd/trunk/server/util_expr_eval.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1128564&r1=1128563&r2=1128564&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sat May 28 07:01:47 2011
@@ -2,6 +2,13 @@
Changes with Apache 2.3.13
+ *) core: Add some features to ap_expr for use by mod_include: a restricted
+ mode that does not allow to bypass request access restrictions; new
+ variables DOCUMENT_URI (alias for REQUEST_URI), LAST_MODIFIED; -A as an
+ alias for -U; an additional data entry in ap_expr_eval_ctx_t for use by
+ the consumer; an extensible ap_expr_exec_ctx() API that allows to use that
+ data entry. [Stefan Fritsch]
+
*) mod_include: Merge directory configs instead of one SSI* config directive
causing all other per-directory SSI* config directives to be reset.
[Stefan Fritsch]
Modified: httpd/httpd/trunk/docs/manual/expr.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/expr.xml?rev=1128564&r1=1128563&r2=1128564&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/expr.xml (original)
+++ httpd/httpd/trunk/docs/manual/expr.xml Sat May 28 07:01:47 2011
@@ -158,6 +158,8 @@ listfunction ::= listfuncname "<strong>(
<td>The scheme part of the request's URI</td></tr>
<tr><td><code>REQUEST_URI</code></td>
<td>The URI of the request</td></tr>
+ <tr><td><code>DOCUMENT_URI</code></td>
+ <td>Same as REQUEST_URI</td></tr>
<tr><td><code>REQUEST_FILENAME</code></td>
<td>The full local filesystem path to the file or script matching the
request, if this has already been determined by the server at the
@@ -166,6 +168,11 @@ listfunction ::= listfuncname "<strong>(
<code>REQUEST_URI</code> </td></tr>
<tr><td><code>SCRIPT_FILENAME</code></td>
<td>Same as <code>REQUEST_FILENAME</code></td></tr>
+ <tr><td><code>LAST_MODIFIED</code></td>
+ <td>The date and time of last modification of the file in the format
+ <code>20101231235959</code>, if this has already been determined by
+ the server at the time <code>LAST_MODIFIED</code> is referenced.
+ </td></tr>
<tr><td><code>SCRIPT_USER</code></td>
<td>The user name of the owner of the script.</td></tr>
<tr><td><code>SCRIPT_GROUP</code></td>
@@ -374,6 +381,8 @@ listfunction ::= listfuncname "<strong>(
currently-configured access controls for that path. This uses an
internal subrequest to do the check, so use it with care - it can
impact your server's performance!</td></tr>
+ <tr><td><code>-A</code></td>
+ <td>Alias for <code>-U</code></td></tr>
<tr><td><code>-n</code></td>
<td>True if string is not empty</td></tr>
<tr><td><code>-z</code></td>
Modified: httpd/httpd/trunk/include/ap_expr.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_expr.h?rev=1128564&r1=1128563&r2=1128564&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_expr.h (original)
+++ httpd/httpd/trunk/include/ap_expr.h Sat May 28 07:01:47 2011
@@ -59,6 +59,11 @@ typedef struct {
#define AP_EXPR_FLAGS_SSL_EXPR_COMPAT 1
/** Don't add siginificant request headers to the Vary response header */
#define AP_EXPR_FLAGS_DONT_VARY 2
+/** Don't allow functions/vars that bypass the current request's access
+ * restrictions or would otherwise leak confidential information.
+ * Used by e.g. mod_include.
+ */
+#define AP_EXPR_FLAGS_RESTRICTED 4
/**
@@ -119,8 +124,20 @@ typedef struct {
* interested in this information.
*/
const char **vary_this;
+ /** Arbitrary context data provided by the caller for custom functions */
+ void *data;
} ap_expr_eval_ctx_t;
+/**
+ * Evaluate a parse tree, full featured version
+ * @param ctx The evaluation context with all data filled in
+ * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
+ * @note *ctx->err will be set to NULL on success, or to an error message on
+ * error
+ * @note request headers used during evaluation will be added to the Vary:
+ * response header if ctx->vary_this is set.
+ */
+AP_DECLARE(int) ap_expr_exec_ctx(ap_expr_eval_ctx_t *ctx);
/**
* The parser can be extended with variable lookup, functions, and
Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1128564&r1=1128563&r2=1128564&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Sat May 28 07:01:47 2011
@@ -323,6 +323,8 @@
* 20110329.3 (2.3.12-dev) Add format field to ap_errorlog_info.
* 20110329.4 (2.3.13-dev) bgrowth and max_balancers to proxy_server_conf.
* 20110329.5 (2.3.13-dev) Add ap_regexec_len()
+ * 20110329.6 (2.3.13-dev) Add AP_EXPR_FLAGS_RESTRICTED, ap_expr_eval_ctx_t->data,
+ * ap_expr_exec_ctx()
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -330,7 +332,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20110329
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 5 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 6 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Modified: httpd/httpd/trunk/server/util_expr_eval.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util_expr_eval.c?rev=1128564&r1=1128563&r2=1128564&view=diff
==============================================================================
--- httpd/httpd/trunk/server/util_expr_eval.c (original)
+++ httpd/httpd/trunk/server/util_expr_eval.c Sat May 28 07:01:47 2011
@@ -384,7 +384,7 @@ static ap_expr_t *ap_expr_info_make(int
ap_expr_t *info = apr_palloc(ctx->pool, sizeof(ap_expr_t));
ap_expr_lookup_parms parms;
parms.type = type;
- parms.flags = 0;
+ parms.flags = ctx->flags;
parms.pool = ctx->pool;
parms.ptemp = ctx->ptemp;
parms.name = name;
@@ -691,12 +691,47 @@ AP_DECLARE(int) ap_expr_exec(request_rec
return ap_expr_exec_re(r, info, 0, NULL, NULL, err);
}
+AP_DECLARE(int) ap_expr_exec_ctx(ap_expr_eval_ctx_t *ctx)
+{
+ int rc;
+
+ AP_DEBUG_ASSERT(ctx->p != NULL);
+ /* XXX: allow r, c == NULL */
+ AP_DEBUG_ASSERT(ctx->r != NULL);
+ AP_DEBUG_ASSERT(ctx->c != NULL);
+ AP_DEBUG_ASSERT(ctx->s != NULL);
+ AP_DEBUG_ASSERT(ctx->err != NULL);
+ AP_DEBUG_ASSERT(ctx->info != NULL);
+ if (ctx->re_pmatch) {
+ AP_DEBUG_ASSERT(ctx->re_source != NULL);
+ AP_DEBUG_ASSERT(ctx->re_nmatch > 0);
+ }
+
+ *ctx->err = NULL;
+ rc = ap_expr_eval(ctx, ctx->info->root_node);
+ if (*ctx->err != NULL) {
+ ap_log_rerror(LOG_MARK(ctx->info), APLOG_ERR, 0, ctx->r,
+ "Evaluation of expression from %s:%d failed: %s",
+ ctx->info->filename, ctx->info->line_number, *ctx->err);
+ return -1;
+ } else {
+ rc = rc ? 1 : 0;
+ ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE4, 0, ctx->r,
+ "Evaluation of expression from %s:%d gave: %d",
+ ctx->info->filename, ctx->info->line_number, rc);
+
+ if (ctx->vary_this)
+ apr_table_merge(ctx->r->headers_out, "Vary", *ctx->vary_this);
+
+ return rc;
+ }
+}
+
AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *info,
apr_size_t nmatch, ap_regmatch_t *pmatch,
const char **source, const char **err)
{
ap_expr_eval_ctx_t ctx;
- int rc;
int dont_vary = (info->flags & AP_EXPR_FLAGS_DONT_VARY);
const char *tmp_source = NULL, *vary_this = NULL;
ap_regmatch_t tmp_pmatch[10];
@@ -711,35 +746,15 @@ AP_DECLARE(int) ap_expr_exec_re(request_
ctx.re_pmatch = pmatch;
ctx.re_source = source;
ctx.vary_this = dont_vary ? NULL : &vary_this;
+ ctx.data = NULL;
if (!pmatch) {
ctx.re_nmatch = 10;
ctx.re_pmatch = tmp_pmatch;
ctx.re_source = &tmp_source;
}
- else {
- AP_DEBUG_ASSERT(source != NULL);
- AP_DEBUG_ASSERT(nmatch > 0);
- }
-
- *err = NULL;
- rc = ap_expr_eval(&ctx, info->root_node);
- if (*err != NULL) {
- ap_log_rerror(LOG_MARK(info), APLOG_ERR, 0, r,
- "Evaluation of expression from %s:%d failed: %s",
- info->filename, info->line_number, *err);
- return -1;
- } else {
- rc = rc ? 1 : 0;
- ap_log_rerror(LOG_MARK(info), APLOG_TRACE4, 0, r,
- "Evaluation of expression from %s:%d gave: %d",
- info->filename, info->line_number, rc);
-
- if (vary_this)
- apr_table_merge(r->headers_out, "Vary", vary_this);
- return rc;
- }
+ return ap_expr_exec_ctx(&ctx);
}
static void add_vary(ap_expr_eval_ctx_t *ctx, const char *name)
@@ -911,12 +926,12 @@ static int op_file_min(ap_expr_eval_ctx_
apr_finfo_t sb;
const char *name = (const char *)data;
if (apr_stat(&sb, arg, APR_FINFO_MIN, ctx->p) != APR_SUCCESS)
- return 0;
+ return FALSE;
switch (name[0]) {
case 'd':
return (sb.filetype == APR_DIR);
case 'e':
- return 1;
+ return TRUE;
case 'f':
return (sb.filetype == APR_REG);
case 's':
@@ -924,7 +939,7 @@ static int op_file_min(ap_expr_eval_ctx_
default:
ap_assert(0);
}
- return 0;
+ return FALSE;
}
static int op_file_link(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
@@ -933,10 +948,10 @@ static int op_file_link(ap_expr_eval_ctx
#if !defined(OS2)
if (apr_stat(&sb, arg, APR_FINFO_MIN | APR_FINFO_LINK, ctx->p) == APR_SUCCESS
&& sb.filetype == APR_LNK) {
- return 1;
+ return TRUE;
}
#endif
- return 0;
+ return FALSE;
}
static int op_file_xbit(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
@@ -944,24 +959,24 @@ static int op_file_xbit(ap_expr_eval_ctx
apr_finfo_t sb;
if (apr_stat(&sb, arg, APR_FINFO_PROT| APR_FINFO_LINK, ctx->p) == APR_SUCCESS
&& (sb.protection & (APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE))) {
- return 1;
+ return TRUE;
}
- return 0;
+ return FALSE;
}
static int op_url_subr(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
{
- int rc = 0;
+ int rc = FALSE;
request_rec *rsub, *r = ctx->r;
if (!r)
- return 0;
+ return FALSE;
/* avoid some infinite recursions */
if (r->main && r->main->uri && r->uri && strcmp(r->main->uri, r->uri) == 0)
- return 0;
+ return FALSE;
rsub = ap_sub_req_lookup_uri(arg, r, NULL);
if (rsub->status < 400) {
- rc = 1;
+ rc = TRUE;
}
ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE5, 0, r,
"Subrequest for -U %s at %s:%d gave status: %d",
@@ -973,16 +988,16 @@ static int op_url_subr(ap_expr_eval_ctx_
static int op_file_subr(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
{
- int rc = 0;
+ int rc = FALSE;
apr_finfo_t sb;
request_rec *rsub, *r = ctx->r;
if (!r)
- return 0;
+ return FALSE;
rsub = ap_sub_req_lookup_file(arg, r, NULL);
if (rsub->status < 300 &&
/* double-check that file exists since default result is 200 */
apr_stat(&sb, rsub->filename, APR_FINFO_MIN, ctx->p) == APR_SUCCESS) {
- rc = 1;
+ rc = TRUE;
}
ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE5, 0, r,
"Subrequest for -F %s at %s:%d gave status: %d",
@@ -1064,6 +1079,8 @@ static const char *request_var_names[] =
"REQUEST_LOG_ID", /* 20 */
"SCRIPT_USER", /* 21 */
"SCRIPT_GROUP", /* 22 */
+ "DOCUMENT_URI", /* 23 */
+ "LAST_MODIFIED", /* 24 */
NULL
};
@@ -1132,6 +1149,17 @@ static const char *request_var_fn(ap_exp
apr_gid_name_get(&result, r->finfo.group, ctx->p);
return result;
}
+ case 23:
+ return r->uri;
+ case 24:
+ {
+ apr_time_exp_t tm;
+ apr_time_exp_lt(&tm, r->mtime);
+ return apr_psprintf(ctx->p, "%02d%02d%02d%02d%02d%02d%02d",
+ (tm.tm_year / 100) + 19, (tm.tm_year % 100),
+ tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min,
+ tm.tm_sec);
+ }
default:
ap_assert(0);
return NULL;
@@ -1326,6 +1354,7 @@ struct expr_provider_single {
const void *func;
const char *name;
ap_expr_lookup_fn_t *arg_parsing_func;
+ int restricted;
};
struct expr_provider_multi {
@@ -1342,46 +1371,47 @@ static const struct expr_provider_multi
};
static const struct expr_provider_single string_func_providers[] = {
- { osenv_func, "osenv", NULL },
- { env_func, "env", NULL },
- { req_table_func, "resp", NULL },
- { req_table_func, "req", NULL },
+ { osenv_func, "osenv", NULL, 0 },
+ { env_func, "env", NULL, 0 },
+ { req_table_func, "resp", NULL, 0 },
+ { req_table_func, "req", NULL, 0 },
/* 'http' as alias for 'req' for compatibility with ssl_expr */
- { req_table_func, "http", NULL },
- { req_table_func, "note", NULL },
- { req_table_func, "reqenv", NULL },
- { tolower_func, "tolower", NULL },
- { toupper_func, "toupper", NULL },
- { escape_func, "escape", NULL },
- { unescape_func, "unescape", NULL },
- { file_func, "file", NULL },
- { filesize_func, "filesize", NULL },
+ { req_table_func, "http", NULL, 0 },
+ { req_table_func, "note", NULL, 0 },
+ { req_table_func, "reqenv", NULL, 0 },
+ { tolower_func, "tolower", NULL, 0 },
+ { toupper_func, "toupper", NULL, 0 },
+ { escape_func, "escape", NULL, 0 },
+ { unescape_func, "unescape", NULL, 0 },
+ { file_func, "file", NULL, 1 },
+ { filesize_func, "filesize", NULL, 1 },
{ NULL, NULL, NULL}
};
/* XXX: base64 encode/decode ? */
static const struct expr_provider_single unary_op_providers[] = {
- { op_nz, "n", NULL },
- { op_nz, "z", NULL },
- { op_R, "R", subnet_parse_arg },
- { op_T, "T", NULL },
- { op_file_min, "d", NULL },
- { op_file_min, "e", NULL },
- { op_file_min, "f", NULL },
- { op_file_min, "s", NULL },
- { op_file_link, "L", NULL },
- { op_file_link, "h", NULL },
- { op_file_xbit, "x", NULL },
- { op_file_subr, "F", NULL },
- { op_url_subr, "U", NULL },
+ { op_nz, "n", NULL, 0 },
+ { op_nz, "z", NULL, 0 },
+ { op_R, "R", subnet_parse_arg, 0 },
+ { op_T, "T", NULL, 0 },
+ { op_file_min, "d", NULL, 1 },
+ { op_file_min, "e", NULL, 1 },
+ { op_file_min, "f", NULL, 1 },
+ { op_file_min, "s", NULL, 1 },
+ { op_file_link, "L", NULL, 1 },
+ { op_file_link, "h", NULL, 1 },
+ { op_file_xbit, "x", NULL, 1 },
+ { op_file_subr, "F", NULL, 0 },
+ { op_url_subr, "U", NULL, 0 },
+ { op_url_subr, "A", NULL, 0 },
{ NULL, NULL, NULL }
};
static const struct expr_provider_single binary_op_providers[] = {
- { op_ipmatch, "ipmatch", subnet_parse_arg },
- { op_fnmatch, "fnmatch", NULL },
- { op_strmatch, "strmatch", NULL },
- { op_strcmatch, "strcmatch", NULL },
+ { op_ipmatch, "ipmatch", subnet_parse_arg, 0 },
+ { op_fnmatch, "fnmatch", NULL, 0 },
+ { op_strmatch, "strmatch", NULL, 0 },
+ { op_strcmatch, "strcmatch", NULL, 0 },
{ NULL, NULL, NULL }
};
@@ -1423,6 +1453,15 @@ static int core_expr_lookup(ap_expr_look
}
while (prov->func) {
if (strcasecmp(prov->name, parms->name) == 0) {
+ if ((parms->flags & AP_EXPR_FLAGS_RESTRICTED)
+ && prov->restricted) {
+ *parms->err =
+ apr_psprintf(parms->ptemp,
+ "%s%s not available in restricted context",
+ (parms->type == AP_EXPR_FUNC_STRING) ? "" : \
"-", + prov->name);
+ return !OK;
+ }
*parms->func = prov->func;
if (prov->arg_parsing_func) {
return prov->arg_parsing_func(parms);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic