freebsd-ports/mail/vpopmail/files/patch-vlistlib.c
Peter Pentchev 9faf368364 The upstream distfile was rerolled with some fixes:
- update the patches
- remove the MD5 checksum
- bump PORTREVISION

Reported by:	"Alexander B. Zubkov" <info@zubkov.info>
2011-01-10 08:30:52 +00:00

465 lines
15 KiB
C

Description: Sanity and safety checks.
Honor lots of limits - convert sprintf() to snprintf(), use the correct
limit size, etc.
Check a couple more calls for errors.
Wait for the correct child process - waitpid() instead of wait().
Add two closedir()'s to fix file descriptor leaks.
Look for the arguments properly if progname should ever containing spaces.
Forwarded: no
Author: Peter Pentchev <roam@FreeBSD.org>
Last-Update: 2011-01-09
--- a/vlistlib.c
+++ b/vlistlib.c
@@ -199,7 +199,7 @@
else { // Have mail list
if ( strstr( Address, "@") == NULL ) return(1);
- if ( parse_email( Address, LI->Name, LI->Domain, MAX_BUFF) != 0 ) return(2);
+ if ( parse_email( Address, LI->Name, LI->Domain, sizeof(LI->Domain)) != 0 ) return(2);
}
// printf( "before GetDomainEntries\n" );
@@ -228,12 +228,12 @@
// printf( "before Dir\n" );
// Build Dir Parm
- sprintf( LI->Dir, "%s/%s", LI->entry->path, QmailName );
+ snprintf( LI->Dir, sizeof(LI->Dir), "%s/%s", LI->entry->path, QmailName );
// printf( "before Dot\n" );
// Build Dot Parm
- sprintf( LI->Dot, "%s/.qmail-%s", LI->entry->path, QmailName );
+ snprintf( LI->Dot, sizeof(LI->Dot), "%s/.qmail-%s", LI->entry->path, QmailName );
LI->ReplyTo = REPLYTO_SENDER;
@@ -278,21 +278,18 @@
char *end;
char *arg;
-
// printf( "\nget_ezmlmidz_line_arguments\nline: %sprogram: %s\nargument: %c\n", line, program, argument );
// does line contain program name?
- if ((strstr(line, program)) != NULL) {
- // find the options
- begin=strchr(line, ' ');
- begin++;
- if (*begin == '-') {
- end=strchr(begin, ' ');
- arg=strchr(begin, argument);
- // if arg is found && it's in the options (before the trailing space), return 1
- if (arg && (arg < end)) return 1;
- }
- }
+ begin = strstr(line, program);
+ if (begin == NULL)
+ return (0);
+ begin=strchr(begin, ' ');
+ if (begin == NULL || begin[1] != '-')
+ return (0);
+ end=strchr(begin + 2, ' ');
+ arg=strchr(begin + 2, argument);
+ if (arg != NULL && (end == NULL || arg < end)) return 1;
return 0;
}
@@ -431,7 +428,6 @@
int BlockArchive = 0;
int GuardArchive = 0;
char TmpBuf2[MAX_BUFF];
- int i;
/*
@@ -442,7 +438,7 @@
LI->Requests = LI->RemoteText = LI->RemoteSub = LI->UnsubConf = LI->SubConf = GuardArchive = 0;
// figure out some options in the -default file
- sprintf(TmpBuf, "%s-default", LI->Dot);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s-default", LI->Dot);
if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
@@ -461,7 +457,7 @@
LI->Indexed = OtherReject = UserPostOnly = LI->Indexed = 0;
// figure out some options in the -accept-default file
- sprintf(TmpBuf, "%s-accept-default", LI->Dot );
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s-accept-default", LI->Dot );
if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
if(strstr(TmpBuf2, "ezmlm-archive") !=0) LI->Indexed = 1;
@@ -470,7 +466,7 @@
} // if fopen
// figure out some options in the qmail file
- sprintf(TmpBuf, "%s", LI->Dot);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s", LI->Dot);
if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
if((ezmlm_getArgs(TmpBuf2, "ezmlm-store", 'P')) > 0) OtherReject = 1;
@@ -482,7 +478,7 @@
// figure out some options in the sql file
- sprintf(TmpBuf, "%s/sql", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/sql", LI->Dir);
if( file_exists( TmpBuf )) {
LI->SQLSupport = 1;
if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
@@ -490,8 +486,7 @@
Tmp = strtok( TmpBuf2, ":" );
printf( " First Token: %s Len: %d\n", Tmp, strlen( Tmp ));
if( NULL != Tmp ) {
- for(i=0; i<strlen(Tmp); i++) LI->SQLHost[i] = Tmp[i];
- LI->SQLHost[i] = (char) 0;
+ snprintf(LI->SQLHost, sizeof(LI->SQLHost), "%s", Tmp);
Tmp = strtok( NULL, ":" );
}
if( NULL != Tmp ) {
@@ -499,23 +494,19 @@
Tmp = strtok( NULL, ":" );
}
if( NULL != Tmp ) {
- for(i=0; i<strlen(Tmp); i++) LI->SQLUser[i] = Tmp[i];
- LI->SQLUser[i] = (char) 0;
+ snprintf(LI->SQLUser, sizeof(LI->SQLUser), "%s", Tmp);
Tmp = strtok( NULL, ":" );
}
if( NULL != Tmp ) {
- for(i=0; i<strlen(Tmp); i++) LI->SQLPass[i] = Tmp[i];
- LI->SQLPass[i] = (char) 0;
+ snprintf(LI->SQLPass, sizeof(LI->SQLPass), "%s", Tmp);
Tmp = strtok( NULL, ":" );
}
if( NULL != Tmp ) {
- for(i=0; i<strlen(Tmp); i++) LI->SQLBase[i] = Tmp[i];
- LI->SQLBase[i] = (char) 0;
+ snprintf(LI->SQLBase, sizeof(LI->SQLBase), "%s", Tmp);
Tmp = strtok( NULL, ":\n" );
}
if( NULL != Tmp ) {
- for(i=0; i<strlen(Tmp); i++) LI->SQLTable[i] = Tmp[i];
- LI->SQLTable[i] = (char) 0;
+ snprintf(LI->SQLTable, sizeof(LI->SQLTable), "%s", Tmp);
}
}
@@ -526,32 +517,32 @@
// figure out a number of options based on file_exists()
- sprintf(TmpBuf, "%s-accept-default", LI->Dot);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s-accept-default", LI->Dot);
Moderation = file_exists(TmpBuf);
- sprintf(TmpBuf, "%s/archived", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/archived", LI->Dir);
LI->Archive = file_exists(TmpBuf);
- sprintf(TmpBuf, "%s/digest/bouncer", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/digest/bouncer", LI->Dir);
LI->Digest = file_exists(TmpBuf);
- sprintf(TmpBuf, "%s/prefix", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/prefix", LI->Dir);
LI->Prefix = file_exists(TmpBuf);
- sprintf(TmpBuf, "%s/public", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/public", LI->Dir);
LI->Public = file_exists(TmpBuf);
- sprintf(TmpBuf, "%s/remote", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/remote", LI->Dir);
LI->Remote = file_exists(TmpBuf);
- sprintf(TmpBuf, "%s/modsub", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/modsub", LI->Dir);
LI->SubMod = file_exists(TmpBuf);
- sprintf(TmpBuf, "%s/text/trailer", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/text/trailer", LI->Dir);
LI->Trailer = file_exists(TmpBuf);
if( LI->Prefix ) { // get prefix value
- sprintf( TmpBuf, "%s/prefix", LI->Dir );
+ snprintf( TmpBuf, sizeof(TmpBuf), "%s/prefix", LI->Dir );
fs=fopen( TmpBuf , "r" );
if( fs ) {
fgets( LI->PrefixText, sizeof(LI->PrefixText), fs );
@@ -562,7 +553,7 @@
// analyze Reply-To
LI->ReplyTo = REPLYTO_SENDER;
- sprintf(TmpBuf, "%s/headeradd", LI->Dir);
+ snprintf(TmpBuf, sizeof(TmpBuf), "%s/headeradd", LI->Dir);
if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
if(strstr(TmpBuf2, "Reply-To:") !=0) {
@@ -571,10 +562,8 @@
} else {
LI->ReplyTo = REPLYTO_ADDRESS;
// Copy just email address
- for( i=0; i<(strlen(TmpBuf2)-11); i++){
- LI->ReplyTo_Addr[i] = TmpBuf2[i+10];
- }
- LI->ReplyTo_Addr[i] = (char) 0;
+ snprintf(LI->ReplyTo_Addr, sizeof(LI->ReplyTo_Addr), "%s",
+ TmpBuf2 + 10);
}
}
} // while fgets
@@ -693,7 +682,7 @@
int ezmlm_make ( listInfoType *LI )
{
// FILE *file;
- int pid;
+ int pid, stat;
// int I;
// char TmpBuf[MAX_BUFF];
char ProgramPath[MAX_BUFF];
@@ -713,13 +702,13 @@
// Program path and name
snprintf(ProgramPath, MAX_BUFF, "%s/ezmlm-make", EZMLMDIR);
- snprintf( OwnerEmail, MAX_BUFF, "-5 %s", LI->OwnerEmail );
// Start with owner email
snprintf( OwnerEmail, MAX_BUFF, "-5 %s", LI->OwnerEmail );
// Get the list options in EZMLM terms
- ezmlm_encode( LI, Options, MAX_OPTIONS );
+ if (ezmlm_encode( LI, Options, MAX_OPTIONS ) != 0)
+ return (-1);
// If SQL selected, setup all the sql data into a single subfield
if( LI->SQLSupport ) {
@@ -750,7 +739,9 @@
execv(ProgramPath, arguments);
exit(127);
} else {
- wait(&pid);
+ if (waitpid(pid, &stat, 0) < 0 ||
+ !WIFEXITED( stat ) || WEXITSTATUS( stat ) != 0 )
+ return (-1);
}
return( 0 );
@@ -818,8 +809,8 @@
pipe(handles);
- sprintf(ProgramPath, "%s/ezmlm-list", EZMLMDIR );
- status = ezmlm_path( LI, mode, MAX_BUFF, ListPath );
+ snprintf(ProgramPath, sizeof(ProgramPath), "%s/ezmlm-list", EZMLMDIR );
+ status = ezmlm_path( LI, mode, sizeof(ListPath), ListPath );
if( status < 0 ) return( status );
pid=fork();
@@ -841,7 +832,9 @@
}
fclose(fs); close(handles[0]);
- wait(&pid);
+ if (waitpid(pid, &status, 0) < 0 ||
+ !WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ return (-1);
// printf( "after load of data\n" );
@@ -861,7 +854,7 @@
char **listSubsList( listInfoType *LI, int mode, int page, int perPage ) {
FILE *fs;
- int handles[2],pid,z = 0,subuser_count = 0;
+ int handles[2],pid,status,z = 0,subuser_count = 0;
char ProgramPath[MAX_BUFF];
char ListPath[MAX_BUFF];
char buf[256];
@@ -871,8 +864,8 @@
pipe(handles);
- sprintf(ProgramPath, "%s/ezmlm-list", EZMLMDIR);
- ezmlm_path( LI, mode, MAX_BUFF, ListPath );
+ snprintf(ProgramPath, sizeof(ProgramPath), "%s/ezmlm-list", EZMLMDIR);
+ ezmlm_path( LI, mode, sizeof(ListPath), ListPath );
pid=fork();
if (pid==0) {
@@ -887,9 +880,11 @@
/* Load subscriber/moderator list */
- sort_init();
+ if (sort_init() != 0)
+ return (NULL);
while( (fgets(buf, sizeof(buf), fs)!= NULL)) {
- sort_add_entry (buf, '\n'); /* don't copy newline */
+ if (sort_add_entry (buf, '\n') != 0) /* don't copy newline */
+ return (NULL);
subuser_count++;
}
@@ -903,7 +898,9 @@
sort_cleanup();
fclose(fs); close(handles[0]);
- wait(&pid);
+ if (waitpid(pid, &status, 0) < 0 ||
+ !WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ return (NULL);
return( 0 );
}
@@ -919,12 +916,12 @@
*/
int listSubsAdd( listInfoType *LI, int mode, char *email ){
- int pid;
+ int pid, status;
char ProgramPath[MAX_BUFF];
char ListPath[MAX_BUFF];
- sprintf(ProgramPath, "%s/ezmlm-sub", EZMLMDIR);
- ezmlm_path( LI, mode, MAX_BUFF, ListPath );
+ snprintf(ProgramPath, sizeof(ProgramPath), "%s/ezmlm-sub", EZMLMDIR);
+ ezmlm_path( LI, mode, sizeof(ListPath), ListPath );
// printf( " subscriberListPath %d %s\n", mode, ListPath );
// printf( "about to exec %s with parms %s\n", ProgramPath, ListPath );
@@ -932,10 +929,10 @@
if (pid==0) {
execl(ProgramPath, "ezmlm-sub", ListPath, email, NULL);
exit(127);
- } else wait(&pid);
-
- /* need to check exit code for failure somehow */
-
+ }
+ if (waitpid(pid, &status, 0) < 0 ||
+ !WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ return (-1);
return(0);
}
@@ -948,12 +945,12 @@
*/
int listSubsDel( listInfoType *LI, int mode, char *email ){
- int pid;
+ int pid, status;
char ProgramPath[MAX_BUFF];
char ListPath[MAX_BUFF];
- sprintf(ProgramPath, "%s/ezmlm-unsub", EZMLMDIR);
- ezmlm_path( LI, mode, MAX_BUFF, ListPath );
+ snprintf(ProgramPath, sizeof(ProgramPath), "%s/ezmlm-unsub", EZMLMDIR);
+ ezmlm_path( LI, mode, sizeof(ListPath), ListPath );
// printf( " subscriberListPath %d %s %s\n", mode, ListPath, TmpBuf );
// printf( "about to exec %s with parms %s\n", ProgramPath, ListPath );
@@ -961,10 +958,10 @@
if (pid==0) {
execl(ProgramPath, "ezmlm-unsub", ListPath, email, NULL);
exit(127);
- } else wait(&pid);
-
- /* need to check exit code for failure somehow */
-
+ }
+ if (waitpid(pid, &status, 0) < 0 ||
+ !WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ return (-1);
return(0);
}
@@ -1031,7 +1028,8 @@
return( NULL );
}
- sort_init();
+ if (sort_init() != 0)
+ return (NULL);
/* Now, display each list */
while( (mydirent=readdir(mydir)) != NULL ) {
@@ -1045,8 +1043,10 @@
fgets(TmpBuf2, sizeof(TmpBuf2), fs);
fclose(fs);
- if ( strstr( TmpBuf2, "ezmlm-reject") != 0 ) {
- sort_add_entry (&mydirent->d_name[7], 0);
+ if ( strstr( TmpBuf2, "ezmlm-reject") != 0 ||
+ strstr( TmpBuf2, "ezmlm-send") != 0 ) {
+ if (sort_add_entry (&mydirent->d_name[7], 0) != 0)
+ return (NULL);
}
}
}
@@ -1058,6 +1058,8 @@
buffSize = perPage * sizeof( *Buff );
Buff = malloc( perPage * sizeof( *Buff ));
+ if (Buff == NULL)
+ return (NULL);
for ( i = 0; i<perPage; ++i) {
J = (( page - 1 ) * perPage ) + i;
@@ -1066,16 +1068,15 @@
break;
}
- fflush( stdout );
-
addr = (char *)sort_get_entry(J);
str_replace (addr, ':', '.');
buffSize = strlen( addr ) + 1;
if( ( Buff[i] = malloc( buffSize ))) {
- fflush( stdout );
strncpy( Buff[i], addr, buffSize );
- }
+ } else {
+ return (NULL);
+ }
}
sort_cleanup();
@@ -1129,14 +1130,15 @@
return(7);
}
- sprintf( MainName, ".qmail-%s", LI->Dot );
- sprintf( SecondName, ".qmail-%s-", LI->Dot );
+ snprintf( MainName, sizeof(MainName), ".qmail-%s", LI->Dot );
+ snprintf( SecondName, sizeof(SecondName), ".qmail-%s-", LI->Dot );
while( (mydirent=readdir(mydir)) != NULL ) {
/* delete the main .qmail-"list" file */
if ( strcmp(MainName, mydirent->d_name) == 0 ) {
snprintf( TargetName, MAX_FILE_NAME, "%s/%s", LI->entry->path, mydirent->d_name);
if ( unlink(TargetName) != 0 ) {
+ closedir(mydir);
return(9);
}
@@ -1144,13 +1146,14 @@
} else if ( strncmp(SecondName, mydirent->d_name, strlen(SecondName)) == 0 ) {
snprintf( TargetName, MAX_FILE_NAME, "%s/%s", LI->entry->path, mydirent->d_name);
if ( unlink(TargetName) != 0 ) {
+ closedir(mydir);
return(10);
}
}
}
closedir(mydir);
- sprintf(TargetName, "%s/%s", LI->entry->path, LI->Name);
+ snprintf(TargetName, sizeof(TargetName), "%s/%s", LI->entry->path, LI->Name);
vdelfiles(TargetName);
return(0);