You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@locus.apache.org on 2000/03/13 21:27:33 UTC
cvs commit: apache-2.0/src/modules/standard mod_actions.c mod_autoindex.c mod_expires.c mod_include.c mod_log_config.c mod_speling.c
jim 00/03/13 12:27:31
Modified: src/include http_core.h
src/main http_core.c http_log.c http_protocol.c util.c
src/modules/proxy proxy_util.c
src/modules/standard mod_actions.c mod_autoindex.c
mod_expires.c mod_include.c mod_log_config.c
mod_speling.c
Log:
Backport the CSS security fixes to Apache 2.0a. Or is that forward
port? My sense of direction is all confused.
Revision Changes Path
1.7 +9 -0 apache-2.0/src/include/http_core.h
Index: http_core.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/include/http_core.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- http_core.h 2000/03/10 00:05:51 1.6
+++ http_core.h 2000/03/13 20:27:16 1.7
@@ -245,6 +245,15 @@
*/
unsigned d_is_fnmatch : 1;
+ /* should we force a charset on any outgoing parameterless content-type?
+ * if so, which charset?
+ */
+#define ADD_DEFAULT_CHARSET_OFF (0)
+#define ADD_DEFAULT_CHARSET_ON (1)
+#define ADD_DEFAULT_CHARSET_UNSET (2)
+ unsigned add_default_charset : 2;
+ char *add_default_charset_name;
+
unsigned long limit_req_body; /* limit on bytes in request msg body */
/* logging options */
1.36 +34 -0 apache-2.0/src/main/http_core.c
Index: http_core.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/http_core.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- http_core.c 2000/03/10 00:06:53 1.35
+++ http_core.c 2000/03/13 20:27:18 1.36
@@ -146,6 +146,9 @@
conf->server_signature = srv_sig_unset;
+ conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET;
+ conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME;
+
return (void *)conf;
}
@@ -257,6 +260,14 @@
conf->server_signature = new->server_signature;
}
+ if (new->add_default_charset != ADD_DEFAULT_CHARSET_UNSET) {
+ conf->add_default_charset = new->add_default_charset;
+ }
+
+ if (new->add_default_charset_name) {
+ conf->add_default_charset_name = new->add_default_charset_name;
+ }
+
return (void*)conf;
}
@@ -1000,6 +1011,27 @@
}
#endif /*GPROF*/
+static const char *set_add_default_charset(cmd_parms *cmd,
+ core_dir_config *d, char *arg)
+{
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
+ if (err != NULL) {
+ return err;
+ }
+ if (!strcasecmp(arg, "Off")) {
+ d->add_default_charset = ADD_DEFAULT_CHARSET_OFF;
+ }
+ else if (!strcasecmp(arg, "On")) {
+ d->add_default_charset = ADD_DEFAULT_CHARSET_ON;
+ d->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME;
+ }
+ else {
+ d->add_default_charset = ADD_DEFAULT_CHARSET_ON;
+ d->add_default_charset_name = arg;
+ }
+ return NULL;
+}
+
static const char *set_document_root(cmd_parms *cmd, void *dummy, char *arg)
{
void *sconf = cmd->server->module_config;
@@ -2294,6 +2326,8 @@
{ "GprofDir", set_gprof_dir, NULL, RSRC_CONF, TAKE1,
"Directory to plop gmon.out files" },
#endif
+{ "AddDefaultCharset", set_add_default_charset, NULL, OR_FILEINFO,
+ TAKE1, "The name of the default charset to add to any Content-Type without one or 'Off' to disable" },
/* Old resource config file commands */
1.35 +2 -1 apache-2.0/src/main/http_log.c
Index: http_log.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/http_log.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- http_log.c 2000/03/10 00:06:53 1.34
+++ http_log.c 2000/03/13 20:27:19 1.35
@@ -469,7 +469,8 @@
if (((level & APLOG_LEVELMASK) <= APLOG_WARNING)
&& (ap_table_get(r->notes, "error-notes") == NULL)) {
ap_table_setn(r->notes, "error-notes",
- ap_pvsprintf(r->pool, fmt, args));
+ ap_escape_html(r->pool, ap_pvsprintf(r->pool, fmt,
+ args)));
}
va_end(args);
}
1.56 +43 -8 apache-2.0/src/main/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- http_protocol.c 2000/03/10 00:06:53 1.55
+++ http_protocol.c 2000/03/13 20:27:20 1.56
@@ -90,6 +90,43 @@
} while (0)
+/*
+ * Builds the content-type that should be sent to the client from the
+ * content-type specified. The following rules are followed:
+ * - if type is NULL, type is set to ap_default_type(r)
+ * - if charset adding is disabled, stop processing and return type.
+ * - then, if there are no parameters on type, add the default charset
+ * - return type
+ */
+static const char *make_content_type(request_rec *r, const char *type) {
+ char *needcset[] = {
+ "text/plain",
+ "text/html",
+ NULL };
+ char **pcset;
+ core_dir_config *conf = (core_dir_config *)ap_get_module_config(
+ r->per_dir_config, &core_module);
+ if (!type) type = ap_default_type(r);
+ if (conf->add_default_charset != ADD_DEFAULT_CHARSET_ON) return type;
+
+ if (ap_strcasestr(type, "charset=") != NULL) {
+ /* already has parameter, do nothing */
+ /* XXX we don't check the validity */
+ ;
+ } else {
+ /* see if it makes sense to add the charset. At present,
+ * we only add it if the Content-type is one of needcset[]
+ */
+ for (pcset = needcset; *pcset ; pcset++)
+ if (ap_strcasestr(type, *pcset) != NULL) {
+ type = ap_pstrcat(r->pool, type, "; charset=",
+ conf->add_default_charset_name, NULL);
+ break;
+ }
+ }
+ return type;
+}
+
static int parse_byterange(char *range, long clength, long *start, long *end)
{
char *dash = strchr(range, '-');
@@ -240,7 +277,7 @@
length);
if (r->byterange > 1) {
- const char *ct = r->content_type ? r->content_type : ap_default_type(r);
+ const char *ct = make_content_type(r, r->content_type);
char ts[MAX_STRING_LEN];
ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end,
@@ -897,7 +934,7 @@
r->status = HTTP_BAD_REQUEST;
ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
"Size of a request header field exceeds server limit.<P>\n"
- "<PRE>\n", field, "</PRE>\n", NULL));
+ "<PRE>\n", ap_escape_html(r->pool, field), "</PRE>\n", NULL));
return;
}
copy = ap_palloc(r->pool, len + 1);
@@ -907,7 +944,7 @@
r->status = HTTP_BAD_REQUEST; /* or abort the bad request */
ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
"Request header field is missing colon separator.<P>\n"
- "<PRE>\n", copy, "</PRE>\n", NULL));
+ "<PRE>\n", ap_escape_html(r->pool, copy), "</PRE>\n", NULL));
return;
}
@@ -1604,10 +1641,8 @@
ap_table_setn(r->headers_out, "Content-Type",
ap_pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/",
"byteranges; boundary=", r->boundary, NULL));
- else if (r->content_type)
- ap_table_setn(r->headers_out, "Content-Type", r->content_type);
- else
- ap_table_setn(r->headers_out, "Content-Type", ap_default_type(r));
+ else ap_table_setn(r->headers_out, "Content-Type", make_content_type(r,
+ r->content_type));
if (r->content_encoding)
ap_table_setn(r->headers_out, "Content-Encoding", r->content_encoding);
@@ -2493,7 +2528,7 @@
r->content_languages = NULL;
r->content_encoding = NULL;
r->clength = 0;
- r->content_type = "text/html";
+ r->content_type = "text/html; charset=iso-8859-1";
if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
ap_table_setn(r->headers_out, "Allow", make_allow(r));
1.33 +34 -0 apache-2.0/src/main/util.c
Index: util.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/util.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- util.c 2000/03/10 00:06:55 1.32
+++ util.c 2000/03/13 20:27:21 1.33
@@ -104,6 +104,8 @@
{
const char *semi;
+ if (intype == NULL) return NULL;
+
semi = strchr(intype, ';');
if (semi == NULL) {
return ap_pstrdup(p, intype);
@@ -275,6 +277,38 @@
ap_unblock_alarms();
}
+/*
+ * Similar to standard strstr() but we ignore case in this version.
+ * Based on the strstr() implementation further below.
+ */
+API_EXPORT(char *) ap_strcasestr(const char *s1, const char *s2)
+{
+ char *p1, *p2;
+ if (*s2 == '\0') {
+ /* an empty s2 */
+ return((char *)s1);
+ }
+ while(1) {
+ for ( ; (*s1 != '\0') && (ap_tolower(*s1) != ap_tolower(*s2)); s1++);
+ if (*s1 == '\0') return(NULL);
+ /* found first character of s2, see if the rest matches */
+ p1 = (char *)s1;
+ p2 = (char *)s2;
+ while (ap_tolower(*++p1) == ap_tolower(*++p2)) {
+ if (*p1 == '\0') {
+ /* both strings ended together */
+ return((char *)s1);
+ }
+ }
+ if (*p2 == '\0') {
+ /* second string ended, a match */
+ break;
+ }
+ /* didn't find a match here, try starting at next character in s1 */
+ s1++;
+ }
+ return((char *)s1);
+}
/*
* Apache stub function for the regex libraries regexec() to make sure the
* whole regex(3) API is available through the Apache (exported) namespace.
1.8 +8 -4 apache-2.0/src/modules/proxy/proxy_util.c
Index: proxy_util.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/proxy/proxy_util.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- proxy_util.c 2000/03/10 00:07:08 1.7
+++ proxy_util.c 2000/03/13 20:27:25 1.8
@@ -822,11 +822,15 @@
ap_table_setn(r->notes, "error-notes",
ap_pstrcat(r->pool,
"The proxy server could not handle the request "
- "<EM><A HREF=\"", r->uri, "\">",
- r->method, " ", r->uri, "</A></EM>.<P>\n"
- "Reason: <STRONG>", message, "</STRONG>", NULL));
+ "<EM><A HREF=\"", ap_escape_uri(r->pool, r->uri),
+ "\">", ap_escape_html(r->pool, r->method),
+ " ",
+ ap_escape_html(r->pool, r->uri), "</A></EM>.<P>\n"
+ "Reason: <STRONG>",
+ ap_escape_html(r->pool, message),
+ "</STRONG>", NULL));
- /* Allow the "error-notes" string to be printed by ap_send_error_response() */
+ /* Allow "error-notes" string to be printed by ap_send_error_response() */
ap_table_setn(r->notes, "verbose-error-to", ap_pstrdup(r->pool, "*"));
r->status_line = ap_psprintf(r->pool, "%3.3u Proxy Error", statuscode);
1.8 +2 -1 apache-2.0/src/modules/standard/mod_actions.c
Index: mod_actions.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_actions.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- mod_actions.c 2000/03/10 00:07:09 1.7
+++ mod_actions.c 2000/03/13 20:27:26 1.8
@@ -159,7 +159,8 @@
{
action_dir_config *conf = (action_dir_config *)
ap_get_module_config(r->per_dir_config, &action_module);
- const char *t, *action = r->handler ? r->handler : r->content_type;
+ const char *t, *action = r->handler ? r->handler :
+ ap_field_noparam(r->pool, r->content_type);
const char *script;
int i;
1.25 +1 -1 apache-2.0/src/modules/standard/mod_autoindex.c
Index: mod_autoindex.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_autoindex.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- mod_autoindex.c 2000/03/10 00:07:11 1.24
+++ mod_autoindex.c 2000/03/13 20:27:27 1.25
@@ -690,7 +690,7 @@
static char *find_item(request_rec *r, ap_array_header_t *list, int path_only)
{
- const char *content_type = r->content_type;
+ const char *content_type = ap_field_noparam(r->pool, r->content_type);
const char *content_encoding = r->content_encoding;
char *path = r->filename;
1.11 +2 -1 apache-2.0/src/modules/standard/mod_expires.c
Index: mod_expires.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_expires.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- mod_expires.c 2000/03/10 00:07:11 1.10
+++ mod_expires.c 2000/03/13 20:27:27 1.11
@@ -441,7 +441,8 @@
if (r->content_type == NULL)
code = NULL;
else
- code = (char *) ap_table_get(conf->expiresbytype, r->content_type);
+ code = (char *) ap_table_get(conf->expiresbytype,
+ ap_field_noparam(r->pool, r->content_type));
if (code == NULL) {
/* no expires defined for that type, is there a default? */
1.22 +27 -2 apache-2.0/src/modules/standard/mod_include.c
Index: mod_include.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_include.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- mod_include.c 2000/03/10 00:07:11 1.21
+++ mod_include.c 2000/03/13 20:27:27 1.22
@@ -943,7 +943,10 @@
{
char tag[MAX_STRING_LEN];
char *tag_val;
+ enum {E_NONE, E_URL, E_ENTITY} encode;
+ encode = E_ENTITY;
+
while (1) {
if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
@@ -952,7 +955,15 @@
const char *val = ap_table_get(r->subprocess_env, tag_val);
if (val) {
- ap_rputs(val, r);
+ if (encode == E_NONE) {
+ ap_rputs(val, r);
+ }
+ else if (encode == E_URL) {
+ ap_rputs(ap_escape_uri(r->pool, val), r);
+ }
+ else if (encode == E_ENTITY) {
+ ap_rputs(ap_escape_html(r->pool, val), r);
+ }
}
else {
ap_rputs("(none)", r);
@@ -961,6 +972,19 @@
else if (!strcmp(tag, "done")) {
return 0;
}
+ else if (!strcmp(tag, "encoding")) {
+ if (!strcasecmp(tag_val, "none")) encode = E_NONE;
+ else if (!strcasecmp(tag_val, "url")) encode = E_URL;
+ else if (!strcasecmp(tag_val, "entity")) encode = E_ENTITY;
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
+ "unknown value \"%s\" to parameter \"encoding\" of "
+ "tag echo in %s",
+ tag_val, r->filename);
+ ap_rputs(error, r);
+ }
+ }
+
else {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
"unknown parameter \"%s\" to tag echo in %s",
@@ -2138,7 +2162,8 @@
}
else if (!strcmp(tag, "done")) {
for (i = 0; i < arr->nelts; ++i) {
- ap_rvputs(r, elts[i].key, "=", elts[i].val, "\n", NULL);
+ ap_rvputs(r, ap_escape_html(r->pool, elts[i].key), "=",
+ ap_escape_html(r->pool, elts[i].val), "\n", NULL);
}
return 0;
}
1.17 +1 -1 apache-2.0/src/modules/standard/mod_log_config.c
Index: mod_log_config.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_log_config.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- mod_log_config.c 2000/03/10 00:07:12 1.16
+++ mod_log_config.c 2000/03/13 20:27:28 1.17
@@ -364,7 +364,7 @@
{
const char *cp = ap_table_get(r->headers_out, a);
if (!strcasecmp(a, "Content-type") && r->content_type) {
- cp = r->content_type;
+ cp = ap_field_noparam(r->pool, r->content_type);
}
if (cp) {
return cp;
1.10 +5 -5 apache-2.0/src/modules/standard/mod_speling.c
Index: mod_speling.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_speling.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- mod_speling.c 2000/03/10 00:07:12 1.9
+++ mod_speling.c 2000/03/13 20:27:29 1.10
@@ -467,7 +467,7 @@
*(const char **)ap_push_array(t) =
"The document name you requested (<code>";
- *(const char **)ap_push_array(t) = r->uri;
+ *(const char **)ap_push_array(t) = ap_escape_html(sub_pool, r->uri);
*(const char **)ap_push_array(t) =
"</code>) could not be found on this server.\n"
"However, we found documents with names similar "
@@ -486,15 +486,15 @@
? r->parsed_uri.query : "",
NULL);
*(const char **)ap_push_array(v) = "\"";
- *(const char **)ap_push_array(v) = vuri;
+ *(const char **)ap_push_array(v) = ap_escape_uri(sub_pool, vuri);
*(const char **)ap_push_array(v) = "\";\"";
*(const char **)ap_push_array(v) = reason;
*(const char **)ap_push_array(v) = "\"";
*(const char **)ap_push_array(t) = "<li><a href=\"";
- *(const char **)ap_push_array(t) = vuri;
+ *(const char **)ap_push_array(t) = ap_escape_uri(sub_pool, vuri);
*(const char **)ap_push_array(t) = "\">";
- *(const char **)ap_push_array(t) = vuri;
+ *(const char **)ap_push_array(t) = ap_escape_html(sub_pool, vuri);
*(const char **)ap_push_array(t) = "</a> (";
*(const char **)ap_push_array(t) = reason;
*(const char **)ap_push_array(t) = ")\n";
@@ -521,7 +521,7 @@
*(const char **)ap_push_array(t) =
"Please consider informing the owner of the "
"<a href=\"";
- *(const char **)ap_push_array(t) = ref;
+ *(const char **)ap_push_array(t) = ap_escape_uri(sub_pool, ref);
*(const char **)ap_push_array(t) = "\">referring page</a> "
"about the broken link.\n";
}