Quoting Nigel Horne <[EMAIL PROTECTED]>:

I am considering adding a patch to maintain a list of
domains that I host for which outgoing emails should not
be scanned. This patch would only kick in when either
the remote host is connected via an authenticated SMTP
session.

I had a similar problem and created an ad-hoc patch, who should to this:

- Definition of internal networks, which contains the internal mail server (-I option)

- Definition of a other reject value for outgoing mails (-s option)

- Definition of Rejecttext for external and internal mails (-R and -S option)

- Don't modify Header and Body for outgoing mails (-o and -O option)

Background: outgoing mails should be scanned, but should not marked. If the Spamcount is greater then -s nn, then the message should be rejected and the reject text could point to an URL, which contains an explanation of the situation for the users. And rejected messages can poinnt to a different URL.

I have attached my patch.

Herbert Straub
#! /bin/sh /usr/share/dpatch/dpatch-run
## 10_spamass-milter-cvs-2006-06-17-rejecttext-and-internal-network2.dpatch by Herbert Straub <[EMAIL PROTECTED]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Customizeable reject text, internal networks and customizeable reject 
## DP: text and score

@DPATCH@

--- spamass-milt/spamass-milter.cpp.ORIG	2006-06-17 11:06:30.000000000 +0200
+++ spamass-milt/spamass-milter.cpp	2006-06-18 14:04:06.000000000 +0200
@@ -154,14 +154,21 @@
 
 int flag_debug = (1<<D_ALWAYS);
 bool flag_reject = false;
+bool flag_reject_intern = false;
 int reject_score = -1;
+int reject_score_intern = -1;
+bool dontmodifyspam_intern = false;    // Don't modify/add body or spam results headers, coming from internal
+bool dontmodify_intern = false;        // Don't add SA headers, ever, coming from internal
 bool dontmodifyspam = false;    // Don't modify/add body or spam results headers
 bool dontmodify = false;        // Don't add SA headers, ever.
 bool flag_sniffuser = false;
 char *defaultuser;				/* Username to send to spamc if there are multiple recipients */
 char *defaultdomain;			/* Domain to append if incoming address has none */
 char *spamdhost;
+char *rejecttext = NULL;				/* If we reject a mail, then use this text */
+char *rejecttext_intern = NULL;		/* If we reject a mail from the internal server, then use this text */
 struct networklist ignorenets;
+struct networklist internalnets;	/* Internal network, see options -s and -S */
 int spamc_argc;
 char **spamc_argv;
 bool flag_bucket = false;
