Haraka 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changes.md +56 -0
- package/Dockerfile +3 -3
- package/Plugins.md +5 -4
- package/README.md +4 -4
- package/TODO +1 -24
- package/config/access.domains +1 -1
- package/config/auth_flat_file.ini +1 -0
- package/config/auth_vpopmaild.ini +4 -2
- package/config/helo.checks.ini +1 -1
- package/config/outbound.ini +1 -1
- package/config/rabbitmq_amqplib.ini +8 -1
- package/connection.js +32 -10
- package/docs/Connection.md +1 -1
- package/docs/Outbound.md +6 -15
- package/docs/Plugins.md +46 -39
- package/docs/Transaction.md +1 -1
- package/docs/{plugins → deprecated}/connect.rdns_access.md +1 -1
- package/docs/{plugins → deprecated}/mail_from.access.md +1 -1
- package/docs/{plugins → deprecated}/rcpt_to.access.md +1 -1
- package/docs/plugins/auth/auth_vpopmaild.md +15 -19
- package/docs/plugins/auth/flat_file.md +23 -30
- package/docs/plugins/clamd.md +1 -1
- package/docs/plugins/queue/rabbitmq_amqplib.md +7 -0
- package/docs/plugins/queue/smtp_forward.md +16 -38
- package/docs/plugins/queue/smtp_proxy.md +9 -11
- package/docs/plugins/relay.md +2 -2
- package/outbound/hmail.js +2 -2
- package/outbound/queue.js +5 -0
- package/outbound/tls.js +1 -1
- package/package.json +31 -31
- package/plugins/auth/auth_base.js +27 -11
- package/plugins/auth/auth_vpopmaild.js +29 -19
- package/plugins/auth/flat_file.js +17 -12
- package/plugins/clamd.js +1 -0
- package/plugins/dns_list_base.js +3 -3
- package/plugins/helo.checks.js +15 -7
- package/plugins/queue/rabbitmq_amqplib.js +1 -1
- package/plugins/queue/smtp_forward.js +21 -15
- package/plugins/tls.js +1 -1
- package/plugins.js +1 -0
- package/tests/config/helo.checks.ini +52 -0
- package/tests/plugins/dns_list_base.js +41 -31
- package/tests/plugins/helo.checks.js +212 -239
- package/tests/plugins/queue/smtp_forward.js +36 -7
- package/tests/queue/multibyte +0 -0
- package/tests/queue/plain +0 -0
- package/transaction.js +1 -1
- package/config/lookup_rdns.strict.ini +0 -12
- package/config/lookup_rdns.strict.timeout +0 -1
- package/config/lookup_rdns.strict.whitelist +0 -1
- package/config/lookup_rdns.strict.whitelist_regex +0 -5
- package/config/rcpt_to.blocklist +0 -1
- package/config/rdns.allow_regexps +0 -0
- package/config/rdns.deny_regexps +0 -0
- package/config.js +0 -6
- package/coverage/lcov.info +0 -13863
- package/coverage/tmp/coverage-42958-1658373250585-0.json +0 -1
- package/coverage/tmp/coverage-42961-1658373250529-0.json +0 -1
- package/docs/plugins/relay_acl.md +0 -29
- package/docs/plugins/relay_all.md +0 -15
- package/docs/plugins/relay_force_routing.md +0 -33
- package/plugins/data.headers.js +0 -4
- package/plugins/relay_all.js +0 -13
- /package/docs/{plugins → deprecated}/rcpt_to.routes.md +0 -0
package/plugins/clamd.js
CHANGED
|
@@ -269,6 +269,7 @@ exports.hook_data_post = function (next, connection) {
|
|
|
269
269
|
if (virus && plugin.rejectRE && // enabled
|
|
270
270
|
plugin.allRE.test(virus) && // has a reject option
|
|
271
271
|
!plugin.rejectRE.test(virus)) { // reject=false set
|
|
272
|
+
txn.add_header('X-Haraka-Virus', virus);
|
|
272
273
|
return next();
|
|
273
274
|
}
|
|
274
275
|
if (!plugin.cfg.reject.virus) { return next(); }
|
package/plugins/dns_list_base.js
CHANGED
|
@@ -126,7 +126,7 @@ exports.multi = function (lookup, zones, cb) {
|
|
|
126
126
|
}
|
|
127
127
|
cb(err, zone, a, true);
|
|
128
128
|
done();
|
|
129
|
-
})
|
|
129
|
+
})
|
|
130
130
|
}
|
|
131
131
|
function zonesDone (err) {
|
|
132
132
|
cb(err, null, null, false);
|
|
@@ -148,8 +148,8 @@ exports.first = function (lookup, zones, cb, cb_each) {
|
|
|
148
148
|
|
|
149
149
|
// has pending queries OR this one is a positive result
|
|
150
150
|
ran_cb = true;
|
|
151
|
-
|
|
152
|
-
})
|
|
151
|
+
cb(err, zone, a);
|
|
152
|
+
})
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
exports.check_zones = function (interval) {
|
package/plugins/helo.checks.js
CHANGED
|
@@ -11,7 +11,6 @@ const checks = [
|
|
|
11
11
|
'bare_ip', // HELO is bare IP (vs required Address Literal)
|
|
12
12
|
'dynamic', // HELO hostname looks dynamic (dsl|dialup|etc...)
|
|
13
13
|
'big_company', // Well known HELOs that must match rdns
|
|
14
|
-
'literal_mismatch', // IP literal that doesn't match remote IP
|
|
15
14
|
'valid_hostname', // HELO hostname is a legal DNS name
|
|
16
15
|
'rdns_match', // HELO hostname matches rDNS
|
|
17
16
|
'forward_dns', // HELO hostname resolves to the connecting IP
|
|
@@ -31,7 +30,7 @@ exports.register = function () {
|
|
|
31
30
|
this.register_hook('helo', 'init');
|
|
32
31
|
this.register_hook('ehlo', 'init');
|
|
33
32
|
|
|
34
|
-
for (const c
|
|
33
|
+
for (const c of checks) {
|
|
35
34
|
if (!this.cfg.check[c]) continue; // disabled in config
|
|
36
35
|
this.register_hook('helo', c);
|
|
37
36
|
this.register_hook('ehlo', c);
|
|
@@ -41,6 +40,13 @@ exports.register = function () {
|
|
|
41
40
|
this.register_hook('helo', 'emit_log');
|
|
42
41
|
this.register_hook('ehlo', 'emit_log');
|
|
43
42
|
|
|
43
|
+
// IP literal that doesn't match remote IP
|
|
44
|
+
this.register_hook('helo', 'literal_mismatch');
|
|
45
|
+
this.register_hook('ehlo', 'literal_mismatch');
|
|
46
|
+
|
|
47
|
+
this.cfg.check.literal_mismatch = this.cfg.check.literal_mismatch ?? 2;
|
|
48
|
+
this.cfg.reject.literal_mismatch = this.cfg.reject.literal_mismatch ?? false;
|
|
49
|
+
|
|
44
50
|
if (this.cfg.check.match_re) {
|
|
45
51
|
const load_re_file = () => {
|
|
46
52
|
const regex_list = utils.valid_regexes(this.config.get('helo.checks.regexps', 'list', load_re_file));
|
|
@@ -95,17 +101,19 @@ exports.load_helo_checks_ini = function () {
|
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
exports.init = function (next, connection, helo) {
|
|
98
|
-
|
|
99
|
-
const hc = connection.results.get('helo.checks');
|
|
100
|
-
if (!hc) { // first HELO result
|
|
104
|
+
if (!connection.results.has('helo.checks', 'helo_host', helo)) {
|
|
101
105
|
connection.results.add(this, {helo_host: helo});
|
|
102
|
-
return next();
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
next();
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
exports.should_skip = function (connection, test_name) {
|
|
112
|
+
if (connection.results.has('helo.checks', '_skip_hooks', test_name)) {
|
|
113
|
+
this.logdebug(connection, `SKIPPING: ${test_name}`);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
connection.results.push(this, {_skip_hooks: test_name});
|
|
109
117
|
|
|
110
118
|
if (this.cfg.skip.relaying && connection.relaying) {
|
|
111
119
|
connection.results.add(this, {skip: `${test_name}(relay)`});
|
|
@@ -491,7 +499,7 @@ exports.get_a_records = async function (host) {
|
|
|
491
499
|
err.code = dns.TIMEOUT;
|
|
492
500
|
this.logerror(err);
|
|
493
501
|
throw err;
|
|
494
|
-
}, (this.cfg.main.dns_timeout ||
|
|
502
|
+
}, (this.cfg.main.dns_timeout || 28) * 1000);
|
|
495
503
|
|
|
496
504
|
// fully qualify, to ignore any search options in /etc/resolv.conf
|
|
497
505
|
if (!/\.$/.test(host)) host = `${host}.`;
|
|
@@ -58,7 +58,7 @@ exports.init_amqp_connection = function () {
|
|
|
58
58
|
return conn.close();
|
|
59
59
|
}
|
|
60
60
|
ch.assertQueue(queueName,
|
|
61
|
-
{durable, autoDelete},
|
|
61
|
+
{durable, autoDelete, arguments: this.config.get("rabbitmq.ini").queue_args},
|
|
62
62
|
(err4, ok2) => {
|
|
63
63
|
if (err4) {
|
|
64
64
|
this.logerror(`Error asserting rabbitmq queue: ${err4}`);
|
|
@@ -26,10 +26,12 @@ exports.register = function () {
|
|
|
26
26
|
this.register_hook('queue', 'queue_forward');
|
|
27
27
|
|
|
28
28
|
if (this.cfg.main.enable_outbound) {
|
|
29
|
+
// deliver local message via smtp forward when relaying=true
|
|
29
30
|
this.register_hook('queue_outbound', 'queue_forward');
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
// may specify more specific [per-domain] outbound routes
|
|
34
|
+
this.register_hook('get_mx', 'get_mx');
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
exports.load_smtp_forward_ini = function () {
|
|
@@ -75,7 +77,7 @@ exports.is_outbound_enabled = function (dom_cfg) {
|
|
|
75
77
|
if ('enable_outbound' in dom_cfg) return dom_cfg.enable_outbound; // per-domain flag
|
|
76
78
|
|
|
77
79
|
return this.cfg.main.enable_outbound; // follow the global configuration
|
|
78
|
-
}
|
|
80
|
+
}
|
|
79
81
|
|
|
80
82
|
exports.check_sender = function (next, connection, params) {
|
|
81
83
|
const txn = connection?.transaction;
|
|
@@ -99,7 +101,7 @@ exports.check_sender = function (next, connection, params) {
|
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
txn.results.add(this, {pass: 'mail_from'});
|
|
102
|
-
|
|
104
|
+
next();
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
exports.set_queue = function (connection, queue_wanted, domain) {
|
|
@@ -110,7 +112,6 @@ exports.set_queue = function (connection, queue_wanted, domain) {
|
|
|
110
112
|
if (!queue_wanted) queue_wanted = dom_cfg.queue || this.cfg.main.queue;
|
|
111
113
|
if (!queue_wanted) return true;
|
|
112
114
|
|
|
113
|
-
|
|
114
115
|
let dst_host = dom_cfg.host || this.cfg.main.host;
|
|
115
116
|
if (dst_host) dst_host = `smtp://${dst_host}`;
|
|
116
117
|
|
|
@@ -164,7 +165,7 @@ exports.check_recipient = function (next, connection, params) {
|
|
|
164
165
|
// the MAIL FROM domain is not local and neither is the RCPT TO
|
|
165
166
|
// Another RCPT plugin may vouch for this recipient.
|
|
166
167
|
txn.results.add(this, {msg: 'rcpt!local'});
|
|
167
|
-
|
|
168
|
+
next();
|
|
168
169
|
}
|
|
169
170
|
|
|
170
171
|
exports.auth = function (cfg, connection, smtp_client) {
|
|
@@ -303,20 +304,24 @@ exports.queue_forward = function (next, connection) {
|
|
|
303
304
|
|
|
304
305
|
smtp_client.on('bad_code', (code, msg) => {
|
|
305
306
|
if (dead_sender() || !txn) return;
|
|
306
|
-
smtp_client.call_next(((code && code[0] === '5') ? DENY : DENYSOFT),
|
|
307
|
-
msg);
|
|
307
|
+
smtp_client.call_next(((code && code[0] === '5') ? DENY : DENYSOFT), msg);
|
|
308
308
|
smtp_client.release();
|
|
309
309
|
});
|
|
310
310
|
});
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
exports.get_mx_next_hop = next_hop => {
|
|
314
|
-
|
|
314
|
+
// queue.wants && queue.next_hop are mechanisms for fine-grained MX routing.
|
|
315
|
+
// Plugins can specify a queue to perform the delivery as well as a route. A
|
|
316
|
+
// plugin that uses this is qmail-deliverable, which can direct email delivery
|
|
317
|
+
// via smtp_forward, outbound (SMTP), and outbound (LMTP).
|
|
318
|
+
const dest = new url.URL(next_hop);
|
|
315
319
|
const mx = {
|
|
316
320
|
priority: 0,
|
|
317
|
-
port: dest.port || 25,
|
|
321
|
+
port: dest.port || (dest.protocol === 'lmtp:' ? 24 : 25),
|
|
318
322
|
exchange: dest.hostname,
|
|
319
323
|
}
|
|
324
|
+
if (dest.protocol === 'lmtp:') mx.using_lmtp = true;
|
|
320
325
|
if (dest.auth) {
|
|
321
326
|
mx.auth_type = 'plain';
|
|
322
327
|
mx.auth_user = dest.auth.split(':')[0];
|
|
@@ -327,9 +332,11 @@ exports.get_mx_next_hop = next_hop => {
|
|
|
327
332
|
|
|
328
333
|
exports.get_mx = function (next, hmail, domain) {
|
|
329
334
|
|
|
330
|
-
|
|
331
|
-
if (
|
|
332
|
-
|
|
335
|
+
const qw = hmail.todo.notes.get('queue.wants')
|
|
336
|
+
if (qw && qw !== 'smtp_forward') return next()
|
|
337
|
+
|
|
338
|
+
if (qw === 'smtp_forward' && hmail.todo.notes.get('queue.next_hop')) {
|
|
339
|
+
return next(OK, this.get_mx_next_hop(hmail.todo.notes.get('queue.next_hop')));
|
|
333
340
|
}
|
|
334
341
|
|
|
335
342
|
const dom = this.cfg.main.domain_selector === 'mail_from' ? hmail.todo.mail_from.host.toLowerCase() : domain.toLowerCase();
|
|
@@ -341,8 +348,7 @@ exports.get_mx = function (next, hmail, domain) {
|
|
|
341
348
|
}
|
|
342
349
|
|
|
343
350
|
const mx_opts = [
|
|
344
|
-
'auth_type', 'auth_user', 'auth_pass', 'bind', 'bind_helo',
|
|
345
|
-
'using_lmtp'
|
|
351
|
+
'auth_type', 'auth_user', 'auth_pass', 'bind', 'bind_helo', 'using_lmtp'
|
|
346
352
|
]
|
|
347
353
|
|
|
348
354
|
const mx = {
|
|
@@ -357,5 +363,5 @@ exports.get_mx = function (next, hmail, domain) {
|
|
|
357
363
|
mx[o] = this.cfg[dom][o];
|
|
358
364
|
})
|
|
359
365
|
|
|
360
|
-
|
|
366
|
+
next(OK, mx);
|
|
361
367
|
}
|
package/plugins/tls.js
CHANGED
|
@@ -75,7 +75,7 @@ exports.set_notls = function (connection) {
|
|
|
75
75
|
|
|
76
76
|
this.lognotice(connection, `STARTTLS failed. Marking ${connection.remote.ip} as non-TLS host for ${expiry} seconds`);
|
|
77
77
|
|
|
78
|
-
server.notes.redis.
|
|
78
|
+
server.notes.redis.setEx(`no_tls|${connection.remote.ip}`, expiry, (new Date()).toISOString());
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
exports.upgrade_connection = function (next, connection, params) {
|
package/plugins.js
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
; disable checks or reject for each test if you are worried about strictness
|
|
2
|
+
|
|
3
|
+
;dns_timeout=30
|
|
4
|
+
|
|
5
|
+
[check]
|
|
6
|
+
match_re=true
|
|
7
|
+
bare_ip=true
|
|
8
|
+
dynamic=true
|
|
9
|
+
big_company=true
|
|
10
|
+
; literal_mismatch: 1 = exact IP match, 2 = IP/24 match, 3 = /24 or RFC1918
|
|
11
|
+
literal_mismatch=2
|
|
12
|
+
valid_hostname=true
|
|
13
|
+
forward_dns=true
|
|
14
|
+
rdns_match=true
|
|
15
|
+
; host_mismatch: hostname differs between EHLO invocations
|
|
16
|
+
host_mismatch=true
|
|
17
|
+
proto_mismatch: host sent EHLO but then tries to sent HELO or vice-versa
|
|
18
|
+
proto_mismatch=true
|
|
19
|
+
|
|
20
|
+
[reject]
|
|
21
|
+
host_mismatch=true
|
|
22
|
+
proto_mismatch=true
|
|
23
|
+
rdns_match=true
|
|
24
|
+
dynamic=true
|
|
25
|
+
bare_ip=true
|
|
26
|
+
literal_mismatch=true
|
|
27
|
+
valid_hostname=true
|
|
28
|
+
forward_dns=true
|
|
29
|
+
big_company=true
|
|
30
|
+
|
|
31
|
+
[skip]
|
|
32
|
+
private_ip=true
|
|
33
|
+
relaying=true
|
|
34
|
+
whitelist=true
|
|
35
|
+
|
|
36
|
+
[bigco]
|
|
37
|
+
msn.com=msn.com
|
|
38
|
+
hotmail.com=hotmail.com
|
|
39
|
+
yahoo.com=yahoo.com,yahoo.co.jp
|
|
40
|
+
yahoo.co.jp=yahoo.com,yahoo.co.jp
|
|
41
|
+
yahoo.co.uk=yahoo.co.uk
|
|
42
|
+
excite.com=excite.com,excitenetwork.com
|
|
43
|
+
mailexcite.com=excite.com,excitenetwork.com
|
|
44
|
+
yahoo.co.jp=yahoo.com,yahoo.co.jp
|
|
45
|
+
mailexcite.com=excite.com,excitenetwork.com
|
|
46
|
+
aol.com=aol.com
|
|
47
|
+
compuserve.com=compuserve.com,adelphia.net
|
|
48
|
+
nortelnetworks.com=nortelnetworks.com,nortel.com
|
|
49
|
+
earthlink.net=earthlink.net
|
|
50
|
+
earthling.net=earthling.net
|
|
51
|
+
google.com=google.com
|
|
52
|
+
gmail.com=google.com,gmail.com
|
|
@@ -69,7 +69,7 @@ exports.multi = {
|
|
|
69
69
|
setUp : _set_up,
|
|
70
70
|
'Spamcop' (test) {
|
|
71
71
|
test.expect(4);
|
|
72
|
-
|
|
72
|
+
this.plugin.multi('127.0.0.2', 'bl.spamcop.net', (err, zone, a, pending) => {
|
|
73
73
|
test.equal(null, err);
|
|
74
74
|
if (pending) {
|
|
75
75
|
test.ok((Array.isArray(a) && a.length > 0));
|
|
@@ -78,12 +78,11 @@ exports.multi = {
|
|
|
78
78
|
else {
|
|
79
79
|
test.done();
|
|
80
80
|
}
|
|
81
|
-
}
|
|
82
|
-
this.plugin.multi('127.0.0.2', 'bl.spamcop.net', cb);
|
|
81
|
+
})
|
|
83
82
|
},
|
|
84
83
|
'CBL' (test) {
|
|
85
84
|
test.expect(4);
|
|
86
|
-
|
|
85
|
+
this.plugin.multi('127.0.0.2', 'xbl.spamhaus.org', (err, zone, a, pending) => {
|
|
87
86
|
test.equal(null, err);
|
|
88
87
|
if (pending) {
|
|
89
88
|
test.ok((Array.isArray(a) && a.length > 0));
|
|
@@ -92,12 +91,12 @@ exports.multi = {
|
|
|
92
91
|
else {
|
|
93
92
|
test.done();
|
|
94
93
|
}
|
|
95
|
-
}
|
|
96
|
-
this.plugin.multi('127.0.0.2', 'xbl.spamhaus.org', cb);
|
|
94
|
+
})
|
|
97
95
|
},
|
|
98
96
|
'Spamcop + CBL' (test) {
|
|
99
97
|
test.expect(12);
|
|
100
|
-
|
|
98
|
+
const dnsbls = ['bl.spamcop.net','xbl.spamhaus.org'];
|
|
99
|
+
this.plugin.multi('127.0.0.2', dnsbls, (err, zone, a, pending) => {
|
|
101
100
|
test.equal(null, err);
|
|
102
101
|
if (pending) {
|
|
103
102
|
test.ok(zone);
|
|
@@ -110,15 +109,20 @@ exports.multi = {
|
|
|
110
109
|
test.equal(false, pending);
|
|
111
110
|
test.done();
|
|
112
111
|
}
|
|
113
|
-
}
|
|
114
|
-
const dnsbls = ['bl.spamcop.net','xbl.spamhaus.org'];
|
|
115
|
-
this.plugin.multi('127.0.0.2', dnsbls, cb);
|
|
112
|
+
})
|
|
116
113
|
},
|
|
117
114
|
'Spamcop + CBL + negative result' (test) {
|
|
118
115
|
test.expect(12);
|
|
119
|
-
|
|
116
|
+
const dnsbls = [ 'bl.spamcop.net','xbl.spamhaus.org' ];
|
|
117
|
+
this.plugin.multi('127.0.0.1', dnsbls, (err, zone, a, pending) => {
|
|
120
118
|
test.equal(null, err);
|
|
121
|
-
|
|
119
|
+
if (a && a[0] && a[0] === '127.255.255.254') {
|
|
120
|
+
test.deepEqual(['127.255.255.254'], a)
|
|
121
|
+
console.warn(`ERROR: DNSBLs don't work with PUBLIC DNS!`)
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
test.equal(null, a)
|
|
125
|
+
}
|
|
122
126
|
if (pending) {
|
|
123
127
|
test.equal(true, pending);
|
|
124
128
|
test.ok(zone);
|
|
@@ -128,14 +132,19 @@ exports.multi = {
|
|
|
128
132
|
test.equal(null, zone);
|
|
129
133
|
test.done();
|
|
130
134
|
}
|
|
131
|
-
}
|
|
132
|
-
const dnsbls = ['bl.spamcop.net','xbl.spamhaus.org'];
|
|
133
|
-
this.plugin.multi('127.0.0.1', dnsbls, cb);
|
|
135
|
+
})
|
|
134
136
|
},
|
|
135
137
|
'IPv6 addresses supported' (test) {
|
|
136
138
|
test.expect(12);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
const dnsbls = ['bl.spamcop.net','xbl.spamhaus.org'];
|
|
140
|
+
this.plugin.multi('::1', dnsbls, (err, zone, a, pending) => {
|
|
141
|
+
if (a && a[0] && a[0] === '127.255.255.254') {
|
|
142
|
+
test.deepEqual(['127.255.255.254'], a)
|
|
143
|
+
console.warn(`ERROR: DNSBLs don't work with PUBLIC DNS!`)
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
test.equal(null, a);
|
|
147
|
+
}
|
|
139
148
|
if (pending) {
|
|
140
149
|
test.deepEqual(null, err);
|
|
141
150
|
test.equal(true, pending);
|
|
@@ -147,9 +156,7 @@ exports.multi = {
|
|
|
147
156
|
test.equal(null, zone);
|
|
148
157
|
test.done();
|
|
149
158
|
}
|
|
150
|
-
}
|
|
151
|
-
const dnsbls = ['bl.spamcop.net','xbl.spamhaus.org'];
|
|
152
|
-
this.plugin.multi('::1', dnsbls, cb);
|
|
159
|
+
})
|
|
153
160
|
}
|
|
154
161
|
}
|
|
155
162
|
|
|
@@ -157,25 +164,28 @@ exports.first = {
|
|
|
157
164
|
setUp : _set_up,
|
|
158
165
|
'positive result' (test) {
|
|
159
166
|
test.expect(3);
|
|
160
|
-
|
|
167
|
+
const dnsbls = [ 'xbl.spamhaus.org', 'bl.spamcop.net' ];
|
|
168
|
+
this.plugin.first('127.0.0.2', dnsbls, (err, zone, a) => {
|
|
161
169
|
test.equal(null, err);
|
|
162
170
|
test.ok(zone);
|
|
163
171
|
test.ok((Array.isArray(a) && a.length > 0));
|
|
164
172
|
test.done();
|
|
165
|
-
}
|
|
166
|
-
const dnsbls = [ 'xbl.spamhaus.org', 'bl.spamcop.net' ];
|
|
167
|
-
this.plugin.first('127.0.0.2', dnsbls , cb);
|
|
173
|
+
})
|
|
168
174
|
},
|
|
169
175
|
'negative result' (test) {
|
|
170
|
-
test.expect(
|
|
171
|
-
|
|
176
|
+
test.expect(2);
|
|
177
|
+
const dnsbls = [ 'xbl.spamhaus.org', 'bl.spamcop.net' ];
|
|
178
|
+
this.plugin.first('127.0.0.1', dnsbls, (err, zone, a) => {
|
|
172
179
|
test.equal(null, err);
|
|
173
|
-
|
|
174
|
-
|
|
180
|
+
if (a && a[0] && a[0] === '127.255.255.254') {
|
|
181
|
+
test.deepEqual(['127.255.255.254'], a)
|
|
182
|
+
console.warn(`ERROR: DNSBLs don't work with PUBLIC DNS!`)
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
test.equal(null, a);
|
|
186
|
+
}
|
|
175
187
|
test.done();
|
|
176
|
-
}
|
|
177
|
-
const dnsbls = [ 'xbl.spamhaus.org', 'bl.spamcop.net' ];
|
|
178
|
-
this.plugin.first('127.0.0.1', dnsbls, cb);
|
|
188
|
+
})
|
|
179
189
|
},
|
|
180
190
|
'each_cb' (test) {
|
|
181
191
|
test.expect(7);
|