9faf368364
- update the patches - remove the MD5 checksum - bump PORTREVISION Reported by: "Alexander B. Zubkov" <info@zubkov.info>
465 lines
15 KiB
C
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);
|