3 Source Code
/**********************************************************************
Aim: Filter out messages comming from debarred hosts
Features:
> uses SMTP connection
> Addresses are specified in the disk file
Arguments:
Req: -p addr
eg. addrfilter -p local:/var/run/f1.sock
TODOS:
> Add command line options for user specified address list file.
Last Updated On: 27/06/2002
**********************************************************************/
#include "filter.h"
#include "libmilter/mfapi.h"
extern struct AddressList *hdr , *end ;
#define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx))
extern sfsistat mlfi_cleanup(SMFICTX *, bool);
sfsistat mlfi_envfrom ( ctx , envfrom )
SMFICTX *ctx ;
char **envfrom ;
{
struct mlfiPriv *priv ;
int fd = -1 ;
/* allocate some private memory */
priv = malloc ( sizeof *priv ) ;
if ( priv == NULL )
{
/* can't accept this message right now */
return SMFIS_TEMPFAIL ;
}
memset ( priv , '\0' , sizeof *priv ) ;
if ( SearchAddress ( envfrom[0] ) )
{
priv -> mlfi_using = true ;
priv -> mlfi_fname = strdup ( "/tmp/msg.XXXXXX" ) ;
if ( priv -> mlfi_fname == NULL )
{
free ( priv ) ;
return SMFIS_TEMPFAIL ;
}
if ( ( fd = mkstemp ( priv -> mlfi_fname ) ) < 0 ||
( priv -> mlfi_fp = fdopen ( fd, "w+" ) ) == NULL )
{
if ( fd >= 0 )
( void ) close ( fd ) ;
free ( priv -> mlfi_fname ) ;
free ( priv ) ;
return SMFIS_TEMPFAIL ;
}
}
else
priv -> mlfi_using = false ;
/* save the private data */
smfi_setpriv ( ctx , priv ) ;
/* continue processing */
return SMFIS_CONTINUE ;
}
sfsistat mlfi_header ( ctx , headerf , headerv )
SMFICTX *ctx ;
char *headerf , *headerv ;
{
/* write the header to the log file */
if ( MLFIPRIV -> mlfi_using )
fprintf ( MLFIPRIV -> mlfi_fp , "%s: %s\r\n" , headerf , headerv ) ;
/* continue processing */
return SMFIS_CONTINUE ;
}
sfsistat mlfi_eoh ( ctx )
SMFICTX *ctx ;
{
/* output the blank line between the header and the body */
if ( MLFIPRIV -> mlfi_using )
fprintf ( MLFIPRIV -> mlfi_fp , "\r\n" ) ;
/* continue processing */
return SMFIS_CONTINUE ;
}
sfsistat mlfi_body ( ctx , bodyp , bodylen )
SMFICTX *ctx ;
u_char *bodyp ;
size_t bodylen ;
{
/* output body block to log file */
if ( MLFIPRIV -> mlfi_using )
{
if ( fwrite ( bodyp , bodylen , 1 , MLFIPRIV -> mlfi_fp ) <= 0 )
{
/* write failed */
( void ) mlfi_cleanup ( ctx , false ) ;
return SMFIS_TEMPFAIL ;
}
}
/* continue processing */
return SMFIS_CONTINUE ;
}
sfsistat mlfi_eom ( ctx )
SMFICTX *ctx ;
{
return mlfi_cleanup ( ctx , true ) ;
}
sfsistat mlfi_close ( ctx )
SMFICTX *ctx ;
{
return SMFIS_ACCEPT ;
}
sfsistat mlfi_abort ( ctx )
SMFICTX *ctx ;
{
return mlfi_cleanup ( ctx , false ) ;
}
sfsistat mlfi_cleanup ( ctx , ok )
SMFICTX *ctx ;
bool ok ;
{
sfsistat rstat = SMFIS_CONTINUE ;
struct mlfiPriv *priv = MLFIPRIV ;
char *p ;
char host[512] ;
char hbuf[1024] ;
if ( priv == NULL )
return rstat ;
/* close the archive file */
if ( priv -> mlfi_using )
{
if ( priv -> mlfi_fp != NULL && fclose ( priv -> mlfi_fp ) == EOF )
{
/* failed; we have to wait until later */
rstat = SMFIS_TEMPFAIL ;
( void ) unlink ( priv -> mlfi_fname ) ;
}
else
if ( ok )
{
/* add a header to the message announcing our presence */
if ( gethostname ( host , sizeof host ) < 0 )
snprintf ( host , sizeof host , "localhost" ) ;
p = strrchr ( priv -> mlfi_fname , '/' ) ;
if ( p == NULL )
p = priv -> mlfi_fname ;
else
p++ ;
snprintf ( hbuf , sizeof hbuf , "%s@%s" , p , host ) ;
smfi_addheader ( ctx , "X-TaKaTaK" , hbuf ) ;
}
else
{
/* message was aborted -- delete the archive file */
( void ) unlink ( priv -> mlfi_fname ) ;
}
/* release private memory */
free ( priv -> mlfi_fname ) ;
free ( priv ) ;
rstat = SMFIS_DISCARD ;
}
smfi_setpriv ( ctx , NULL ) ;
/* return status */
return rstat ;
}
struct smfiDesc smfilter =
{
"SampleFilter", /* filter name */
SMFI_VERSION, /* version code -- do not change */
SMFIF_ADDHDRS, /* flags */
NULL, /* connection info filter */
NULL, /* SMTP HELO command filter */
mlfi_envfrom, /* envelope sender filter */
NULL, /* envelope recipient filter */
mlfi_header, /* header filter */
mlfi_eoh, /* end of header */
mlfi_body, /* body block filter */
mlfi_eom, /* end of message */
mlfi_abort, /* message aborted */
mlfi_close /* connection cleanup */
};
int main ( int argc , char *argv[] )
{
int c ;
register char *Afile ;
/* Process command line arguments */
Afile = NULL ;
while ( ( c = getopt ( argc , argv , "p:a:" ) ) != -1 )
{
switch ( c )
{
case 'p' :
if ( optarg == NULL || *optarg == '\0' )
{
( void ) fprintf ( stderr , "Illegal conn: %s\n" , optarg ) ;
exit ( EX_USAGE ) ;
}
( void ) smfi_setconn ( optarg ) ;
break ;
case 'a' :
if ( optarg == NULL || *optarg == '\0' )
{
( void ) fprintf ( stderr , "Address List filename required.\n" ) ;
exit ( EX_USAGE ) ;
}
Afile = optarg ;
break ;
}
}
if ( !Afile )
Afile = strdup ( ADDRLST ) ;
if ( !Afile )
err_exit ( "mem alloc" ) ;
printf ( "Using address list file <%s>.\n" , Afile ) ;
ReadAddressList ( Afile ) ;
if ( smfi_register ( smfilter ) == MI_FAILURE )
{
fprintf ( stderr , "smfi_register failed\n" ) ;
exit ( EX_UNAVAILABLE ) ;
}
printf ( "TaKaTak registered.\n" ) ;
return smfi_main() ;
}
int err_exit ( char *ptr )
{
printf ( "\nABNORMAL TERMINATION:%s failure\n" , ptr ) ;
exit ( 1 ) ;
}
/* eof */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#define MAXROW 80
#ifndef true
#define true 1
#define false 0
#endif
struct AddressList
{
char *snder ;
struct AddressList *next ;
};
struct AddressList *hdr , *end ;
int ReadAddressList ( char * ) ;
int SearchAddress ( char * ) ;
int AddAddress ( char * ) ;
int err_exit ( char * ) ;
int ReadAddressList ( char *fname )
{
FILE *fp ;
char rowstr[MAXROW] ;
int len ;
fp = fopen ( fname , "r" ) ;
if ( !fp )
err_exit ( "file open" ) ;
printf ( "Debarred list:\n" ) ;
while ( fgets ( rowstr , MAXROW , fp ) )
{
len = strlen ( rowstr ) ;
if ( len == MAXROW - 1 ) /* MAXROW limit exceeded */
err_exit ( "MAXROW limit" ) ;
if ( rowstr[len - 1] == '\n' )
rowstr[len - 1] = '\0' ;
if ( len > 1 )
AddAddress ( rowstr ) ;
}
return 0 ;
}
int AddAddress ( char *addr )
{
struct AddressList *tmp ;
tmp = ( struct AddressList * ) malloc ( sizeof ( struct AddressList ) ) ;
if ( !tmp )
err_exit ( "mem alloc" ) ;
printf ( "<%s>.\n" , addr ) ;
tmp -> snder = strdup ( addr ) ;
if ( ! ( tmp -> snder ) )
err_exit ( "mem alloc" ) ;
tmp -> next = NULL ;
if ( !hdr )
{
hdr = end = tmp ;
return 0 ;
}
end -> next = tmp ;
end = tmp ;
return 0 ;
}
int SearchAddress ( char *addr )
{
struct AddressList *tmp ;
tmp = hdr ;
while ( tmp )
{
if ( strstr ( addr , tmp -> snder ) )
return true ;
tmp = tmp -> next ;
}
return false ;
}
/* eof */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#ifndef true
typedef int bool ;
#define true 1
#define false 0
#endif
#define ADDRLST "listaddr.txt"
#define MSGIDS "msgids.txt"
struct mlfiPriv
{
bool mlfi_using ; /*if current msg is to be spooled then contains true*/
char *mlfi_fname ; /*name of the file to be spooled in*/
FILE *mlfi_fp ; /*file descriptor of the file to be spooled in*/
};
/* eof */