You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dirk-Willem van Gulik <di...@webweaving.org> on 2003/12/18 15:13:41 UTC
Escaping of outside chars
We've just been looking at a case of an (admittently) doggy resolver
library which led through non-ASCII chars (as part of some i18n efford)
and hence allowed for alien chars to end up in the log files. Which
royally screwed the operator.
The patch below goes a bit further than the current escaping added
recently - and adds a %t to the ap_snprintf(). Specically around some
resover returns.
Posting here as it may be of use for some people. I am too far removed
from day to day httpd dev to even consider committing this.
Have fun,
Dw
Index: src/ApacheCore.def
===================================================================
RCS file: /home/cvs/apache-1.3/src/ApacheCore.def,v
retrieving revision 1.35
diff -u -r1.35 ApacheCore.def
--- src/ApacheCore.def 18 Jun 2002 04:19:46 -0000 1.35
+++ src/ApacheCore.def 18 Dec 2003 14:05:51 -0000
@@ -447,3 +447,4 @@
ap_getline @439
ap_get_chunk_size @440
ap_escape_logitem @441
+ ap_escape_snbuff @442
Index: src/ap/ap_snprintf.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/ap/ap_snprintf.c,v
retrieving revision 1.54
diff -u -r1.54 ap_snprintf.c
--- src/ap/ap_snprintf.c 3 Feb 2003 17:13:17 -0000 1.54
+++ src/ap/ap_snprintf.c 18 Dec 2003 14:05:51 -0000
@@ -118,6 +118,10 @@
*/
#define NUM_BUF_SIZE 512
+/* Max size for escaped string (%t) argument.
+ */
+#define STR_BUF_SIZE (MAX_STRING_LEN)
+
/*
* cvt.c - IEEE floating point formatting routines for FreeBSD
* from GNU libc-4.6.27. Modified to be thread safe.
@@ -714,6 +718,7 @@
/*
* Default variable settings
*/
+ char strbuff[ STR_BUF_SIZE ];
adjust = RIGHT;
alternate_form = print_sign = print_blank = NO;
pad_char = ' ';
@@ -915,9 +920,14 @@
case 's':
+ case 't':
s = va_arg(ap, char *);
if (s != NULL) {
- s_len = strlen(s);
+ if (*fmt == 't') {
+ s_len = ap_escape_snbuff(strbuff,sizeof(strbuff),s);
+ s = strbuff;
+ } else
+ s_len = strlen(s);
if (adjust_precision && precision < s_len)
s_len = precision;
}
Index: src/include/httpd.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/httpd.h,v
retrieving revision 1.374
diff -u -r1.374 httpd.h
@@ -1028,6 +1029,7 @@
API_EXPORT(char *) ap_construct_server(pool *p, const char *hostname,
unsigned port, const request_rec *r);
API_EXPORT(char *) ap_escape_logitem(pool *p, const char *str);
+API_EXPORT(int) ap_escape_snbuff(char *buff, int size, const char *str);
API_EXPORT(size_t) ap_escape_errorlog_item(char *dest, const char *source,
size_t buflen);
API_EXPORT(char *) ap_escape_shell_cmd(pool *p, const char *s);
Index: src/main/http_core.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_core.c,v
retrieving revision 1.327
diff -u -r1.327 http_core.c
@@ -3669,7 +3671,7 @@
}
if ((r->uri[0] != '/') && strcmp(r->uri, "*")) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "Invalid URI in request %s", r->the_request);
+ "Invalid URI in request %t", r->the_request);
return BAD_REQUEST;
}
@@ -4003,7 +4005,7 @@
if (r->method_number == M_INVALID) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "Invalid method in request %s",
+ "Invalid method in request %t",
ap_escape_logitem(r->pool, r->the_request));
return NOT_IMPLEMENTED;
}
@@ -4016,7 +4018,7 @@
if (r->finfo.st_mode == 0 || (r->path_info && *r->path_info)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
- "File does not exist: %s",r->path_info ?
+ "File does not exist: %t",r->path_info ?
ap_pstrcat(r->pool, r->filename, r->path_info, NULL)
: r->filename);
return HTTP_NOT_FOUND;
Index: src/main/http_log.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_log.c,v
retrieving revision 1.97
diff -u -r1.97 http_log.c
--- src/main/http_log.c 14 Dec 2003 18:16:50 -0000 1.97
+++ src/main/http_log.c 18 Dec 2003 14:05:54 -0000
@@ -549,13 +549,13 @@
API_EXPORT(void) ap_log_error_old(const char *err, server_rec *s)
{
- ap_log_error(APLOG_MARK, APLOG_ERR, s, "%s", err);
+ ap_log_error(APLOG_MARK, APLOG_ERR, s, "%t", err);
}
API_EXPORT(void) ap_log_unixerr(const char *routine, const char *file,
const char *msg, server_rec *s)
{
- ap_log_error(file, 0, APLOG_ERR, s, "%s", msg);
+ ap_log_error(file, 0, APLOG_ERR, s, "%t", msg);
}
API_EXPORT_NONSTD(void) ap_log_printf(const server_rec *s, const char *fmt, ...)
@@ -570,7 +570,7 @@
API_EXPORT(void) ap_log_reason(const char *reason, const char *file, request_rec *r)
{
ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
- "access to %s failed for %s, reason: %s",
+ "access to %t failed for %t, reason: %t",
file,
ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME),
reason);
Index: src/main/http_main.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.605
diff -u -r1.605 http_main.c
--- src/main/http_main.c 19 Oct 2003 18:00:35 -0000 1.605
+++ src/main/http_main.c 18 Dec 2003 14:05:58 -0000
@@ -1541,7 +1541,7 @@
dirconf = current_conn->server->lookup_defaults;
if (!current_conn->keptalive) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,
- current_conn->server, "[client %s] %s timed out",
+ current_conn->server, "[client %t] %s timed out",
current_conn->remote_ip,
timeout_name ? timeout_name : "request");
}
Index: src/main/http_protocol.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
retrieving revision 1.330
diff -u -r1.330 http_protocol.c
--- src/main/http_protocol.c 3 Feb 2003 17:13:22 -0000 1.330
+++ src/main/http_protocol.c 18 Dec 2003 14:05:59 -0000
@@ -1252,7 +1252,7 @@
* comes through...
*/
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "client sent invalid HTTP/0.9 request: HEAD %s",
+ "client sent invalid HTTP/0.9 request: HEAD %t",
r->uri);
r->header_only = 0;
r->status = HTTP_BAD_REQUEST;
@@ -1287,7 +1287,7 @@
r->status = HTTP_BAD_REQUEST;
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
"client sent HTTP/1.1 request without hostname "
- "(see RFC2616 section 14.23): %s", r->uri);
+ "(see RFC2616 section 14.23): %t", r->uri);
}
if (r->status != HTTP_OK) {
ap_send_error_response(r, 0);
@@ -1316,7 +1316,7 @@
r->status = HTTP_EXPECTATION_FAILED;
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r,
"client sent an unrecognized expectation value of "
- "Expect: %s", expect);
+ "Expect: %t", expect);
ap_send_error_response(r, 0);
(void) ap_discard_request_body(r);
ap_log_transaction(r);
@@ -1411,7 +1411,7 @@
if (!ap_auth_name(r)) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
- r, "need AuthName: %s", r->uri);
+ r, "need AuthName: %t", r->uri);
return SERVER_ERROR;
}
@@ -1423,7 +1423,7 @@
if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
/* Client tried to authenticate using wrong auth scheme */
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "client used wrong authentication scheme: %s", r->uri);
+ "client used wrong authentication scheme: %t", r->uri);
ap_note_basic_auth_failure(r);
return AUTH_REQUIRED;
}
@@ -2006,12 +2006,12 @@
if (tenc) {
if (strcasecmp(tenc, "chunked")) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "Unknown Transfer-Encoding %s", tenc);
+ "Unknown Transfer-Encoding %t", tenc);
return HTTP_NOT_IMPLEMENTED;
}
if (r->read_body == REQUEST_CHUNKED_ERROR) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "chunked Transfer-Encoding forbidden: %s", r->uri);
+ "chunked Transfer-Encoding forbidden: %t", r->uri);
return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
}
@@ -2049,7 +2049,7 @@
if ((r->read_body == REQUEST_NO_BODY) &&
(r->read_chunked || (r->remaining > 0))) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "%s with body is not allowed for %s", r->method, r->uri);
+ "%t with body is not allowed for %t", r->method, r->uri);
return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
@@ -2057,7 +2057,7 @@
if (max_body && ((unsigned long)r->remaining > max_body)
&& (r->remaining >= 0)) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "Request content-length of %s is larger than the configured "
+ "Request content-length of %t is larger than the configured "
"limit of %lu", lenp, max_body);
return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
Index: src/main/http_request.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_request.c,v
retrieving revision 1.171
diff -u -r1.171 http_request.c
--- src/main/http_request.c 18 Oct 2003 14:15:58 -0000 1.171
+++ src/main/http_request.c 18 Dec 2003 14:06:00 -0000
@@ -296,7 +296,7 @@
else
#endif
ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "access to %s failed", r->uri);
+ "access to %t failed", r->uri);
return HTTP_FORBIDDEN;
}
#else
@@ -1176,7 +1176,7 @@
{
if (status == DECLINED) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, r,
- "configuration error: couldn't %s: %s", phase, r->uri);
+ "configuration error: couldn't %s: %t", phase, r->uri);
ap_die(SERVER_ERROR, r);
}
else
Index: src/main/http_vhost.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_vhost.c,v
retrieving revision 1.35
diff -u -r1.35 http_vhost.c
--- src/main/http_vhost.c 3 Feb 2003 17:13:23 -0000 1.35
+++ src/main/http_vhost.c 18 Dec 2003 14:06:00 -0000
@@ -220,7 +220,7 @@
if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
- "Cannot resolve host name %s --- ignoring!", w);
+ "Cannot resolve host name %t --- ignoring!", w);
if (t != NULL)
*t = ':';
return NULL;
Index: src/main/util.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/util.c,v
retrieving revision 1.208
diff -u -r1.208 util.c
--- src/main/util.c 14 Dec 2003 18:16:50 -0000 1.208
+++ src/main/util.c 18 Dec 2003 14:06:01 -0000
@ -1469,54 +1512,90 @@
return where;
}
-/* escape a string for logging */
-API_EXPORT(char *) ap_escape_logitem(pool *p, const char *str)
+/* Take the buffer in 'str' and copy it into buff (up to size
+ * bytes, including the terminating \0) - printing chars from the
+ * T_ESCAPE_LOGITEM in their escaped format. The function returns
+ * a count (excluding the terminating \0); useful in combination with
+ * buff==NULL; which will prevent writing into the buff.
+ */
+API_EXPORT(int ) ap_escape_snbuff(char *buff, int size, const char *str)
{
- char *ret;
unsigned char *d;
const unsigned char *s;
+ int n = 0;
- if (str == NULL)
- return NULL;
+ if (str == NULL || *str == '\0' || size <=0) {
+ if (buff)
+ buff[0] = '\0';
+ return 0;
+ }
- ret = ap_palloc(p, 4 * strlen(str) + 1); /* Be safe */
- d = (unsigned char *)ret;
+ d = (unsigned char *)buff;
s = (const unsigned char *)str;
for (; *s; ++s) {
-
if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
- *d++ = '\\';
+ if (buff)
+ *d++ = '\\';
+ if (n >= size - 2)
+ break;
switch(*s) {
case '\b':
- *d++ = 'b';
+ if (buff) *d++ = 'b';
break;
case '\n':
- *d++ = 'n';
+ if (buff) *d++ = 'n';
break;
case '\r':
- *d++ = 'r';
+ if (buff) *d++ = 'r';
break;
case '\t':
- *d++ = 't';
+ if (buff) *d++ = 't';
break;
case '\v':
- *d++ = 'v';
+ if (buff) *d++ = 'v';
break;
case '\\':
case '"':
- *d++ = *s;
+ if (buff) *d++ = *s;
break;
default:
- c2x(*s, d);
- *d = 'x';
- d += 3;
- }
+ if (n >= size -3)
+ break;
+ if (buff) {
+ c2x(*s, d);
+ *d = 'x';
+ d += 3;
+ }
+ n+=2;
+ }
+ n+=2;
+ }
+ else {
+ if (n >= size -1);
+ break;
+ if (buff)
+ *d++ = *s;
+ n++;
}
- else
- *d++ = *s;
}
- *d = '\0';
+ if (buff)
+ *d = '\0';
+ n++; /* Also count the terminating \0. */
+ return n;
+}
+
+/* escape a string for logging */
+API_EXPORT(char *) ap_escape_logitem(pool *p, const char *str)
+{
+ char *ret;
+ int n;
+
+ if (str == NULL)
+ return NULL;
+ n = 4 * strlen(str) + 1; /* Be safe */
+ ret = ap_palloc(p,n);
+ ap_escape_snbuff(ret,n,str);
return ret;
}
Index: src/main/util_script.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/util_script.c,v
retrieving revision 1.167
diff -u -r1.167 util_script.c
--- src/main/util_script.c 3 Feb 2003 17:13:23 -0000 1.167
+++ src/main/util_script.c 18 Dec 2003 14:06:02 -0000
@@ -565,7 +565,7 @@
ap_kill_timeout(r);
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
- "%s: %s", malformed, r->filename);
+ "%t: %s", malformed, r->filename);
return HTTP_INTERNAL_SERVER_ERROR;
}
Index: src/support/httpd.exp
===================================================================
RCS file: /home/cvs/apache-1.3/src/support/httpd.exp,v
retrieving revision 1.41
diff -u -r1.41 httpd.exp
--- src/support/httpd.exp 17 Jan 2003 12:23:10 -0000 1.41
+++ src/support/httpd.exp 18 Dec 2003 14:06:03 -0000
@@ -107,6 +107,7 @@
ap_error_log2stderr
ap_escape_html
ap_escape_logitem
+ap_escape_snbuff
ap_escape_path_segment
ap_escape_quotes
ap_escape_shell_cmd