mirror of
https://git.freebsd.org/ports.git
synced 2025-07-18 01:39:16 -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
|
||||
PORTVERSION= 2.25b
|
||||
PORTREVISION= 5
|
||||
PORTREVISION= 6
|
||||
CATEGORIES= www ipv6
|
||||
MASTER_SITES= http://www.acme.com/software/thttpd/ \
|
||||
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 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;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,42 @@
|
|||
--- 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. */
|
||||
|
@ -46,7 +82,7 @@
|
|||
/* 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 );
|
||||
|
@ -54,7 +90,7 @@
|
|||
}
|
||||
|
||||
if ( sz < 0 && errno == EINTR )
|
||||
@@ -1786,7 +1820,11 @@
|
||||
@@ -1777,7 +1815,11 @@
|
||||
**
|
||||
** And ECONNRESET isn't interesting either.
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue