Browse code

Drop root priviliges and support quanrantine

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

Nigel Horne authored on 2003/11/22 20:48:32
Showing 2 changed files
... ...
@@ -76,6 +76,8 @@ or if clamd is on a different machine
76 76
 
77 77
 You should have received a script to put into /etc/init.d with this software.
78 78
 
79
+run 'chown clamav /usr/local/sbin/clamav-milter; chmod 4700 /usr/local/sbin/clamav-milter
80
+
79 81
 CHANGE HISTORY
80 82
 
81 83
 Changes
... ...
@@ -148,6 +150,8 @@ Changes
148 148
 0.65	15/11/03 Upissue of clamav
149 149
 0.65a	19/11/03 Close cmdSocket earlier
150 150
 		Added setpgrp()
151
+0.65b	22/11/03 Ensure milter is not run as root if requested
152
+		Added quarantine support
151 153
 
152 154
 BUG REPORTS
153 155
 
... ...
@@ -46,6 +46,7 @@
46 46
  *	CLAMAV_FLAGS="--max-children=2 --server=192.168.1.9 local:/var/run/clamav.sock"
47 47
  * 8) You should have received a script to put into /etc/init.d with this
48 48
  * software.
49
+ * 9) run 'chown clamav /usr/local/sbin/clamav-milter; chmod 4700 /usr/local/sbin/clamav-milter
49 50
  *
50 51
  * Tested OK on Linux/x86 (RH8.0) with gcc3.2.
51 52
  *	cc -O3 -pedantic -Wuninitialized -Wall -pipe -mcpu=pentium -march=pentium -fomit-frame-pointer -ffast-math -finline-functions -funroll-loops clamav-milter.c -pthread -lmilter ../libclamav/.libs/libclamav.a ../clamd/cfgfile.o ../clamd/others.o
... ...
@@ -153,9 +154,14 @@
153 153
  *	0.65	15/11/03 Upissue of clamav
154 154
  *	0.65a	19/11/03 Close cmdSocket earlier
155 155
  *			Added setpgrp()
156
+ *	0.65b	22/11/03 Ensure milter is not run as root if requested
157
+ *			Added quarantine support
156 158
  *
157 159
  * Change History:
158 160
  * $Log: clamav-milter.c,v $
161
+ * Revision 1.21  2003/11/22 11:47:45  nigelhorne
162
+ * Drop root priviliges and support quanrantine
163
+ *
159 164
  * Revision 1.20  2003/11/19 16:32:22  nigelhorne
160 165
  * Close cmdSocket earlier
161 166
  *
... ...
@@ -201,9 +207,9 @@
201 201
  * Revision 1.6  2003/09/28 16:37:23  nigelhorne
202 202
  * Added -f flag use MaxThreads if --max-children not set
203 203
  */
204
-static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.20 2003/11/19 16:32:22 nigelhorne Exp $";
204
+static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.21 2003/11/22 11:47:45 nigelhorne Exp $";
205 205
 
206
-#define	CM_VERSION	"0.65a"
206
+#define	CM_VERSION	"0.65b"
207 207
 
208 208
 /*#define	CONFDIR	"/usr/local/etc"*/
209 209
 
... ...
@@ -238,6 +244,7 @@ static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.20 2003/11/19 16:32:22 nig
238 238
 #include <signal.h>
239 239
 #include <regex.h>
240 240
 #include <fcntl.h>
241
+#include <pwd.h>
241 242
 
242 243
 #define _GNU_SOURCE
243 244
 #include "getopt.h"
... ...
@@ -252,7 +259,6 @@ static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.20 2003/11/19 16:32:22 nig
252 252
  * TODO: Support ThreadTimeout, LogTime and Logfile from the conf
253 253
  *	 file
254 254
  * TODO: Allow more than one clamdscan server to be given
255
- * TODO: Optionally quanrantine infected e-mails
256 255
  */
257 256
 
258 257
 /*
... ...
@@ -303,6 +309,10 @@ static	int	qflag = 0;	/*
303 303
 				 * found is the syslog, so it's best to
304 304
 				 * enable LogSyslog in clamav.conf
305 305
 				 */