@@ -181,7 +188,7 @@
 main(int argc, char* argv[])
 {
    int c, err = 0;
-   const char *args = "fd:mMp:P:r:u:D:i:b:B:e:x";
+   const char *args = "fd:mMp:P:r:R:s:S:u:D:i:n:oOp:b:B:e:x";
    char *sock = NULL;
    bool dofork = false;
    char *pidfilename = NULL;
@@ -193,6 +200,11 @@
 
    openlog("spamass-milter", LOG_PID, LOG_MAIL);
 
+
+    syslog(LOG_ERR, "argc: %d", argc);
+	for (int xy=0; xy<argc; xy++) {
+			syslog(LOG_ERR, "argv[%d]: %s", xy, argv[xy]);
+	}
 	/* Process command line options */
 	while ((c = getopt(argc, argv, args)) != -1) {
 		switch (c) {
@@ -222,6 +234,17 @@
 				dontmodifyspam = true;
 				smfilter.xxfi_flags &= ~(SMFIF_CHGBODY|SMFIF_CHGHDRS);
 				break;
+			case 'n':
+				debug(D_MISC, "Parsing internal network list");
+				parse_networklist(optarg, &internalnets);
+				break;
+			case 'o':
+				dontmodifyspam_intern = true;
+				break;
+			case 'O':
+				dontmodify_intern = true;
+				dontmodifyspam_intern = true;
+				break;
 			case 'p':
 				sock = strdup(optarg);
 				break;
@@ -232,6 +255,16 @@
 				flag_reject = true;
 				reject_score = atoi(optarg);
 				break;
+			case 'R':
+				rejecttext = strdup (optarg);
+				break;
+			case 's':
+				flag_reject_intern = true;
+				reject_score_intern = atoi(optarg);
+				break;
+			case 'S':
+				rejecttext_intern = strdup(optarg);
+				break;
 			case 'u':
 				flag_sniffuser = true;
 				defaultuser = strdup(optarg);
@@ -294,11 +327,22 @@
       cout << "   -f: fork into background" << endl;
       cout << "   -i: skip (ignore) checks from these IPs or netblocks" << endl;
       cout << "          example: -i 192.168.12.5,10.0.0.0/8,172.16.0.0/255.255.0.0" << endl;
+      cout << "   -I network: define the internal network. Works in combination with\n"
+	      "          the options -s and -S\n"
+	      "          Example: -I 192.168.12.5,10.0.0.0/8,172.16.0.0/255.255.0.0" << endl;
       cout << "   -m: don't modify body, Content-type: or Subject:" << endl;
       cout << "   -M: don't modify the message at all" << endl;
       cout << "   -P pidfile: Put processid in pidfile" << endl;
       cout << "   -r nn: reject messages with a score >= nn with an SMTP error.\n"
               "          use -1 to reject any messages tagged by SA." << endl;
+      cout << "   -R RejectText: using this Reject Text." << endl;
+      cout << "   -s nn: reject messages from the internal network\n"
+	      "          with a score >= nn with an SMTP error.\n"
+	      "          use -1 to reject any messages tagged by SA.\n"
+	      "          This require the specification of the internal network\n"
+	      "          with the -I option." << endl;
+      cout << "   -S RejectText: specifiy a alternate reject text for rejects\n"
+	      "          coming from the internal network" << endl;
       cout << "   -u defaultuser: pass the recipient's username to spamc.\n"
               "          Uses 'defaultuser' if there are multiple recipients." << endl;
       cout << "   -x: pass email address through alias and virtusertable expansion." << endl;
@@ -307,6 +351,14 @@
       exit(EX_USAGE);
    }
 
+	/* Set standard reject text */
+	if (rejecttext == NULL) {
+		rejecttext = strdup ("Blocked by SpamAssassin");
+	}
+	if (rejecttext_intern == NULL) {
+		rejecttext_intern = strdup ("Blocked by Spamassassin");
+	}
+
 	if (pidfilename)
 	{
 		unlink(pidfilename);
@@ -377,8 +429,20 @@
 	debug(D_UORI, "u_or_i: newstring: <%s>", newstring.c_str());
 
 	oldsize = callsetter(*assassin,setter)(newstring);
-      
-	if (!dontmodify)
+
+	struct context *sctx = (struct context*)smfi_getpriv(ctx);
+	bool internal_network=false;
+	if (ip_in_networklist(sctx->connect_ip, &internalnets)) {
+		internal_network=true;
+		debug(D_NET, "%s is in our internal list(update_or_insert)",
+	    		inet_ntoa(sctx->connect_ip));
+	}
+
+	/*
+	 * if -M then dontmodify headers
+	 * if -O and -n, then dont modify headers (mail from internal network)
+	 */
+	if (!(dontmodify || (dontmodify_intern && internal_network)))
 	{
 		if (newstring != oldstring)
 		{
@@ -422,14 +486,26 @@
   update_or_insert(assassin, ctx, assassin->spam_flag(), &SpamAssassin::set_spam_flag, "X-Spam-Flag");
   update_or_insert(assassin, ctx, assassin->spam_status(), &SpamAssassin::set_spam_status, "X-Spam-Status");
 
+  bool internal_network = false;
+  struct context *sctx = (struct context*)smfi_getpriv(ctx);
+  
+  if (ip_in_networklist(sctx->connect_ip, &internalnets))
+  {
+	internal_network = true;
+	debug(D_NET, "%s is in our internal list - accepting message",
+	    inet_ntoa(sctx->connect_ip));
+  }
+
   /* Summarily reject the message if SA tagged it, or if we have a minimum
      score, reject if it exceeds that score. */
-  if (flag_reject)
+  if (flag_reject || flag_reject_intern)
   {
 	bool do_reject = false;
-	if (reject_score == -1 && !assassin->spam_flag().empty())
+
+	if ((flag_reject && reject_score == -1 && !assassin->spam_flag().empty()) ||
+		(flag_reject_intern && reject_score_intern == -1 && !assassin->spam_flag().empty()))
 		do_reject = true;
-	if (reject_score != -1)
+	if (reject_score != -1 || reject_score_intern != -1)
 	{
 		int score, rv;
 		const char *spam_status = assassin->spam_status().c_str();
@@ -445,14 +521,15 @@
 		else 
 		{
 			debug(D_MISC, "SA score: %d", score);
-			if (score >= reject_score)
+			if ((flag_reject && score >= reject_score) ||
+				(flag_reject_intern && score >= reject_score_intern))
 				do_reject = true;
 		}
 	}
 	if (do_reject)
 	{
 		debug(D_MISC, "Rejecting");
-		smfi_setreply(ctx, "550", "5.7.1", "Blocked by SpamAssassin");
+		smfi_setreply(ctx, "550", "5.7.1", (internal_network) ?(rejecttext_intern) : (rejecttext));
 
 
 		if (flag_bucket)
@@ -560,7 +637,9 @@
   //  However, only issue the header replacement calls if the content has
   //  actually changed. If SA didn't change subject or content-type, don't
   //  replace here unnecessarily.
-  if (!dontmodifyspam && assassin->spam_flag().size()>0)
+  //
+  //  if -O and -n, then don't modiy Mail (mail from internal network)
+  if (!(dontmodifyspam || (dontmodifyspam_intern && internal_network)) && assassin->spam_flag().size()>0)
     {
 	  update_or_insert(assassin, ctx, assassin->subject(), &SpamAssassin::set_subject, "Subject");
 	  update_or_insert(assassin, ctx, assassin->content_type(), &SpamAssassin::set_content_type, "Content-Type");
_______________________________________________
Spamass-milt-list mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/spamass-milt-list
  • White list Nigel Horne
    • Re: White list Herbert Straub

Reply via email to