--- fnord-1.10/httpd.c 2005-08-03 13:32:50.000000000 +0200 +++ fnord-1.10-20071104/httpd.c 2007-11-04 22:07:27.000000000 +0100 @@ -70,6 +70,12 @@ * equal sign ('='), fnord will throw away the URI part. */ #define REDIRECT +/* uncomment the following line to get apache-style common log file + * format. Please note that that format is not usable for ad-hoc + * analysis using awk and friends, but you will be able to use Apache + * log analysis tools. */ +/* #define COLF */ + /* uncomment the following line to make fnord tarpit queries from * EmailSiphon (an email harvester for spammers) */ #define TARPIT @@ -169,11 +175,6 @@ char* remote_ident; #endif -static void sanitize(char* ua) { /* replace strings with underscores for logging */ - int j; - for (j=0; ua[j]; ++j) if (isspace(ua[j])) ua[j]='_'; -} - static int buffer_put2digits(buffer* b,unsigned int i) { char x[2]; x[0]=(i/10)+'0'; @@ -181,6 +182,16 @@ return buffer_put(b,x,2); } +static void buffer_putsescaped(buffer* b,const char* url,int aos) { + while (url && *url) { + char c=*url; + if (c==' ' || c=='\n' || c=='\t' || c=='\r' && aos) return; + if (c<=' ' || c>=127) c='_'; + buffer_put(b,&c,1); + ++url; + } +} + static void dolog(off_t len) { /* write a log line to stderr */ #ifdef COLF time_t t=time(0); @@ -212,7 +223,7 @@ case HEAD: buffer_puts(buffer_2,"HEAD "); break; default: buffer_puts(buffer_2,"? "); break; } - buffer_puts(buffer_2,url); + buffer_putsescaped(buffer_2,url,1); buffer_puts(buffer_2,httpversion?" HTTP/1.1\" ":" HTTP/1.0\" "); buffer_putulong(buffer_2,retcode); buffer_putspace(buffer_2); @@ -225,18 +236,15 @@ buffer_putspace(buffer_2); buffer_putrange(buffer_2,len); buffer_putspace(buffer_2); - sanitize(host); - buffer_puts(buffer_2,host); + buffer_putsescaped(buffer_2,host,0); buffer_putspace(buffer_2); - sanitize(ua); - buffer_puts(buffer_2,ua); + buffer_putsescaped(buffer_2,ua,0); buffer_putspace(buffer_2); if (!refer) refer="none"; - sanitize(refer); - buffer_puts(buffer_2,refer); + buffer_putsescaped(buffer_2,refer,0); buffer_putspace(buffer_2); if (url) - buffer_puts(buffer_2,url); + buffer_putsescaped(buffer_2,url,1); else buffer_puts(buffer_2,"(null)"); #endif @@ -653,6 +661,7 @@ buf[i]=0; break; } + while (*c==' ' || *c=='\t') ++c; return c; } } @@ -694,6 +703,7 @@ { "xbm", "image/x-xbitmap" }, { "xpm", "image/x-xpixmap" }, { "xwd", "image/x-xwindowdump" }, + { "ico", "image/x-icon" }, { 0 } }; /* try to find out MIME type and content encoding. @@ -880,7 +890,7 @@ } static void redirectboilerplate() { - buffer_puts(buffer_1,"HTTP/1.0 301 Go Away\r\nConnection: close\r\nLocation: "); + buffer_puts(buffer_1,"HTTP/1.0 301 Go Away\r\nConnection: close\r\nContent-Length: 0\r\nLocation: "); } static void handleredirect(const char *url,const char* origurl) { @@ -1362,9 +1372,9 @@ { char *tmp; - if ((tmp=header(buf,len,"User-Agent"))) ua=tmp; - if ((tmp=header(buf,len,"Referer"))) refer=tmp; - if ((tmp=header(buf,len,"Accept-Encoding"))) accept_enc=tmp; + ua=header(buf,len,"User-Agent"); + refer=header(buf,len,"Referer"); + accept_enc=header(buf,len,"Accept-Encoding"); #ifdef KEEPALIVE if ((tmp=header(buf,len,"Connection"))) { /* see if it's "keep-alive" or "close" */ if (!strcasecmp(tmp,"keep-alive")) @@ -1374,13 +1384,13 @@ } #endif #ifdef CGI - if ((tmp=header(buf,len,"Cookie"))) cookie=tmp; - if ((tmp=header(buf,len,"Authorization"))) auth_type=tmp; + cookie=header(buf,len,"Cookie"); + auth_type=header(buf,len,"Authorization"); if (method==POST) { - if ((tmp=header(buf,len,"Content-Type"))) content_type=tmp; - if ((tmp=header(buf,len,"Content-Length"))) content_len=tmp; - if (tmp) { - scan_ulong(tmp,&post_len); + content_type=header(buf,len,"Content-Type"); + content_len=header(buf,len,"Content-Length"); + if (content_len) { + scan_ulong(content_len,&post_len); post_miss=buf+len+1; post_mlen=in-len-1; if (post_len<=post_mlen) post_mlen=post_len; @@ -1390,7 +1400,7 @@ } #ifdef TARPIT - if (str_equal(ua,"EmailSiphon")) { sleep(120); exit(0); } + if (ua && str_equal(ua,"EmailSiphon")) { sleep(120); exit(0); } #endif port=getenv("TCPLOCALPORT");