You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
8.5 KiB
290 lines
8.5 KiB
6 years ago
|
Add authenticated bits information into the dummy generated
|
||
|
Received-header for SpamAssassin to facilitate adding a rule
|
||
|
to score mail from authenticated clients.
|
||
|
|
||
|
Discussion:
|
||
|
http://bugzilla.redhat.com/496769
|
||
|
http://www.gossamer-threads.com/lists/spamassassin/users/146948
|
||
|
|
||
|
This patch also moves some of the macro collection to the
|
||
|
ENVFROM callback, where the required macros are available by default.
|
||
|
|
||
|
--- README
|
||
|
+++ README
|
||
|
@@ -55,16 +55,28 @@ configuring sendmail through m4 & the se
|
||
|
adding the lines
|
||
|
|
||
|
INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/sendmail/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl
|
||
|
-define(`confMILTER_MACROS_CONNECT',`t, b, j, _, {daemon_name}, {if_name}, {if_addr}')dnl
|
||
|
-define(`confMILTER_MACROS_HELO',`s, {tls_version}, {cipher}, {cipher_bits}, {cert_subject}, {cert_issuer}')dnl
|
||
|
-define(`confMILTER_MACROS_ENVFROM',`{auth_authen}, {auth_type}')dnl
|
||
|
-define(`confMILTER_MACROS_ENVRCPT',`r, v, Z')dnl
|
||
|
+define(`confMILTER_MACROS_ENVRCPT',confMILTER_MACROS_ENVRCPT`, b, r, v, Z')dnl
|
||
|
+
|
||
|
|
||
|
should do the trick. Of course you need to modify the path of the
|
||
|
socket if you put another one into the startup script. The timeouts
|
||
|
have been increased somewhat because SpamAssassin may chew on it for a
|
||
|
little while on a slow machine.
|
||
|
|
||
|
+If you are using multiple milter mail filters on your mail server, you may
|
||
|
+have overridden the default values of some of the confMILTER_MACROS_*
|
||
|
+macros whilst configuring the other filters. You need to ensure that at
|
||
|
+least the following values are present:
|
||
|
+
|
||
|
+confMILTER_MACROS_CONNECT must include the {j} and {_} macros
|
||
|
+(all included by default)
|
||
|
+
|
||
|
+confMILTER_MACROS_ENVFROM must include the {i}, {auth_authen}, {auth_ssf}
|
||
|
+and {auth_type} macros (all included by default)
|
||
|
+
|
||
|
+confMILTER_MACROS_ENVRCPT must include the {b}, {r}, {v}, and {Z} macros
|
||
|
+
|
||
|
+
|
||
|
Now recreate sendmail.cf, restart sendmail and experiment around a bit
|
||
|
with the setup to make sure it is working.
|
||
|
|
||
|
--- spamass-milter.cpp
|
||
|
+++ spamass-milter.cpp
|
||
|
@@ -702,6 +702,7 @@ sfsistat
|
||
|
mlfi_connect(SMFICTX * ctx, char *hostname, _SOCK_ADDR * hostaddr)
|
||
|
{
|
||
|
struct context *sctx;
|
||
|
+ const char *macro_j, *macro__;
|
||
|
int rv;
|
||
|
|
||
|
debug(D_FUNC, "mlfi_connect: enter");
|
||
|
@@ -726,8 +727,31 @@ mlfi_connect(SMFICTX * ctx, char *hostna
|
||
|
}
|
||
|
sctx->assassin = NULL;
|
||
|
sctx->helo = NULL;
|
||
|
-
|
||
|
- /* store a pointer to it with setpriv */
|
||
|
+ sctx->our_fqdn = NULL;
|
||
|
+ sctx->sender_address = NULL;
|
||
|
+ sctx->queueid = NULL;
|
||
|
+ sctx->auth_authen = NULL;
|
||
|
+ sctx->auth_ssf = NULL;
|
||
|
+
|
||
|
+ /* store our FQDN */
|
||
|
+ macro_j = smfi_getsymval(ctx, const_cast<char *>("j"));
|
||
|
+ if (!macro_j)
|
||
|
+ {
|
||
|
+ macro_j = "localhost";
|
||
|
+ warnmacro("j", "CONNECT");
|
||
|
+ }
|
||
|
+ sctx->our_fqdn = strdup(macro_j);
|
||
|
+
|
||
|
+ /* store the validated sending site's address */
|
||
|
+ macro__ = smfi_getsymval(ctx, const_cast<char *>("_"));
|
||
|
+ if (!macro__)
|
||
|
+ {
|
||
|
+ macro__ = "unknown";
|
||
|
+ warnmacro("_", "CONNECT");
|
||
|
+ }
|
||
|
+ sctx->sender_address = strdup(macro__);
|
||
|
+
|
||
|
+ /* store a pointer to our private data with setpriv */
|
||
|
rv = smfi_setpriv(ctx, sctx);
|
||
|
if (rv != MI_SUCCESS)
|
||
|
{
|
||
|
@@ -778,7 +802,7 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
|
||
|
{
|
||
|
SpamAssassin* assassin;
|
||
|
struct context *sctx = (struct context *)smfi_getpriv(ctx);
|
||
|
- const char *queueid;
|
||
|
+ const char *queueid, *macro_auth_ssf, *macro_auth_authen;
|
||
|
|
||
|
if (sctx == NULL)
|
||
|
{
|
||
|
@@ -814,17 +838,44 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
|
||
|
|
||
|
// remember the MAIL FROM address
|
||
|
assassin->set_from(string(envfrom[0]));
|
||
|
-
|
||
|
+
|
||
|
+ // remember the queueid for this message
|
||
|
queueid=smfi_getsymval(ctx, const_cast<char *>("i"));
|
||
|
if (!queueid)
|
||
|
{
|
||
|
queueid="unknown";
|
||
|
warnmacro("i", "ENVFROM");
|
||
|
}
|
||
|
- assassin->queueid = queueid;
|
||
|
-
|
||
|
+ sctx->queueid = strdup(queueid);
|
||
|
debug(D_MISC, "queueid=%s", queueid);
|
||
|
|
||
|
+ // remember the SMTP AUTH login name
|
||
|
+ macro_auth_authen = smfi_getsymval(ctx, const_cast<char *>("{auth_authen}"));
|
||
|
+ if (!macro_auth_authen)
|
||
|
+ {
|
||
|
+ macro_auth_authen = "";
|
||
|
+ // Don't issue a warning for the auth_authen macro as
|
||
|
+ // it is likely to be unset much of the time - it's
|
||
|
+ // only set if the client has authenticated.
|
||
|
+ //
|
||
|
+ // Similarly, we only issue warnings for the other
|
||
|
+ // auth-related macros if {auth_authen) is available.
|
||
|
+ //
|
||
|
+ // warnmacro("auth_authen", "ENVFROM");
|
||
|
+ }
|
||
|
+ sctx->auth_authen = strdup(macro_auth_authen);
|
||
|
+
|
||
|
+ // remember the SASL cipher bits
|
||
|
+ macro_auth_ssf = smfi_getsymval(ctx, const_cast<char *>("{auth_ssf}"));
|
||
|
+ if (!macro_auth_ssf)
|
||
|
+ {
|
||
|
+ macro_auth_ssf = "";
|
||
|
+ if (strlen(macro_auth_authen)) {
|
||
|
+ warnmacro("auth_ssf", "ENVFROM");
|
||
|
+ }
|
||
|
+ }
|
||
|
+ sctx->auth_ssf = strdup(macro_auth_ssf);
|
||
|
+
|
||
|
// tell Milter to continue
|
||
|
debug(D_FUNC, "mlfi_envfrom: exit");
|
||
|
|
||
|
@@ -918,7 +969,8 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
|
||
|
|
||
|
*/
|
||
|
const char *macro_b, *macro_i, *macro_j, *macro_r,
|
||
|
- *macro_s, *macro_v, *macro_Z, *macro__;
|
||
|
+ *macro_s, *macro_v, *macro_Z, *macro__,
|
||
|
+ *macro_auth_ssf, *macro_auth_authen;
|
||
|
char date[32];
|
||
|
|
||
|
/* RFC 822 date. */
|
||
|
@@ -933,20 +985,13 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
|
||
|
}
|
||
|
|
||
|
/* queue ID */
|
||
|
- macro_i = smfi_getsymval(ctx, const_cast<char *>("i"));
|
||
|
- if (!macro_i)
|
||
|
- {
|
||
|
- macro_i = "unknown";
|
||
|
- warnmacro("i", "ENVRCPT");
|
||
|
- }
|
||
|
+ macro_i = sctx->queueid;
|
||
|
|
||
|
- /* FQDN of this site */
|
||
|
- macro_j = smfi_getsymval(ctx, const_cast<char *>("j"));
|
||
|
- if (!macro_j)
|
||
|
- {
|
||
|
- macro_j = "localhost";
|
||
|
- warnmacro("j", "ENVRCPT");
|
||
|
- }
|
||
|
+ /* FQDN */
|
||
|
+ macro_j = sctx->our_fqdn;
|
||
|
+
|
||
|
+ /* Sender address */
|
||
|
+ macro__ = sctx->sender_address;
|
||
|
|
||
|
/* Protocol used to receive the message */
|
||
|
macro_r = smfi_getsymval(ctx, const_cast<char *>("r"));
|
||
|
@@ -955,7 +1000,11 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
|
||
|
macro_r = "SMTP";
|
||
|
warnmacro("r", "ENVRCPT");
|
||
|
}
|
||
|
-
|
||
|
+
|
||
|
+ /* SMTP AUTH details */
|
||
|
+ macro_auth_authen = sctx->auth_authen;
|
||
|
+ macro_auth_ssf = sctx->auth_ssf;
|
||
|
+
|
||
|
/* Sendmail currently cannot pass us the {s} macro, but
|
||
|
I do not know why. Leave this in for the day sendmail is
|
||
|
fixed. Until that day, use the value remembered by
|
||
|
@@ -983,22 +1032,25 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
|
||
|
warnmacro("Z", "ENVRCPT");
|
||
|
}
|
||
|
|
||
|
- /* Validated sending site's address */
|
||
|
- macro__ = smfi_getsymval(ctx, const_cast<char *>("_"));
|
||
|
- if (!macro__)
|
||
|
+ assassin->output((string)"X-Envelope-From: "+assassin->from()+"\r\n");
|
||
|
+ assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
|
||
|
+
|
||
|
+ string rec_header;
|
||
|
+
|
||
|
+ rec_header = (string) "Received: from " + macro_s + " (" + macro__ + ")\r\n\t";
|
||
|
+
|
||
|
+ if (strlen(macro_auth_ssf))
|
||
|
{
|
||
|
- macro__ = "unknown";
|
||
|
- warnmacro("_", "ENVRCPT");
|
||
|
+ rec_header += (string) "(authenticated bits=" + macro_auth_ssf + ")\r\n\t";
|
||
|
}
|
||
|
|
||
|
- assassin->output((string)"X-Envelope-From: "+assassin->from()+"\r\n");
|
||
|
- assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
|
||
|
+ rec_header += (string) "by " + macro_j + " (" + macro_v + "/" + macro_Z + ") with " +
|
||
|
+ macro_r + " id " + macro_i + ";\r\n\t" +
|
||
|
+ macro_b + "\r\n\t" +
|
||
|
+ "(envelope-from " + assassin->from() + ")\r\n";
|
||
|
|
||
|
- assassin->output((string)
|
||
|
- "Received: from "+macro_s+" ("+macro__+")\r\n\t"+
|
||
|
- "by "+macro_j+" ("+macro_v+"/"+macro_Z+") with "+macro_r+" id "+macro_i+";\r\n\t"+
|
||
|
- macro_b+"\r\n\t"+
|
||
|
- "(envelope-from "+assassin->from()+")\r\n");
|
||
|
+ debug(D_SPAMC, "Received header for spamc: %s", rec_header.c_str());
|
||
|
+ assassin->output(rec_header);
|
||
|
|
||
|
} else
|
||
|
assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
|
||
|
@@ -1244,16 +1296,27 @@ mlfi_close(SMFICTX* ctx)
|
||
|
{
|
||
|
struct context *sctx;
|
||
|
debug(D_FUNC, "mlfi_close");
|
||
|
-
|
||
|
+
|
||
|
sctx = (struct context*)smfi_getpriv(ctx);
|
||
|
if (sctx == NULL)
|
||
|
return SMFIS_ACCEPT;
|
||
|
|
||
|
if (sctx->helo)
|
||
|
free(sctx->helo);
|
||
|
+ if (sctx->our_fqdn)
|
||
|
+ free(sctx->our_fqdn);
|
||
|
+ if (sctx->sender_address)
|
||
|
+ free(sctx->sender_address);
|
||
|
+ if (sctx->queueid)
|
||
|
+ free(sctx->queueid);
|
||
|
+ if (sctx->auth_authen)
|
||
|
+ free(sctx->auth_authen);
|
||
|
+ if (sctx->auth_ssf)
|
||
|
+ free(sctx->auth_ssf);
|
||
|
+
|
||
|
free(sctx);
|
||
|
smfi_setpriv(ctx, NULL);
|
||
|
-
|
||
|
+
|
||
|
return SMFIS_ACCEPT;
|
||
|
}
|
||
|
|
||
|
--- spamass-milter.h
|
||
|
+++ spamass-milter.h
|
||
|
@@ -168,9 +168,6 @@ public:
|
||
|
// List of recipients after alias/virtusertable expansion
|
||
|
list <string> expandedrcpt;
|
||
|
|
||
|
- // the sendmail queue id for this message; used for logging
|
||
|
- string queueid;
|
||
|
-
|
||
|
// Process handling variables
|
||
|
pid_t pid;
|
||
|
int pipe_io[2][2];
|
||
|
@@ -181,6 +178,11 @@ struct context
|
||
|
{
|
||
|
char connect_ip[64]; // remote IP address
|
||
|
char *helo;
|
||
|
+ char *our_fqdn;
|
||
|
+ char *sender_address;
|
||
|
+ char *queueid;
|
||
|
+ char *auth_authen;
|
||
|
+ char *auth_ssf;
|
||
|
SpamAssassin *assassin; // pointer to the SA object if we're processing a message
|
||
|
};
|
||
|
|