Haraka 3.0.0 → 3.0.2
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 +41 -0
- package/Plugins.md +2 -0
- package/bin/haraka +5 -4
- package/config/outbound.ini +1 -1
- package/connection.js +32 -10
- package/dkim.js +2 -1
- package/docs/plugins/clamd.md +1 -1
- package/docs/plugins/queue/smtp_forward.md +15 -37
- package/docs/plugins/queue/smtp_proxy.md +9 -11
- package/outbound/tls.js +1 -1
- package/package.json +52 -52
- package/plugins/dns_list_base.js +3 -3
- package/plugins/helo.checks.js +14 -6
- package/plugins/queue/smtp_forward.js +22 -16
- package/plugins/tls.js +1 -1
- package/smtp_client.js +1 -1
- 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/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/Changes.md
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
|
|
2
2
|
### Unreleased
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
### [3.0.2] - 2023-06-12
|
|
6
|
+
|
|
7
|
+
#### Fixed
|
|
8
|
+
|
|
9
|
+
- feat(q_forward): add LMTP routing handling #3199
|
|
10
|
+
- chore(q_forward): tighten up queue.wants handling #3199
|
|
11
|
+
- doc(q_forward): improve markdown formatting #3199
|
|
12
|
+
- helo.checks: several fixes, #3191
|
|
13
|
+
- q/smtp_forward: correct path to next_hop #3186
|
|
14
|
+
- don't leak addr parsing errors into SMTP conversation #3185
|
|
15
|
+
- connection: handle dns.reverse invalid throws on node v20 #3184
|
|
16
|
+
- rename redis command setex to setEx #3181
|
|
17
|
+
|
|
18
|
+
#### Changed
|
|
19
|
+
|
|
20
|
+
- test(helo.checks): add regression tests for #3191 #3195
|
|
21
|
+
- connection: handle dns.reverse invalid throws on node v20
|
|
22
|
+
- build(deps): bump ipaddr.js from 2.0.1 to 2.1.0 #3194
|
|
23
|
+
- chore: bump a few dependency versions #3184
|
|
24
|
+
- dns_list_base: avoid test failure when public DNS used #3184
|
|
25
|
+
- doc(outbound.ini) update link #3159
|
|
26
|
+
- doc(clamd.md) fixed spelling error #3155
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### [3.0.1] - 2023-01-19
|
|
30
|
+
|
|
31
|
+
#### Fixed
|
|
32
|
+
|
|
33
|
+
- fix(bin/haraka): set server.cfg and pass to conn, fixes #3143
|
|
34
|
+
- fix(bin/haraka): correct error messages for help options #3142
|
|
35
|
+
- fix: dkim_verify fails to find record #3149
|
|
36
|
+
|
|
37
|
+
#### Changed
|
|
38
|
+
|
|
39
|
+
- plugins: Add haraka-plugin-outbound-logger to registry #3146
|
|
40
|
+
- dep(pi-spf): bump version 1.1.3 to 1.2.0
|
|
41
|
+
|
|
42
|
+
|
|
4
43
|
### [3.0.0] - 2022-12-17
|
|
5
44
|
|
|
6
45
|
#### Added
|
|
@@ -1329,3 +1368,5 @@
|
|
|
1329
1368
|
|
|
1330
1369
|
|
|
1331
1370
|
[3.0.0]: https://github.com/haraka/Haraka/releases/tag/3.0.0
|
|
1371
|
+
[3.0.1]: https://github.com/haraka/Haraka/releases/tag/3.0.1
|
|
1372
|
+
[3.0.2]: https://github.com/haraka/Haraka/releases/tag/3.0.2
|
package/Plugins.md
CHANGED
|
@@ -69,6 +69,7 @@ Create a PR adding yours to this list.
|
|
|
69
69
|
| [messagesniffer][url-msgsniff] | Anti-spam via [MessageSniffer][url-ms] |
|
|
70
70
|
| [milter][url-milter] | milter support |
|
|
71
71
|
| [mongodb][mongo-url] | Queue emails to MongoDB |
|
|
72
|
+
| [outbound-logger][url-outbound-logger] | JSON logging of outbound email traffic. Logs useful metadata about delivered/bounced emails |
|
|
72
73
|
| [prevent_credential_leaks][url-creds] | Prevent users from emailing their credentials |
|
|
73
74
|
| [process_title][url-proctitle] | Populate `ps` output with activity counters |
|
|
74
75
|
| queue/[discard][url-qdisc] | queues messages to /dev/null |
|
|
@@ -190,4 +191,5 @@ Create a PR adding yours to this list.
|
|
|
190
191
|
[url-wildduck]: https://github.com/nodemailer/haraka-plugin-wildduck
|
|
191
192
|
[url-xclient]: https://github.com/haraka/Haraka/blob/master/docs/plugins/xclient.md
|
|
192
193
|
[mongo-url]: https://github.com/Helpmonks/haraka-plugin-mongodb
|
|
194
|
+
[url-outbound-logger]: https://github.com/mr-karan/haraka-plugin-outbound-logger
|
|
193
195
|
|
package/bin/haraka
CHANGED
|
@@ -383,7 +383,7 @@ else if (parsed.qlist) {
|
|
|
383
383
|
}
|
|
384
384
|
else if (parsed.qstat) {
|
|
385
385
|
if (!parsed.configs) {
|
|
386
|
-
fail("
|
|
386
|
+
fail("qstat option requires config path");
|
|
387
387
|
}
|
|
388
388
|
process.env.HARAKA = parsed.configs;
|
|
389
389
|
logger = require(path.join(base, "logger"));
|
|
@@ -435,7 +435,7 @@ else if (parsed.graceful) {
|
|
|
435
435
|
}
|
|
436
436
|
else if (parsed.qempty) {
|
|
437
437
|
if (!parsed.configs) {
|
|
438
|
-
fail("
|
|
438
|
+
fail("qempty option requires config path");
|
|
439
439
|
}
|
|
440
440
|
fail("qempty is unimplemented");
|
|
441
441
|
}
|
|
@@ -476,7 +476,7 @@ else if (parsed.order) {
|
|
|
476
476
|
}
|
|
477
477
|
else if (parsed.test) {
|
|
478
478
|
if (!parsed.configs) {
|
|
479
|
-
fail("
|
|
479
|
+
fail("test option requires config path");
|
|
480
480
|
}
|
|
481
481
|
process.env.HARAKA = parsed.configs;
|
|
482
482
|
try {
|
|
@@ -528,9 +528,10 @@ else if (parsed.test) {
|
|
|
528
528
|
address () {
|
|
529
529
|
return { port: 25, family: 'ipv4', address: '127.0.0.1' };
|
|
530
530
|
},
|
|
531
|
+
cfg : require('haraka-config').get('smtp.ini'),
|
|
531
532
|
notes: new Notes(),
|
|
532
533
|
}
|
|
533
|
-
const connection = Connection.createConnection(client, server);
|
|
534
|
+
const connection = Connection.createConnection(client, server, server.cfg);
|
|
534
535
|
if (parsed['set-relay']) connection.relaying = true;
|
|
535
536
|
|
|
536
537
|
const run_next_hook = function () {
|
package/config/outbound.ini
CHANGED
package/connection.js
CHANGED
|
@@ -15,7 +15,7 @@ const constants = require('haraka-constants');
|
|
|
15
15
|
const net_utils = require('haraka-net-utils');
|
|
16
16
|
const Notes = require('haraka-notes');
|
|
17
17
|
const utils = require('haraka-utils');
|
|
18
|
-
const { Address }
|
|
18
|
+
const { Address } = require('address-rfc2821');
|
|
19
19
|
const ResultStore = require('haraka-results');
|
|
20
20
|
|
|
21
21
|
// Haraka libs
|
|
@@ -734,9 +734,16 @@ class Connection {
|
|
|
734
734
|
});
|
|
735
735
|
break;
|
|
736
736
|
default:
|
|
737
|
-
dns.reverse
|
|
738
|
-
|
|
739
|
-
|
|
737
|
+
// BUG: dns.reverse throws on invalid input (and sometimes valid
|
|
738
|
+
// input nodejs/node#47847). Also throws when empty results
|
|
739
|
+
try {
|
|
740
|
+
dns.reverse(this.remote.ip, (err, domains) => {
|
|
741
|
+
this.rdns_response(err, domains);
|
|
742
|
+
})
|
|
743
|
+
}
|
|
744
|
+
catch (err) {
|
|
745
|
+
this.rdns_response(err, []);
|
|
746
|
+
}
|
|
740
747
|
}
|
|
741
748
|
}
|
|
742
749
|
rdns_response (err, domains) {
|
|
@@ -1319,16 +1326,15 @@ class Connection {
|
|
|
1319
1326
|
this.errors++;
|
|
1320
1327
|
return this.respond(503, 'Use EHLO/HELO before MAIL');
|
|
1321
1328
|
}
|
|
1322
|
-
// Require authentication on
|
|
1329
|
+
// Require authentication on ports 587 & 465
|
|
1323
1330
|
if (!this.relaying && [587,465].includes(this.local.port)) {
|
|
1324
1331
|
this.errors++;
|
|
1325
1332
|
return this.respond(550, 'Authentication required');
|
|
1326
1333
|
}
|
|
1334
|
+
|
|
1327
1335
|
let results;
|
|
1328
|
-
let from;
|
|
1329
1336
|
try {
|
|
1330
1337
|
results = rfc1869.parse('mail', line, this.cfg.main.strict_rfc1869 && !this.relaying);
|
|
1331
|
-
from = new Address (results.shift());
|
|
1332
1338
|
}
|
|
1333
1339
|
catch (err) {
|
|
1334
1340
|
this.errors++;
|
|
@@ -1343,9 +1349,18 @@ class Connection {
|
|
|
1343
1349
|
return this.respond(452, 'Internal Server Error');
|
|
1344
1350
|
}
|
|
1345
1351
|
else {
|
|
1346
|
-
return this.respond(501, [
|
|
1352
|
+
return this.respond(501, ['Command parsing failed', err]);
|
|
1347
1353
|
}
|
|
1348
1354
|
}
|
|
1355
|
+
|
|
1356
|
+
let from;
|
|
1357
|
+
try {
|
|
1358
|
+
from = new Address(results.shift());
|
|
1359
|
+
}
|
|
1360
|
+
catch (err) {
|
|
1361
|
+
return this.respond(501, `Invalid MAIL FROM address`);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1349
1364
|
// Get rest of key=value pairs
|
|
1350
1365
|
const params = {};
|
|
1351
1366
|
results.forEach(param => {
|
|
@@ -1382,10 +1397,8 @@ class Connection {
|
|
|
1382
1397
|
}
|
|
1383
1398
|
|
|
1384
1399
|
let results;
|
|
1385
|
-
let recip;
|
|
1386
1400
|
try {
|
|
1387
1401
|
results = rfc1869.parse('rcpt', line, this.cfg.main.strict_rfc1869 && !this.relaying);
|
|
1388
|
-
recip = new Address(results.shift());
|
|
1389
1402
|
}
|
|
1390
1403
|
catch (err) {
|
|
1391
1404
|
this.errors++;
|
|
@@ -1403,6 +1416,15 @@ class Connection {
|
|
|
1403
1416
|
return this.respond(501, ["Command parsing failed", err]);
|
|
1404
1417
|
}
|
|
1405
1418
|
}
|
|
1419
|
+
|
|
1420
|
+
let recip;
|
|
1421
|
+
try {
|
|
1422
|
+
recip = new Address(results.shift());
|
|
1423
|
+
}
|
|
1424
|
+
catch (err) {
|
|
1425
|
+
return this.respond(501, `Invalid RCPT TO address`);
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1406
1428
|
// Get rest of key=value pairs
|
|
1407
1429
|
const params = {};
|
|
1408
1430
|
results.forEach((param) => {
|
package/dkim.js
CHANGED
|
@@ -302,7 +302,8 @@ class DKIMObject {
|
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
if (!res) return this.result('no key for signature', 'invalid');
|
|
305
|
-
for (const
|
|
305
|
+
for (const recordSegments of res) {
|
|
306
|
+
const record = recordSegments.join('');
|
|
306
307
|
if (!record.includes('p=')) {
|
|
307
308
|
this.debug(`${this.identity}: ignoring TXT record: ${record}`);
|
|
308
309
|
continue;
|
package/docs/plugins/clamd.md
CHANGED
|
@@ -133,7 +133,7 @@ meeting following criteria.
|
|
|
133
133
|
via regexp by enclosing the pattern in //.
|
|
134
134
|
|
|
135
135
|
To negate a match (e.g. reject if it matches), prefix the match with !.
|
|
136
|
-
Negative matches are always tested
|
|
136
|
+
Negative matches are always tested first.
|
|
137
137
|
|
|
138
138
|
Example:
|
|
139
139
|
|
|
@@ -1,27 +1,18 @@
|
|
|
1
|
-
queue/smtp\_forward
|
|
1
|
+
# queue/smtp\_forward
|
|
2
2
|
==================
|
|
3
3
|
|
|
4
|
-
This plugin delivers to another mail server. This is a common setup when you
|
|
5
|
-
want to have a mail server with a solid pedigree of outbound delivery to
|
|
6
|
-
other hosts, and inbound delivery to users.
|
|
4
|
+
This plugin delivers to another mail server. This is a common setup when you want to have a mail server with a solid pedigree of outbound delivery to other hosts, and inbound delivery to users.
|
|
7
5
|
|
|
8
|
-
In comparison to `queue/smtp_proxy`, this plugin waits until queue time to
|
|
9
|
-
attempt the ongoing connection. This can be a benefit in reducing connections
|
|
10
|
-
to your inbound mail server when you have content filtering (such as
|
|
11
|
-
spamassassin) enabled. A possible downside is that it also delays recipient
|
|
12
|
-
validation that the ongoing mail server may provide until queue time.
|
|
6
|
+
In comparison to `queue/smtp_proxy`, this plugin waits until queue time to attempt the ongoing connection. This can be a benefit in reducing connections to your inbound mail server when you have content filtering (such as spamassassin) enabled. A possible downside is that it also delays recipient validation that the ongoing mail server may provide until queue time.
|
|
13
7
|
|
|
14
|
-
Configuration
|
|
8
|
+
## Configuration
|
|
15
9
|
-------------
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Configuration is stored in this file in the following keys:
|
|
11
|
+
Configuration is stored in smtp\_forward.ini in the following keys:
|
|
20
12
|
|
|
21
13
|
* enable\_outbound=[true]
|
|
22
14
|
|
|
23
|
-
SMTP forward outbound messages (set to false to enable Haraka's separate
|
|
24
|
-
Outbound mail routing (MX based delivery)).
|
|
15
|
+
SMTP forward outbound messages (set to false to enable Haraka's separate Outbound mail routing (MX based delivery)).
|
|
25
16
|
|
|
26
17
|
* host=HOST
|
|
27
18
|
|
|
@@ -33,14 +24,11 @@ Configuration
|
|
|
33
24
|
|
|
34
25
|
* connect\_timeout=SECONDS
|
|
35
26
|
|
|
36
|
-
The maximum amount of time to wait when creating a new connection
|
|
37
|
-
to the host. Default: 30 seconds.
|
|
27
|
+
The maximum amount of time to wait when creating a new connection to the host. Default: 30 seconds.
|
|
38
28
|
|
|
39
29
|
* timeout=SECONDS
|
|
40
30
|
|
|
41
|
-
The amount of seconds to let a backend connection live idle in the
|
|
42
|
-
connection pool. This should always be less than the global plugin
|
|
43
|
-
timeout, which should in turn be less than the connection timeout.
|
|
31
|
+
The amount of seconds to let a backend connection live idle in the connection pool. This should always be less than the global plugin timeout, which should in turn be less than the connection timeout.
|
|
44
32
|
|
|
45
33
|
* max\_connections=NUMBER
|
|
46
34
|
|
|
@@ -48,12 +36,9 @@ Configuration
|
|
|
48
36
|
|
|
49
37
|
* enable\_tls=[true]
|
|
50
38
|
|
|
51
|
-
Enable TLS with the forward host (if supported). TLS uses options
|
|
52
|
-
from the tls plugin. If key and cert are provided in the the outbound section of the tls plugin,
|
|
53
|
-
that certificate will be used as a TLS Client Certificate.
|
|
39
|
+
Enable TLS with the forward host (if supported). TLS uses options from the tls plugin. If key and cert are provided in the the outbound section of the tls plugin, that certificate will be used as a TLS Client Certificate.
|
|
54
40
|
|
|
55
|
-
This option controls the use of TLS via `STARTTLS`. This plugin does not work with
|
|
56
|
-
SMTP over TLS.
|
|
41
|
+
This option controls the use of TLS via `STARTTLS`. This plugin does not work with SMTP over TLS.
|
|
57
42
|
|
|
58
43
|
* auth\_type=[plain\|login]
|
|
59
44
|
|
|
@@ -69,9 +54,7 @@ Configuration
|
|
|
69
54
|
|
|
70
55
|
* queue
|
|
71
56
|
|
|
72
|
-
Which queue plugin to use. Default: undefined. The default bahavior is to
|
|
73
|
-
use smtp_forward for inbound connections and outbound for relaying
|
|
74
|
-
connections. This option is used for complex mail routes.
|
|
57
|
+
Which queue plugin to use. Default: undefined. The default bahavior is to use smtp_forward for inbound connections and outbound for relaying connections. This option is used for complex mail routes.
|
|
75
58
|
|
|
76
59
|
* check_sender=false
|
|
77
60
|
|
|
@@ -86,18 +69,13 @@ Configuration
|
|
|
86
69
|
|
|
87
70
|
# Per-Domain Configuration
|
|
88
71
|
|
|
89
|
-
More specific forward routes for domains can be defined. The domain is
|
|
90
|
-
chosen based on the value of the `domain_selector` config variable.
|
|
72
|
+
More specific forward routes for domains can be defined. The domain is chosen based on the value of the `domain_selector` config variable.
|
|
91
73
|
|
|
92
|
-
When `domain_selector` is set to `rcpt_to` (the default), more specific
|
|
93
|
-
routes are only honored for SMTP connections with a single recipient or SMTP
|
|
94
|
-
connections where every recipient host is identical.
|
|
74
|
+
When `domain_selector` is set to `rcpt_to` (the default), more specific routes are only honored for SMTP connections with a single recipient or SMTP connections where every recipient host is identical.
|
|
95
75
|
|
|
96
|
-
When `domain_selector` is set to `mail_from`, the domain of the MAIL FROM
|
|
97
|
-
address is used.
|
|
76
|
+
When `domain_selector` is set to `mail_from`, the domain of the MAIL FROM address is used.
|
|
98
77
|
|
|
99
|
-
enable\_outbound can be set or unset on a per-domain level to enable or disable
|
|
100
|
-
forwarding for specific domains.
|
|
78
|
+
enable\_outbound can be set or unset on a per-domain level to enable or disable forwarding for specific domains.
|
|
101
79
|
|
|
102
80
|
# default SMTP host
|
|
103
81
|
host=1.2.3.4
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
queue/smtp\_proxy
|
|
1
|
+
# queue/smtp\_proxy
|
|
2
2
|
================
|
|
3
3
|
|
|
4
4
|
This plugin delivers to another mail server. This is a common setup when you
|
|
@@ -12,14 +12,12 @@ particular one important facility to some setups is recipient filtering.
|
|
|
12
12
|
However be aware that other than connect and HELO-time filtering, you will
|
|
13
13
|
have as many connections to your ongoing SMTP server as you have to Haraka.
|
|
14
14
|
|
|
15
|
-
Configuration
|
|
15
|
+
## Configuration
|
|
16
16
|
-------------
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Configuration is stored in this file in the following keys:
|
|
18
|
+
Configuration is stored in smtp\_proxy.ini in the following keys:
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
* enable\_outbound=[true]
|
|
23
21
|
|
|
24
22
|
SMTP proxy outbound messages (set to false to enable Haraka's
|
|
25
23
|
separate Outbound mail routing (MX based delivery)).
|
|
@@ -27,9 +25,9 @@ Configuration
|
|
|
27
25
|
* host=HOST
|
|
28
26
|
|
|
29
27
|
The host to connect to.
|
|
30
|
-
|
|
28
|
+
|
|
31
29
|
* port=PORT
|
|
32
|
-
|
|
30
|
+
|
|
33
31
|
The port to connect to.
|
|
34
32
|
|
|
35
33
|
* connect\_timeout=SECONDS
|
|
@@ -38,17 +36,17 @@ Configuration
|
|
|
38
36
|
to the host. Default if unspecified is 30 seconds.
|
|
39
37
|
|
|
40
38
|
* timeout=SECONDS
|
|
41
|
-
|
|
39
|
+
|
|
42
40
|
The amount of seconds to let a backend connection live idle in the
|
|
43
41
|
proxy pool. This should always be less than the global plugin timeout,
|
|
44
42
|
which should in turn be less than the connection timeout.
|
|
45
43
|
|
|
46
44
|
* max\_connections=NUMBER
|
|
47
|
-
|
|
45
|
+
|
|
48
46
|
Maximum number of connections to create at any given time.
|
|
49
47
|
|
|
50
48
|
* enable\_tls=[true|yes|1]
|
|
51
|
-
|
|
49
|
+
|
|
52
50
|
Enable TLS with the forward host (if supported). TLS uses options from
|
|
53
51
|
the tls plugin.
|
|
54
52
|
|
package/outbound/tls.js
CHANGED
|
@@ -95,7 +95,7 @@ class OutboundTLS {
|
|
|
95
95
|
|
|
96
96
|
logger.lognotice(this, `TLS connection failed. Marking ${host} as non-TLS for ${expiry} seconds`);
|
|
97
97
|
|
|
98
|
-
this.db.
|
|
98
|
+
this.db.setEx(dbkey, expiry, (new Date()).toISOString())
|
|
99
99
|
.then(cb)
|
|
100
100
|
.catch(err => {
|
|
101
101
|
logger.logerror(this, `Redis returned error: ${err}`);
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"server",
|
|
10
10
|
"email"
|
|
11
11
|
],
|
|
12
|
-
"version": "3.0.
|
|
12
|
+
"version": "3.0.2",
|
|
13
13
|
"homepage": "http://haraka.github.io",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -20,65 +20,65 @@
|
|
|
20
20
|
"node": ">=16"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"address-rfc2821"
|
|
24
|
-
"address-rfc2822"
|
|
25
|
-
"async"
|
|
26
|
-
"daemon"
|
|
27
|
-
"ipaddr.js"
|
|
28
|
-
"node-gyp"
|
|
29
|
-
"nopt"
|
|
30
|
-
"npid"
|
|
31
|
-
"semver"
|
|
32
|
-
"sprintf-js"
|
|
33
|
-
"haraka-config"
|
|
34
|
-
"haraka-constants"
|
|
35
|
-
"haraka-dsn"
|
|
36
|
-
"haraka-email-message"
|
|
37
|
-
"haraka-message-stream"
|
|
38
|
-
"haraka-net-utils"
|
|
39
|
-
"haraka-notes"
|
|
23
|
+
"address-rfc2821": "^2.0.1",
|
|
24
|
+
"address-rfc2822": "^2.1.0",
|
|
25
|
+
"async": "^3.2.4",
|
|
26
|
+
"daemon": "~1.1.0",
|
|
27
|
+
"ipaddr.js": "~2.1.0",
|
|
28
|
+
"node-gyp": "^9.4.0",
|
|
29
|
+
"nopt": "~7.2.0",
|
|
30
|
+
"npid": "~0.4.0",
|
|
31
|
+
"semver": "~7.5.2",
|
|
32
|
+
"sprintf-js": "~1.1.2",
|
|
33
|
+
"haraka-config": "^1.1.0",
|
|
34
|
+
"haraka-constants": "^1.0.6",
|
|
35
|
+
"haraka-dsn": "^1.0.4",
|
|
36
|
+
"haraka-email-message": "^1.2.0",
|
|
37
|
+
"haraka-message-stream": "^1.2.0",
|
|
38
|
+
"haraka-net-utils": "^1.5.0",
|
|
39
|
+
"haraka-notes": "^1.0.6",
|
|
40
40
|
"haraka-plugin-attachment": "^1.0.7",
|
|
41
|
-
"haraka-plugin-spf"
|
|
42
|
-
"haraka-plugin-redis"
|
|
43
|
-
"haraka-results"
|
|
44
|
-
"haraka-tld"
|
|
45
|
-
"haraka-utils"
|
|
46
|
-
"openssl-wrapper"
|
|
47
|
-
"sockaddr"
|
|
41
|
+
"haraka-plugin-spf": "1.2.0",
|
|
42
|
+
"haraka-plugin-redis": "^2.0.5",
|
|
43
|
+
"haraka-results": "^2.2.3",
|
|
44
|
+
"haraka-tld": "^1.1.1",
|
|
45
|
+
"haraka-utils": "^1.0.3",
|
|
46
|
+
"openssl-wrapper": "^0.3.4",
|
|
47
|
+
"sockaddr": "^1.0.1"
|
|
48
48
|
},
|
|
49
49
|
"optionalDependencies": {
|
|
50
|
-
"haraka-plugin-access"
|
|
51
|
-
"haraka-plugin-aliases"
|
|
52
|
-
"haraka-plugin-asn"
|
|
50
|
+
"haraka-plugin-access": "^1.1.5",
|
|
51
|
+
"haraka-plugin-aliases": "^1.0.1",
|
|
52
|
+
"haraka-plugin-asn": "^2.0.1",
|
|
53
53
|
"haraka-plugin-auth-ldap": "^1.0.2",
|
|
54
|
-
"haraka-plugin-dcc"
|
|
55
|
-
"haraka-plugin-elasticsearch"
|
|
56
|
-
"haraka-plugin-fcrdns"
|
|
57
|
-
"haraka-plugin-graph"
|
|
58
|
-
"haraka-plugin-geoip"
|
|
59
|
-
"haraka-plugin-headers"
|
|
60
|
-
"haraka-plugin-karma"
|
|
61
|
-
"haraka-plugin-limit"
|
|
62
|
-
"haraka-plugin-p0f"
|
|
63
|
-
"haraka-plugin-qmail-deliverable"
|
|
54
|
+
"haraka-plugin-dcc": "^1.0.1",
|
|
55
|
+
"haraka-plugin-elasticsearch": "^1.0.6",
|
|
56
|
+
"haraka-plugin-fcrdns": "^1.1.0",
|
|
57
|
+
"haraka-plugin-graph": "^1.0.5",
|
|
58
|
+
"haraka-plugin-geoip": "^1.0.17",
|
|
59
|
+
"haraka-plugin-headers": "^1.0.3",
|
|
60
|
+
"haraka-plugin-karma": "^2.1.0",
|
|
61
|
+
"haraka-plugin-limit": "^1.1.0",
|
|
62
|
+
"haraka-plugin-p0f": "^1.0.9",
|
|
63
|
+
"haraka-plugin-qmail-deliverable": "^1.2.1",
|
|
64
64
|
"haraka-plugin-known-senders": "^1.0.8",
|
|
65
65
|
"haraka-plugin-rcpt-ldap": "^1.0.0",
|
|
66
|
-
"haraka-plugin-recipient-routes"
|
|
67
|
-
"haraka-plugin-rspamd"
|
|
68
|
-
"haraka-plugin-syslog"
|
|
69
|
-
"haraka-plugin-uribl"
|
|
70
|
-
"haraka-plugin-watch"
|
|
71
|
-
"ocsp"
|
|
72
|
-
"redis"
|
|
73
|
-
"tmp"
|
|
66
|
+
"haraka-plugin-recipient-routes": "^1.0.4",
|
|
67
|
+
"haraka-plugin-rspamd": "^1.2.0",
|
|
68
|
+
"haraka-plugin-syslog": "^1.0.3",
|
|
69
|
+
"haraka-plugin-uribl": "^1.0.6",
|
|
70
|
+
"haraka-plugin-watch": "^2.0.2",
|
|
71
|
+
"ocsp": "~1.2.0",
|
|
72
|
+
"redis": "^4.5.1",
|
|
73
|
+
"tmp": "~0.2.1"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"nodeunit-x"
|
|
77
|
-
"haraka-test-fixtures"
|
|
78
|
-
"mock-require"
|
|
79
|
-
"eslint"
|
|
80
|
-
"eslint-plugin-haraka"
|
|
81
|
-
"nodemailer"
|
|
76
|
+
"nodeunit-x": "^0.16.0",
|
|
77
|
+
"haraka-test-fixtures": "^1.3.0",
|
|
78
|
+
"mock-require": "^3.0.3",
|
|
79
|
+
"eslint": "^8.42.0",
|
|
80
|
+
"eslint-plugin-haraka": "^1.0.15",
|
|
81
|
+
"nodemailer": "^6.9.3"
|
|
82
82
|
},
|
|
83
83
|
"bugs": {
|
|
84
84
|
"mail": "haraka.mail@gmail.com",
|
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)`});
|