306
+static	char *quarantine;	/*
307
+				 * If a virus is found in an email redirect
308
+				 * it to this account
309
+				 */
306 310
 static	int	nflag = 0;	/*
307 311
 				 * Don't add X-Virus-Scanned to header. Patch
308 312
 				 * from Dirk Meyer <dirk.meyer@dinoex.sub.org>
... ...
@@ -347,16 +357,17 @@ help(void)
347 347
 
348 348
 	puts("\t--bounce\t\t-b\tSend a failure message to the sender.");
349 349
 	puts("\t--config-file=FILE\t-c FILE\tRead configuration from FILE.");
350
-	puts("\t--dont-scan-on-error\t\t-d\tPass e-mails through unscanned if a system error occurs.");
351
-	puts("\t--force-scan\tForce scan all messages (overrides (-o and -l).");
350
+	puts("\t--dont-scan-on-error\t-d\tPass e-mails through unscanned if a system error occurs.");
351
+	puts("\t--force-scan\t\t-f\tForce scan all messages (overrides (-o and -l).");
352 352
 	puts("\t--help\t\t\t-h\tThis message.");
353 353
 	puts("\t--local\t\t\t-l\tScan messages sent from machines on our LAN.");
354 354
 	puts("\t--outgoing\t\t-o\tScan outgoing messages from this machine.");
355 355
 	puts("\t--noxheader\t\t-n\tSuppress X-Virus-Scanned header.");
356 356
 	puts("\t--postmaster\t\t-p\tPostmaster address [default=postmaster].");
357
-	puts("\t--postmaster-only\t\t-P\tSend warnings only to the postmaster.");
357
+	puts("\t--postmaster-only\t-P\tSend warnings only to the postmaster.");
358
+	puts("\t--quarantine=USER\t-Q USER\tQuanrantine e-mail account.");
358 359
 	puts("\t--quiet\t\t\t-q\tDon't send e-mail notifications of interceptions.");
359
-	puts("\t--server=ADDRESS\t-s ADDRESS\tIP address of server running clamd (when using TCPsocket).");
360
+	puts("\t--server=ADDRESS\t-s ADDR\tIP address of server running clamd (when using TCPsocket).");
360 361
 	puts("\t--version\t\t-V\tPrint the version number of this software.");
361 362
 #ifdef	CL_DEBUG
362 363
 	puts("\t--debug-level=n\t\t-x n\tSets the debug level to 'n'.");
... ...
@@ -370,6 +381,7 @@ main(int argc, char **argv)
370 370
 	char *port = NULL;
371 371
 	const char *cfgfile = CL_DEFAULT_CFG;
372 372
 	struct cfgstruct *cpt;
373
+        struct passwd *user;
373 374
 	struct smfiDesc smfilter = {
374 375
 		"ClamAv", /* filter name */
375 376
 		SMFI_VERSION,	/* version code -- leave untouched */
