mainSpamAssassin Milter Plugin - Support: sr #101082, Patch for redirecting messages

 
 

sr #101082: Patch for redirecting messages

Submitter:  Raj Mathur <raju>
Submitted:  Sun 14 Jul 2002 02:22:07 AM UTC
   
 
Category:  None Priority:  5 - Normal
Severity:  2 - Minor Status:  None
Privacy:  Public Assigned to:  None
Open/Closed:  Open Operating System:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Mon 15 Jul 2002 10:32:48 AM UTC, comment #1: 


Never mind, uploaded to patches.  Hope someone takes it in
hand and massages it into the main distribution.

Raj Mathur <raju>
Sun 14 Jul 2002 02:22:07 AM UTC, original submission:  


I've patched spamass-milter (SM) so that it now accepts
an additional
command-line argument for the e-mail address of the
spammaster.  If
this argument is given, SM redirects mails identified
as spam by
SpamAssassin to this address, and saves the original
RCPT TO's in
X-Spam-RCPT headers.  The mail is NOT sent to the original
recipients.

I'm using this patch on a Sendmail relay server and I
think it'd be
useful for anyone who provides a pure relay service for
customers.
Spam messages originating from customers can be
redirected, and the
spammaster can subsequently edit and re-submit the
marked messages if
s/he feels that they've been wrongly identified as spam.

The patched SM has been running on a server relaying
for a /19 for the past 2 weeks or so without problems.

BTW, please don't complain about my coding style ;-)

-- Raju

--- Patch ---
diff -u --recursive --new-file
spamass-milter-0.1.1-old/ChangeLog
spamass-milter-0.1.1/ChangeLog
--- spamass-milter-0.1.1-old/ChangeLog Thu Jan 31 21:35:09 2002
+++ spamass-milter-0.1.1/ChangeLog Sun Jun 30 19:39:00 2002
@@ -1,3 +1,31 @@
+2002-06-30  Raj Mathur  <raju@kandalaya.org>
+
+

  • spamass-milter.h: Add callback for RCPT

(mlfi_envrcpt) to list
+
of callbacks.
+
Add flags SMFIF_ADDRCPT|SMFIF_DELRCPT to enable tweaking of
+
envelope RCPT TO's in the program.
+
Add method set_rcpt to SpamAssassin class.
+
Add data variables rcpt and nextrcpt to SpamAssassin class.
+
Currently fixed at 1024 rcpt's, maybe we can make this
dynamic
+
some time.
+
+

  • spamass-milter.cpp: Add additional argument to

program for
+
spammaster e-mail address.  If this is given, messages
marked as
+
SPAM will be redirected to spammaster instead of being
relayed to
+
original recipients.  Original recipient list will be
saved in
+
X-Spam-RCPT headers.
+
(main): Check for extra (argv[2]) argument and save as
spammaster
+
address.
+
(assassinate): If spammaster is defined remove original
RCPT TO's
+
from envelope (add corresponding X-Spam-RCPT headers)
and add RCPT
+
TO spammaster.  Free memory allocated by strdup in
mlfi_envrcpt.
+
(mlfi_envrcpt): New function, callback for each RCPT TO
+
encountered by sendmail.
+
(SpamAssassin): Clear the rcpt array (is this
required?) and
+
initialise nextrcpt.
+
(set_rcpt): New function, called by mlfi_envrcpt to
save the RCPT
+
TO address.
+
 2002-01-31  Georg C. F. Greve  <greve@gnu.org>
 
  * spamass-milter.cpp (set_spam_checker_version): see below
diff -u --recursive --new-file
spamass-milter-0.1.1-old/spamass-milter.cpp
spamass-milter-0.1.1/spamass-milter.cpp
--- spamass-milter-0.1.1-old/spamass-milter.cpp Thu Jan 31 21:35:09 2002
+++ spamass-milter-0.1.1/spamass-milter.cpp Sun Jun 30 19:33:23 2002
@@ -101,21 +101,32 @@
 
 // {{{ main()
 
