Changes with Apache 1.3.30
+ *) SECURITY [CAN-2003-0020]: Escape arbitrary data before writing
+ into the errorlog. [André Malo]
+
*) '%X' is now accepted as an alias for '%c' in the
LogFormat directive. This allows you to configure logging
to still log the connection status even with mod_ssl
* ap_note_cleanups_for_file_ex(),
* ap_popenf_ex() and ap_psocket_ex().
* 19990320.15 - ap_is_recursion_limit_exceeded()
+ * 19990320.16 - ap_escape_errorlog_item()
*/
#define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 19990320
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 15 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 16 /* 0...n */
/* Useful for testing for features. */
#define AP_MODULE_MAGIC_AT_LEAST(major,minor) \
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(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);
API_EXPORT(int) ap_count_dirs(const char *path);
const server_rec *s, const request_rec *r,
const char *fmt, va_list args)
{
- char errstr[MAX_STRING_LEN];
+ char errstr[MAX_STRING_LEN], scratch[MAX_STRING_LEN];
size_t len;
int save_errno = errno;
FILE *logf;
}
#endif
- len += ap_vsnprintf(errstr + len, sizeof(errstr) - len, fmt, args);
+ if (ap_vsnprintf(scratch, sizeof(scratch) - len, fmt, args)) {
+ len += ap_escape_errorlog_item(errstr + len, scratch,
+ sizeof(errstr) - len);
+ }
/* NULL if we are logging to syslog */
if (logf) {
return ret;
}
+API_EXPORT(size_t) ap_escape_errorlog_item(char *dest, const char *source,
+ size_t buflen)
+{
+ unsigned char *d, *ep;
+ const unsigned char *s;
+
+ if (!source || !buflen) { /* be safe */
+ return 0;
+ }
+
+ d = (unsigned char *)dest;
+ s = (const unsigned char *)source;
+ ep = d + buflen - 1;
+
+ for (; d < ep && *s; ++s) {
+
+ if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
+ *d++ = '\\';
+ if (d >= ep) {
+ --d;
+ break;
+ }
+
+ switch(*s) {
+ case '\b':
+ *d++ = 'b';
+ break;
+ case '\n':
+ *d++ = 'n';
+ break;
+ case '\r':
+ *d++ = 'r';
+ break;
+ case '\t':
+ *d++ = 't';
+ break;
+ case '\v':
+ *d++ = 'v';
+ break;
+ case '\\':
+ *d++ = *s;
+ break;
+ case '"': /* no need for this in error log */
+ d[-1] = *s;
+ break;
+ default:
+ if (d >= ep - 2) {
+ ep = --d; /* break the for loop as well */
+ break;
+ }
+ c2x(*s, d);
+ *d = 'x';
+ d += 3;
+ }
+ }
+ else {
+ *d++ = *s;
+ }
+ }
+ *d = '\0';
+
+ return (d - (unsigned char *)dest);
+}
API_EXPORT(char *) ap_escape_shell_cmd(pool *p, const char *str)
{