[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-167-g4319a8f

acab acab at 77e5149b-7576-45b1-b177-96237e5ba77b
Fri Jun 12 19:11:18 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit ffbdf556713a0d7c7c40cc01a9a25d94199f4d74
Author: acab <acab at 77e5149b-7576-45b1-b177-96237e5ba77b>
Date:   Wed Apr 15 16:56:17 2009 +0000

    bb#1549
    
    git-svn-id: http://svn.clamav.net/svn/clamav-devel/trunk@5041 77e5149b-7576-45b1-b177-96237e5ba77b

diff --git a/ChangeLog b/ChangeLog
index 35fd60d..5267eb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Tue Apr 15 18:47:22 CEST 2009 (acab)
+------------------------------------
+ * clamav-milter: add support for action QuarantineReject (bb#1549)
+
+Tue Apr 15 17:03:30 CEST 2009 (acab)
+------------------------------------
+ * clamav-milter: add support for AddHeader=Add, properly remove
+		  existing headers (bb#1549)
+
 Mon Apr 13 11:48:33 EEST 2009 (edwin)
 -------------------------------------
  * contrib/split-tarball.sh: Apply modifications by Michael
diff --git a/clamav-milter/clamav-milter.c b/clamav-milter/clamav-milter.c
index 9846a02..c66613a 100644
--- a/clamav-milter/clamav-milter.c
+++ b/clamav-milter/clamav-milter.c
@@ -56,7 +56,7 @@ int main(int argc, char **argv) {
     memset(&descr, 0, sizeof(struct smfiDesc));
     descr.xxfi_name = "ClamAV";			/* filter name */
     descr.xxfi_version = SMFI_VERSION;		/* milter version */
-    descr.xxfi_flags = SMFIF_CHGHDRS|SMFIF_QUARANTINE; /* flags */
+    descr.xxfi_flags = SMFIF_QUARANTINE;	/* flags */
     descr.xxfi_connect = clamfi_connect;	/* connection info filter */
     descr.xxfi_envfrom = clamfi_envfrom;	/* envelope sender filter */
     descr.xxfi_envrcpt = clamfi_envrcpt;	/* envelope recipient filter */
@@ -219,7 +219,8 @@ int main(int argc, char **argv) {
 	return 1;
     }
 
-    if(optget(opts, "AddHeader")->enabled) {
+    pt = optget(opts, "AddHeader")->strarg;
+    if(strcasecmp(pt, "No")) {
 	char myname[255];
 
 	if(!gethostname(myname, sizeof(myname))) {
@@ -230,7 +231,15 @@ int main(int argc, char **argv) {
 	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s", get_version());
 	    xvirushdr[sizeof(xvirushdr)-1] = '\0';
 	}
-	addxvirus = 1;
+
+	descr.xxfi_flags |= SMFIF_ADDHDRS;
+
+	if(strcasecmp(pt, "Add")) { /* Replace or Yes */
+	    descr.xxfi_flags |= SMFIF_CHGHDRS;
+	    addxvirus = 1;
+	} else { /* Add */
+	    addxvirus = 2;
+	}
     }
     
     if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
diff --git a/clamav-milter/clamfi.c b/clamav-milter/clamfi.c
index 04f3a78..a4df626 100644
--- a/clamav-milter/clamfi.c
+++ b/clamav-milter/clamfi.c
@@ -52,7 +52,7 @@ static sfsistat (*CleanAction)(SMFICTX *ctx);
 static sfsistat (*InfectedAction)(SMFICTX *ctx);
 static char *rejectfmt = NULL;
 
-int addxvirus = 0;
+int addxvirus = 0; /* 0 - don't add | 1 - replace | 2 - add */
 char xvirushdr[255];
 enum {
     LOGINF_NONE,
@@ -76,12 +76,24 @@ struct CLAMFI {
     unsigned int bufsz;
     unsigned int all_whitelisted;
     unsigned int gotbody;
+    unsigned int scanned_count;
+    unsigned int status_count;
 };
 
 
-static void add_x_header(SMFICTX *ctx, char *st) {
-    smfi_chgheader(ctx, (char *)"X-Virus-Scanned", 1, xvirushdr);
-    smfi_chgheader(ctx, (char *)"X-Virus-Status", 1, st);
+static void add_x_header(SMFICTX *ctx, char *st, unsigned int scanned, unsigned int status) {
+    if(addxvirus == 1) {
+	while(scanned)
+	    if(smfi_chgheader(ctx, (char *)"X-Virus-Scanned", scanned--, NULL) != MI_SUCCESS)
+		logg("^Failed to remove existing X-Virus-Scanned header\n");
+	while(status)
+	    if(smfi_chgheader(ctx, (char *)"X-Virus-Status", status--, NULL) != MI_SUCCESS)
+		logg("^Failed to remove existing X-Virus-Status header\n");
+    }
+    if(smfi_addheader(ctx, (char *)"X-Virus-Scanned", xvirushdr) != MI_SUCCESS)
+	logg("^Failed to add X-Virus-Scanned header\n");
+    if(smfi_addheader(ctx, (char *)"X-Virus-Status", st) != MI_SUCCESS)
+	logg("^Failed to add X-Virus-Status header\n");
 }
 
 enum CFWHAT {
@@ -201,6 +213,11 @@ sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv) {
 	    cf->msg_id = strdup(headerv ? headerv : "");
     }
 
+    if(addxvirus==1) {
+	if(!strcasecmp(headerf, "X-Virus-Scanned")) cf->scanned_count++;
+	if(!strcasecmp(headerf, "X-Virus-Status")) cf->status_count++;
+    }
+
     if((ret = sendchunk(cf, (unsigned char *)headerf, strlen(headerf), ctx)) != SMFIS_CONTINUE)
 	return ret;
     if((ret = sendchunk(cf, (unsigned char *)": ", 2, ctx)) != SMFIS_CONTINUE)
@@ -290,7 +307,7 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
 
     len = strlen(reply);
     if(len>5 && !strcmp(reply + len - 5, ": OK\n")) {
-	if(addxvirus) add_x_header(ctx, "Clean");
+	if(addxvirus) add_x_header(ctx, "Clean", cf->scanned_count, cf->status_count);
 	ret = CleanAction(ctx);
     } else if (len>7 && !strcmp(reply + len - 7, " FOUND\n")) {
 	cf->virusname = NULL;
@@ -309,7 +326,7 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
 		    char msg[255];
 		    snprintf(msg, sizeof(msg), "Infected (%s)", vir);
 		    msg[sizeof(msg)-1] = '\0';
-		    add_x_header(ctx, msg);
+		    add_x_header(ctx, msg, cf->scanned_count, cf->status_count);
 		}
 
 		if(loginfected) {
@@ -378,6 +395,8 @@ static int parse_action(char *action) {
 	return 3;
     if(!strcasecmp(action, "Quarantine"))
 	return 4;
+    if(!strcasecmp(action, "QuarantineReject"))
+	return 5;
     logg("!Unknown action %s\n", action);
     return -1;
 }
@@ -395,12 +414,18 @@ static sfsistat action_reject(_UNUSED_ SMFICTX *ctx) {
 static sfsistat action_blackhole(_UNUSED_ SMFICTX *ctx)  {
     return SMFIS_DISCARD;
 }
-static sfsistat action_quarantine(SMFICTX *ctx) {
+static sfsistat quarantine_common(SMFICTX *ctx, sfsistat ret) {
     if(smfi_quarantine(ctx, "quarantined by clamav-milter") != MI_SUCCESS) {
 	logg("^Failed to quarantine message\n");
 	return SMFIS_TEMPFAIL;
     }
-    return SMFIS_ACCEPT;
+    return ret;
+}
+static sfsistat action_quarantine(SMFICTX *ctx) {
+    return quarantine_common(ctx, SMFIS_ACCEPT);
+}
+static sfsistat action_quarantine_reject(SMFICTX *ctx) {
+    return quarantine_common(ctx, SMFIS_REJECT);
 }
 static sfsistat action_reject_msg(SMFICTX *ctx) {
     struct CLAMFI *cf;
@@ -463,6 +488,9 @@ int init_actions(struct optstruct *opts) {
 	case 4:
 	    CleanAction = action_quarantine;
 	    break;
+	case 5:
+	    CleanAction = action_quarantine_reject;
+	    break;
 	default:
 	    logg("!Invalid action %s for option OnClean\n", opt->strarg);
 	    return 1;
@@ -483,6 +511,9 @@ int init_actions(struct optstruct *opts) {
 	case 4:
 	    InfectedAction = action_quarantine;
 	    break;
+	case 5:
+	    InfectedAction = action_quarantine_reject;
+	    break;
 	case 2:
 	    InfectedAction = action_reject_msg;
 	    if((opt = optget(opts, "RejectMsg"))->enabled) {
@@ -554,6 +585,10 @@ sfsistat clamfi_envfrom(SMFICTX *ctx, char **argv) {
     cf->all_whitelisted = 1;
     cf->gotbody = 0;
     cf->msg_subj = cf->msg_date = cf->msg_id = NULL;
+    if(addxvirus==1) {
+	cf->scanned_count = 0;
+	cf->status_count = 0;
+    }
     smfi_setpriv(ctx, (void *)cf);
 
     return SMFIS_CONTINUE;
diff --git a/etc/clamav-milter.conf b/etc/clamav-milter.conf
index 7c017f7..84b9e03 100644
--- a/etc/clamav-milter.conf
+++ b/etc/clamav-milter.conf
@@ -132,11 +132,15 @@ Example
 # - Defer
 #   Return a temporary failure message (4xx) to the peer
 # - Blackhole (not available for OnFail)
-#   Like accept but the message is sent to oblivion
+#   Like Accept but the message is sent to oblivion
 # - Quarantine (not available for OnFail)
-#   Like accept but message is quarantined instead of being delivered
-#   In sendmail the quarantine queue can be examined via mailq -qQ
-#   For Postfix this causes the message to be accepted but placed on hold
+#   Like Accept but message is quarantined instead of being delivered
+# - QuarantineReject (not available for OnFail)
+#   like Reject but a copy of the message is also quarantined
+#   Note: in Postfix this acts the same as Quarantine
+#
+# NOTE: In Sendmail the quarantine queue can be examined via mailq -qQ
+# For Postfix this causes the message to be placed on hold
 # 
 # Action to be performed on clean messages (mostly useful for testing)
 # Default Accept
@@ -158,11 +162,15 @@ Example
 # Default: MTA specific
 #RejectMsg 
 
-# If this option is set to Yes, an "X-Virus-Scanned" and an "X-Virus-Status"
-# headers will be attached to each processed message, possibly replacing
-# existing headers. 
-# Default: No
-#AddHeader Yes
+# If this option is set to "Replace" (or "Yes"), an "X-Virus-Scanned" and an
+# "X-Virus-Status" headers will be attached to each processed message, possibly
+# replacing existing headers.
+# If it is set to Add, the X-Virus headers are added possibly on top of the
+# existing ones.
+# Note that while "Replace" can potentially break DKIM signatures, "Add" may
+# confuse procmail and similar filters.
+# Default: no
+#AddHeader Replace
 
 
 ##
diff --git a/shared/optparser.c b/shared/optparser.c
index 70cec97..8f0a32a 100644
--- a/shared/optparser.c
+++ b/shared/optparser.c
@@ -373,15 +373,15 @@ const struct clam_option clam_options[] = {
 
     { "LocalNet", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_MILTER, "Messages originating from these hosts/networks will not be scanned\nThis option takes a host(name)/mask pair in CIRD notation and can be\nrepeated several times. If \"/mask\" is omitted, a host is assumed.\nTo specify a locally orignated, non-smtp, email use the keyword \"local\".", "local\n192.168.0.0/24\n1111:2222:3333::/48" },
 
-    { "OnClean", NULL, 0, TYPE_STRING, "^(Accept|Reject|Defer|Blackhole|Quarantine)$", -1, "Accept", 0, OPT_MILTER, "Action to be performed on clean messages (mostly useful for testing).\nThe following actions are available:\nAccept: the message is accepted for delievery;\nReject: immediately refuse delievery (a 5xx error is returned to the peer);\nDefer: return a temporary failure message (4xx) to the peer;\nBlackhole: like accept but the message is sent to oblivion;\nQuarantine: like accept but message is quarantined instead of being delivered,\n    in sendmail the quarantine queue can be examined via mailq -qQ,\n    for Postfix this causes the message to be accepted but placed on hold.", "Accept" },
+    { "OnClean", NULL, 0, TYPE_STRING, "^(Accept|Reject|Defer|Blackhole|Quarantine|QuarantineReject)$", -1, "Accept", 0, OPT_MILTER, "Action to be performed on clean messages (mostly useful for testing).\nThe following actions are available:\nAccept: the message is accepted for delievery\nReject: immediately refuse delievery (a 5xx error is returned to the peer)\nDefer: return a temporary failure message (4xx) to the peer\nBlackhole: like Accept but the message is sent to oblivion\nQuarantine: like Accept but message is quarantined instead of being delivered\nQuarantineReject: like Reject but a copy of the message is also quarantined", "Accept" },
 
-    { "OnInfected", NULL, 0, TYPE_STRING, "^(Accept|Reject|Defer|Blackhole|Quarantine)$", -1, "Quarantine", 0, OPT_MILTER, "Action to be performed on infected messages.\nThe following actions are available:\nAccept: the message is accepted for delievery;\nReject: immediately refuse delievery (a 5xx error is returned to the peer);\nDefer: return a temporary failure message (4xx) to the peer;\nBlackhole: like accept but the message is sent to oblivion;\nQuarantine: like accept but message is quarantined instead of being delivered,\n    in sendmail the quarantine queue can be examined via mailq -qQ,\n    for Postfix this causes the message to be accepted but placed on hold.", "Quarantine" },
+    { "OnInfected", NULL, 0, TYPE_STRING, "^(Accept|Reject|Defer|Blackhole|Quarantine|QuarantineReject)$", -1, "Quarantine", 0, OPT_MILTER, "Action to be performed on clean messages (mostly useful for testing).\nThe following actions are available:\nAccept: the message is accepted for delievery\nReject: immediately refuse delievery (a 5xx error is returned to the peer)\nDefer: return a temporary failure message (4xx) to the peer\nBlackhole: like Accept but the message is sent to oblivion\nQuarantine: like Accept but message is quarantined instead of being delivered\nQuarantineReject: like Reject but a copy of the message is also quarantined", "Quarantine" },
 
-    { "OnFail", NULL, 0, TYPE_STRING, "^(Accept|Reject|Defer)$", -1, "Defer", 0, OPT_MILTER, "Action to be performed on error conditions (this includes failure to\nallocate data structures, no scanners available, network timeouts, unknown\nscanner replies and the like).\nThe following actions are available:\nAccept: the message is accepted for delievery;\nReject: immediately refuse delievery (a 5xx error is returned to the peer);\nDefer: return a temporary failure message (4xx) to the peer.", "Defer" },
+    { "OnFail", NULL, 0, TYPE_STRING, "^(Accept|Reject|Defer)$", -1, "Defer", 0, OPT_MILTER, "Action to be performed on error conditions (this includes failure to\nallocate data structures, no scanners available, network timeouts, unknown\nscanner replies and the like.\nThe following actions are available:\nAccept: the message is accepted for delievery;\nReject: immediately refuse delievery (a 5xx error is returned to the peer);\nDefer: return a temporary failure message (4xx) to the peer.", "Defer" },
 
     { "RejectMsg", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows to set a specific rejection reason for infected messages\nand it's therefore only useful together with \"OnInfected Reject\"\nThe string \"%v\", if present, will be replaced with the virus name.", "MTA specific" },
 
-    { "AddHeader", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_MILTER, "If this option is set to Yes, an \"X-Virus-Scanned\" and an \"X-Virus-Status\"\nheaders will be attached to each processed message, possibly replacing\nexisting headers.", "Yes" },
+    { "AddHeader", NULL, 0, TYPE_STRING, "^(No|Replace|Yes|Add)$", -1, "no", 0, OPT_MILTER, "If this option is set to \"Replace\" (or \"Yes\"), an \"X-Virus-Scanned\" and an\n\"X-Virus-Status\" headers will be attached to each processed message, possibly\nreplacing existing headers.\nIf it is set to Add, the X-Virus headers are added possibly on top of the\nexisting ones.\nNote that while \"Replace\" can potentially break DKIM signatures, \"Add\" may\nconfuse procmail and similar filters.", "Replace" },
 
     { "Chroot", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "Chroot to the specified directory.\nChrooting is performed just after reading the config file and before\ndropping privileges.", "/newroot" },
 

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list