You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@spamassassin.apache.org by Jean-Yves Avenard <jy...@gmail.com> on 2010/01/14 03:29:22 UTC

How to check if user is authenticated via Sendmail

Hi

Mail system is made of
Sendmail as MTA -> spamass-milter -> spamd

Legitimate users are using the sendmail server over TLS and first need
to authenticate themselves before being able to post.

Is there a way to have a particular score if the sender has
succesfully authenticated ?

Like if the sender was authenticated then score is -10.0 etc

I only realised two days ago of the issue with DATE_20XX ; so many
people have had their mail tagged as spam which as made the
auto-whitelist heavily biased toward scoring everything as spam now..

I want to make sure it doesn't happen, and if someone is
authenticated, I know they aren't spammer.

Thanks!
Jean-Yves

Re: How to check if user is authenticated via Sendmail

Posted by Jean-Yves Avenard <jy...@gmail.com>.
Hi

2010/1/15 Ted Mittelstaedt <te...@ipinc.net>:
> Yeah, this patch was discussed close to 6 years ago:
>
> http://lists.nongnu.org/archive/html/spamass-milt-list/2004-03/msg00014.html
>
> Unfortunately although the spamass-milter maintainer said he would
> add this, he never did, and the project appears to have been orphaned
> a few years later.
>
> Interesting to see it made it into the optional ports patchs - I use
> FreeBSD myself and I didn't realize the maintainer had done that.

A different patch, but with similar effect is also in the
Debian/Ubuntu spamass-milter ; the argument for Ubuntu is -I

Re: How to check if user is authenticated via Sendmail

Posted by Ted Mittelstaedt <te...@ipinc.net>.
Yeah, this patch was discussed close to 6 years ago:

http://lists.nongnu.org/archive/html/spamass-milt-list/2004-03/msg00014.html

Unfortunately although the spamass-milter maintainer said he would
add this, he never did, and the project appears to have been orphaned
a few years later.

Interesting to see it made it into the optional ports patchs - I use
FreeBSD myself and I didn't realize the maintainer had done that.

Ted

