Index: head/www/thttpd/Makefile =================================================================== --- head/www/thttpd/Makefile (revision 377323) +++ head/www/thttpd/Makefile (revision 377324) @@ -1,55 +1,55 @@ # Created by: Anders Nordby # $FreeBSD$ PORTNAME= thttpd PORTVERSION= 2.25b -PORTREVISION= 5 +PORTREVISION= 6 CATEGORIES= www ipv6 MASTER_SITES= http://www.acme.com/software/thttpd/ \ http://atreides.freenix.no/~anders/ MAINTAINER= danfe@FreeBSD.org COMMENT= Tiny/turbo/throttling HTTP server with CGI support USES= gmake # parallel builds (-jX) are broken with BSD make(1) GNU_CONFIGURE= yes USE_RC_SUBR= ${PORTNAME} SUB_FILES= pkg-message thttpd.conf.sample SUB_LIST= WWWOWN=${WWWOWN} WWWGRP=${WWWGRP} OPTIONS_DEFINE= SENDFILE IPREAL OPTIONS_DEFAULT= SENDFILE SENDFILE_DESC= Use sendfile(2) to serve files IPREAL_DESC= Respect (pass on) "X-Forwarded-For" header SENDFILE_EXTRA_PATCHES= ${FILESDIR}/extra-patch-config.h IPREAL_EXTRA_PATCHES= ${FILESDIR}/extra-patch-ip_real post-patch: .for f in extras/htpasswd.1 extras/htpasswd.c thttpd.8 extras/Makefile.in @${REINPLACE_CMD} -e '/\.htpasswd/!s|htpasswd|thttpdpasswd|g' \ ${WRKSRC}/${f} .endfor @${REINPLACE_CMD} -e 's|/var/www|${WWWDIR}|' \ ${WRKSRC}/extras/makeweb.1 @${MV} ${WRKSRC}/extras/htpasswd.1 ${WRKSRC}/extras/thttpdpasswd.1 @${MV} ${WRKSRC}/extras/htpasswd.c ${WRKSRC}/extras/thttpdpasswd.c do-install: ${INSTALL_PROGRAM} ${WRKSRC}/thttpd ${STAGEDIR}${PREFIX}/sbin ${INSTALL_PROGRAM} ${WRKSRC}/extras/makeweb \ ${WRKSRC}/extras/thttpdpasswd ${STAGEDIR}${PREFIX}/bin ${INSTALL_SCRIPT} ${WRKSRC}/extras/syslogtocern \ ${STAGEDIR}${PREFIX}/bin @${MKDIR} ${STAGEDIR}${PREFIX}/www/data \ ${STAGEDIR}${PREFIX}/www/cgi-bin ${INSTALL_PROGRAM} ${WRKSRC}/cgi-src/redirect ${WRKSRC}/cgi-src/ssi \ ${WRKSRC}/cgi-src/phf ${STAGEDIR}${PREFIX}/www/cgi-bin ${INSTALL_MAN} ${WRKSRC}/extras/makeweb.1 \ ${WRKSRC}/extras/thttpdpasswd.1 ${STAGEDIR}${PREFIX}/man/man1 ${INSTALL_MAN} ${WRKSRC}/thttpd.8 ${WRKSRC}/cgi-src/redirect.8 \ ${WRKSRC}/cgi-src/ssi.8 ${WRKSRC}/extras/syslogtocern.8 \ ${STAGEDIR}${PREFIX}/man/man8 ${INSTALL_DATA} ${WRKDIR}/thttpd.conf.sample ${STAGEDIR}${PREFIX}/etc .include Index: head/www/thttpd/files/patch-extras_htpasswd.c =================================================================== --- head/www/thttpd/files/patch-extras_htpasswd.c (nonexistent) +++ head/www/thttpd/files/patch-extras_htpasswd.c (revision 377324) @@ -0,0 +1,201 @@ +--- extras/htpasswd.c.orig 2001-12-19 00:08:08 UTC ++++ extras/htpasswd.c +@@ -21,7 +21,12 @@ extern char *crypt(const char *key, cons + #define LF 10 + #define CR 13 + ++#define CPW_LEN 13 ++ ++/* ie 'string' + '\0' */ + #define MAX_STRING_LEN 256 ++/* ie 'maxstring' + ':' + cpassword */ ++#define MAX_LINE_LEN MAX_STRING_LEN+1+CPW_LEN + + int tfd; + char temp_template[] = "/tmp/htp.XXXXXX"; +@@ -137,8 +142,9 @@ add_password( char* user, FILE* f ) + } + + static void usage(void) { +- fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n"); +- fprintf(stderr,"The -c flag creates a new file.\n"); ++ fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n" ++ "The -c flag creates a new file.\n" ++ "Will prompt for password, unless given on stdin.\n"); + exit(1); + } + +@@ -151,51 +157,131 @@ void interrupted(int signo) { + int main(int argc, char *argv[]) { + FILE *tfp,*f; + char user[MAX_STRING_LEN]; +- char line[MAX_STRING_LEN]; +- char l[MAX_STRING_LEN]; ++ char pwfilename[MAX_STRING_LEN]; ++ char line[MAX_LINE_LEN]; ++ char l[MAX_LINE_LEN]; + char w[MAX_STRING_LEN]; + char command[MAX_STRING_LEN]; +- int found; ++ int found,u; + + tfd = -1; ++ u = 2; /* argv[u] is username, unless... */ + signal(SIGINT,(void (*)(int))interrupted); + if(argc == 4) { ++ u = 3; + if(strcmp(argv[1],"-c")) + usage(); ++ if((f=fopen(argv[2],"r")) != NULL) { ++ fclose(f); ++ fprintf(stderr, ++ "Password file %s already exists.\n" ++ "Delete it first, if you really want to overwrite it.\n", ++ argv[2]); ++ exit(1); ++ } ++ } else if(argc != 3) usage(); ++ /* check uname length; underlying system will take care of pwdfile ++ name too long */ ++ if (strlen(argv[u]) >= MAX_STRING_LEN) { ++ fprintf(stderr,"Username too long (max %i): %s\n", ++ MAX_STRING_LEN-1, argv[u]); ++ exit(1); ++ } ++ ++ if(argc == 4) { + if(!(tfp = fopen(argv[2],"w"))) { + fprintf(stderr,"Could not open passwd file %s for writing.\n", + argv[2]); + perror("fopen"); + exit(1); + } ++ if (strlen(argv[2]) > (sizeof(pwfilename) - 1)) { ++ fprintf(stderr, "%s: filename is too long\n", argv[0]); ++ exit(1); ++ } ++ if (((strchr(argv[2], ';')) != NULL) || ((strchr(argv[2], '>')) != NULL)) { ++ fprintf(stderr, "%s: filename contains an illegal character\n", ++ argv[0]); ++ exit(1); ++ } ++ if (strlen(argv[3]) > (sizeof(user) - 1)) { ++ fprintf(stderr, "%s: username is too long\n", argv[0], ++ sizeof(user) - 1); ++ exit(1); ++ } ++ if ((strchr(argv[3], ':')) != NULL) { ++ fprintf(stderr, "%s: username contains an illegal character\n", ++ argv[0]); ++ exit(1); ++ } + printf("Adding password for %s.\n",argv[3]); + add_password(argv[3],tfp); + fclose(tfp); + exit(0); +- } else if(argc != 3) usage(); ++ } + +- tfd = mkstemp(temp_template); +- if(!(tfp = fdopen(tfd,"w"))) { +- fprintf(stderr,"Could not open temp file.\n"); ++ if (strlen(argv[1]) > (sizeof(pwfilename) - 1)) { ++ fprintf(stderr, "%s: filename is too long\n", argv[0]); ++ exit(1); ++ } ++ if (((strchr(argv[1], ';')) != NULL) || ((strchr(argv[1], '>')) != NULL)) { ++ fprintf(stderr, "%s: filename contains an illegal character\n", ++ argv[0]); ++ exit(1); ++ } ++ if (strlen(argv[2]) > (sizeof(user) - 1)) { ++ fprintf(stderr, "%s: username is too long\n", argv[0], ++ sizeof(user) - 1); ++ exit(1); ++ } ++ if ((strchr(argv[2], ':')) != NULL) { ++ fprintf(stderr, "%s: username contains an illegal character\n", ++ argv[0]); + exit(1); + } +- + if(!(f = fopen(argv[1],"r"))) { + fprintf(stderr, + "Could not open passwd file %s for reading.\n",argv[1]); + fprintf(stderr,"Use -c option to create new one.\n"); + exit(1); + } ++ if(freopen(argv[1],"a",f) == NULL) { ++ fprintf(stderr, ++ "Could not open passwd file %s for writing!.\n" ++ "Changes would be lost.\n",argv[1]); ++ exit(1); ++ } ++ f = freopen(argv[1],"r",f); ++ ++ /* pwdfile is there, go on with tempfile now ... */ ++ tfd = mkstemp(temp_template); ++ if(!(tfp = fdopen(tfd,"w"))) { ++ fprintf(stderr,"Could not open temp file.\n"); ++ exit(1); ++ } ++ /* already checked for boflw ... */ + strcpy(user,argv[2]); + + found = 0; +- while(!(getline(line,MAX_STRING_LEN,f))) { ++ /* line we get is username:pwd, or possibly any other cruft */ ++ while(!(getline(line,MAX_LINE_LEN,f))) { ++ char *i; ++ + if(found || (line[0] == '#') || (!line[0])) { + putline(tfp,line); + continue; + } +- strcpy(l,line); +- getword(w,l,':'); ++ i = index(line,':'); ++ w[0] = '\0'; ++ /* actually, cpw is CPW_LEN chars and never null, hence ':' should ++ always be at line[strlen(line)-CPW_LEN-1] in a valid user:cpw line ++ Here though we may allow for pre-hancrafted pwdfile (!)... ++ But still need to check for length limits. ++ */ ++ if (i != 0 && i-line <= MAX_STRING_LEN-1) { ++ strcpy(l,line); ++ getword(w,l,':'); ++ } + if(strcmp(user,w)) { + putline(tfp,line); + continue; +@@ -210,10 +296,28 @@ int main(int argc, char *argv[]) { + printf("Adding user %s\n",user); + add_password(user,tfp); + } ++ /* close, rewind & copy */ ++ fclose(f); ++ fclose(tfp); ++ f = fopen(argv[1],"w"); ++ if(f==NULL) { ++ fprintf(stderr,"Failed re-opening %s!?\n",argv[1]); ++ exit(1); ++ } ++ tfp = fopen(temp_template,"r"); ++ if(tfp==NULL) { ++ fprintf(stderr,"Failed re-opening tempfile!?\n"); ++ exit(1); ++ } ++ { ++ int c; ++ while((c=fgetc(tfp))!=EOF && !feof(tfp)) { ++ fputc(c,f); ++ /* fputc(c,stderr); */ ++ } ++ } + fclose(f); + fclose(tfp); +- sprintf(command,"cp %s %s",temp_template,argv[1]); +- system(command); + unlink(temp_template); + exit(0); + } Property changes on: head/www/thttpd/files/patch-extras_htpasswd.c ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/thttpd/files/patch-libhttpd.c =================================================================== --- head/www/thttpd/files/patch-libhttpd.c (revision 377323) +++ head/www/thttpd/files/patch-libhttpd.c (revision 377324) @@ -1,12 +1,30 @@ --- libhttpd.c.orig Mon May 27 01:22:26 2002 +++ libhttpd.c Sun Oct 20 23:49:58 2002 -@@ -3816,6 +3816,9 @@ +@@ -1483,7 +1483,7 @@ + httpd_realloc_str( &checked, &maxchecked, checkedlen ); + (void) strcpy( checked, path ); + /* Trim trailing slashes. */ +- while ( checked[checkedlen - 1] == '/' ) ++ while ( checkedlen && checked[checkedlen - 1] == '/' ) + { + checked[checkedlen - 1] = '\0'; + --checkedlen; +@@ -1502,7 +1502,7 @@ + restlen = strlen( path ); + httpd_realloc_str( &rest, &maxrest, restlen ); + (void) strcpy( rest, path ); +- if ( rest[restlen - 1] == '/' ) ++ if ( restlen && rest[restlen - 1] == '/' ) + rest[--restlen] = '\0'; /* trim trailing slash */ + if ( ! tildemapped ) + /* Remove any leading slashes. */ +@@ -3889,6 +3889,9 @@ httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl ); return -1; } +#ifdef USE_SENDFILE + hc->file_fd = *((int *) hc->file_address); +#endif send_mime( hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size, hc->sb.st_mtime ); Index: head/www/thttpd/files/patch-thttpd.c =================================================================== --- head/www/thttpd/files/patch-thttpd.c (revision 377323) +++ head/www/thttpd/files/patch-thttpd.c (revision 377324) @@ -1,69 +1,105 @@ --- thttpd.c.orig Wed Jun 29 19:50:59 2005 +++ thttpd.c Sun Jun 17 21:30:11 2007 -@@ -1723,12 +1723,45 @@ +@@ -331,6 +331,7 @@ + re_open_logfile( void ) + { + FILE* logfp; ++ int retchmod; + + if ( no_log || hs == (httpd_server*) 0 ) + return; +@@ -340,7 +341,8 @@ + { + syslog( LOG_NOTICE, "re-opening logfile" ); + logfp = fopen( logfile, "a" ); +- if ( logfp == (FILE*) 0 ) ++ retchmod = chmod( logfile, S_IRUSR|S_IWUSR ); ++ if ( logfp == (FILE*) 0 || retchmod != 0 ) + { + syslog( LOG_CRIT, "re-opening %.80s - %m", logfile ); + return; +@@ -360,6 +362,7 @@ + gid_t gid = 32767; + char cwd[MAXPATHLEN+1]; + FILE* logfp; ++ int retchmod; + int num_ready; + int cnum; + connecttab* c; +@@ -429,7 +432,8 @@ + else + { + logfp = fopen( logfile, "a" ); +- if ( logfp == (FILE*) 0 ) ++ retchmod = chmod( logfile, S_IRUSR|S_IWUSR|S_IRGRP ); ++ if ( logfp == (FILE*) 0 || retchmod != 0 ) + { + syslog( LOG_CRIT, "%.80s - %m", logfile ); + perror( logfile ); +@@ -1714,12 +1718,45 @@ if ( hc->responselen == 0 ) { /* No, just write the file. */ +#ifdef USE_SENDFILE + off_t sbytes; + + sz = sendfile( + hc->file_fd, hc->conn_fd, c->next_byte_index, + MIN( c->end_byte_index - c->next_byte_index, max_bytes ), + NULL, &sbytes, 0 ); + if (sz == -1 && errno == EAGAIN) + sz = sbytes > 0 ? sbytes : -1; + else if (sz == 0) + sz = sbytes; +#else sz = write( hc->conn_fd, &(hc->file_address[c->next_byte_index]), MIN( c->end_byte_index - c->next_byte_index, max_bytes ) ); +#endif } else { +#ifdef USE_SENDFILE + struct sf_hdtr sf; + struct iovec iv; + off_t sbytes; + + iv.iov_base = hc->response; + iv.iov_len = hc->responselen; + sf.headers = &iv; + sf.hdr_cnt = 1; + sf.trailers = NULL; + sf.trl_cnt = 0; + sz = sendfile( + hc->file_fd, hc->conn_fd, c->next_byte_index, + MIN( c->end_byte_index - c->next_byte_index, max_bytes ), + &sf, &sbytes, 0 ); + if (sz == -1 && errno == EAGAIN) + sz = sbytes > 0 ? sbytes : -1; + else if (sz == 0) + sz = sbytes; +#else /* Yes. We'll combine headers and file into a single writev(), ** hoping that this generates a single packet. */ -@@ -1739,6 +1772,7 @@ +@@ -1730,6 +1767,7 @@ iv[1].iov_base = &(hc->file_address[c->next_byte_index]); iv[1].iov_len = MIN( c->end_byte_index - c->next_byte_index, max_bytes ); sz = writev( hc->conn_fd, iv, 2 ); +#endif } if ( sz < 0 && errno == EINTR ) -@@ -1786,7 +1820,11 @@ +@@ -1777,7 +1815,11 @@ ** ** And ECONNRESET isn't interesting either. */ - if ( errno != EPIPE && errno != EINVAL && errno != ECONNRESET ) + if ( errno != EPIPE && errno != EINVAL && errno != ECONNRESET +#ifdef USE_SENDFILE + && errno != ENOTCONN +#endif + ) syslog( LOG_ERR, "write - %m sending %.80s", hc->encodedurl ); clear_connection( c, tvP ); return;