]>
Commit | Line | Data |
---|---|---|
2d65235e AM |
1 | commit 2357aa78ccd7182cad14307eb89cb1065f078356 |
2 | Author: Jeremy Harris <jgh146exb@wizmail.org> | |
3 | Date: Sun Aug 1 18:15:39 2021 +0100 | |
4 | ||
5 | ACL: "seen" condition | |
6 | ||
7 | diff --git a/src/src/acl.c b/src/src/acl.c | |
8 | index f47259ca0..be17b5768 100644 | |
9 | --- a/src/src/acl.c | |
10 | +++ b/src/src/acl.c | |
11 | @@ -103,6 +103,7 @@ enum { ACLC_ACL, | |
12 | ACLC_REGEX, | |
13 | #endif | |
14 | ACLC_REMOVE_HEADER, | |
15 | + ACLC_SEEN, | |
16 | ACLC_SENDER_DOMAINS, | |
17 | ACLC_SENDERS, | |
18 | ACLC_SET, | |
19 | @@ -288,6 +289,7 @@ static condition_def conditions[] = { | |
20 | ACL_BIT_MIME | ACL_BIT_NOTSMTP | | |
21 | ACL_BIT_NOTSMTP_START), | |
22 | }, | |
23 | + [ACLC_SEEN] = { US"seen", TRUE, FALSE, 0 }, | |
24 | [ACLC_SENDER_DOMAINS] = { US"sender_domains", FALSE, FALSE, | |
25 | ACL_BIT_AUTH | ACL_BIT_CONNECT | | |
26 | ACL_BIT_HELO | | |
27 | @@ -2815,6 +2817,143 @@ return rc; | |
28 | ||
29 | ||
30 | ||
31 | +/************************************************* | |
32 | +* Handle a check for previously-seen * | |
33 | +*************************************************/ | |
34 | + | |
35 | +/* | |
36 | +ACL clauses like: seen = -5m / key=$foo / readonly | |
37 | + | |
38 | +Return is true for condition-true - but the semantics | |
39 | +depend heavily on the actual use-case. | |
40 | + | |
41 | +Negative times test for seen-before, positive for seen-more-recently-than | |
42 | +(the given interval before current time). | |
43 | + | |
44 | +All are subject to history not having been cleaned from the DB. | |
45 | + | |
46 | +Default for seen-before is to create if not present, and to | |
47 | +update if older than 10d (with the seen-test time). | |
48 | +Default for seen-since is to always create or update. | |
49 | + | |
50 | +Options: | |
51 | + key=value. Default key is $sender_host_address | |
52 | + readonly | |
53 | + write | |
54 | + refresh=<interval>: update an existing DB entry older than given | |
55 | + amount. Default refresh lacking this option is 10d. | |
56 | + The update sets the record timestamp to the seen-test time. | |
57 | + | |
58 | +XXX do we need separate nocreate, noupdate controls? | |
59 | + | |
60 | +Arguments: | |
61 | + arg the option string for seen= | |
62 | + where ACL_WHERE_xxxx indicating which ACL this is | |
63 | + log_msgptr for error messages | |
64 | + | |
65 | +Returns: OK - Condition is true | |
66 | + FAIL - Condition is false | |
67 | + DEFER - Problem opening history database | |
68 | + ERROR - Syntax error in options | |
69 | +*/ | |
70 | + | |
71 | +static int | |
72 | +acl_seen(const uschar * arg, int where, uschar ** log_msgptr) | |
73 | +{ | |
74 | +enum { SEEN_DEFAULT, SEEN_READONLY, SEEN_WRITE }; | |
75 | + | |
76 | +const uschar * list = arg; | |
77 | +int slash = '/', equal = '=', interval, mode = SEEN_DEFAULT, yield = FAIL; | |
78 | +BOOL before; | |
79 | +int refresh = 10 * 24 * 60 * 60; /* 10 days */ | |
80 | +const uschar * ele, * key = sender_host_address; | |
81 | +open_db dbblock, * dbm; | |
82 | +dbdata_seen * dbd; | |
83 | +time_t now; | |
84 | + | |
85 | +/* Parse the first element, the time-relation. */ | |
86 | + | |
87 | +if (!(ele = string_nextinlist(&list, &slash, NULL, 0))) | |
88 | + goto badparse; | |
89 | +if ((before = *ele == '-')) | |
90 | + ele++; | |
91 | +if ((interval = readconf_readtime(ele, 0, FALSE)) < 0) | |
92 | + goto badparse; | |
93 | + | |
94 | +/* Remaining elements are options */ | |
95 | + | |
96 | +while ((ele = string_nextinlist(&list, &slash, NULL, 0))) | |
97 | + if (Ustrncmp(ele, "key=", 4) == 0) | |
98 | + key = ele + 4; | |
99 | + else if (Ustrcmp(ele, "readonly") == 0) | |
100 | + mode = SEEN_READONLY; | |
101 | + else if (Ustrcmp(ele, "write") == 0) | |
102 | + mode = SEEN_WRITE; | |
103 | + else if (Ustrncmp(ele, "refresh=", 8) == 0) | |
104 | + { | |
105 | + if ((refresh = readconf_readtime(ele + 8, 0, FALSE)) < 0) | |
106 | + goto badparse; | |
107 | + } | |
108 | + else | |
109 | + goto badopt; | |
110 | + | |
111 | +if (!(dbm = dbfn_open(US"seen", O_RDWR, &dbblock, TRUE, TRUE))) | |
112 | + { | |
113 | + HDEBUG(D_acl) debug_printf_indent("database for 'seen' not available\n"); | |
114 | + *log_msgptr = US"database for 'seen' not available"; | |
115 | + return DEFER; | |
116 | + } | |
117 | + | |
118 | +dbd = dbfn_read_with_length(dbm, key, NULL); | |
119 | +now = time(NULL); | |
120 | +if (dbd) /* an existing record */ | |
121 | + { | |
122 | + time_t diff = now - dbd->time_stamp; /* time since the record was written */ | |
123 | + | |
124 | + if (before ? diff >= interval : diff < interval) | |
125 | + yield = OK; | |
126 | + | |
127 | + if (mode == SEEN_READONLY) | |
128 | + { HDEBUG(D_acl) debug_printf_indent("seen db not written (readonly)\n"); } | |
129 | + else if (mode == SEEN_WRITE || !before) | |
130 | + { | |
131 | + dbd->time_stamp = now; | |
132 | + dbfn_write(dbm, key, dbd, sizeof(*dbd)); | |
133 | + HDEBUG(D_acl) debug_printf_indent("seen db written (update)\n"); | |
134 | + } | |
135 | + else if (diff >= refresh) | |
136 | + { | |
137 | + dbd->time_stamp = now - interval; | |
138 | + dbfn_write(dbm, key, dbd, sizeof(*dbd)); | |
139 | + HDEBUG(D_acl) debug_printf_indent("seen db written (refresh)\n"); | |
140 | + } | |
141 | + } | |
142 | +else | |
143 | + { /* No record found, yield always FAIL */ | |
144 | + if (mode != SEEN_READONLY) | |
145 | + { | |
146 | + dbdata_seen d = {.time_stamp = now}; | |
147 | + dbfn_write(dbm, key, &d, sizeof(*dbd)); | |
148 | + HDEBUG(D_acl) debug_printf_indent("seen db written (create)\n"); | |
149 | + } | |
150 | + else | |
151 | + HDEBUG(D_acl) debug_printf_indent("seen db not written (readonly)\n"); | |
152 | + } | |
153 | + | |
154 | +dbfn_close(dbm); | |
155 | +return yield; | |
156 | + | |
157 | + | |
158 | +badparse: | |
159 | + *log_msgptr = string_sprintf("failed to parse '%s'", arg); | |
160 | + return ERROR; | |
161 | +badopt: | |
162 | + *log_msgptr = string_sprintf("unrecognised option '%s' in '%s'", ele, arg); | |
163 | + return ERROR; | |
164 | +} | |
165 | + | |
166 | + | |
167 | + | |
168 | /************************************************* | |
169 | * The udpsend ACL modifier * | |
170 | *************************************************/ | |
171 | @@ -3740,6 +3879,10 @@ for (; cb; cb = cb->next) | |
172 | setup_remove_header(arg); | |
173 | break; | |
174 | ||
175 | + case ACLC_SEEN: | |
176 | + rc = acl_seen(arg, where, log_msgptr); | |
177 | + break; | |
178 | + | |
179 | case ACLC_SENDER_DOMAINS: | |
180 | { | |
181 | uschar *sdomain; | |
182 | diff --git a/src/src/dbstuff.h b/src/src/dbstuff.h | |
183 | index 2f00dffb4..94db7f7fd 100644 | |
184 | --- a/src/src/dbstuff.h | |
185 | +++ b/src/src/dbstuff.h | |
186 | @@ -788,6 +788,12 @@ typedef struct { | |
187 | uschar bloom[40]; /* Bloom filter which may be larger than this */ | |
188 | } dbdata_ratelimit_unique; | |
189 | ||
190 | + | |
191 | +/* For "seen" ACL condition */ | |
192 | +typedef struct { | |
193 | + time_t time_stamp; | |
194 | +} dbdata_seen; | |
195 | + | |
196 | #ifndef DISABLE_PIPE_CONNECT | |
197 | /* This structure records the EHLO responses, cleartext and crypted, | |
198 | for an IP, as bitmasks (cf. OPTION_TLS). For LIMITS, also values | |
199 | diff --git a/src/src/exim_dbutil.c b/src/src/exim_dbutil.c | |
200 | index 13f74540e..45b778fc0 100644 | |
201 | --- a/src/src/exim_dbutil.c | |
202 | +++ b/src/src/exim_dbutil.c | |
203 | @@ -21,7 +21,9 @@ argument is the name of the database file. The available names are: | |
204 | misc: miscellaneous hints data | |
205 | wait-<t>: message waiting information; <t> is a transport name | |
206 | callout: callout verification cache | |
207 | + ratelimit: ACL 'ratelimit' condition | |
208 | tls: TLS session resumption cache | |
209 | + seen: ACL 'seen' condition | |
210 | ||
211 | There are a number of common subroutines, followed by three main programs, | |
212 | whose inclusion is controlled by -D on the compilation command. */ | |
213 | @@ -38,6 +40,7 @@ whose inclusion is controlled by -D on the compilation command. */ | |
214 | #define type_callout 4 | |
215 | #define type_ratelimit 5 | |
216 | #define type_tls 6 | |
217 | +#define type_seen 7 | |
218 | ||
219 | ||
220 | /* This is used by our cut-down dbfn_open(). */ | |
221 | @@ -126,7 +129,7 @@ static void | |
222 | usage(uschar *name, uschar *options) | |
223 | { | |
224 | printf("Usage: exim_%s%s <spool-directory> <database-name>\n", name, options); | |
225 | -printf(" <database-name> = retry | misc | wait-<transport-name> | callout | ratelimit | tls\n"); | |
226 | +printf(" <database-name> = retry | misc | wait-<transport-name> | callout | ratelimit | tls | seen\n"); | |
227 | exit(1); | |
228 | } | |
229 | ||
230 | @@ -150,6 +153,7 @@ if (argc == 3) | |
231 | if (Ustrcmp(argv[2], "callout") == 0) return type_callout; | |
232 | if (Ustrcmp(argv[2], "ratelimit") == 0) return type_ratelimit; | |
233 | if (Ustrcmp(argv[2], "tls") == 0) return type_tls; | |
234 | + if (Ustrcmp(argv[2], "seen") == 0) return type_seen; | |
235 | } | |
236 | usage(name, options); | |
237 | return -1; /* Never obeyed */ | |
238 | @@ -581,6 +585,7 @@ for (uschar * key = dbfn_scan(dbm, TRUE, &cursor); | |
239 | dbdata_ratelimit *ratelimit; | |
240 | dbdata_ratelimit_unique *rate_unique; | |
241 | dbdata_tls_session *session; | |
242 | + dbdata_seen *seen; | |
243 | int count_bad = 0; | |
244 | int length; | |
245 | uschar *t; | |
246 | @@ -720,6 +725,11 @@ for (uschar * key = dbfn_scan(dbm, TRUE, &cursor); | |
247 | session = (dbdata_tls_session *)value; | |
248 | printf(" %s %.*s\n", keybuffer, length, session->session); | |
249 | break; | |
250 | + | |
251 | + case type_seen: | |
252 | + seen = (dbdata_seen *)value; | |
253 | + printf("%s\t%s\n", keybuffer, print_time(seen->time_stamp)); | |
254 | + break; | |
255 | } | |
256 | } | |
257 | store_reset(reset_point); | |
258 | diff --git a/test/confs/0626 b/test/confs/0626 | |
259 | new file mode 100644 | |
260 | index 000000000..872c4b20a | |
261 | --- /dev/null | |
262 | +++ b/test/confs/0626 | |
263 | @@ -0,0 +1,31 @@ | |
264 | +# Exim test configuration 0626 | |
265 | +# ACL seen condition | |
266 | + | |
267 | +.include DIR/aux-var/std_conf_prefix | |
268 | + | |
269 | + | |
270 | +# ----- Main settings ----- | |
271 | + | |
272 | +primary_hostname = test.ex | |
273 | +queue_only | |
274 | + | |
275 | +acl_smtp_rcpt = chk_rcpt | |
276 | + | |
277 | +# ----- ACL ----- | |
278 | + | |
279 | +begin acl | |
280 | + | |
281 | +chk_rcpt: | |
282 | + accept seen = OPT | |
283 | + | |
284 | +# seen = never / $sender_host_addreee / per_call | |
285 | +# seen = before=10s | |
286 | +# seen = before=10s / write | |
287 | +# seen = since / readonly | |
288 | +# | |
289 | +# seen = -10s | |
290 | +# seen = -10s / readonly | |
291 | +# seen = 2s | |
292 | +# seen = 0s / update=20d | |
293 | +# | |
294 | +# End | |
295 | diff --git a/test/scripts/0000-Basic/0626 b/test/scripts/0000-Basic/0626 | |
296 | new file mode 100644 | |
297 | index 000000000..6da58ee48 | |
298 | --- /dev/null | |
299 | +++ b/test/scripts/0000-Basic/0626 | |
300 | @@ -0,0 +1,82 @@ | |
301 | +# ACL 'seen' condition | |
302 | +# | |
303 | +exim -DOPT='-1s' -bh 127.0.0.1 | |
304 | +HELO test | |
305 | +MAIL FROM:<tester@test.ex> | |
306 | +RCPT TO:<a1@test.ex> | |
307 | +QUIT | |
308 | +**** | |
309 | +# Check that a hints DB was created. | |
310 | +# Only the key is useful thanks to munging; should match the IP used above. | |
311 | +dump seen | |
312 | +# | |
313 | +sleep 1 | |
314 | +# should now see old-enough record | |
315 | +exim -DOPT='-1s' -bh 127.0.0.1 | |
316 | +HELO test | |
317 | +MAIL FROM:<tester@test.ex> | |
318 | +RCPT TO:<a1@test.ex> | |
319 | +QUIT | |
320 | +**** | |
321 | +# force an update (visible via debug output in stdout for -bh) | |
322 | +exim -DOPT='-1s / write' -bh 127.0.0.1 | |
323 | +HELO test | |
324 | +MAIL FROM:<tester@test.ex> | |
325 | +RCPT TO:<a1@test.ex> | |
326 | +QUIT | |
327 | +**** | |
328 | +# default key should change with ip | |
329 | +exim -DOPT='-1s' -bh HOSTIPV4 | |
330 | +HELO test | |
331 | +MAIL FROM:<tester@test.ex> | |
332 | +RCPT TO:<a1@test.ex> | |
333 | +QUIT | |
334 | +**** | |
335 | +dump seen | |
336 | +# explicit key (also checking expansion) | |
337 | +exim -DOPT='-1s / key=${sender_host_address}_foo' -bh 127.0.0.1 | |
338 | +HELO test | |
339 | +MAIL FROM:<tester@test.ex> | |
340 | +RCPT TO:<a1@test.ex> | |
341 | +QUIT | |
342 | +**** | |
343 | +dump seen | |
344 | +# check refresh | |
345 | +sleep 1 | |
346 | +exim -DOPT='-1s / refresh=1s' -bh 127.0.0.1 | |
347 | +HELO test | |
348 | +MAIL FROM:<tester@test.ex> | |
349 | +RCPT TO:<a1@test.ex> | |
350 | +QUIT | |
351 | +**** | |
352 | +# | |
353 | +# | |
354 | +# | |
355 | +# | |
356 | +# | |
357 | +# test for seen-more-recently-than | |
358 | +# that previous one should be no older than 5s, so this should pass | |
359 | +# do not update | |
360 | +# check list-parsing spaceless while we're here | |
361 | +exim -DOPT='5s/key=${sender_host_address}_foo/readonly' -bh 127.0.0.1 | |
362 | +HELO test | |
363 | +MAIL FROM:<tester@test.ex> | |
364 | +RCPT TO:<a1@test.ex> | |
365 | +QUIT | |
366 | +**** | |
367 | +# check the above no-update by waiting longer than the later-than interval; should fail | |
368 | +# should update | |
369 | +sleep 2 | |
370 | +exim -DOPT='1s / key=${sender_host_address}_foo' -bh 127.0.0.1 | |
371 | +HELO test | |
372 | +MAIL FROM:<tester@test.ex> | |
373 | +RCPT TO:<a1@test.ex> | |
374 | +QUIT | |
375 | +**** | |
376 | +# having updated, should pass | |
377 | +exim -DOPT='1s / key=${sender_host_address}_foo' -bh 127.0.0.1 | |
378 | +HELO test | |
379 | +MAIL FROM:<tester@test.ex> | |
380 | +RCPT TO:<a1@test.ex> | |
381 | +QUIT | |
382 | +**** | |
383 | diff --git a/test/stderr/0626 b/test/stderr/0626 | |
384 | new file mode 100644 | |
385 | index 000000000..25e96bc4e | |
386 | --- /dev/null | |
387 | +++ b/test/stderr/0626 | |
388 | @@ -0,0 +1,142 @@ | |
389 | +>>> host in hosts_connection_nolog? no (option unset) | |
390 | +>>> host in host_lookup? no (option unset) | |
391 | +>>> host in host_reject_connection? no (option unset) | |
392 | +>>> host in sender_unqualified_hosts? no (option unset) | |
393 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
394 | +>>> host in helo_verify_hosts? no (option unset) | |
395 | +>>> host in helo_try_verify_hosts? no (option unset) | |
396 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
397 | +>>> test in helo_lookup_domains? no (end of list) | |
398 | +>>> using ACL "chk_rcpt" | |
399 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
400 | +>>> check seen = -1s | |
401 | +>>> seen db written (create) | |
402 | +>>> accept: condition test failed in ACL "chk_rcpt" | |
403 | +>>> end of ACL "chk_rcpt": implicit DENY | |
404 | +LOG: H=(test) [127.0.0.1] F=<tester@test.ex> rejected RCPT <a1@test.ex> | |
405 | +>>> host in hosts_connection_nolog? no (option unset) | |
406 | +>>> host in host_lookup? no (option unset) | |
407 | +>>> host in host_reject_connection? no (option unset) | |
408 | +>>> host in sender_unqualified_hosts? no (option unset) | |
409 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
410 | +>>> host in helo_verify_hosts? no (option unset) | |
411 | +>>> host in helo_try_verify_hosts? no (option unset) | |
412 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
413 | +>>> test in helo_lookup_domains? no (end of list) | |
414 | +>>> using ACL "chk_rcpt" | |
415 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
416 | +>>> check seen = -1s | |
417 | +>>> accept: condition test succeeded in ACL "chk_rcpt" | |
418 | +>>> end of ACL "chk_rcpt": ACCEPT | |
419 | +>>> host in hosts_connection_nolog? no (option unset) | |
420 | +>>> host in host_lookup? no (option unset) | |
421 | +>>> host in host_reject_connection? no (option unset) | |
422 | +>>> host in sender_unqualified_hosts? no (option unset) | |
423 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
424 | +>>> host in helo_verify_hosts? no (option unset) | |
425 | +>>> host in helo_try_verify_hosts? no (option unset) | |
426 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
427 | +>>> test in helo_lookup_domains? no (end of list) | |
428 | +>>> using ACL "chk_rcpt" | |
429 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
430 | +>>> check seen = -1s / write | |
431 | +>>> seen db written (update) | |
432 | +>>> accept: condition test succeeded in ACL "chk_rcpt" | |
433 | +>>> end of ACL "chk_rcpt": ACCEPT | |
434 | +>>> host in hosts_connection_nolog? no (option unset) | |
435 | +>>> host in host_lookup? no (option unset) | |
436 | +>>> host in host_reject_connection? no (option unset) | |
437 | +>>> host in sender_unqualified_hosts? no (option unset) | |
438 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
439 | +>>> host in helo_verify_hosts? no (option unset) | |
440 | +>>> host in helo_try_verify_hosts? no (option unset) | |
441 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
442 | +>>> test in helo_lookup_domains? no (end of list) | |
443 | +>>> using ACL "chk_rcpt" | |
444 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
445 | +>>> check seen = -1s | |
446 | +>>> seen db written (create) | |
447 | +>>> accept: condition test failed in ACL "chk_rcpt" | |
448 | +>>> end of ACL "chk_rcpt": implicit DENY | |
449 | +LOG: H=(test) [ip4.ip4.ip4.ip4] F=<tester@test.ex> rejected RCPT <a1@test.ex> | |
450 | +>>> host in hosts_connection_nolog? no (option unset) | |
451 | +>>> host in host_lookup? no (option unset) | |
452 | +>>> host in host_reject_connection? no (option unset) | |
453 | +>>> host in sender_unqualified_hosts? no (option unset) | |
454 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
455 | +>>> host in helo_verify_hosts? no (option unset) | |
456 | +>>> host in helo_try_verify_hosts? no (option unset) | |
457 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
458 | +>>> test in helo_lookup_domains? no (end of list) | |
459 | +>>> using ACL "chk_rcpt" | |
460 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
461 | +>>> check seen = -1s / key=${sender_host_address}_foo | |
462 | +>>> = -1s / key=127.0.0.1_foo | |
463 | +>>> seen db written (create) | |
464 | +>>> accept: condition test failed in ACL "chk_rcpt" | |
465 | +>>> end of ACL "chk_rcpt": implicit DENY | |
466 | +LOG: H=(test) [127.0.0.1] F=<tester@test.ex> rejected RCPT <a1@test.ex> | |
467 | +>>> host in hosts_connection_nolog? no (option unset) | |
468 | +>>> host in host_lookup? no (option unset) | |
469 | +>>> host in host_reject_connection? no (option unset) | |
470 | +>>> host in sender_unqualified_hosts? no (option unset) | |
471 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
472 | +>>> host in helo_verify_hosts? no (option unset) | |
473 | +>>> host in helo_try_verify_hosts? no (option unset) | |
474 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
475 | +>>> test in helo_lookup_domains? no (end of list) | |
476 | +>>> using ACL "chk_rcpt" | |
477 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
478 | +>>> check seen = -1s / refresh=1s | |
479 | +>>> seen db written (refresh) | |
480 | +>>> accept: condition test succeeded in ACL "chk_rcpt" | |
481 | +>>> end of ACL "chk_rcpt": ACCEPT | |
482 | +>>> host in hosts_connection_nolog? no (option unset) | |
483 | +>>> host in host_lookup? no (option unset) | |
484 | +>>> host in host_reject_connection? no (option unset) | |
485 | +>>> host in sender_unqualified_hosts? no (option unset) | |
486 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
487 | +>>> host in helo_verify_hosts? no (option unset) | |
488 | +>>> host in helo_try_verify_hosts? no (option unset) | |
489 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
490 | +>>> test in helo_lookup_domains? no (end of list) | |
491 | +>>> using ACL "chk_rcpt" | |
492 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
493 | +>>> check seen = 5s/key=${sender_host_address}_foo/readonly | |
494 | +>>> = 5s/key=127.0.0.1_foo/readonly | |
495 | +>>> seen db not written (readonly) | |
496 | +>>> accept: condition test succeeded in ACL "chk_rcpt" | |
497 | +>>> end of ACL "chk_rcpt": ACCEPT | |
498 | +>>> host in hosts_connection_nolog? no (option unset) | |
499 | +>>> host in host_lookup? no (option unset) | |
500 | +>>> host in host_reject_connection? no (option unset) | |
501 | +>>> host in sender_unqualified_hosts? no (option unset) | |
502 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
503 | +>>> host in helo_verify_hosts? no (option unset) | |
504 | +>>> host in helo_try_verify_hosts? no (option unset) | |
505 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
506 | +>>> test in helo_lookup_domains? no (end of list) | |
507 | +>>> using ACL "chk_rcpt" | |
508 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
509 | +>>> check seen = 1s / key=${sender_host_address}_foo | |
510 | +>>> = 1s / key=127.0.0.1_foo | |
511 | +>>> seen db written (update) | |
512 | +>>> accept: condition test failed in ACL "chk_rcpt" | |
513 | +>>> end of ACL "chk_rcpt": implicit DENY | |
514 | +LOG: H=(test) [127.0.0.1] F=<tester@test.ex> rejected RCPT <a1@test.ex> | |
515 | +>>> host in hosts_connection_nolog? no (option unset) | |
516 | +>>> host in host_lookup? no (option unset) | |
517 | +>>> host in host_reject_connection? no (option unset) | |
518 | +>>> host in sender_unqualified_hosts? no (option unset) | |
519 | +>>> host in recipient_unqualified_hosts? no (option unset) | |
520 | +>>> host in helo_verify_hosts? no (option unset) | |
521 | +>>> host in helo_try_verify_hosts? no (option unset) | |
522 | +>>> host in helo_accept_junk_hosts? no (option unset) | |
523 | +>>> test in helo_lookup_domains? no (end of list) | |
524 | +>>> using ACL "chk_rcpt" | |
525 | +>>> processing "accept" (TESTSUITE/test-config 19) | |
526 | +>>> check seen = 1s / key=${sender_host_address}_foo | |
527 | +>>> = 1s / key=127.0.0.1_foo | |
528 | +>>> seen db written (update) | |
529 | +>>> accept: condition test succeeded in ACL "chk_rcpt" | |
530 | +>>> end of ACL "chk_rcpt": ACCEPT | |
531 | diff --git a/test/stdout/0626 b/test/stdout/0626 | |
532 | new file mode 100644 | |
533 | index 000000000..44b481f31 | |
534 | --- /dev/null | |
535 | +++ b/test/stdout/0626 | |
536 | @@ -0,0 +1,99 @@ | |
537 | + | |
538 | +**** SMTP testing session as if from host 127.0.0.1 | |
539 | +**** but without any ident (RFC 1413) callback. | |
540 | +**** This is not for real! | |
541 | + | |
542 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
543 | +250 test.ex Hello test [127.0.0.1]\r | |
544 | +250 OK\r | |
545 | +550 Administrative prohibition\r | |
546 | +221 test.ex closing connection\r | |
547 | ++++++++++++++++++++++++++++ | |
548 | +127.0.0.1 07-Mar-2000 12:21:52 | |
549 | + | |
550 | +**** SMTP testing session as if from host 127.0.0.1 | |
551 | +**** but without any ident (RFC 1413) callback. | |
552 | +**** This is not for real! | |
553 | + | |
554 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
555 | +250 test.ex Hello test [127.0.0.1]\r | |
556 | +250 OK\r | |
557 | +250 Accepted\r | |
558 | +221 test.ex closing connection\r | |
559 | + | |
560 | +**** SMTP testing session as if from host 127.0.0.1 | |
561 | +**** but without any ident (RFC 1413) callback. | |
562 | +**** This is not for real! | |
563 | + | |
564 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
565 | +250 test.ex Hello test [127.0.0.1]\r | |
566 | +250 OK\r | |
567 | +250 Accepted\r | |
568 | +221 test.ex closing connection\r | |
569 | + | |
570 | +**** SMTP testing session as if from host ip4.ip4.ip4.ip4 | |
571 | +**** but without any ident (RFC 1413) callback. | |
572 | +**** This is not for real! | |
573 | + | |
574 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
575 | +250 test.ex Hello test [ip4.ip4.ip4.ip4]\r | |
576 | +250 OK\r | |
577 | +550 Administrative prohibition\r | |
578 | +221 test.ex closing connection\r | |
579 | ++++++++++++++++++++++++++++ | |
580 | +ip4.ip4.ip4.ip4 07-Mar-2000 12:21:52 | |
581 | +127.0.0.1 07-Mar-2000 12:21:52 | |
582 | + | |
583 | +**** SMTP testing session as if from host 127.0.0.1 | |
584 | +**** but without any ident (RFC 1413) callback. | |
585 | +**** This is not for real! | |
586 | + | |
587 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
588 | +250 test.ex Hello test [127.0.0.1]\r | |
589 | +250 OK\r | |
590 | +550 Administrative prohibition\r | |
591 | +221 test.ex closing connection\r | |
592 | ++++++++++++++++++++++++++++ | |
593 | +127.0.0.1_foo 07-Mar-2000 12:21:52 | |
594 | +ip4.ip4.ip4.ip4 07-Mar-2000 12:21:52 | |
595 | +127.0.0.1 07-Mar-2000 12:21:52 | |
596 | + | |
597 | +**** SMTP testing session as if from host 127.0.0.1 | |
598 | +**** but without any ident (RFC 1413) callback. | |
599 | +**** This is not for real! | |
600 | + | |
601 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
602 | +250 test.ex Hello test [127.0.0.1]\r | |
603 | +250 OK\r | |
604 | +250 Accepted\r | |
605 | +221 test.ex closing connection\r | |
606 | + | |
607 | +**** SMTP testing session as if from host 127.0.0.1 | |
608 | +**** but without any ident (RFC 1413) callback. | |
609 | +**** This is not for real! | |
610 | + | |
611 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
612 | +250 test.ex Hello test [127.0.0.1]\r | |
613 | +250 OK\r | |
614 | +250 Accepted\r | |
615 | +221 test.ex closing connection\r | |
616 | + | |
617 | +**** SMTP testing session as if from host 127.0.0.1 | |
618 | +**** but without any ident (RFC 1413) callback. | |
619 | +**** This is not for real! | |
620 | + | |
621 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
622 | +250 test.ex Hello test [127.0.0.1]\r | |
623 | +250 OK\r | |
624 | +550 Administrative prohibition\r | |
625 | +221 test.ex closing connection\r | |
626 | + | |
627 | +**** SMTP testing session as if from host 127.0.0.1 | |
628 | +**** but without any ident (RFC 1413) callback. | |
629 | +**** This is not for real! | |
630 | + | |
631 | +220 test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r | |
632 | +250 test.ex Hello test [127.0.0.1]\r | |
633 | +250 OK\r | |
634 | +250 Accepted\r | |
635 | +221 test.ex closing connection\r |