Jean-Yves Avenard wrote:
> I found this optional patch in the FreeBSD ports.
> 
> It does exactly what I want ; bypass all test if the message was sent
> over an authenticated connection...
> 
> Could easily be adapted to simply add an extra header for spamassassin
> to check on
> 
> 
> diff -u orig/spamass-milter.1.in spamass-milter.1.in
> --- orig/spamass-milter.1.in	Thu Mar 18 10:37:08 2004
> +++ spamass-milter.1.in	Wed Oct 18 18:06:23 2006
> @@ -199,6 +199,9 @@
>  Requires the
>  .Fl u
>  flag.
> +.It Fl a
> +Causes spamass-milter to pass through unchecked any messages from connections
> +established using SMTP authentication.  This is useful for sites with
> remote users.
>  .It Fl - Ar spamc flags ...
>  Pass all remaining options to spamc.
>  This allows you to connect to a remote spamd with
> diff -u orig/spamass-milter.cpp spamass-milter.cpp
> --- orig/spamass-milter.cpp	Thu Mar 23 13:41:36 2006
> +++ spamass-milter.cpp	Wed Oct 18 21:13:25 2006
> @@ -170,6 +170,7 @@
>  bool flag_full_email = false;		/* pass full email address to spamc */
>  bool flag_expand = false;	/* alias/virtusertable expansion */
>  bool warnedmacro = false;	/* have we logged that we couldn't fetch a macro? */
> +bool auth = false;		/* don't scan authenticated users */
> 
>  #if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */
>  static pthread_mutex_t popen_mutex = PTHREAD_MUTEX_INITIALIZER;
> @@ -181,7 +182,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:u:D:i:b:B:e:xa";
>     char *sock = NULL;
>     bool dofork = false;
>     char *pidfilename = NULL;
> @@ -196,6 +197,9 @@
>  	/* Process command line options */
>  	while ((c = getopt(argc, argv, args)) != -1) {
>  		switch (c) {
> +			case 'a':
> +				auth = true;
> +				break;
>  			case 'f':
>  				dofork = true;
>  				break;
> @@ -281,7 +285,7 @@
>        cout << "SpamAssassin Sendmail Milter Plugin" << endl;
>        cout << "Usage: spamass-milter -p socket [-b|-B bucket] [-d
> xx[,yy...]] [-D host]" << endl;
>        cout << "                      [-e defaultdomain] [-f] [-i
> networks] [-m] [-M]" << endl;
> -      cout << "                      [-P pidfile] [-r nn] [-u
> defaultuser] [-x]" << endl;
> +      cout << "                      [-P pidfile] [-r nn] [-u
> defaultuser] [-x] [-a]" << endl;
>        cout << "                      [-- spamc args ]" << endl;
>        cout << "   -p socket: path to create socket" << endl;
>        cout << "   -b bucket: redirect spam to this mail address.  The
> orignal" << endl;
> @@ -302,6 +306,7 @@
>        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;
> +      cout << "   -a: don't scan messages over an authenticated
> connection." << endl;
>        cout << "   -- spamc args: pass the remaining flags to spamc." << endl;
> 
>        exit(EX_USAGE);
> @@ -782,6 +787,15 @@
>      return SMFIS_TEMPFAIL;
>    }
>    /* debug(D_ALWAYS, "ZZZ got private context %p", sctx); */
> +
> +  if (auth) {
> +    const char *auth_type = smfi_getsymval(ctx, "{auth_type}");
> +
> +    if (auth_type) {
> +      debug(D_MISC, "auth_type=%s", auth_type);
> +      return SMFIS_ACCEPT;
> +    }
> +  }
> 
>    debug(D_FUNC, "mlfi_envfrom: enter");
>    try {


Re: How to check if user is authenticated via Sendmail

Posted by Jean-Yves Avenard <jy...@gmail.com>.
I found this optional patch in the FreeBSD ports.

It does exactly what I want ; bypass all test if the message was sent
over an authenticated connection...

Could easily be adapted to simply add an extra header for spamassassin
to check on


diff -u orig/spamass-milter.1.in spamass-milter.1.in
--- orig/spamass-milter.1.in	Thu Mar 18 10:37:08 2004
+++ spamass-milter.1.in	Wed Oct 18 18:06:23 2006
@@ -199,6 +199,9 @@
 Requires the
 .Fl u
 flag.
+.It Fl a
+Causes spamass-milter to pass through unchecked any messages from connections
+established using SMTP authentication.  This is useful for sites with
remote users.
 .It Fl - Ar spamc flags ...
 Pass all remaining options to spamc.
 This allows you to connect to a remote spamd with
diff -u orig/spamass-milter.cpp spamass-milter.cpp
--- orig/spamass-milter.cpp	Thu Mar 23 13:41:36 2006
+++ spamass-milter.cpp	Wed Oct 18 21:13:25 2006
@@ -170,6 +170,7 @@
 bool flag_full_email = false;		/* pass full email address to spamc */
 bool flag_expand = false;	/* alias/virtusertable expansion */
 bool warnedmacro = false;	/* have we logged that we couldn't fetch a macro? */
+bool auth = false;		/* don't scan authenticated users */

 #if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */
 static pthread_mutex_t popen_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -181,7 +182,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:u:D:i:b:B:e:xa";
    char *sock = NULL;
    bool dofork = false;
    char *pidfilename = NULL;
@@ -196,6 +197,9 @@
 	/* Process command line options */
 	while ((c = getopt(argc, argv, args)) != -1) {
 		switch (c) {
+			case 'a':
+				auth = true;
+				break;
 			case 'f':
 				dofork = true;
 				break;
@@ -281,7 +285,7 @@
       cout << "SpamAssassin Sendmail Milter Plugin" << endl;
       cout << "Usage: spamass-milter -p socket [-b|-B bucket] [-d
xx[,yy...]] [-D host]" << endl;
       cout << "                      [-e defaultdomain] [-f] [-i
networks] [-m] [-M]" << endl;
-      cout << "                      [-P pidfile] [-r nn] [-u
defaultuser] [-x]" << endl;
+      cout << "                      [-P pidfile] [-r nn] [-u
defaultuser] [-x] [-a]" << endl;
       cout << "                      [-- spamc args ]" << endl;
       cout << "   -p socket: path to create socket" << endl;
       cout << "   -b bucket: redirect spam to this mail address.  The
