mirror of
https://git.freebsd.org/ports.git
synced 2025-07-18 09:49:18 -04:00
Bring another several patches from Gentoo and Red Hat (also relevant to the
upcoming 2.26): - Fix potential buffer overflow in expand_symlinks() function of libhttpd.c - Better handling of tempfile and additional input validation in htpasswd(1) - Make sure that the logfile is created or reopened as read/write by thttpd (www) user only (modified to allow group read access as well so web admin won't have to su(1) to super-user or "www" to be able to read logs) [1] Bump port revision to account for these and previous changes. Gentoo bug: 458896 [1] Security: CVE-2013-0348 [1]
This commit is contained in:
parent
14b98461cf
commit
31b51c9317
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=377324
4 changed files with 260 additions and 5 deletions
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
PORTNAME= thttpd
|
PORTNAME= thttpd
|
||||||
PORTVERSION= 2.25b
|
PORTVERSION= 2.25b
|
||||||
PORTREVISION= 5
|
PORTREVISION= 6
|
||||||
CATEGORIES= www ipv6
|
CATEGORIES= www ipv6
|
||||||
MASTER_SITES= http://www.acme.com/software/thttpd/ \
|
MASTER_SITES= http://www.acme.com/software/thttpd/ \
|
||||||
http://atreides.freenix.no/~anders/
|
http://atreides.freenix.no/~anders/
|
||||||
|
|
201
www/thttpd/files/patch-extras_htpasswd.c
Normal file
201
www/thttpd/files/patch-extras_htpasswd.c
Normal file
|
@ -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);
|
||||||
|
}
|
|
@ -1,6 +1,24 @@
|
||||||
--- libhttpd.c.orig Mon May 27 01:22:26 2002
|
--- libhttpd.c.orig Mon May 27 01:22:26 2002
|
||||||
+++ libhttpd.c Sun Oct 20 23:49:58 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 );
|
httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,42 @@
|
||||||
--- thttpd.c.orig Wed Jun 29 19:50:59 2005
|
--- thttpd.c.orig Wed Jun 29 19:50:59 2005
|
||||||
+++ thttpd.c Sun Jun 17 21:30:11 2007
|
+++ 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 )
|
if ( hc->responselen == 0 )
|
||||||
{
|
{
|
||||||
/* No, just write the file. */
|
/* No, just write the file. */
|
||||||
|
@ -46,7 +82,7 @@
|
||||||
/* Yes. We'll combine headers and file into a single writev(),
|
/* Yes. We'll combine headers and file into a single writev(),
|
||||||
** hoping that this generates a single packet.
|
** 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_base = &(hc->file_address[c->next_byte_index]);
|
||||||
iv[1].iov_len = MIN( c->end_byte_index - c->next_byte_index, max_bytes );
|
iv[1].iov_len = MIN( c->end_byte_index - c->next_byte_index, max_bytes );
|
||||||
sz = writev( hc->conn_fd, iv, 2 );
|
sz = writev( hc->conn_fd, iv, 2 );
|
||||||
|
@ -54,7 +90,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( sz < 0 && errno == EINTR )
|
if ( sz < 0 && errno == EINTR )
|
||||||
@@ -1786,7 +1820,11 @@
|
@@ -1777,7 +1815,11 @@
|
||||||
**
|
**
|
||||||
** And ECONNRESET isn't interesting either.
|
** And ECONNRESET isn't interesting either.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue