Browse code

Allow access to sendmail variables in the template file

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@615 77e5149b-7576-45b1-b177-96237e5ba77b

Nigel Horne authored on 2004/06/16 17:13:02
Showing 4 changed files
... ...
@@ -1,3 +1,14 @@
1
+Wed Jun 16 09:09:45 BST 2004 (njh)
2
+----------------------------------
3
+  * clamav-milter:		Added access to sendmail variables in template
4
+	files
5
+				Use qualified host name for X-Virus-Scanned
6
+	header when localSocket is set
7
+  * docs/man/clamav-milter.8:	Added access to sendmail variables in template
8
+	files
9
+  * libclamav:			Added small performance improvements
10
+  				Added thread safety measures
11
+
1 12
 Tue Jun 15 22:41:03 CEST 2004 (tk)
2 13
 ----------------------------------
3 14
   * clamscan, clamd, freshclam: call geteuid() instead of getuid() to avoid
... ...
@@ -404,6 +404,11 @@ Changes
404 404
 0.72a	8/6/04	--from didn't take an option (fix to 0.71a)
405 405
 0.73	14/6/04	Up-issued
406 406
 0.73a	14/6/04	Added support for Windows SFU 3.5
407
+0.73b	15/6/04	Use fully qualified host name for X-Virus-Scanned header when
408
+			localSocket is set
409
+		In template files support {sendmail-variable} and support \%v
410
+			to send the %v string
411
+		Tidyup handling if the quarantine directory can't be created
407 412
 
408 413
 BUG REPORTS
409 414
 
... ...
@@ -26,6 +26,9 @@
26 26
  *
27 27
  * Change History:
28 28
  * $Log: clamav-milter.c,v $
29
+ * Revision 1.97  2004/06/16 08:08:47  nigelhorne
30
+ * Allow access to sendmail variables in the template file
31
+ *
29 32
  * Revision 1.96  2004/06/14 14:34:15  nigelhorne
30 33
  * Added support for Windows SFU 3.5
31 34
  *
... ...
@@ -299,9 +302,9 @@
299 299
  * Revision 1.6  2003/09/28 16:37:23  nigelhorne
300 300
  * Added -f flag use MaxThreads if --max-children not set
301 301
  */
302
-static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.96 2004/06/14 14:34:15 nigelhorne Exp $";
302
+static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.97 2004/06/16 08:08:47 nigelhorne Exp $";
303 303
 
304
-#define	CM_VERSION	"0.73a"
304
+#define	CM_VERSION	"0.73b"
305 305
 
306 306
 /*#define	CONFDIR	"/usr/local/etc"*/
307 307
 