orignal" << endl;
@@ -302,6 +306,7 @@
       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;
+      cout << "   -a: don't scan messages over an authenticated
connection." << endl;
       cout << "   -- spamc args: pass the remaining flags to spamc." << endl;

       exit(EX_USAGE);
@@ -782,6 +787,15 @@
     return SMFIS_TEMPFAIL;
   }
   /* debug(D_ALWAYS, "ZZZ got private context %p", sctx); */
+
+  if (auth) {
+    const char *auth_type = smfi_getsymval(ctx, "{auth_type}");
+
+    if (auth_type) {
+      debug(D_MISC, "auth_type=%s", auth_type);
+      return SMFIS_ACCEPT;
+    }
+  }

   debug(D_FUNC, "mlfi_envfrom: enter");
   try {

Re: How to check if user is authenticated via Sendmail

Posted by David B Funk <db...@engineering.uiowa.edu>.
On Thu, 14 Jan 2010, Daryl C. W. O'Shea wrote:

> On 13/01/2010 9:29 PM, Jean-Yves Avenard wrote:
> > Hi
> >
> > Mail system is made of
> > Sendmail as MTA -> spamass-milter -> spamd
> >
> > Legitimate users are using the sendmail server over TLS and first need
> > to authenticate themselves before being able to post.
> >
> > Is there a way to have a particular score if the sender has
> > succesfully authenticated ?
>
> There's already a rule that checks for (the opposite) of this...
> __LAST_UNTRUSTED_RELAY_NO_AUTH.
>
> If you invert it with a meta rule you'll get what you want...
>
> meta AUTHD_RELAY !__LAST_UNTRUSTED_RELAY_NO_AUTH
> describe AUTHD_RELAY Message submission was via an authenticated user
> score AUTHD_RELAY -10
>
> Daryl

That would be assuming that spamass-milter correctly interpolated the auth
bits in the "Received" header it synthesizes so that SA could make that
determination. I know that version 0.3.1 of spamass-milter did
-NOT- do that. Does anybody know if there's a newer version of it?
(the savannah.nongnu.org site seems to have 0.3.1 as the last version).

-- 
Dave Funk                                  University of Iowa
<dbfunk (at) engineering.uiowa.edu>        College of Engineering
319/335-5751   FAX: 319/384-0549           1256 Seamans Center
Sys_admin/Postmaster/cell_admin            Iowa City, IA 52242-1527
#include <std_disclaimer.h>
Better is not better, 'standard' is better. B{

Re: How to check if user is authenticated via Sendmail

Posted by "Daryl C. W. O'Shea" <sp...@dostech.ca>.
On 13/01/2010 9:29 PM, Jean-Yves Avenard wrote:
> Hi
> 
> Mail system is made of
> Sendmail as MTA -> spamass-milter -> spamd
> 
> Legitimate users are using the sendmail server over TLS and first need
> to authenticate themselves before being able to post.
> 
> Is there a way to have a particular score if the sender has
> succesfully authenticated ?

There's already a rule that checks for (the opposite) of this...
__LAST_UNTRUSTED_RELAY_NO_AUTH.

If you invert it with a meta rule you'll get what you want...

meta AUTHD_RELAY !__LAST_UNTRUSTED_RELAY_NO_AUTH
describe AUTHD_RELAY Message submission was via an authenticated user
score AUTHD_RELAY -10

Daryl


Re: How to check if user is authenticated via Sendmail

Posted by John Hardin <jh...@impsec.org>.
On Wed, 13 Jan 2010, David B Funk wrote:

> On Wed, 13 Jan 2010, John Hardin wrote:
>
>>    header  AUTH_SMTP  Received =~ /\(authenticated bits=\d+\) by mail\.impsec\.org /
>
> One risk to this rule, a savvy spammer could forge a "Received" header 
> to mimic that information to gain your white-list score (now that it's 
> been publicized on this list they know ;).

That's why I included the MTA name in the rule. Including that forces the 
spammer to forge site-specific Received: headers to get a hit.

> To prevent forgeries from getting that free ride, test against the 
> special Received pseudo-headers, either "X-Spam-Relays-Internal" or 
> "X-Spam-Relays-Trusted" You might want to experiment to see what works 
> best.

That's probably a much better solution.

On Thu, 14 Jan 2010, Daryl C. W. O'Shea wrote:

> meta AUTHD_RELAY !__LAST_UNTRUSTED_RELAY_NO_AUTH
> describe AUTHD_RELAY Message submission was via an authenticated user
> score AUTHD_RELAY -10

And that's better still.

-- 
  John Hardin KA7OHZ                    http://www.impsec.org/~jhardin/
  jhardin@impsec.org    FALaholic #11174     pgpk -a jhardin@impsec.org
  key: 0xB8732E79 -- 2D8C 34F4 6411 F507 136C  AF76 D822 E6E6 B873 2E79
-----------------------------------------------------------------------
   USMC Rules of Gunfighting #20: The faster you finish the fight,
   the less shot you will get.
-----------------------------------------------------------------------
  3 days until Benjamin Franklin's 304th Birthday

Re: How to check if user is authenticated via Sendmail

Posted by Jean-Yves Avenard <jy...@gmail.com>.
Hi there

2010/1/14 David B Funk <db...@engineering.uiowa.edu>:
> A caveat, as you're using sendmail with a milter, be aware that the milter
> taps into the mail stream -before- the local sendmail "Received" header is
> added. Therefore the milter has to synthesize the "Received" header
> itself (to mimic what sendmail will create). Make sure that your milter
> will correctly add that "(authenticated bits=" stuff itself.

What do you mean by add the (authenticated...) in the milter ?

So at the time spamassassin receives the mail ; there's no "Received"
header yet ?

How would you test if the user is authenticated or not then


> some early versions didn't do this correctly.
> (this is assuming that the users are connecting/authenticating to the
> sendmail instance that you're running your milter on. If they're going
> to an upstream instance then this won't be an issue).

That's my case ; sendmail/milter/sa are all on the same host

Re: How to check if user is authenticated via Sendmail

Posted by David B Funk <db...@engineering.uiowa.edu>.
On Wed, 13 Jan 2010, John Hardin wrote:

> On Thu, 14 Jan 2010, Jean-Yves Avenard wrote:
>
> > Mail system is made of
> > Sendmail as MTA -> spamass-milter -> spamd
> >
> > Legitimate users are using the sendmail server over TLS and first need
> > to authenticate themselves before being able to post.
> >
> > Is there a way to have a particular score if the sender has
> > succesfully authenticated ?
> >
> > Like if the sender was authenticated then score is -10.0 etc
>
> Take a look at the Received header that your MTA inserts for an
> authenticated session. It will look something like this:
>
>    Received: from [192.168.1.86] ([xxx.202.179.87])
>      (authenticated bits=0)
>      by mail.impsec.org (8.13.7/8.13.7) with ESMTP id n7OIlctS024743
>      (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
>      for <jh...@impsec.org>; Mon, 24 Aug 2009 11:47:42 -0700
>
> The "by mail.impsec.org" would be _your_ MTA.
>
> Such a rule might be: (warning, untested!)
>
>    header  AUTH_SMTP  Received =~ /\(authenticated bits=\d+\) by mail\.impsec\.org /
>    score   AUTH_SMTP  -10.0
>
> ...substituting _your_ MTA name, of course.

One risk to this rule, a savvy spammer could forge a "Received" header to
mimic that information to gain your white-list score (now that it's been
publicized on this list they know ;).

To prevent forgeries from getting that free ride, test against the special
Received pseudo-headers, either "X-Spam-Relays-Internal" or "X-Spam-Relays-Trusted"
You might want to experiment to see what works best.

A caveat, as you're using sendmail with a milter, be aware that the milter
taps into the mail stream -before- the local sendmail "Received" header is
added. Therefore the milter has to synthesize the "Received" header
itself (to mimic what sendmail will create). Make sure that your milter
will correctly add that "(authenticated bits=" stuff itself.
some early versions didn't do this correctly.
(this is assuming that the users are connecting/authenticating to the
sendmail instance that you're running your milter on. If they're going
to an upstream instance then this won't be an issue).


-- 
Dave Funk                                  University of Iowa
<dbfunk (at) engineering.uiowa.edu>        College of Engineering
319/335-5751   FAX: 319/384-0549           1256 Seamans Center
Sys_admin/Postmaster/cell_admin            Iowa City, IA 52242-1527
#include <std_disclaimer.h>
Better is not better, 'standard' is better. B{

Re: How to check if user is authenticated via Sendmail

Posted by Jean-Yves Avenard <jy...@gmail.com>.
Hi

2010/1/14 John Hardin <jh...@impsec.org>:

> Take a look at the Received header that your MTA inserts for an
> authenticated session. It will look something like this:

Thanks for the hint..

I had a try with adding a hydrix.cf file containing:
header AUTH_SMTP Received =~ /\(authenticated bits=[0-9]+\) by
(mail|www)\.domain\.com/
describe AUTH_SMTP Come	from authenticated mail	server
score AUTH_SMTP  -10.0

restarted spamassassin , but not having much luck

I then simplified the rule with just:
header AUTH_SMTP Received =~ /\(authenticated bits=[0-9]+\)

and still no luck
Received: from minime.private.domain.com
	(authenticated bits=0)
	by mail.domain.com (8.14.4/8.14.4) with ESMTP id o0E4sbxh042310
	(version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT)
	for <jy...@gmail.com>; Thu, 14 Jan 2010 15:54:38 +1100 (EST)
	(envelope-from jean-yves.avenard@domain.com)
From: Jean-Yves Avenard <je...@domain.com>
Content-Type: multipart/alternative; boundary=Apple-Mail-47--477649399
Subject: test #2
Date: Thu, 14 Jan 2010 15:54:35 +1100
Message-Id: <77...@hydrix.com>
To: Jean-Yves Avenard <jy...@gmail.com>
Mime-Version: 1.0 (Apple Message framework v1077)
X-Mailer: Apple Mail (2.1077)
X-Spam-Status: No, score=-3.4 required=5.5 tests=BAYES_00,HTML_MESSAGE
	autolearn=no version=3.2.5
X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on
	server2.private.domain.com


So it didn't even register with that rule ...

Re: How to check if user is authenticated via Sendmail

Posted by John Hardin <jh...@impsec.org>.
On Thu, 14 Jan 2010, Jean-Yves Avenard wrote:

> Mail system is made of
> Sendmail as MTA -> spamass-milter -> spamd
>
> Legitimate users are using the sendmail server over TLS and first need
> to authenticate themselves before being able to post.
>
> Is there a way to have a particular score if the sender has
> succesfully authenticated ?
>
> Like if the sender was authenticated then score is -10.0 etc

Take a look at the Received header that your MTA inserts for an 
authenticated session. It will look something like this:

   Received: from [192.168.1.86] ([xxx.202.179.87])
     (authenticated bits=0)
     by mail.impsec.org (8.13.7/8.13.7) with ESMTP id n7OIlctS024743
     (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
     for <jh...@impsec.org>; Mon, 24 Aug 2009 11:47:42 -0700

The "by mail.impsec.org" would be _your_ MTA.

Such a rule might be: (warning, untested!)

   header  AUTH_SMTP  Received =~ /\(authenticated bits=\d+\) by mail\.impsec\.org /
   score   AUTH_SMTP  -10.0

...substituting _your_ MTA name, of course.

-- 
  John Hardin KA7OHZ                    http://www.impsec.org/~jhardin/
  jhardin@impsec.org    FALaholic #11174     pgpk -a jhardin@impsec.org
  key: 0xB8732E79 -- 2D8C 34F4 6411 F507 136C  AF76 D822 E6E6 B873 2E79
-----------------------------------------------------------------------
   Rights can only ever be individual, which means that you cannot
   gain a right by joining a mob, no matter how shiny the issued
   badges are, or how many of your neighbors are part of it.  -- Marko
-----------------------------------------------------------------------
  4 days until Benjamin Franklin's 304th Birthday