diff --git a/thttpd-2.25b-CVE-2005-3124.patch b/thttpd-2.25b-CVE-2005-3124.patch index c41ec46..c456f8d 100644 --- a/thttpd-2.25b-CVE-2005-3124.patch +++ b/thttpd-2.25b-CVE-2005-3124.patch @@ -1,7 +1,7 @@ -diff -ru thttpd-2.23beta1.orig/extras/syslogtocern thttpd-2.23beta1/extras/syslogtocern ---- thttpd-2.23beta1.orig/extras/syslogtocern 1999-09-15 18:00:54.000000000 +0200 -+++ thttpd-2.23beta1/extras/syslogtocern 2005-10-26 01:45:34.000000000 +0200 -@@ -31,8 +31,8 @@ +diff -Naupr thttpd-2.25b.orig/extras/syslogtocern thttpd-2.25b/extras/syslogtocern +--- thttpd-2.25b.orig/extras/syslogtocern 2005-06-29 19:50:23.000000000 +0200 ++++ thttpd-2.25b/extras/syslogtocern 2008-09-25 10:42:27.000000000 +0200 +@@ -31,8 +31,8 @@ if [ $# -lt 1 ] ; then exit 1 fi @@ -11,9 +11,81 @@ diff -ru thttpd-2.23beta1.orig/extras/syslogtocern thttpd-2.23beta1/extras/syslo +trap " [ -f \"$tmp1\" ] && /bin/rm -f -- \"$tmp1\"" 0 1 2 3 13 15 # Gather up all the thttpd entries. - egrep ' thttpd\[' $* > $tmp1 -@@ -65,4 +65,3 @@ + egrep -h ' thttpd\[' "$@" > $tmp1 +@@ -65,4 +65,3 @@ awk < $tmp1 '{if ( ! ( NF >= 15 && $7 == sed -e "s,\([A-Z][a-z][a-z] [0-9 ][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\) [^ ]* thttpd\[[0-9]*\]: \(.*\),[\1 ${year}] \2," > error_log # Done. -rm -f $tmp1 +diff -Naupr thttpd-2.25b.orig/extras/syslogtocern.orig thttpd-2.25b/extras/syslogtocern.orig +--- thttpd-2.25b.orig/extras/syslogtocern.orig 1970-01-01 01:00:00.000000000 +0100 ++++ thttpd-2.25b/extras/syslogtocern.orig 2005-06-29 19:50:23.000000000 +0200 +@@ -0,0 +1,68 @@ ++#!/bin/sh ++# ++# syslogtocern - convert thttpd syslog entries into CERN Combined Log Format ++# ++# Copyright � 1995,1998 by Jef Poskanzer . ++# All rights reserved. ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# 1. Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# 2. Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in the ++# documentation and/or other materials provided with the distribution. ++# ++# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++# SUCH DAMAGE. ++ ++if [ $# -lt 1 ] ; then ++ echo "usage: $0 logfile ..." >&2 ++ exit 1 ++fi ++ ++tmp1=/tmp/stc1.$$ ++rm -f $tmp1 ++ ++# Gather up all the thttpd entries. ++egrep -h ' thttpd\[' "$@" > $tmp1 ++ ++# Figure out the current year - it's not in syslog's output. Some versions ++# of date have the %Y directive to give the full four-digit year, but others ++# only have %y. ++year=`date +%y` ++if [ $year -gt 70 ] ; then ++ year=19$year ++else ++ year=20$year ++fi ++ ++# If the current year isn't the year that the logfile was generated, we need ++# to fix it. This will most likely happen once a year, when this script is ++# run on January 1st for December 31st's logfile. So, if the current month ++# is January and there are December dates in the log file, we subtract one. ++# This should cover most cases. ++if [ `date +%m` -eq 1 -a `head -1 $tmp1 | awk '{print $1}'` = "Dec" ] ; then ++ year=`echo $year - 1 | bc` ++fi ++ ++# Do access_log. ++awk < $tmp1 '{if ( NF >= 15 && $7 == "-" && $12 >= 100 && $12 < 510) print;}' | ++ sed -e "s,\([A-Z][a-z][a-z]\) \([0-9 ][0-9]\) \([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\) [^ ]* thttpd\[[0-9]*\]: \([^ ]* [^ ]* [^ ]*\) \(.*\),\4 [\2/\1/${year}:\3] \5," -e 's,\[ ,[0,' > access_log ++ ++# Do error_log. ++awk < $tmp1 '{if ( ! ( NF >= 15 && $7 == "-" && $12 >= 100 && $12 < 510) ) print;}' | ++ sed -e "s,\([A-Z][a-z][a-z] [0-9 ][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\) [^ ]* thttpd\[[0-9]*\]: \(.*\),[\1 ${year}] \2," > error_log ++ ++# Done. ++rm -f $tmp1 diff --git a/thttpd-2.25b-fixes.patch b/thttpd-2.25b-fixes.patch index 7915adc..e74863d 100644 --- a/thttpd-2.25b-fixes.patch +++ b/thttpd-2.25b-fixes.patch @@ -1,8 +1,6 @@ -This patch comes from the Debian thttpd package. Many thanks to Daniel Baumann -for all the recent changes. - ---- thttpd-2.23beta1.orig/extras/htpasswd.1 -+++ thttpd-2.23beta1/extras/htpasswd.1 +diff -Naupr thttpd-2.25b.orig/extras/htpasswd.1 thttpd-2.25b/extras/htpasswd.1 +--- thttpd-2.25b.orig/extras/htpasswd.1 1998-05-07 19:01:04.000000000 +0200 ++++ thttpd-2.25b/extras/htpasswd.1 2008-09-25 10:43:13.000000000 +0200 @@ -1,8 +1,8 @@ -.TH htpasswd 1 "05 May 1998" +.TH thtpasswd 1 "05 May 1998" @@ -15,9 +13,10 @@ for all the recent changes. .RB [ -c ] .I passwordfile .I username ---- thttpd-2.23beta1.orig/extras/htpasswd.c -+++ thttpd-2.23beta1/extras/htpasswd.c -@@ -21,7 +21,12 @@ +diff -Naupr thttpd-2.25b.orig/extras/htpasswd.c thttpd-2.25b/extras/htpasswd.c +--- thttpd-2.25b.orig/extras/htpasswd.c 2001-12-19 01:08:08.000000000 +0100 ++++ thttpd-2.25b/extras/htpasswd.c 2008-09-25 10:43:13.000000000 +0200 +@@ -21,7 +21,12 @@ extern char *crypt(const char *key, cons #define LF 10 #define CR 13 @@ -30,7 +29,7 @@ for all the recent changes. int tfd; char temp_template[] = "/tmp/htp.XXXXXX"; -@@ -137,8 +142,9 @@ +@@ -137,8 +142,9 @@ add_password( char* user, FILE* f ) } static void usage(void) { @@ -42,7 +41,7 @@ for all the recent changes. exit(1); } -@@ -151,17 +157,37 @@ +@@ -151,17 +157,37 @@ void interrupted(int signo) { int main(int argc, char *argv[]) { FILE *tfp,*f; char user[MAX_STRING_LEN]; @@ -83,7 +82,7 @@ for all the recent changes. if(!(tfp = fopen(argv[2],"w"))) { fprintf(stderr,"Could not open passwd file %s for writing.\n", argv[2]); -@@ -172,12 +198,6 @@ +@@ -172,12 +198,6 @@ int main(int argc, char *argv[]) { add_password(argv[3],tfp); fclose(tfp); exit(0); @@ -96,7 +95,7 @@ for all the recent changes. } if(!(f = fopen(argv[1],"r"))) { -@@ -186,16 +206,43 @@ +@@ -186,16 +206,43 @@ int main(int argc, char *argv[]) { fprintf(stderr,"Use -c option to create new one.\n"); exit(1); } @@ -143,7 +142,7 @@ for all the recent changes. if(strcmp(user,w)) { putline(tfp,line); continue; -@@ -210,10 +257,28 @@ +@@ -210,10 +257,28 @@ int main(int argc, char *argv[]) { printf("Adding user %s\n",user); add_password(user,tfp); } @@ -174,8 +173,9 @@ for all the recent changes. unlink(temp_template); exit(0); } ---- thttpd-2.23beta1.orig/extras/makeweb.1 -+++ thttpd-2.23beta1/extras/makeweb.1 +diff -Naupr thttpd-2.25b.orig/extras/makeweb.1 thttpd-2.25b/extras/makeweb.1 +--- thttpd-2.25b.orig/extras/makeweb.1 2005-06-29 19:53:22.000000000 +0200 ++++ thttpd-2.25b/extras/makeweb.1 2008-09-25 10:43:13.000000000 +0200 @@ -2,11 +2,17 @@ .SH NAME makeweb - create user web directory @@ -195,9 +195,10 @@ for all the recent changes. .SH "SEE ALSO thttpd(8) .SH AUTHOR ---- thttpd-2.23beta1.orig/extras/makeweb.c -+++ thttpd-2.23beta1/extras/makeweb.c -@@ -47,6 +47,10 @@ +diff -Naupr thttpd-2.25b.orig/extras/makeweb.c thttpd-2.25b/extras/makeweb.c +--- thttpd-2.25b.orig/extras/makeweb.c 2005-06-29 19:53:25.000000000 +0200 ++++ thttpd-2.25b/extras/makeweb.c 2008-09-25 10:43:13.000000000 +0200 +@@ -48,6 +48,10 @@ static char* argv0; @@ -208,7 +209,7 @@ for all the recent changes. static void check_room( int size, int len ) -@@ -120,28 +124,44 @@ +@@ -121,28 +125,44 @@ This is probably a configuration error.\ int main( int argc, char** argv ) { @@ -259,7 +260,7 @@ for all the recent changes. } username = pwd->pw_name; homedir = pwd->pw_dir; -@@ -158,11 +178,9 @@ +@@ -159,11 +179,9 @@ main( int argc, char** argv ) (void) strcat( dirname, TILDE_MAP_2 ); check_dir( dirname, pwd->pw_uid, pwd->pw_gid ); @@ -272,9 +273,270 @@ for all the recent changes. #ifdef TILDE_MAP_1 prefix = TILDE_MAP_1; #else /* TILDE_MAP_1 */ ---- thttpd-2.23beta1.orig/thttpd.8 -+++ thttpd-2.23beta1/thttpd.8 -@@ -259,7 +259,7 @@ +diff -Naupr thttpd-2.25b.orig/extras/makeweb.c.orig thttpd-2.25b/extras/makeweb.c.orig +--- thttpd-2.25b.orig/extras/makeweb.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ thttpd-2.25b/extras/makeweb.c.orig 2005-06-29 19:53:25.000000000 +0200 +@@ -0,0 +1,256 @@ ++/* makeweb.c - let a user create a web subdirectory ++** ++** Copyright � 1995 by Jef Poskanzer . ++** All rights reserved. ++** ++** Redistribution and use in source and binary forms, with or without ++** modification, are permitted provided that the following conditions ++** are met: ++** 1. Redistributions of source code must retain the above copyright ++** notice, this list of conditions and the following disclaimer. ++** 2. Redistributions in binary form must reproduce the above copyright ++** notice, this list of conditions and the following disclaimer in the ++** documentation and/or other materials provided with the distribution. ++** ++** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++** SUCH DAMAGE. ++*/ ++ ++/* This is intended to be installed setgid to a group that has ++** write access to the system web directory. It allows any user ++** to create a subdirectory there. It also makes a symbolic link ++** in the user's home directory pointing at the new web subdir. ++*/ ++ ++ ++#include "../config.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define LINK "public_html" ++ ++static char* argv0; ++ ++ ++static void ++check_room( int size, int len ) ++ { ++ if ( len > size ) ++ { ++ (void) fprintf( stderr, "%s: internal error, out of room\n", argv0 ); ++ exit( 1 ); ++ } ++ } ++ ++ ++static void ++end_with_slash( char* str ) ++ { ++ if ( str[strlen( str ) - 1] != '/' ) ++ (void) strcat( str, "/" ); ++ } ++ ++ ++static void ++check_dir( char* dirname, uid_t uid, gid_t gid ) ++ { ++ struct stat sb; ++ ++ /* Check the directory. */ ++ if ( stat( dirname, &sb ) < 0 ) ++ { ++ if ( errno != ENOENT ) ++ { ++ perror( dirname ); ++ exit( 1 ); ++ } ++ /* Doesn't exist. Try to make it. */ ++ if ( mkdir( dirname, 0755 ) < 0 ) ++ { ++ if ( errno == ENOENT ) ++ (void) printf( "\ ++Some part of the path %s does not exist.\n\ ++This is probably a configuration error.\n", dirname ); ++ else ++ perror( dirname ); ++ exit( 1 ); ++ } ++ (void) printf( "Created web directory %s\n", dirname ); ++ /* Try to change the group of the new dir to the user's group. */ ++ (void) chown( dirname, -1, gid ); ++ } ++ else ++ { ++ /* The directory already exists. Well, check that it is in ++ ** fact a directory. ++ */ ++ if ( ! S_ISDIR( sb.st_mode ) ) ++ { ++ (void) printf( ++ "%s already exists but is not a directory!\n", dirname ); ++ exit( 1 ); ++ } ++ if ( sb.st_uid != uid ) ++ { ++ (void) printf( ++ "%s already exists but you don't own it!\n", dirname ); ++ exit( 1 ); ++ } ++ (void) printf( "Web directory %s already existed.\n", dirname ); ++ } ++ } ++ ++ ++int ++main( int argc, char** argv ) ++ { ++ char* webdir; ++ char* prefix; ++ struct passwd* pwd; ++ char* username; ++ char* homedir; ++ char dirname[5000]; ++ char linkname[5000]; ++ char linkbuf[5000]; ++ struct stat sb; ++ ++ argv0 = argv[0]; ++ if ( argc != 1 ) ++ { ++ (void) fprintf( stderr, "usage: %s\n", argv0 ); ++ exit( 1 ); ++ } ++ ++ pwd = getpwuid( getuid() ); ++ if ( pwd == (struct passwd*) 0 ) ++ { ++ (void) fprintf( stderr, "%s: can't find your username\n", argv0 ); ++ exit( 1 ); ++ } ++ username = pwd->pw_name; ++ homedir = pwd->pw_dir; ++ ++#ifdef TILDE_MAP_2 ++ ++ /* All we have to do for the TILDE_MAP_2 case is make sure there's ++ ** a public_html subdirectory. ++ */ ++ check_room( ++ sizeof(dirname), strlen( homedir ) + strlen( TILDE_MAP_2 ) + 2 ); ++ (void) strcpy( dirname, homedir ); ++ end_with_slash( dirname ); ++ (void) strcat( dirname, TILDE_MAP_2 ); ++ ++ check_dir( dirname, pwd->pw_uid, pwd->pw_gid ); ++ ++#else /* TILDE_MAP_2 */ ++ ++ /* Gather the pieces. */ ++ webdir = WEBDIR; ++#ifdef TILDE_MAP_1 ++ prefix = TILDE_MAP_1; ++#else /* TILDE_MAP_1 */ ++ prefix = ""; ++#endif /* TILDE_MAP_1 */ ++ ++ /* Assemble the directory name. Be paranoid cause we're sgid. */ ++ check_room( ++ sizeof(dirname), ++ strlen( webdir ) + strlen( prefix ) + strlen( username ) + 3 ); ++ (void) strcpy( dirname, webdir ); ++ end_with_slash( dirname ); ++ if ( strlen( prefix ) != 0 ) ++ { ++ (void) strcat( dirname, prefix ); ++ end_with_slash( dirname ); ++ } ++ (void) strcat( dirname, username ); ++ ++ /* Assemble the link name. */ ++ check_room( sizeof(linkname), strlen( homedir ) + strlen( LINK ) + 2 ); ++ (void) strcpy( linkname, homedir ); ++ end_with_slash( linkname ); ++ (void) strcat( linkname, LINK ); ++ ++ check_dir( dirname, pwd->pw_uid, pwd->pw_gid ); ++ ++ /* Check the symlink. */ ++ try_link_again: ; ++ if ( lstat( linkname, &sb ) < 0 ) ++ { ++ if ( errno != ENOENT ) ++ { ++ perror( linkname ); ++ exit( 1 ); ++ } ++ /* Doesn't exist. Try to make it. */ ++ if ( symlink( dirname, linkname ) < 0 ) ++ { ++ if ( errno == ENOENT ) ++ (void) printf( "\ ++Some part of the path %s does not exist.\n\ ++This is probably a configuration error.\n", linkname ); ++ else ++ perror( linkname ); ++ exit( 1 ); ++ } ++ (void) printf( "Created symbolic link %s\n", linkname ); ++ } ++ else ++ { ++ /* The link already exists. Well, check that it is in ++ ** fact a link. ++ */ ++ if ( ! S_ISLNK( sb.st_mode ) ) ++ { ++ (void) printf( "\ ++%s already exists but is not a\n\ ++symbolic link! Perhaps you have a real web subdirectory in your\n\ ++home dir from a previous web server configuration? You may have\n\ ++to rename it, run %s again, and then copy in the old\n\ ++contents.\n", linkname, argv0 ); ++ exit( 1 ); ++ } ++ /* Check the existing link's contents. */ ++ if ( readlink( linkname, linkbuf, sizeof(linkbuf) ) < 0 ) ++ { ++ perror( linkname ); ++ exit( 1 ); ++ } ++ if ( strcmp( dirname, linkbuf ) == 0 ) ++ (void) printf( "Symbolic link %s already existed.\n", linkname ); ++ else ++ { ++ (void) printf( "\ ++Symbolic link %s already existed\n\ ++but it points to the wrong place! Attempting to remove and\n\ ++recreate it.\n", linkname ); ++ if ( unlink( linkname ) < 0 ) ++ { ++ perror( linkname ); ++ exit( 1 ); ++ } ++ goto try_link_again; ++ } ++ } ++#endif /* TILDE_MAP_2 */ ++ ++ exit( 0 ); ++ } +diff -Naupr thttpd-2.25b.orig/thttpd.8 thttpd-2.25b/thttpd.8 +--- thttpd-2.25b.orig/thttpd.8 2005-06-29 19:50:56.000000000 +0200 ++++ thttpd-2.25b/thttpd.8 2008-09-25 10:43:13.000000000 +0200 +@@ -270,7 +270,7 @@ called .htpasswd by default. This file is formatted as the familiar colon-separated username/encrypted-password pair, records delimited by newlines. The protection does not carry over to subdirectories. @@ -283,12 +545,612 @@ for all the recent changes. modify .htpasswd files. .PP Relevant config.h option: AUTH_FILE -@@ -534,7 +534,7 @@ - Currently the best alternative for log rotation is to send a USR1 signal, - shutting down thttpd altogether, and then restart it. +@@ -562,7 +562,7 @@ This is a little tricky to set up correc + chroot() then the log file must be within the chroot tree, but it's + definitely doable. .SH "SEE ALSO" -redirect(8), ssi(8), makeweb(1), htpasswd(1), syslogtocern(8), weblog_parse(1), http_get(1) +thtpasswd(1), syslogtocern(8) .SH THANKS .PP Many thanks to contributors, reviewers, testers: +diff -Naupr thttpd-2.25b.orig/thttpd.8.orig thttpd-2.25b/thttpd.8.orig +--- thttpd-2.25b.orig/thttpd.8.orig 1970-01-01 01:00:00.000000000 +0100 ++++ thttpd-2.25b/thttpd.8.orig 2005-06-29 19:50:56.000000000 +0200 +@@ -0,0 +1,596 @@ ++.TH thttpd 8 "29 February 2000" ++.SH NAME ++thttpd - tiny/turbo/throttling HTTP server ++.SH SYNOPSIS ++.B thttpd ++.RB [ -C ++.IR configfile ] ++.RB [ -p ++.IR port ] ++.RB [ -d ++.IR dir ] ++.RB [ -dd ++.IR data_dir ] ++.RB [ -r | -nor ] ++.RB [ -s | -nos ] ++.RB [ -v | -nov ] ++.RB [ -g | -nog ] ++.RB [ -u ++.IR user ] ++.RB [ -c ++.IR cgipat ] ++.RB [ -t ++.IR throttles ] ++.RB [ -h ++.IR host ] ++.RB [ -l ++.IR logfile ] ++.RB [ -i ++.IR pidfile ] ++.RB [ -T ++.IR charset ] ++.RB [ -P ++.IR P3P ] ++.RB [ -M ++.IR maxage ] ++.RB [ -V ] ++.RB [ -D ] ++.SH DESCRIPTION ++.PP ++.I thttpd ++is a simple, small, fast, and secure HTTP server. ++It doesn't have a lot of special features, but it suffices for most uses of ++the web, it's about as fast as the best full-featured servers (Apache, NCSA, ++Netscape), ++and it has one extremely useful feature (URL-traffic-based throttling) ++that no other server currently has. ++.SH OPTIONS ++.TP ++.B -C ++Specifies a config-file to read. ++All options can be set either by command-line flags or in the config file. ++See below for details. ++.TP ++.B -p ++Specifies an alternate port number to listen on. ++The default is 80. ++The config-file option name for this flag is "port", ++and the config.h option is DEFAULT_PORT. ++.TP ++.B -d ++Specifies a directory to chdir() to at startup. ++This is merely a convenience - you could just as easily ++do a cd in the shell script that invokes the program. ++The config-file option name for this flag is "dir", ++and the config.h options are WEBDIR, USE_USER_DIR. ++.TP ++.B -r ++Do a chroot() at initialization time, restricting file access ++to the program's current directory. ++If -r is the compiled-in default, then -nor disables it. ++See below for details. ++The config-file option names for this flag are "chroot" and "nochroot", ++and the config.h option is ALWAYS_CHROOT. ++.TP ++.B -dd ++Specifies a directory to chdir() to after chrooting. ++If you're not chrooting, you might as well do a single chdir() with ++the -d flag. ++If you are chrooting, this lets you put the web files in a subdirectory ++of the chroot tree, instead of in the top level mixed in with the ++chroot files. ++The config-file option name for this flag is "data_dir". ++.TP ++.B -nos ++Don't do explicit symbolic link checking. ++Normally, thttpd explicitly expands any symbolic links in filenames, ++to check that the resulting path stays within the original document tree. ++If you want to turn off this check and save some CPU time, you can use ++the -nos flag, however this is not recommended. ++Note, though, that if you are using the chroot option, the symlink ++checking is unnecessary and is turned off, so the safe way to save ++those CPU cycles is to use chroot. ++The config-file option names for this flag are "symlinkcheck" and "nosymlinkcheck". ++.TP ++.B -v ++Do el-cheapo virtual hosting. ++If -v is the compiled-in default, then -nov disables it. ++See below for details. ++The config-file option names for this flag are "vhost" and "novhost", ++and the config.h option is ALWAYS_VHOST. ++.TP ++.B -g ++Use a global passwd file. ++This means that every file in the entire document tree is protected by ++the single .htpasswd file at the top of the tree. ++Otherwise the semantics of the .htpasswd file are the same. ++If this option is set but there is no .htpasswd file in ++the top-level directory, then thttpd proceeds as if the option was ++not set - first looking for a local .htpasswd file, and if that doesn't ++exist either then serving the file without any password. ++If -g is the compiled-in default, then -nog disables it. ++The config-file option names for this flag are "globalpasswd" and ++"noglobalpasswd", ++and the config.h option is ALWAYS_GLOBAL_PASSWD. ++.TP ++.B -u ++Specifies what user to switch to after initialization when started as root. ++The default is "nobody". ++The config-file option name for this flag is "user", ++and the config.h option is DEFAULT_USER. ++.TP ++.B -c ++Specifies a wildcard pattern for CGI programs, for instance "**.cgi" ++or "/cgi-bin/*". ++See below for details. ++The config-file option name for this flag is "cgipat", ++and the config.h option is CGI_PATTERN. ++.TP ++.B -t ++Specifies a file of throttle settings. ++See below for details. ++The config-file option name for this flag is "throttles". ++.TP ++.B -h ++Specifies a hostname to bind to, for multihoming. ++The default is to bind to all hostnames supported on the local machine. ++See below for details. ++The config-file option name for this flag is "host", ++and the config.h option is SERVER_NAME. ++.TP ++.B -l ++Specifies a file for logging. ++If no -l argument is specified, thttpd logs via syslog(). ++If "-l /dev/null" is specified, thttpd doesn't log at all. ++The config-file option name for this flag is "logfile". ++.TP ++.B -i ++Specifies a file to write the process-id to. ++If no file is specified, no process-id is written. ++You can use this file to send signals to thttpd. ++See below for details. ++The config-file option name for this flag is "pidfile". ++.TP ++.B -T ++Specifies the character set to use with text MIME types. ++The default is iso-8859-1. ++The config-file option name for this flag is "charset", ++and the config.h option is DEFAULT_CHARSET. ++.TP ++.B -P ++Specifies a P3P server privacy header to be returned with all responses. ++See http://www.w3.org/P3P/ for details. ++Thttpd doesn't do anything at all with the string except put it in the ++P3P: response header. ++The config-file option name for this flag is "p3p". ++.TP ++.B -M ++Specifies the number of seconds to be used in a "Cache-Control: max-age" ++header to be returned with all responses. ++An equivalent "Expires" header is also generated. ++The default is no Cache-Control or Expires headers, ++which is just fine for most sites. ++The config-file option name for this flag is "max_age". ++.TP ++.B -V ++Shows the current version info. ++.TP ++.B -D ++This was originally just a debugging flag, however it's worth mentioning ++because one of the things it does is prevent thttpd from making itself ++a background daemon. ++Instead it runs in the foreground like a regular program. ++This is necessary when you want to run thttpd wrapped in a little shell ++script that restarts it if it exits. ++.SH "CONFIG-FILE" ++.PP ++All the command-line options can also be set in a config file. ++One advantage of using a config file is that the file can be changed, ++and thttpd will pick up the changes with a restart. ++.PP ++The syntax of the config file is simple, a series of "option" or ++"option=value" separated by whitespace. ++The option names are listed above with their corresponding command-line flags. ++.SH "CHROOT" ++.PP ++chroot() is a system call that restricts the program's view ++of the filesystem to the current directory and directories ++below it. ++It becomes impossible for remote users to access any file ++outside of the initial directory. ++The restriction is inherited by child processes, so CGI programs get it too. ++This is a very strong security measure, and is recommended. ++The only downside is that only root can call chroot(), so this means ++the program must be started as root. ++However, the last thing it does during initialization is to ++give up root access by becoming another user, so this is safe. ++.PP ++The program can also be compile-time configured to always ++do a chroot(), without needing the -r flag. ++.PP ++Note that with some other web servers, such as NCSA httpd, setting ++up a directory tree for use with chroot() is complicated, involving ++creating a bunch of special directories and copying in various files. ++With thttpd it's a lot easier, all you have to do is make sure ++any shells, utilities, and config files used by your CGI programs and ++scripts are available. ++If you have CGI disabled, or if you make a policy that all CGI programs ++must be written in a compiled language such as C and statically linked, ++then you probably don't have to do any setup at all. ++.PP ++However, one thing you should do is tell syslogd about the chroot tree, ++so that thttpd can still generate syslog messages. ++Check your system's syslodg man page for how to do this. ++In FreeBSD you would put something like this in /etc/rc.conf: ++.nf ++ syslogd_flags="-l /usr/local/www/data/dev/log" ++.fi ++Substitute in your own chroot tree's pathname, of course. ++Don't worry about creating the log socket, syslogd wants to do that itself. ++(You may need to create the dev directory.) ++In Linux the flag is -a instead of -l, and there may be other differences. ++.PP ++Relevant config.h option: ALWAYS_CHROOT. ++.SH "CGI" ++.PP ++thttpd supports the CGI 1.1 spec. ++.PP ++In order for a CGI program to be run, its name must match the pattern ++specified either at compile time or on the command line with the -c flag. ++This is a simple shell-style filename pattern. ++You can use * to match any string not including a slash, ++or ** to match any string including slashes, ++or ? to match any single character. ++You can also use multiple such patterns separated by |. ++The patterns get checked against the filename ++part of the incoming URL. ++Don't forget to quote any wildcard characters so that the shell doesn't ++mess with them. ++.PP ++Restricting CGI programs to a single directory lets the site administrator ++review them for security holes, and is strongly recommended. ++If there are individual users that you trust, you can enable their ++directories too. ++.PP ++If no CGI pattern is specified, neither here nor at compile time, ++then CGI programs cannot be run at all. ++If you want to disable CGI as a security measure, that's how you do it, just ++comment out the patterns in the config file and don't run with the -c flag. ++.PP ++Note: the current working directory when a CGI program gets run is ++the directory that the CGI program lives in. ++This isn't in the CGI 1.1 spec, but it's what most other HTTP servers do. ++.PP ++Relevant config.h options: CGI_PATTERN, CGI_TIMELIMIT, CGI_NICE, CGI_PATH, CGI_LD_LIBRARY_PATH, CGIBINDIR. ++.SH "BASIC AUTHENTICATION" ++.PP ++Basic Authentication is available as an option at compile time. ++If enabled, it uses a password file in the directory to be protected, ++called .htpasswd by default. ++This file is formatted as the familiar colon-separated ++username/encrypted-password pair, records delimited by newlines. ++The protection does not carry over to subdirectories. ++The utility program htpasswd(1) is included to help create and ++modify .htpasswd files. ++.PP ++Relevant config.h option: AUTH_FILE ++.SH "THROTTLING" ++.PP ++The throttle file lets you set maximum byte rates on URLs or URL groups. ++You can optionally set a minimum rate too. ++The format of the throttle file is very simple. ++A # starts a comment, and the rest of the line is ignored. ++Blank lines are ignored. ++The rest of the lines should consist of a pattern, whitespace, and a number. ++The pattern is a simple shell-style filename pattern, using ?/**/*, or ++multiple such patterns separated by |. ++.PP ++The numbers in the file are byte rates, specified in units of bytes per second. ++For comparison, a v.90 modem gives about 5000 B/s depending on compression, ++a double-B-channel ISDN line about 12800 B/s, and a T1 line is about ++150000 B/s. ++If you want to set a minimum rate as well, use number-number. ++.PP ++Example: ++.nf ++ # throttle file for www.acme.com ++ ++ ** 2000-100000 # limit total web usage to 2/3 of our T1, ++ # but never go below 2000 B/s ++ **.jpg|**.gif 50000 # limit images to 1/3 of our T1 ++ **.mpg 20000 # and movies to even less ++ jef/** 20000 # jef's pages are too popular ++.fi ++.PP ++Throttling is implemented by checking each incoming URL filename against all ++of the patterns in the throttle file. ++The server accumulates statistics on how much bandwidth each pattern ++has accounted for recently (via a rolling average). ++If a URL matches a pattern that has been exceeding its specified limit, ++then the data returned is actually slowed down, with ++pauses between each block. ++If that's not possible (e.g. for CGI programs) or if the bandwidth has gotten ++way larger than the limit, then the server returns a special code ++saying 'try again later'. ++.PP ++The minimum rates are implemented similarly. ++If too many people are trying to fetch something at the same time, ++throttling may slow down each connection so much that it's not really ++useable. ++Furthermore, all those slow connections clog up the server, using ++up file handles and connection slots. ++Setting a minimum rate says that past a certain point you should not ++even bother - the server returns the 'try again later" code and the ++connection isn't even started. ++.PP ++There is no provision for setting a maximum connections/second throttle, ++because throttling a request uses as much cpu as handling it, so ++there would be no point. ++There is also no provision for throttling the number of simultaneous ++connections on a per-URL basis. ++However you can control the overall number of connections for the whole ++server very simply, by setting the operating system's per-process file ++descriptor limit before starting thttpd. ++Be sure to set the hard limit, not the soft limit. ++.SH "MULTIHOMING" ++.PP ++Multihoming means using one machine to serve multiple hostnames. ++For instance, if you're an internet provider and you want to let ++all of your customers have customized web addresses, you might ++have www.joe.acme.com, www.jane.acme.com, and your own www.acme.com, ++all running on the same physical hardware. ++This feature is also known as "virtual hosts". ++There are three steps to setting this up. ++.PP ++One, make DNS entries for all of the hostnames. ++The current way to do this, allowed by HTTP/1.1, is to use CNAME aliases, ++like so: ++.nf ++ www.acme.com IN A 192.100.66.1 ++ www.joe.acme.com IN CNAME www.acme.com ++ www.jane.acme.com IN CNAME www.acme.com ++.fi ++However, this is incompatible with older HTTP/1.0 browsers. ++If you want to stay compatible, there's a different way - use A records ++instead, each with a different IP address, like so: ++.nf ++ www.acme.com IN A 192.100.66.1 ++ www.joe.acme.com IN A 192.100.66.200 ++ www.jane.acme.com IN A 192.100.66.201 ++.fi ++This is bad because it uses extra IP addresses, a somewhat scarce resource. ++But if you want people with older browsers to be able to visit your ++sites, you still have to do it this way. ++.PP ++Step two. ++If you're using the modern CNAME method of multihoming, then you can ++skip this step. ++Otherwise, using the older multiple-IP-address method you ++must set up IP aliases or multiple interfaces for the extra addresses. ++You can use ifconfig(8)'s alias command to tell the machine to answer to ++all of the different IP addresses. ++Example: ++.nf ++ ifconfig le0 www.acme.com ++ ifconfig le0 www.joe.acme.com alias ++ ifconfig le0 www.jane.acme.com alias ++.fi ++If your OS's version of ifconfig doesn't have an alias command, you're ++probably out of luck (but see http://www.acme.com/software/thttpd/notes.html). ++.PP ++Third and last, you must set up thttpd to handle the multiple hosts. ++The easiest way is with the -v flag, or the ALWAYS_VHOST config.h option. ++This works with either CNAME multihosting or multiple-IP multihosting. ++What it does is send each incoming request to a subdirectory based on the ++hostname it's intended for. ++All you have to do in order to set things up is to create those subdirectories ++in the directory where thttpd will run. ++With the example above, you'd do like so: ++.nf ++ mkdir www.acme.com www.joe.acme.com www.jane.acme.com ++.fi ++If you're using old-style multiple-IP multihosting, you should also create ++symbolic links from the numeric addresses to the names, like so: ++.nf ++ ln -s www.acme.com 192.100.66.1 ++ ln -s www.joe.acme.com 192.100.66.200 ++ ln -s www.jane.acme.com 192.100.66.201 ++.fi ++This lets the older HTTP/1.0 browsers find the right subdirectory. ++.PP ++There's an optional alternate step three if you're using multiple-IP ++multihosting: run a separate thttpd process for each hostname, using ++the -h flag to specify which one is which. ++This gives you more flexibility, since you can run each of these processes ++in separate directories, with different throttle files, etc. ++Example: ++.nf ++ thttpd -r -d /usr/www -h www.acme.com ++ thttpd -r -d /usr/www/joe -u joe -h www.joe.acme.com ++ thttpd -r -d /usr/www/jane -u jane -h www.jane.acme.com ++.fi ++But remember, this multiple-process method does not work with CNAME ++multihosting - for that, you must use a single thttpd process with ++the -v flag. ++.SH "CUSTOM ERRORS" ++.PP ++thttpd lets you define your own custom error pages for the various ++HTTP errors. ++There's a separate file for each error number, all stored in one ++special directory. ++The directory name is "errors", at the top of the web directory tree. ++The error files should be named "errNNN.html", where NNN is the error number. ++So for example, to make a custom error page for the authentication failure ++error, which is number 401, you would put your HTML into the file ++"errors/err401.html". ++If no custom error file is found for a given error number, then the ++usual built-in error page is generated. ++.PP ++If you're using the virtual hosts option, you can also have different ++custom error pages for each different virtual host. ++In this case you put another "errors" directory in the top of that ++virtual host's web tree. ++thttpd will look first in the virtual host errors directory, and ++then in the server-wide errors directory, and if neither of those ++has an appropriate error file then it will generate the built-in error. ++.SH "NON-LOCAL REFERERS" ++.PP ++Sometimes another site on the net will embed your image files in their ++HTML files, which basically means they're stealing your bandwidth. ++You can prevent them from doing this by using non-local referer filtering. ++With this option, certain files can only be fetched via a local referer. ++The files have to be referenced by a local web page. ++If a web page on some other site references the files, that fetch will ++be blocked. ++There are three config-file variables for this feature: ++.TP ++.B urlpat ++A wildcard pattern for the URLs that should require a local referer. ++This is typically just image files, sound files, and so on. ++For example: ++.nf ++ urlpat=**.jpg|**.gif|**.au|**.wav ++.fi ++For most sites, that one setting is all you need to enable referer filtering. ++.TP ++.B noemptyreferers ++By default, requests with no referer at all, or a null referer, or a ++referer with no apparent hostname, are allowed. ++With this variable set, such requests are disallowed. ++.TP ++.B localpat ++A wildcard pattern that specifies the local host or hosts. ++This is used to determine if the host in the referer is local or not. ++If not specified it defaults to the actual local hostname. ++.SH SYMLINKS ++.PP ++thttpd is very picky about symbolic links. ++Before delivering any file, it first checks each element in the path ++to see if it's a symbolic link, and expands them all out to get the final ++actual filename. ++Along the way it checks for things like links with ".." that go above ++the server's directory, and absolute symlinks (ones that start with a /). ++These are prohibited as security holes, so the server returns an ++error page for them. ++This means you can't set up your web directory with a bunch of symlinks ++pointing to individual users' home web directories. ++Instead you do it the other way around - the user web directories are ++real subdirs of the main web directory, and in each user's home ++dir there's a symlink pointing to their actual web dir. ++.PP ++The CGI pattern is also affected - it gets matched against the fully-expanded ++filename. So, if you have a single CGI directory but then put a symbolic ++link in it pointing somewhere else, that won't work. The CGI program will be ++treated as a regular file and returned to the client, instead of getting run. ++This could be confusing. ++.SH PERMISSIONS ++.PP ++thttpd is also picky about file permissions. ++It wants data files (HTML, images) to be world readable. ++Readable by the group that the thttpd process runs as is not enough - thttpd ++checks explicitly for the world-readable bit. ++This is so that no one ever gets surprised by a file that's not set ++world-readable and yet somehow is readable by the HTTP server and ++therefore the *whole* world. ++.PP ++The same logic applies to directories. ++As with the standard Unix "ls" program, thttpd will only let you ++look at the contents of a directory if its read bit is on; but ++as with data files, this must be the world-read bit, not just the ++group-read bit. ++.PP ++thttpd also wants the execute bit to be *off* for data files. ++A file that is marked executable but doesn't match the CGI pattern ++might be a script or program that got accidentally left in the ++wrong directory. ++Allowing people to fetch the contents of the file might be a security breach, ++so this is prohibited. ++Of course if an executable file *does* match the CGI pattern, then it ++just gets run as a CGI. ++.PP ++In summary, data files should be mode 644 (rw-r--r--), ++directories should be 755 (rwxr-xr-x) if you want to allow indexing and ++711 (rwx--x--x) to disallow it, and CGI programs should be mode ++755 (rwxr-xr-x) or 711 (rwx--x--x). ++.SH LOGS ++.PP ++thttpd does all of its logging via syslog(3). ++The facility it uses is configurable. ++Aside from error messages, there are only a few log entry types of interest, ++all fairly similar to CERN Common Log Format: ++.nf ++ Aug 6 15:40:34 acme thttpd[583]: 165.113.207.103 - - "GET /file" 200 357 ++ Aug 6 15:40:43 acme thttpd[583]: 165.113.207.103 - - "HEAD /file" 200 0 ++ Aug 6 15:41:16 acme thttpd[583]: referer http://www.acme.com/ -> /dir ++ Aug 6 15:41:16 acme thttpd[583]: user-agent Mozilla/1.1N ++.fi ++The package includes a script for translating these log entries info ++CERN-compatible files. ++Note that thttpd does not translate numeric IP addresses into domain names. ++This is both to save time and as a minor security measure (the numeric ++address is harder to spoof). ++.PP ++Relevant config.h option: LOG_FACILITY. ++.PP ++If you'd rather log directly to a file, you can use the -l command-line ++flag. But note that error messages still go to syslog. ++.SH SIGNALS ++.PP ++thttpd handles a couple of signals, which you can send via the ++standard Unix kill(1) command: ++.TP ++.B INT,TERM ++These signals tell thttpd to shut down immediately. ++Any requests in progress get aborted. ++.TP ++.B USR1 ++This signal tells thttpd to shut down as soon as it's done servicing ++all current requests. ++In addition, the network socket it uses to accept new connections gets ++closed immediately, which means a fresh thttpd can be started up ++immediately. ++.TP ++.B USR2 ++This signal tells thttpd to generate the statistics syslog messages ++immediately, instead of waiting for the regular hourly update. ++.TP ++.B HUP ++This signal tells thttpd to close and re-open its (non-syslog) log file, ++for instance if you rotated the logs and want it to start using the ++new one. ++This is a little tricky to set up correctly, for instance if you are using ++chroot() then the log file must be within the chroot tree, but it's ++definitely doable. ++.SH "SEE ALSO" ++redirect(8), ssi(8), makeweb(1), htpasswd(1), syslogtocern(8), weblog_parse(1), http_get(1) ++.SH THANKS ++.PP ++Many thanks to contributors, reviewers, testers: ++John LoVerso, Jordan Hayes, Chris Torek, Jim Thompson, Barton Schaffer, ++Geoff Adams, Dan Kegel, John Hascall, Bennett Todd, KIKUCHI Takahiro, ++Catalin Ionescu. ++Special thanks to Craig Leres for substantial debugging and development, ++and for not complaining about my coding style very much. ++.SH AUTHOR ++Copyright � 1995,1998,1999,2000 by Jef Poskanzer . ++All rights reserved. ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++.\" SUCH DAMAGE. diff --git a/thttpd.spec b/thttpd.spec index 5f964d4..dc928a7 100644 --- a/thttpd.spec +++ b/thttpd.spec @@ -3,7 +3,7 @@ Summary: Tiny, turbo, throttleable lightweight http server Name: thttpd Version: 2.25b -Release: 16%{?dist} +Release: 17%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.acme.com/software/thttpd/ @@ -156,7 +156,10 @@ fi %changelog -* Tue Feb 19 2008 Fedora Release Engineering - 2.25b-16 +* Thu Sep 25 2008 Matthias Saou 2.25b-17 +- Update patches to remove fuzz. + +* Tue Feb 19 2008 Fedora Release Engineering - Autorebuild for GCC 4.3 * Mon Oct 22 2007 Matthias Saou 2.25b-15