+// If this gets set from argv then spam mails should
be redirected to
+// spammaster instead of being passed on to the
original RCPT's.
+
+static char *spammaster = 0 ;
+
 int
 main(int argc, char* argv[])
 {
-  // ONLY command line option: socket filename!
-  if ( argc != 2 )
+  // command line options: socket filename, optional
address of spammaster!
+  if ( argc !=2 && argc != 3 )
     {
       cout << PACKAGE << "- Version" << VERSION << endl;
       cout << "SpamAssassin Sendmail Milter Plugin" <<
endl;
-      cout << "Usage: spamass-milter <socket>" << endl;
+      cout << "Usage: spamass-milter <socket>
[spammaster mail ID]" << endl;
       _exit(0);
     };
 
   // set connection socket
   smfi_setconn(argv[1]);
 
+  // Save spammaster address
+  if ( argc == 3 )
+  {
+     spammaster = argv [2] ;
+  }
+
   // register callbacks with Milter
   if (smfi_register(smfilter) == MI_FAILURE)
     {
@@ -222,6 +233,9 @@
   //  Subject:
   //  Content-Type:
   //  <Body>
+  //
+  // Put original RCPTs as extra headers and send to
spammaster if
+  // defined.
   //
   if (assassin->spam_flag().size()>0)
     {
@@ -258,11 +272,32 @@
       string::size_type body_size =
assassin->d().size() - bob;
       unsigned char* bodyp = (unsigned char*)
  const_cast<char*>(assassin->d().substr(bob,
string::npos).c_str());
+
       if ( smfi_replacebody(ctx, bodyp, body_size) ==
MI_FAILURE )
  throw string("error. could not replace body.");
      
+      if ( spammaster )
+      {
+         // OK, do the RCPT stuph now.
+         for ( int i = 0 ; i < assassin -> nextrcpt ;
i++ )
+         {
+            smfi_delrcpt ( ctx , assassin -> rcpt [i] ) ;
+            smfi_addheader ( ctx , "X-Spam-RCPT" ,
assassin -> rcpt [i] ) ;
+         }
+         smfi_addrcpt ( ctx , spammaster ) ;
+      }
+
     };
 
+  if ( spammaster )
+  {
+     // Free the memory allocated by strdup for RCPTs
+     for ( int i = 0 ; i < assassin -> nextrcpt ; i++ )
+     {
+        free ( assassin -> rcpt [i] ) ;
+     }
+  }
+
   // erase mail right away
   assassin->d().erase();
  
@@ -329,6 +364,23 @@
 };
 
 //
+// Gets called repeatedly for all envelope RCPT commands
+//
+// Saves the RCPT values in an array in the private data.
+//
+sfsistat
+   mlfi_envrcpt ( SMFICTX ctx, char *argv )
+{
+   if ( spammaster )
+   {
+      SpamAssassin* assassin =
static_cast<SpamAssassin*>(smfi_getpriv(ctx));
+      assassin -> set_rcpt ( strdup ( argv [0] ) ) ;
+   }
+   return SMFIS_CONTINUE ;
+}
+
+
+//
 // Gets called repeatedly for all header fields
 //
 // assembles the headers and passes them on to the
SpamAssassin client
@@ -528,6 +580,13 @@
   if (pipe(pipe_io[1]))
     throw string(string("pipe error:
")+string(strerror(errno)));
  
+  if ( spammaster )
+  {
+     // Clear RCPTS
+     memset ( rcpt , 0 , sizeof ( rcpt ) ) ;
+     nextrcpt = 0 ;
+  }
+
   // now execute SpamAssassin client for contact with
SpamAssassin spamd
 
   // start child process
@@ -794,6 +853,22 @@
   _subject = val;
   return (old);
 };
+
+// This should only get called if spammaster is
non-null, so don't
+// need to check that here.
+
+void
+   SpamAssassin::set_rcpt ( const char *r )
+{
+   if ( nextrcpt < (int) ( sizeof ( rcpt ) / sizeof (
char * ) ) - 1 )
+   {
+      rcpt [nextrcpt] = (char *) r ;
+#if DEBUG
+      cerr << "RCPT[" << nextrcpt << "]: " << rcpt
[nextrcpt] << "\n" ;
+#endif
+   }
+   nextrcpt++ ;
+}
 
 //
 // Read all output from SpamAssassin client
diff -u --recursive --new-file
spamass-milter-0.1.1-old/spamass-milter.h
spamass-milter-0.1.1/spamass-milter.h
--- spamass-milter-0.1.1-old/spamass-milter.h Thu Jan 31 21:35:09 2002
+++ spamass-milter-0.1.1/spamass-milter.h Sat Jun 29 16:30:41 2002
@@ -9,6 +9,7 @@
 string retrieve_field(const string&, const string&);
 
 sfsistat mlfi_envfrom(SMFICTX*, char**);
+sfsistat mlfi_envrcpt(SMFICTX*, char**);
 sfsistat mlfi_header(SMFICTX*, char*, char*);
 sfsistat mlfi_eoh(SMFICTX*);
 sfsistat mlfi_body(SMFICTX*, u_char *, size_t);
@@ -21,11 +22,11 @@
   {
     "SpamAssassin", // filter name
     SMFI_VERSION,   // version code -- leave untouched
-    SMFIF_ADDHDRS|SMFIF_CHGHDRS|SMFIF_CHGBODY,  // flags
+  
SMFIF_ADDHDRS|SMFIF_CHGHDRS|SMFIF_CHGBODY|SMFIF_ADDRCPT|SMFIF_DELRCPT,
 // flags
     NULL, // info filter callback
     NULL, // HELO filter callback
     mlfi_envfrom, // envelope filter callback
-    NULL, // envelope recipient filter callback
+    mlfi_envrcpt, // envelope recipient filter callback
     mlfi_header, // header filter callback
     mlfi_eoh, // end of header callback
     mlfi_body, // body filter callback
@@ -59,6 +60,7 @@
   string::size_type set_spam_checker_version(const
string&);
   string::size_type set_content_type(const string&);
   string::size_type set_subject(const string&);
+   void set_rcpt ( const char *rcpt ) ;
 
 private:
   void empty_and_close_pipe();
@@ -79,7 +81,12 @@
   // Process handling variables
   pid_t pid;
   int pipe_io[2][2];

+
+   // Recipient list
+   char
+      *rcpt [1024] ;
+   int
+      nextrcpt ;
 };
 
 void assassinate(SMFICTX*, SpamAssassin*);


Raj Mathur <raju>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

CC list is empty

 

There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

Only logged-in users can vote.

 

No changes have been made to this item

Back to the top

Powered by Savane 3.13-54b4.
Corresponding source code