Started coding e-mail template support

git-svn: trunk@507
remotes/push_mirror/metadata
Nigel Horne 21 years ago
parent ad2f8396f1
commit 3ce543c7c2
  1. 1
      clamav-devel/clamav-milter/INSTALL
  2. 151
      clamav-devel/clamav-milter/clamav-milter.c
  3. 6
      clamav-devel/docs/man/clamav-milter.8

@ -319,6 +319,7 @@ Changes
0.70i 9/4/04 Handle clamd giving up on StreamMaxLength before clamav-milter
0.70j 15/4/04 Handle systems without inet_ntop
0.70k 17/4/04 Put the virus message in the 550 rejection
0.70l 19/4/04 Started coding e-mail template support
BUG REPORTS

@ -319,9 +319,13 @@
* clamav-milter
* 0.70j 15/4/04 Handle systems without inet_ntop
* 0.70k 17/4/04 Put the virus message in the 550 rejection
* 0.70l 19/4/04 Started coding e-mail template support
*
* Change History:
* $Log: clamav-milter.c,v $
* Revision 1.75 2004/04/19 13:28:00 nigelhorne
* Started coding e-mail template support
*
* Revision 1.74 2004/04/17 20:39:04 nigelhorne
* Add the virus name into the 550 rejection if sent
*
@ -529,9 +533,9 @@
* Revision 1.6 2003/09/28 16:37:23 nigelhorne
* Added -f flag use MaxThreads if --max-children not set
*/
static char const rcsid[] = "$Id: clamav-milter.c,v 1.74 2004/04/17 20:39:04 nigelhorne Exp $";
static char const rcsid[] = "$Id: clamav-milter.c,v 1.75 2004/04/19 13:28:00 nigelhorne Exp $";
#define CM_VERSION "0.70k"
#define CM_VERSION "0.70l"
/*#define CONFDIR "/usr/local/etc"*/
@ -611,6 +615,7 @@ typedef unsigned short in_port_t;
* TODO: Decide action (bounce, discard, reject etc.) based on the virus
* found. Those with faked addresses, such as SCO.A want discarding,
* others could be bounced properly.
* TODO: Encrypt mails sent to clamd to stop sniffers
*/
struct header_node_t {
@ -667,6 +672,7 @@ static void header_list_add(header_list_t list, const char *headerf, const char
static void header_list_print(header_list_t list, FILE *fp);
static int connect2clamd(struct privdata *privdata);
static void checkClamd(void);
static int sendtemplate(const char *filename, FILE *sendmail, const char *clamdMessage);
static char clamav_version[128];
static int fflag = 0; /* force a scan, whatever */
@ -734,6 +740,7 @@ static int logClean = 1; /*
*/
static char *signature = "-- \nScanned by ClamAv - http://www.clamav.net\n";
static time_t signatureStamp;
static char *templatefile; /* e-mail to be sent when virus detected */
#ifdef CL_DEBUG
static int debug_level = 0;
@ -769,7 +776,7 @@ static void
help(void)
{
printf("\n\tclamav-milter version %s\n", CM_VERSION);
puts("\tCopyright (C) 2003 Nigel Horne <njh@despammed.com>\n");
puts("\tCopyright (C) 2004 Nigel Horne <njh@despammed.com>\n");
puts("\t--bounce\t\t-b\tSend a failure message to the sender.");
puts("\t--config-file=FILE\t-c FILE\tRead configuration from FILE.");
@ -791,6 +798,7 @@ help(void)
puts("\t--server=SERVER\t\t-s SERVER\tHostname/IP address of server(s) running clamd (when using TCPsocket).");
puts("\t--sign\t\t\t-S\tAdd a hard-coded signature to each scanned message.");
puts("\t--signature-file\t-F\tLocation of signature file.");
puts("\t--template-file\t-s\tLocation of e-mail template file.");
puts("\t--version\t\t-V\tPrint the version number of this software.");
#ifdef CL_DEBUG
puts("\t--debug-level=n\t\t-x n\tSets the debug level to 'n'.");
@ -838,9 +846,9 @@ main(int argc, char **argv)
for(;;) {
int opt_index = 0;
#ifdef CL_DEBUG
const char *args = "bc:CDfF:lm:nNop:PqQ:dhHs:SU:Vx:";
const char *args = "bc:CDfF:lm:nNop:PqQ:dhHs:St:U:Vx:";
#else
const char *args = "bc:CDfF:lm:nNop:PqQ:dhHs:SU:V";
const char *args = "bc:CDfF:lm:nNop:PqQ:dhHs:St:U:V";
#endif
static struct option long_options[] = {
@ -907,6 +915,9 @@ main(int argc, char **argv)
{
"signature-file", 1, NULL, 'F'
},
{
"template-file", 1, NULL, 't'
},
{
"version", 0, NULL, 'V'
},
@ -992,6 +1003,9 @@ main(int argc, char **argv)
smfilter.xxfi_flags |= SMFIF_CHGBODY;
Sflag++;
break;
case 't': /* e-mail template file */
templatefile = optarg;
break;
case 'U': /* quarantine path */
quarantine_dir = optarg;
break;
@ -1076,6 +1090,16 @@ main(int argc, char **argv)
if(sigFilename && !updateSigFile())
return EX_USAGE;
if(templatefile) {
int fd = open(templatefile, O_RDONLY);
if(fd < 0) {
perror(templatefile);
return EX_CONFIG;
}
close(fd);
}
if(!cfgopt(copt, "StreamSaveToDisk")) {
fprintf(stderr, "%s: StreamSavetoDisk not enabled in %s\n",
argv[0], cfgfile);
@ -2122,34 +2146,37 @@ clamfi_eom(SMFICTX *ctx)
fputs("Auto-Submitted: auto-submitted (antivirus notify)\n", sendmail);
fputs("Subject: Virus intercepted\n\n", sendmail);
if(bflag)
fputs("A message you sent to\n\t", sendmail);
else if(pflag)
/*
* The message is only going to the
* postmaster, so include some useful
* information
*/
fprintf(sendmail, "The message %s sent from %s to\n\t",
sendmailId, from);
else
fprintf(sendmail, "A message sent from %s to\n\t",
from);
for(to = privdata->to; *to; to++)
fprintf(sendmail, "%s\n", *to);
fputs("contained a virus and has not been delivered.\n\t", sendmail);
fputs(mess, sendmail);
if(privdata->filename != NULL)
fprintf(sendmail, "\nThe message in question has been quarantined as %s\n", privdata->filename);
if(hflag) {
fprintf(sendmail, "\nThe message was received by %s from %s via %s\n\n",
smfi_getsymval(ctx, "j"), from,
smfi_getsymval(ctx, "_"));
fputs("For your information, the original message headers were:\n\n", sendmail);
header_list_print(privdata->headers, sendmail);
if((templatefile == NULL) ||
(sendtemplate(templatefile, sendmail, mess) < 0)) {
if(bflag)
fputs("A message you sent to\n\t", sendmail);
else if(pflag)
/*
* The message is only going to the
* postmaster, so include some useful
* information
*/
fprintf(sendmail, "The message %s sent from %s to\n\t",
sendmailId, from);
else
fprintf(sendmail, "A message sent from %s to\n\t",
from);
for(to = privdata->to; *to; to++)
fprintf(sendmail, "%s\n", *to);
fputs("contained a virus and has not been delivered.\n\t", sendmail);
fputs(mess, sendmail);
if(privdata->filename != NULL)
fprintf(sendmail, "\nThe message in question has been quarantined as %s\n", privdata->filename);
if(hflag) {
fprintf(sendmail, "\nThe message was received by %s from %s via %s\n\n",
smfi_getsymval(ctx, "j"), from,
smfi_getsymval(ctx, "_"));
fputs("For your information, the original message headers were:\n\n", sendmail);
header_list_print(privdata->headers, sendmail);
}
}
pclose(sendmail);
@ -2554,7 +2581,7 @@ header_list_print(header_list_t list, FILE *fp)
for(iter = list->first; iter; iter = iter->next)
fprintf(fp, "%s\n", iter->header);
}
/*
* Establish a connection to clamd
* Returns success (1) or failure (0)
@ -2782,3 +2809,59 @@ checkClamd(void)
perror("clamd");
}
}
/*
* Send a templated message about an intercepted message. Very basic for
* now, just to prove it works, will enhance the flexability later, only
* supports %v at present. And only one instance of %v at that
*/
static int
sendtemplate(const char *filename, FILE *sendmail, const char *clamdMessage)
{
FILE *fin = fopen(filename, "r");
struct stat statb;
char *buf, *ptr;
int rc;
if(fin == NULL) {
perror(filename);
if(use_syslog)
syslog(LOG_ERR, "Can't open e-mail template file %s\n",
filename);
return -1;
}
if(fstat(fileno(fin), &statb) < 0) {
/* File disappeared in race condition? */
perror(filename);
if(use_syslog)
syslog(LOG_ERR, "Can't stat e-mail template file %s\n",
filename);
fclose(fin);
return -1;
}
buf = cli_malloc(statb.st_size + 1);
if(buf == NULL) {
if(use_syslog)
syslog(LOG_ERR, "Out of memory\n");
fclose(fin);
return -1;
}
fread(buf, sizeof(char), statb.st_size, fin);
fclose(fin);
buf[statb.st_size] = '\0';
if((ptr = strstr(buf, "%v")) != NULL) {
*ptr = '\0';
ptr = &ptr[2];
fputs(buf, sendmail);
/* Need to peel out the virus name and just send that */
fputs(clamdMessage, sendmail);
rc = (fputs(ptr, sendmail) == EOF) ? -1 : 0;
} else
rc = (fputs(buf, sendmail) == EOF) ? -1 : 0;
free(buf);
return 0;
}

@ -131,6 +131,12 @@ Location of file to be appended to each scanned message. Overrides \-S.
Maximum number of children.
There is no default, if this argument is not \fBclamav\-milter\fR will
spawn as many children as is necessary.
.TP
\fB\-\-template\-file=file \-t file\fR
File points to a file whose contents is sent whenever a virus is intercepted.
The first occurance of %v within the file is replaced with the message
returned from clamd, which includes the name of the virus.
If no file is given, clamav\-milter defaults to a hardcoded message.
.SH "EXAMPLES"
.LP
clamav\-milter \-\-max\-children=2 \-ol local:/var/run/clamav/clmilter.sock

Loading…
Cancel
Save