... ...
@@ -447,7 +450,7 @@ static	void	header_list_add(header_list_t list, const char *headerf, const char
447 447
 static	void	header_list_print(header_list_t list, FILE *fp);
448 448
 static	int	connect2clamd(struct privdata *privdata);
449 449
 static	void	checkClamd(void);
450
-static	int	sendtemplate(const char *filename, FILE *sendmail, const char *clamdMessage);
450
+static	int	sendtemplate(SMFICTX *ctx, const char *filename, FILE *sendmail, const char *clamdMessage);
451 451
 
452 452
 static	char	clamav_version[128];
453 453
 static	int	fflag = 0;	/* force a scan, whatever */
... ...
@@ -1909,13 +1912,19 @@ clamfi_eom(SMFICTX *ctx)
1909 1909
 		char buf[1024];
1910 1910
 
1911 1911
 		/*
1912
-		 * Include the hostname where the scan took place:
1912
+		 * Include the hostname where the scan took place
1913 1913
 		 */
1914
-		if(localSocket)
1914
+		if(localSocket) {
1915
+			char hostname[32];
1916
+
1917
+			if(gethostname(hostname, sizeof(hostname)) < 0)
1918
+				strncpy(hostname,
1919
+					smfi_getsymval(ctx, "{j}"),
1920
+					sizeof(hostname) - 1);
1921
+
1915 1922
 			snprintf(buf, sizeof(buf) - 1, "%s\n\ton %s",
1916
-				clamav_version,
1917
-				smfi_getsymval(ctx, "{j}"));
1918
-		else {
1923
+				clamav_version, hostname);
1924
+		} else {
1919 1925
 			char *hostname = cli_strtok(serverHostNames, privdata->serverNumber, ":");
1920 1926
 
1921 1927
 			if(hostname) {
... ...
@@ -2107,7 +2116,7 @@ clamfi_eom(SMFICTX *ctx)
2107 2107
 				fputs("Subject: Virus intercepted\n\n", sendmail);
2108 2108
 
2109 2109
 				if((templatefile == NULL) ||
2110
-				   (sendtemplate(templatefile, sendmail, mess) < 0)) {
2110
+				   (sendtemplate(ctx, templatefile, sendmail, mess) < 0)) {
2111 2111
 					if(bflag)
2112 2112
 						fputs("A message you sent to\n", sendmail);
2113 2113
 					else if(pflag)
... ...
@@ -2273,7 +2282,11 @@ clamfi_free(struct privdata *privdata)
2273 2273
 		}
2274 2274
 
2275 2275
 		if(privdata->filename != NULL) {
2276
-			if(unlink(privdata->filename) < 0) {
2276
+			/*
2277
+			 * Don't print an error if the file hasn't been created
2278
+			 * yet
2279
+			 */
2280
+			if((unlink(privdata->filename) < 0) && (errno != ENOENT)) {
2277 2281
 				perror(privdata->filename);
2278 2282
 				if(use_syslog)
2279 2283
 					syslog(LOG_ERR,
... ...
@@ -2531,7 +2544,8 @@ updateSigFile(void)
2531 2531
 	signatureStamp = statb.st_mtime;
2532 2532
 
2533 2533
 	signature = cli_realloc(signature, statb.st_size);
2534
-	read(fd, signature, statb.st_size);
2534
+	if(signature)
2535
+		read(fd, signature, statb.st_size);
2535 2536
 	close(fd);
2536 2537
 
2537 2538
 	return statb.st_size;
... ...
@@ -2653,7 +2667,12 @@ connect2clamd(struct privdata *privdata)
2653 2653
 		sprintf(privdata->filename, "%s/%02d%02d%02d", quarantine_dir,
2654 2654
 			YY, MM, DD);
2655 2655
 
2656
-		(void)mkdir(privdata->filename, 0700);
2656
+		if(mkdir(privdata->filename, 0700) < 0) {
2657
+			perror(privdata->filename);
2658
+			if(use_syslog)
2659
+				syslog(LOG_ERR, "mkdir %s failed", privdata->filename);
2660
+			return 0;
2661
+		}
2657 2662
 
2658 2663
 		do {
2659 2664
 			sprintf(privdata->filename,
... ...
@@ -2866,18 +2885,20 @@ checkClamd(void)
2866 2866
 /*
2867 2867
  * Send a templated message about an intercepted message. Very basic for
2868 2868
  * now, just to prove it works, will enhance the flexability later, only
2869
- * supports %v at present. And only one instance of %v at that
2869
+ * supports %v and {sendmail_variables} at present. And only one instance of
2870
+ * %v at that.
2870 2871
  *
2871 2872
  * TODO: more template features
2872 2873
  * TODO: allow filename to start with a '|' taken to mean the output of
2873 2874
  *	a program
2875
+ * TODO: allow { to be escaped with a \ character
2874 2876
  */
2875 2877
 static int
2876
-sendtemplate(const char *filename, FILE *sendmail, const char *clamdMessage)
2878
+sendtemplate(SMFICTX *ctx, const char *filename, FILE *sendmail, const char *clamdMessage)
2877 2879
 {
2878 2880
 	FILE *fin = fopen(filename, "r");
2879 2881
 	struct stat statb;
2880
-	char *buf, *ptr;
2882
+	char *buf, *ptr, *ptr2;
2881 2883
 	int rc;
2882 2884
 
2883 2885
 	if(fin == NULL) {
... ...
@@ -2899,22 +2920,43 @@ sendtemplate(const char *filename, FILE *sendmail, const char *clamdMessage)
2899 2899
 	}
2900 2900
 	buf = cli_malloc(statb.st_size + 1);
2901 2901
 	if(buf == NULL) {
2902
+		fclose(fin);
2902 2903
 		if(use_syslog)
2903 2904
 			syslog(LOG_ERR, "Out of memory");
2904
-		fclose(fin);
2905 2905
 		return -1;
2906 2906
 	}
2907 2907
 	fread(buf, sizeof(char), statb.st_size, fin);
2908 2908
 	fclose(fin);
2909 2909
 	buf[statb.st_size] = '\0';
2910 2910
 
2911
-	if((ptr = strstr(buf, "%v")) != NULL) {
2911
+	/* FIXME: \%v should be %%v */
2912
+	if(((ptr = strstr(buf, "%v")) != NULL) && (strstr(buf, "\\%v") == NULL)) {
2912 2913
 		*ptr = '\0';
2913 2914
 		ptr = &ptr[2];
2914 2915
 		fputs(buf, sendmail);
2915 2916
 		/* Need to peel out the virus name and just send that */
2916 2917
 		fputs(clamdMessage, sendmail);
2917 2918
 		rc = (fputs(ptr, sendmail) == EOF) ? -1 : 0;
2919
+	} else if((ptr = strchr(buf, '{')) && (ptr2 = strchr(ptr, '}'))) {
2920
+		char *var;
2921
+
2922
+		*ptr++ = '\0';
2923
+		fputs(buf, sendmail);
2924
+		*ptr2++ = '\0';
2925
+
2926
+		if((var = cli_malloc(strlen(ptr) + 3)) != NULL) {
2927
+			sprintf(var, "{%s}", ptr);
2928
+			if((ptr = smfi_getsymval(ctx, var)) != NULL)
2929
+				fputs(ptr, sendmail);
2930
+			else if(use_syslog) {
2931
+				fputs(var, sendmail);
2932
+				syslog(LOG_ERR,
2933
+					"%s: Unknown sendmail variable \"%s\"\n",
2934
+					filename, var);
2935
+			}
2936
+			free(var);
2937
+		}
2938
+		fputs(ptr2, sendmail);
2918 2939
 	} else
2919 2940
 		rc = (fputs(buf, sendmail) == EOF) ? -1 : 0;
2920 2941
 
... ...
@@ -146,7 +146,7 @@ maximum time a pending thread will be held up is 1 minute, so the number
146 146
 of threads can exceed this number for short periods of time.
147 147
 There is no default, if this argument is not \fBclamav\-milter\fR will
148 148
 spawn as many children as is necessary.
149
-.TP
149
+.LP
150 150
 Most users will not need this option, if in doubt do not set it.
151 151
 .TP
152 152
 \fB\-\-template\-file=file \-t file\fR
... ...
@@ -154,6 +154,9 @@ File points to a file whose contents is sent as the warning message whenever a
154 154
 virus is intercepted.
155 155
 The first occurance of %v within the file is replaced with the message
156 156
 returned from clamd, which includes the name of the virus.
157
+The %v string can be escaped, thus \\%v, to send the string %v.
158
+Any occurance of strings in braces are replaced with the appropriate
159
+{sendmail-variable}.
157 160
 If the \-t option is not given, clamav\-milter defaults to a hardcoded message.
158 161
 .SH "EXAMPLES"
159 162
 .LP