... ...
@@ -397,10 +409,11 @@ main(int argc, char **argv)
397 397
 	for(;;) {
398 398
 		int opt_index = 0;
399 399
 #ifdef	CL_DEBUG
400
-		const char *args = "bc:flnopPqdhs:Vx:";
400
+		const char *args = "bc:flnopPqQdhs:Vx:";
401 401
 #else
402
-		const char *args = "bc:flnopPqdhs:V";
402
+		const char *args = "bc:flnopPqQdhs:V";
403 403
 #endif
404
+
404 405
 		static struct option long_options[] = {
405 406
 			{
406 407
 				"bounce", 0, NULL, 'b'
... ...
@@ -436,6 +449,9 @@ main(int argc, char **argv)
436 436
 				"quiet", 0, NULL, 'q'
437 437
 			},
438 438
 			{
439
+				"quarantine", 1, NULL, 'Q',
440
+			},
441
+			{
439 442
 				"max-children", 1, NULL, 'm'
440 443
 			},
441 444
 			{
... ...
@@ -485,6 +501,7 @@ main(int argc, char **argv)
485 485
 				break;
486 486
 			case 'n':	/* don't add X-Virus-Scanned */
487 487
 				nflag++;
488
+				smfilter.xxfi_flags &= ~SMFIF_ADDHDRS;
488 489
 				break;
489 490
 			case 'o':	/* scan outgoing mail */
490 491
 				oflag++;
... ...
@@ -498,6 +515,10 @@ main(int argc, char **argv)
498 498
 			case 'q':	/* send NO notification email */
499 499
 				qflag++;
500 500
 				break;
501
+			case 'Q':	/* quarantine e-mail address */
502
+				quarantine = optarg;
503
+				smfilter.xxfi_flags |= SMFIF_CHGHDRS|SMFIF_ADDRCPT|SMFIF_DELRCPT;
504
+				break;
501 505
 			case 's':	/* server running clamd */
502 506
 				serverIP = optarg;
503 507
 				break;
... ...
@@ -511,9 +532,9 @@ main(int argc, char **argv)
511 511
 #endif
512 512
 			default:
513 513
 #ifdef	CL_DEBUG
514
-				fprintf(stderr, "Usage: %s [-b] [-c=FILE] [--max-children=num] [-l] [-o] [-p=address] [-P] [-q] [-x#] socket-addr\n", argv[0]);
514
+				fprintf(stderr, "Usage: %s [-b] [-c FILE] [--max-children=num] [-l] [-o] [-p address] [-P] [-q] [-Q USER] [-x#] socket-addr\n", argv[0]);
515 515
 #else
516
-				fprintf(stderr, "Usage: %s [-b] [-c=FILE] [--max-children=num] [-l] [-o] [-p=address] [-P] [-q] socket-addr\n", argv[0]);
516
+				fprintf(stderr, "Usage: %s [-b] [-c FILE] [--max-children=num] [-l] [-o] [-p address] [-P] [-q] [-Q USER] socket-addr\n", argv[0]);
517 517
 #endif
518 518
 				return EX_USAGE;
519 519
 		}
... ...
@@ -534,6 +555,17 @@ main(int argc, char **argv)
534 534
 		return EX_CONFIG;
535 535
 	}
536 536
 
537
+	/* drop priviledges */
538
+	if((getuid() == 0) && (cpt = cfgopt(copt, "User"))) {
539
+		if((user = getpwnam(cpt->strarg)) == NULL) {
540
+			fprintf(stderr, "%s: Can't get information about user %s.\n", argv[0], cpt->strarg);
541
+			return EX_CONFIG;
542
+		}
543
+
544
+		setuid(user->pw_uid);
545
+	} else
546
+		fprintf(stderr, "%s: running as root is not recommended\n", argv[0]);
547
+
537 548
 	if(!cfgopt(copt, "StreamSaveToDisk")) {
538 549
 		fprintf(stderr, "%s: StreamSavetoDisk not enabled in %s\n",
539 550
 			argv[0], cfgfile);
... ...
@@ -743,7 +775,7 @@ pingServer(void)
743 743
 	snprintf(clamav_version, sizeof(clamav_version),
744 744
 		"ClamAV version '%s', clamav-milter version '%s'",
745 745
 		buf, CM_VERSION);
746
-		
746
+
747 747
 	return 1;
748 748
 }
749 749
 
... ...
@@ -1254,6 +1286,7 @@ clamfi_eom(SMFICTX *ctx)
1254 1254
 #ifdef	CL_DEBUG
1255 1255
 		puts(err);
1256 1256
 #endif
1257
+		free(err);
1257 1258
 
1258 1259
 		if(!qflag) {
1259 1260
 			sendmail = popen("/usr/lib/sendmail -t", "w");
... ...
@@ -1287,10 +1320,28 @@ clamfi_eom(SMFICTX *ctx)
1287 1287
 				pclose(sendmail);
1288 1288
 			}
1289 1289
 		}
1290
+		if(quarantine) {
1291
+			for(to = privdata->to; *to; to++) {
1292
+				smfi_delrcpt(ctx, *to);
1293
+				free(*to);
1294
+			}
1295
+			free(privdata->to);
1296
+			privdata->to = NULL;
1297
+			if(smfi_addrcpt(ctx, quarantine) == MI_FAILURE) {
1298
+				if(use_syslog)
1299
+					syslog(LOG_DEBUG, "Can't set quarantine user %s", quarantine);
1300
+				else
1301
+					fprintf(stderr, "Can't set quarantine user %s\n", quarantine);
1302
+			} else {
1303
+				/*
1304
+				 * FIXME: doesn't work if there's no subject
1305
+				 */
1306
+				smfi_chgheader(ctx, "Subject", 1, mess);
1307
+			}
1308
+		} else
1309
+			rc = SMFIS_REJECT;	/* Delete the e-mail */
1290 1310
 
1291 1311
 		smfi_setreply(ctx, "550", "5.7.1", "Virus detected by ClamAV - http://clamav.elektrapro.com");
1292
-		rc = SMFIS_REJECT;
1293
-		free(err);
1294 1312
 	}
1295 1313
 	clamfi_cleanup(ctx);
1296 1314