1 Add authenticated bits information into the dummy generated
2 Received-header for SpamAssassin to facilitate adding a rule
3 to score mail from authenticated clients.
6 http://bugzilla.redhat.com/496769
7 http://www.gossamer-threads.com/lists/spamassassin/users/146948
9 This patch also moves some of the macro collection to the
10 ENVFROM callback, where the required macros are available by default.
12 diff -up spamass-milter-0.3.2/README.bits spamass-milter-0.3.2/README
13 --- spamass-milter-0.3.2/README.bits 2008-04-23 17:11:42.000000000 +0100
14 +++ spamass-milter-0.3.2/README 2011-02-15 11:02:47.877271392 +0000
15 @@ -55,15 +55,26 @@ configuring sendmail through m4 & the se
18 INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/sendmail/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl
19 -define(`confMILTER_MACROS_CONNECT',`t, b, j, _, {daemon_name}, {if_name}, {if_addr}')dnl
20 -define(`confMILTER_MACROS_HELO',`s, {tls_version}, {cipher}, {cipher_bits}, {cert_subject}, {cert_issuer}')dnl
21 -define(`confMILTER_MACROS_ENVRCPT',`r, v, Z')dnl
22 +define(`confMILTER_MACROS_ENVRCPT',confMILTER_MACROS_ENVRCPT`, b, r, v, Z')dnl
24 should do the trick. Of course you need to modify the path of the
25 socket if you put another one into the startup script. The timeouts
26 have been increased somewhat because SpamAssassin may chew on it for a
27 little while on a slow machine.
29 +If you are using multiple milter mail filters on your mail server, you may
30 +have overridden the default values of some of the confMILTER_MACROS_*
31 +macros whilst configuring the other filters. You need to ensure that at
32 +least the following values are present:
34 +confMILTER_MACROS_CONNECT must include the {j} and {_} macros
35 +(all included by default)
37 +confMILTER_MACROS_ENVFROM must include the {i}, {auth_authen} and {auth_ssf}
38 +macros (all included by default)
40 +confMILTER_MACROS_ENVRCPT must include the {b}, {r}, {v}, and {Z} macros
42 Now recreate sendmail.cf, restart sendmail and experiment around a bit
43 with the setup to make sure it is working.
45 diff -up spamass-milter-0.3.2/spamass-milter.cpp.bits spamass-milter-0.3.2/spamass-milter.cpp
46 --- spamass-milter-0.3.2/spamass-milter.cpp.bits 2011-02-15 10:53:49.349259089 +0000
47 +++ spamass-milter-0.3.2/spamass-milter.cpp 2011-02-15 10:53:49.353259721 +0000
48 @@ -678,6 +678,7 @@ sfsistat
49 mlfi_connect(SMFICTX * ctx, char *hostname, _SOCK_ADDR * hostaddr)
52 + const char *macro_j, *macro__;
55 debug(D_FUNC, "mlfi_connect: enter");
56 @@ -695,8 +696,31 @@ mlfi_connect(SMFICTX * ctx, char *hostna
58 sctx->assassin = NULL;
61 - /* store a pointer to it with setpriv */
62 + sctx->our_fqdn = NULL;
63 + sctx->sender_address = NULL;
64 + sctx->queueid = NULL;
65 + sctx->auth_authen = NULL;
66 + sctx->auth_ssf = NULL;
68 + /* store our FQDN */
69 + macro_j = smfi_getsymval(ctx, const_cast<char *>("j"));
72 + macro_j = "localhost";
73 + warnmacro("j", "CONNECT");
75 + sctx->our_fqdn = strdup(macro_j);
77 + /* store the validated sending site's address */
78 + macro__ = smfi_getsymval(ctx, const_cast<char *>("_"));
81 + macro__ = "unknown";
82 + warnmacro("_", "CONNECT");
84 + sctx->sender_address = strdup(macro__);
86 + /* store a pointer to our private data with setpriv */
87 rv = smfi_setpriv(ctx, sctx);
90 @@ -745,7 +769,7 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
92 SpamAssassin* assassin;
93 struct context *sctx = (struct context *)smfi_getpriv(ctx);
94 - const char *queueid;
95 + const char *queueid, *macro_auth_ssf, *macro_auth_authen;
99 @@ -787,17 +811,44 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
101 // remember the MAIL FROM address
102 assassin->set_from(string(envfrom[0]));
105 + // remember the queueid for this message
106 queueid=smfi_getsymval(ctx, const_cast<char *>("i"));
110 warnmacro("i", "ENVFROM");
112 - assassin->queueid = queueid;
114 + sctx->queueid = strdup(queueid);
115 debug(D_MISC, "queueid=%s", queueid);
117 + // remember the SMTP AUTH login name
118 + macro_auth_authen = smfi_getsymval(ctx, const_cast<char *>("{auth_authen}"));
119 + if (!macro_auth_authen)
121 + macro_auth_authen = "";
122 + // Don't issue a warning for the auth_authen macro as
123 + // it is likely to be unset much of the time - it's
124 + // only set if the client has authenticated.
126 + // Similarly, we only issue warnings for the other
127 + // auth-related macros if {auth_authen) is available.
129 + // warnmacro("auth_authen", "ENVFROM");
131 + sctx->auth_authen = strdup(macro_auth_authen);
133 + // remember the SASL cipher bits
134 + macro_auth_ssf = smfi_getsymval(ctx, const_cast<char *>("{auth_ssf}"));
135 + if (!macro_auth_ssf)
137 + macro_auth_ssf = "";
138 + if (strlen(macro_auth_authen)) {
139 + warnmacro("auth_ssf", "ENVFROM");
142 + sctx->auth_ssf = strdup(macro_auth_ssf);
144 // tell Milter to continue
145 debug(D_FUNC, "mlfi_envfrom: exit");
147 @@ -888,7 +939,8 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
150 const char *macro_b, *macro_i, *macro_j, *macro_r,
151 - *macro_s, *macro_v, *macro_Z, *macro__;
152 + *macro_s, *macro_v, *macro_Z, *macro__,
153 + *macro_auth_ssf, *macro_auth_authen;
157 @@ -903,20 +955,13 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
161 - macro_i = smfi_getsymval(ctx, const_cast<char *>("i"));
164 - macro_i = "unknown";
165 - warnmacro("i", "ENVRCPT");
167 + macro_i = sctx->queueid;
169 - /* FQDN of this site */
170 - macro_j = smfi_getsymval(ctx, const_cast<char *>("j"));
173 - macro_j = "localhost";
174 - warnmacro("j", "ENVRCPT");
177 + macro_j = sctx->our_fqdn;
179 + /* Sender address */
180 + macro__ = sctx->sender_address;
182 /* Protocol used to receive the message */
183 macro_r = smfi_getsymval(ctx, const_cast<char *>("r"));
184 @@ -925,7 +970,11 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
186 warnmacro("r", "ENVRCPT");
190 + /* SMTP AUTH details */
191 + macro_auth_authen = sctx->auth_authen;
192 + macro_auth_ssf = sctx->auth_ssf;
194 /* Sendmail currently cannot pass us the {s} macro, but
195 I do not know why. Leave this in for the day sendmail is
196 fixed. Until that day, use the value remembered by
197 @@ -953,22 +1002,25 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
198 warnmacro("Z", "ENVRCPT");
201 - /* Validated sending site's address */
202 - macro__ = smfi_getsymval(ctx, const_cast<char *>("_"));
204 + assassin->output((string)"X-Envelope-From: "+assassin->from()+"\r\n");
205 + assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
209 + rec_header = (string) "Received: from " + macro_s + " (" + macro__ + ")\r\n\t";
211 + if (strlen(macro_auth_ssf))
213 - macro__ = "unknown";
214 - warnmacro("_", "ENVRCPT");
215 + rec_header += (string) "(authenticated bits=" + macro_auth_ssf + ")\r\n\t";
218 - assassin->output((string)"X-Envelope-From: "+assassin->from()+"\r\n");
219 - assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
220 + rec_header += (string) "by " + macro_j + " (" + macro_v + "/" + macro_Z + ") with " +
221 + macro_r + " id " + macro_i + ";\r\n\t" +
222 + macro_b + "\r\n\t" +
223 + "(envelope-from " + assassin->from() + ")\r\n";
225 - assassin->output((string)
226 - "Received: from "+macro_s+" ("+macro__+")\r\n\t"+
227 - "by "+macro_j+" ("+macro_v+"/"+macro_Z+") with "+macro_r+" id "+macro_i+";\r\n\t"+
229 - "(envelope-from "+assassin->from()+")\r\n");
230 + debug(D_SPAMC, "Received header for spamc: %s", rec_header.c_str());
231 + assassin->output(rec_header);
234 assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
235 @@ -1214,16 +1266,27 @@ mlfi_close(SMFICTX* ctx)
237 struct context *sctx;
238 debug(D_FUNC, "mlfi_close");
241 sctx = (struct context*)smfi_getpriv(ctx);
247 + if (sctx->our_fqdn)
248 + free(sctx->our_fqdn);
249 + if (sctx->sender_address)
250 + free(sctx->sender_address);
252 + free(sctx->queueid);
253 + if (sctx->auth_authen)
254 + free(sctx->auth_authen);
255 + if (sctx->auth_ssf)
256 + free(sctx->auth_ssf);
259 smfi_setpriv(ctx, NULL);
265 diff -up spamass-milter-0.3.2/spamass-milter.h.bits spamass-milter-0.3.2/spamass-milter.h
266 --- spamass-milter-0.3.2/spamass-milter.h.bits 2011-02-15 10:53:49.342257983 +0000
267 +++ spamass-milter-0.3.2/spamass-milter.h 2011-02-15 10:53:49.354259879 +0000
268 @@ -154,9 +154,6 @@ public:
269 // List of recipients after alias/virtusertable expansion
270 list <string> expandedrcpt;
272 - // the sendmail queue id for this message; used for logging
275 // Process handling variables
278 @@ -167,6 +164,11 @@ struct context
280 struct in_addr connect_ip; // remote IP address
283 + char *sender_address;
287 SpamAssassin *assassin; // pointer to the SA object if we're processing a message