summarylogtreecommitdiffstats
path: root/spamass-milter-0.4.0-bits.patch
blob: 61090fdd24a40c31b6c7d95e55666de3638ec80f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
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
 };