Haraka 3.2.1 → 3.3.1
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/.githooks/pre-commit +41 -0
- package/.prettierignore +1 -0
- package/.qlty/.gitignore +7 -0
- package/.qlty/configs/.shellcheckrc +1 -0
- package/.qlty/qlty.toml +15 -0
- package/CHANGELOG.md +29 -5
- package/CONTRIBUTORS.md +5 -5
- package/README.md +6 -3
- package/bin/haraka +12 -4
- package/config/connection.ini +6 -0
- package/connection.js +67 -68
- package/contrib/bsd-rc.d/haraka +2 -0
- package/docs/CoreConfig.md +2 -0
- package/docs/HAProxy.md +4 -1
- package/eslint.config.mjs +2 -30
- package/haraka.js +2 -2
- package/line_socket.js +6 -33
- package/outbound/hmail.js +18 -29
- package/outbound/index.js +3 -3
- package/outbound/queue.js +8 -5
- package/package.json +49 -46
- package/plugins/auth/auth_proxy.js +7 -4
- package/plugins/block_me.js +1 -1
- package/plugins/delay_deny.js +1 -1
- package/plugins/queue/qmail-queue.js +1 -1
- package/plugins/queue/quarantine.js +5 -5
- package/plugins/queue/smtp_bridge.js +1 -1
- package/plugins/queue/smtp_proxy.js +2 -2
- package/plugins/status.js +2 -2
- package/plugins/toobusy.js +1 -1
- package/plugins.js +4 -3
- package/server.js +172 -28
- package/smtp_client.js +2 -1
- package/test/connection.js +119 -2
- package/test/fixtures/haproxy_allowed/config/connection.ini +3 -0
- package/test/fixtures/haproxy_disabled/config/connection.ini +3 -0
- package/test/fixtures/haproxy_untrusted/config/connection.ini +3 -0
- package/test/fixtures/line_socket.js +1 -1
- package/test/fixtures/util_hmailitem.js +2 -3
- package/test/outbound/index.js +6 -7
- package/test/outbound/qfile.js +1 -1
- package/test/outbound/queue.js +2 -2
- package/test/plugins/auth/auth_base.js +17 -17
- package/test/plugins/auth/auth_bridge.js +3 -3
- package/test/plugins/auth/auth_vpopmaild.js +3 -3
- package/test/plugins/auth/flat_file.js +16 -21
- package/test/plugins/block_me.js +7 -23
- package/test/plugins/data.signatures.js +17 -20
- package/test/plugins/delay_deny.js +3 -4
- package/test/plugins/prevent_credential_leaks.js +17 -21
- package/test/plugins/process_title.js +12 -6
- package/test/plugins/queue/deliver.js +7 -8
- package/test/plugins/queue/discard.js +3 -4
- package/test/plugins/queue/lmtp.js +5 -6
- package/test/plugins/queue/qmail-queue.js +7 -8
- package/test/plugins/queue/quarantine.js +3 -4
- package/test/plugins/queue/smtp_bridge.js +5 -7
- package/test/plugins/queue/smtp_forward.js +49 -60
- package/test/plugins/queue/smtp_proxy.js +6 -7
- package/test/plugins/rcpt_to.host_list_base.js +6 -9
- package/test/plugins/rcpt_to.in_host_list.js +6 -11
- package/test/plugins/record_envelope_addresses.js +33 -60
- package/test/plugins/reseed_rng.js +3 -3
- package/test/plugins/status.js +4 -5
- package/test/plugins/tarpit.js +3 -4
- package/test/plugins/tls.js +3 -5
- package/test/plugins/toobusy.js +186 -9
- package/test/plugins/xclient.js +7 -4
- package/test/server.js +425 -1
- package/test/smtp_client.js +11 -18
- package/test/tls_socket.js +3 -6
- package/tls_socket.js +3 -3
- package/transaction.js +3 -3
- package/address.js +0 -53
- package/endpoint.js +0 -96
- package/host_pool.js +0 -169
- package/outbound/fsync_writestream.js +0 -44
- package/outbound/timer_queue.js +0 -86
- package/rfc1869.js +0 -93
- package/test/endpoint.js +0 -128
- package/test/host_pool.js +0 -188
- package/test/rfc1869.js +0 -89
package/eslint.config.mjs
CHANGED
|
@@ -1,30 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { fileURLToPath } from 'node:url'
|
|
4
|
-
import js from '@eslint/js'
|
|
5
|
-
import { FlatCompat } from '@eslint/eslintrc'
|
|
6
|
-
|
|
7
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
8
|
-
const __dirname = path.dirname(__filename)
|
|
9
|
-
const compat = new FlatCompat({
|
|
10
|
-
baseDirectory: __dirname,
|
|
11
|
-
recommendedConfig: js.configs.recommended,
|
|
12
|
-
allConfig: js.configs.all,
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
export default [
|
|
16
|
-
...compat.extends('@haraka'),
|
|
17
|
-
{
|
|
18
|
-
languageOptions: {
|
|
19
|
-
globals: {
|
|
20
|
-
...globals.node,
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
rules: {
|
|
25
|
-
'prefer-template': 'warn',
|
|
26
|
-
'no-unneeded-ternary': 1,
|
|
27
|
-
'no-unused-vars': 0,
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
]
|
|
1
|
+
import haraka from '@haraka/eslint-config'
|
|
2
|
+
export default [...haraka]
|
package/haraka.js
CHANGED
|
@@ -12,7 +12,7 @@ if (!process.env.HARAKA) {
|
|
|
12
12
|
process.env.HARAKA = process.env.HARAKA || path.resolve('.')
|
|
13
13
|
try {
|
|
14
14
|
require.paths.push(makePathJoin())
|
|
15
|
-
} catch
|
|
15
|
+
} catch {
|
|
16
16
|
process.env.NODE_PATH = process.env.NODE_PATH ? `${process.env.NODE_PATH}:${makePathJoin()}` : makePathJoin()
|
|
17
17
|
require('module')._initPaths() // Horrible hack
|
|
18
18
|
}
|
|
@@ -60,7 +60,7 @@ process.on('SIGHUP', () => {
|
|
|
60
60
|
server.flushQueue()
|
|
61
61
|
})
|
|
62
62
|
|
|
63
|
-
process.on('exit', (
|
|
63
|
+
process.on('exit', () => {
|
|
64
64
|
if (shutting_down) return
|
|
65
65
|
const [, filename] = process.argv
|
|
66
66
|
process.title = path.basename(filename, '.js')
|
package/line_socket.js
CHANGED
|
@@ -1,40 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
//
|
|
2
|
+
// Back-compat shim. The Socket class lives in haraka-net-utils as LineSocket;
|
|
3
|
+
// the line-processing helper is `add_line_processor` there. The connect()
|
|
4
|
+
// helper stays here because it depends on Haraka's tls_socket.
|
|
3
5
|
|
|
4
|
-
const
|
|
5
|
-
const utils = require('haraka-utils')
|
|
6
|
+
const { LineSocket, add_line_processor } = require('haraka-net-utils')
|
|
6
7
|
|
|
7
8
|
const tls_socket = require('./tls_socket')
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
constructor(options) {
|
|
11
|
-
super(options)
|
|
12
|
-
setup_line_processor(this)
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function setup_line_processor(socket) {
|
|
17
|
-
let current_data = ''
|
|
18
|
-
|
|
19
|
-
socket.on('data', function on_socket_data(data) {
|
|
20
|
-
current_data += data
|
|
21
|
-
let results
|
|
22
|
-
while ((results = utils.line_regexp.exec(current_data))) {
|
|
23
|
-
const this_line = results[1]
|
|
24
|
-
current_data = current_data.slice(this_line.length)
|
|
25
|
-
socket.emit('line', this_line)
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
socket.on('end', function on_socket_end() {
|
|
30
|
-
if (current_data.length) {
|
|
31
|
-
socket.emit('line', current_data)
|
|
32
|
-
}
|
|
33
|
-
current_data = ''
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
exports.Socket = Socket
|
|
10
|
+
exports.Socket = LineSocket
|
|
38
11
|
|
|
39
12
|
// New interface - uses TLS
|
|
40
13
|
exports.connect = (port, host) => {
|
|
@@ -46,6 +19,6 @@ exports.connect = (port, host) => {
|
|
|
46
19
|
options.host = host
|
|
47
20
|
}
|
|
48
21
|
const sock = tls_socket.connect(options)
|
|
49
|
-
|
|
22
|
+
add_line_processor(sock)
|
|
50
23
|
return sock
|
|
51
24
|
}
|
package/outbound/hmail.js
CHANGED
|
@@ -7,7 +7,7 @@ const dns = require('node:dns')
|
|
|
7
7
|
const net = require('node:net')
|
|
8
8
|
const path = require('node:path')
|
|
9
9
|
|
|
10
|
-
const { Address } = require('
|
|
10
|
+
const { Address } = require('@haraka/email-address')
|
|
11
11
|
const config = require('haraka-config')
|
|
12
12
|
const constants = require('haraka-constants')
|
|
13
13
|
const DSN = require('haraka-dsn')
|
|
@@ -24,7 +24,7 @@ const _qfile = require('./qfile')
|
|
|
24
24
|
const outbound = require('./index')
|
|
25
25
|
const obtls = require('./tls')
|
|
26
26
|
|
|
27
|
-
const FsyncWriteStream =
|
|
27
|
+
const FsyncWriteStream = utils.FsyncWriteStream
|
|
28
28
|
|
|
29
29
|
let queue_dir
|
|
30
30
|
let temp_fail_queue
|
|
@@ -713,7 +713,7 @@ class HMailItem extends events.EventEmitter {
|
|
|
713
713
|
break
|
|
714
714
|
case 'CRAM-MD5':
|
|
715
715
|
// The response is our challenge
|
|
716
|
-
return send_command(cram_md5_response(mx.auth_user, mx.auth_pass, resp))
|
|
716
|
+
return send_command(utils.cram_md5_response(mx.auth_user, mx.auth_pass, resp))
|
|
717
717
|
default:
|
|
718
718
|
// This shouldn't happen...
|
|
719
719
|
}
|
|
@@ -975,7 +975,7 @@ class HMailItem extends events.EventEmitter {
|
|
|
975
975
|
data_stream.on('error', (err) => {
|
|
976
976
|
cb(err)
|
|
977
977
|
})
|
|
978
|
-
} catch
|
|
978
|
+
} catch {
|
|
979
979
|
this.populate_bounce_message_with_headers(from, to, reason, header, cb)
|
|
980
980
|
}
|
|
981
981
|
}
|
|
@@ -1247,7 +1247,7 @@ class HMailItem extends events.EventEmitter {
|
|
|
1247
1247
|
plugins.run_hooks('bounce', this, err)
|
|
1248
1248
|
}
|
|
1249
1249
|
|
|
1250
|
-
bounce_respond(retval
|
|
1250
|
+
bounce_respond(retval) {
|
|
1251
1251
|
if (retval !== constants.cont) {
|
|
1252
1252
|
this.loginfo(`Plugin responded with: ${retval}. Not sending bounce.`)
|
|
1253
1253
|
return this.discard() // calls next_cb
|
|
@@ -1272,7 +1272,7 @@ class HMailItem extends events.EventEmitter {
|
|
|
1272
1272
|
from,
|
|
1273
1273
|
recip,
|
|
1274
1274
|
data_lines.join(''),
|
|
1275
|
-
(code
|
|
1275
|
+
(code) => {
|
|
1276
1276
|
if (code === constants.deny) {
|
|
1277
1277
|
// failed to even queue the mail
|
|
1278
1278
|
return self.double_bounce('Unable to queue the bounce message. Not sending bounce!')
|
|
@@ -1466,20 +1466,18 @@ class HMailItem extends events.EventEmitter {
|
|
|
1466
1466
|
rs.on('error', (err) => {
|
|
1467
1467
|
err_handler(err, 'hmail.data_stream reader')
|
|
1468
1468
|
})
|
|
1469
|
-
rs.on('end', () => {
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
})
|
|
1482
|
-
ws.destroySoon()
|
|
1469
|
+
rs.on('end', async () => {
|
|
1470
|
+
try {
|
|
1471
|
+
await ws.close()
|
|
1472
|
+
const dest_path = path.join(queue_dir, fname)
|
|
1473
|
+
await fs.rename(tmp_path, dest_path)
|
|
1474
|
+
const split_mail = new HMailItem(fname, dest_path, hmail.notes)
|
|
1475
|
+
split_mail.once('ready', () => {
|
|
1476
|
+
cb(split_mail)
|
|
1477
|
+
})
|
|
1478
|
+
} catch (err) {
|
|
1479
|
+
err_handler(err, 'tmp file close/rename')
|
|
1480
|
+
}
|
|
1483
1481
|
})
|
|
1484
1482
|
}
|
|
1485
1483
|
|
|
@@ -1504,12 +1502,3 @@ module.exports.obtls = obtls
|
|
|
1504
1502
|
logger.add_log_methods(HMailItem)
|
|
1505
1503
|
|
|
1506
1504
|
const smtp_regexp = /^([2345]\d\d)([ -])#?(?:(\d\.\d\.\d)\s)?(.*)/
|
|
1507
|
-
|
|
1508
|
-
function cram_md5_response(username, password, challenge) {
|
|
1509
|
-
const crypto = require('crypto')
|
|
1510
|
-
const c = utils.unbase64(challenge)
|
|
1511
|
-
const hmac = crypto.createHmac('md5', password)
|
|
1512
|
-
hmac.update(c)
|
|
1513
|
-
const digest = hmac.digest('hex')
|
|
1514
|
-
return utils.base64(`${username} ${digest}`)
|
|
1515
|
-
}
|
package/outbound/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const fs = require('node:fs/promises')
|
|
4
4
|
const path = require('node:path')
|
|
5
5
|
|
|
6
|
-
const { Address } = require('
|
|
6
|
+
const { Address } = require('@haraka/email-address')
|
|
7
7
|
const config = require('haraka-config')
|
|
8
8
|
const constants = require('haraka-constants')
|
|
9
9
|
const net_utils = require('haraka-net-utils')
|
|
@@ -13,7 +13,7 @@ const ResultStore = require('haraka-results')
|
|
|
13
13
|
const logger = require('../logger')
|
|
14
14
|
const trans = require('../transaction')
|
|
15
15
|
const plugins = require('../plugins')
|
|
16
|
-
const FsyncWriteStream =
|
|
16
|
+
const FsyncWriteStream = utils.FsyncWriteStream
|
|
17
17
|
|
|
18
18
|
const obc = require('./config')
|
|
19
19
|
const queuelib = require('./queue')
|
|
@@ -241,7 +241,7 @@ exports.send_trans_email = function (transaction, next) {
|
|
|
241
241
|
transaction.results = new ResultStore(connection)
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
connection.pre_send_trans_email_respond = async (
|
|
244
|
+
connection.pre_send_trans_email_respond = async () => {
|
|
245
245
|
const deliveries = get_deliveries(transaction)
|
|
246
246
|
const hmails = []
|
|
247
247
|
const ok_paths = []
|
package/outbound/queue.js
CHANGED
|
@@ -4,11 +4,12 @@ const child_process = require('node:child_process')
|
|
|
4
4
|
const fs = require('node:fs/promises')
|
|
5
5
|
const path = require('node:path')
|
|
6
6
|
|
|
7
|
-
const { Address } = require('
|
|
7
|
+
const { Address } = require('@haraka/email-address')
|
|
8
8
|
const config = require('haraka-config')
|
|
9
|
+
const utils = require('haraka-utils')
|
|
9
10
|
|
|
10
11
|
const logger = require('../logger')
|
|
11
|
-
const TimerQueue =
|
|
12
|
+
const TimerQueue = utils.TimerQueue
|
|
12
13
|
const HMailItem = require('./hmail')
|
|
13
14
|
const obc = require('./config')
|
|
14
15
|
const _qfile = require('./qfile')
|
|
@@ -101,7 +102,7 @@ const delivery_queue = (exports.delivery_queue = new Queue(async (hmail) => {
|
|
|
101
102
|
})
|
|
102
103
|
}))
|
|
103
104
|
|
|
104
|
-
const temp_fail_queue = (exports.temp_fail_queue = new TimerQueue())
|
|
105
|
+
const temp_fail_queue = (exports.temp_fail_queue = new TimerQueue(1000, { logger }))
|
|
105
106
|
|
|
106
107
|
let queue_count = 0
|
|
107
108
|
|
|
@@ -111,7 +112,7 @@ exports.list_queue = async () => {
|
|
|
111
112
|
return exports._load_cur_queue(null, exports._list_file)
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
exports._stat_file = async (
|
|
115
|
+
exports._stat_file = async () => {
|
|
115
116
|
queue_count++
|
|
116
117
|
}
|
|
117
118
|
|
|
@@ -180,7 +181,9 @@ exports.rename_to_actual_pid = async (file, parts) => {
|
|
|
180
181
|
await fs.rename(path.join(exports.queue_dir, file), path.join(exports.queue_dir, new_filename))
|
|
181
182
|
return new_filename
|
|
182
183
|
} catch (err) {
|
|
183
|
-
throw new Error(`Unable to rename queue file: ${file} to ${new_filename}
|
|
184
|
+
throw new Error(`Unable to rename queue file: ${file} to ${new_filename}`, {
|
|
185
|
+
cause: err,
|
|
186
|
+
})
|
|
184
187
|
}
|
|
185
188
|
}
|
|
186
189
|
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"author": "Matt Sergeant <helpme@gmail.com>
|
|
2
|
+
"author": "Matt Sergeant <helpme@gmail.com>",
|
|
3
3
|
"name": "Haraka",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "An SMTP Server project.",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"server",
|
|
10
10
|
"email"
|
|
11
11
|
],
|
|
12
|
-
"version": "3.
|
|
12
|
+
"version": "3.3.1",
|
|
13
13
|
"homepage": "http://haraka.github.io",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -20,77 +20,80 @@
|
|
|
20
20
|
"node": ">=20"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@haraka/email-address": "~3.1.
|
|
24
|
-
"haraka-config": "~1.6.
|
|
25
|
-
"haraka-constants": "~1.0.
|
|
23
|
+
"@haraka/email-address": "~3.1.6",
|
|
24
|
+
"haraka-config": "~1.6.3",
|
|
25
|
+
"haraka-constants": "~1.0.8",
|
|
26
26
|
"haraka-dsn": "~1.2.0",
|
|
27
|
-
"haraka-email-message": "~1.
|
|
28
|
-
"haraka-net-utils": "~1.
|
|
27
|
+
"haraka-email-message": "~1.4.0",
|
|
28
|
+
"haraka-net-utils": "~1.9.2",
|
|
29
29
|
"haraka-notes": "~1.1.3",
|
|
30
|
-
"haraka-plugin-redis": "~2.0
|
|
31
|
-
"haraka-results": "~2.
|
|
32
|
-
"haraka-tld": "~1.3.
|
|
33
|
-
"haraka-utils": "~
|
|
30
|
+
"haraka-plugin-redis": "~2.1.0",
|
|
31
|
+
"haraka-results": "~2.4.0",
|
|
32
|
+
"haraka-tld": "~1.3.6",
|
|
33
|
+
"haraka-utils": "~2.2.1",
|
|
34
34
|
"ipaddr.js": "~2.4.0",
|
|
35
|
-
"node-gyp": "~12.
|
|
36
|
-
"nopt": "~10.0.
|
|
37
|
-
"redis": "~
|
|
38
|
-
"semver": "~7.8.
|
|
35
|
+
"node-gyp": "~12.4.0",
|
|
36
|
+
"nopt": "~10.0.1",
|
|
37
|
+
"redis": "~6.0.0",
|
|
38
|
+
"semver": "~7.8.4"
|
|
39
39
|
},
|
|
40
40
|
"optionalDependencies": {
|
|
41
41
|
"@haraka/ocsp": "~1.2.0",
|
|
42
|
-
"haraka-plugin-access": "~1.
|
|
43
|
-
"haraka-plugin-aliases": "~1.0
|
|
44
|
-
"haraka-plugin-asn": "~2.
|
|
45
|
-
"haraka-plugin-attachment": "~1.2.
|
|
46
|
-
"haraka-plugin-bounce": "~2.1
|
|
47
|
-
"haraka-plugin-clamd": "~1.0.
|
|
42
|
+
"haraka-plugin-access": "~1.4.0",
|
|
43
|
+
"haraka-plugin-aliases": "~1.1.0",
|
|
44
|
+
"haraka-plugin-asn": "~2.2.0",
|
|
45
|
+
"haraka-plugin-attachment": "~1.2.1",
|
|
46
|
+
"haraka-plugin-bounce": "~2.2.1",
|
|
47
|
+
"haraka-plugin-clamd": "~1.0.3",
|
|
48
48
|
"haraka-plugin-dcc": "~1.0.3",
|
|
49
49
|
"haraka-plugin-dkim": "~1.2.0",
|
|
50
|
-
"haraka-plugin-dns-list": "~1.
|
|
50
|
+
"haraka-plugin-dns-list": "~1.3.0",
|
|
51
51
|
"haraka-plugin-early_talker": "~1.0.2",
|
|
52
|
-
"haraka-plugin-fcrdns": "~1.1
|
|
52
|
+
"haraka-plugin-fcrdns": "~1.2.1",
|
|
53
53
|
"haraka-plugin-geoip": "~1.1.2",
|
|
54
|
-
"haraka-plugin-greylist": "~1.
|
|
55
|
-
"haraka-plugin-headers": "~1.
|
|
56
|
-
"haraka-plugin-helo.checks": "~1.1.
|
|
57
|
-
"haraka-plugin-karma": "~2.
|
|
58
|
-
"haraka-plugin-known-senders": "~1.
|
|
59
|
-
"haraka-plugin-limit": "~1.2
|
|
60
|
-
"haraka-plugin-mail_from.is_resolvable": "~1.
|
|
61
|
-
"haraka-plugin-messagesniffer": "~1.0.
|
|
62
|
-
"haraka-plugin-qmail-deliverable": "~1.
|
|
54
|
+
"haraka-plugin-greylist": "~1.2.1",
|
|
55
|
+
"haraka-plugin-headers": "~1.2.0",
|
|
56
|
+
"haraka-plugin-helo.checks": "~1.1.3",
|
|
57
|
+
"haraka-plugin-karma": "~2.5.2",
|
|
58
|
+
"haraka-plugin-known-senders": "~1.2.0",
|
|
59
|
+
"haraka-plugin-limit": "~1.3.2",
|
|
60
|
+
"haraka-plugin-mail_from.is_resolvable": "~1.3.0",
|
|
61
|
+
"haraka-plugin-messagesniffer": "~1.0.2",
|
|
62
|
+
"haraka-plugin-qmail-deliverable": "~1.4.0",
|
|
63
63
|
"haraka-plugin-relay": "~1.0.2",
|
|
64
64
|
"haraka-plugin-rspamd": "~1.6.0",
|
|
65
|
-
"haraka-plugin-spamassassin": "~1.0
|
|
66
|
-
"haraka-plugin-spf": "~1.
|
|
67
|
-
"haraka-plugin-syslog": "~1.1.
|
|
68
|
-
"haraka-plugin-uribl": "~
|
|
65
|
+
"haraka-plugin-spamassassin": "~1.1.0",
|
|
66
|
+
"haraka-plugin-spf": "~1.3.0",
|
|
67
|
+
"haraka-plugin-syslog": "~1.1.2",
|
|
68
|
+
"haraka-plugin-uribl": "~2.0.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@haraka/eslint-config": "~
|
|
72
|
-
"haraka-test-fixtures": "
|
|
73
|
-
"mock-require": "~3.0.3"
|
|
71
|
+
"@haraka/eslint-config": "~3.0.0",
|
|
72
|
+
"haraka-test-fixtures": "^1.7.1",
|
|
73
|
+
"mock-require": "~3.0.3",
|
|
74
|
+
"toobusy-js": "^0.5.1"
|
|
74
75
|
},
|
|
75
76
|
"bugs": {
|
|
76
77
|
"mail": "haraka.mail@gmail.com",
|
|
77
78
|
"url": "https://github.com/haraka/Haraka/issues"
|
|
78
79
|
},
|
|
79
80
|
"bin": {
|
|
80
|
-
"haraka": "
|
|
81
|
-
"haraka_grep": "
|
|
81
|
+
"haraka": "bin/haraka",
|
|
82
|
+
"haraka_grep": "bin/haraka_grep"
|
|
82
83
|
},
|
|
83
84
|
"scripts": {
|
|
85
|
+
"prepare": "git rev-parse --git-dir >/dev/null 2>&1 && git config core.hooksPath .githooks || true",
|
|
84
86
|
"format": "npm run prettier:fix && npm run lint:fix",
|
|
85
|
-
"lint": "npx eslint *.js outbound plugins plugins/*/*.js test test/*/*.js test/*/*/*.js
|
|
86
|
-
"lint:fix": "npx eslint --fix *.js outbound plugins plugins/*/*.js test test/*/*.js test/*/*/*.js
|
|
87
|
+
"lint": "npx eslint *.js outbound plugins plugins/*/*.js test test/*/*.js test/*/*/*.js",
|
|
88
|
+
"lint:fix": "npx eslint --fix *.js outbound plugins plugins/*/*.js test test/*/*.js test/*/*/*.js",
|
|
87
89
|
"prettier": "npx prettier . --check",
|
|
88
90
|
"prettier:fix": "npx prettier . --write --log-level=warn",
|
|
91
|
+
"qlty": "qlty smells --all",
|
|
89
92
|
"test": "sh ./run_tests",
|
|
93
|
+
"test:coverage": "node --test --test-concurrency=1 --experimental-test-coverage --test-coverage-include=*.js --test-coverage-include=plugins/**/*.js --test-coverage-include=outbound/*.js",
|
|
94
|
+
"test:coverage:lcov": "mkdir -p coverage && node --test --test-concurrency=1 --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=coverage/lcov.info --test-coverage-include=*.js --test-coverage-include=plugins/**/*.js --test-coverage-include=outbound/*.js",
|
|
90
95
|
"versions": "npx npm-dep-mgr check",
|
|
91
|
-
"versions:fix": "npx npm-dep-mgr update"
|
|
92
|
-
"test:coverage": "node --test --test-concurrency=1 --experimental-test-coverage",
|
|
93
|
-
"test:coverage:lcov": "mkdir -p coverage && node --test --test-concurrency=1 --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=coverage/lcov.info"
|
|
96
|
+
"versions:fix": "npx npm-dep-mgr update"
|
|
94
97
|
},
|
|
95
98
|
"prettier": {
|
|
96
99
|
"singleQuote": true,
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
// Proxy AUTH requests selectively by domain
|
|
2
2
|
|
|
3
|
-
const net = require('node:net')
|
|
4
|
-
|
|
5
3
|
const utils = require('haraka-utils')
|
|
6
4
|
const net_utils = require('haraka-net-utils')
|
|
7
5
|
|
|
@@ -56,8 +54,12 @@ exports.try_auth_proxy = function (connection, hosts, user, passwd, cb) {
|
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
const self = this
|
|
59
|
-
|
|
60
|
-
if (
|
|
57
|
+
const ep = net_utils.endpoint(hosts.shift(), 25)
|
|
58
|
+
if (ep instanceof Error) {
|
|
59
|
+
connection.logerror(this, `invalid host: ${ep.message}`)
|
|
60
|
+
return this.try_auth_proxy(connection, hosts, user, passwd, cb)
|
|
61
|
+
}
|
|
62
|
+
const { host, port } = ep
|
|
61
63
|
let methods = []
|
|
62
64
|
let auth_complete = false
|
|
63
65
|
let auth_success = false
|
|
@@ -134,6 +136,7 @@ exports.try_auth_proxy = function (connection, hosts, user, passwd, cb) {
|
|
|
134
136
|
// certificate to negotiate TLS, so always STARTTLS when
|
|
135
137
|
// the backend offers it. The local key/cert are only
|
|
136
138
|
// attached if configured (mutual TLS), not required.
|
|
139
|
+
/* eslint no-useless-assignment: 0 */
|
|
137
140
|
key = self.config.get(self.tls_cfg.main.key || 'tls_key.pem', 'binary')
|
|
138
141
|
cert = self.config.get(self.tls_cfg.main.cert || 'tls_cert.pem', 'binary')
|
|
139
142
|
this.on('secure', () => {
|
package/plugins/block_me.js
CHANGED
|
@@ -53,7 +53,7 @@ exports.hook_data_post = function (next, connection) {
|
|
|
53
53
|
connection.logerror(this, `Unable to append to mail_from.blocklist: ${err}`)
|
|
54
54
|
return
|
|
55
55
|
}
|
|
56
|
-
fs.write(fd, `${to_block}\n`, null, 'UTF-8', (
|
|
56
|
+
fs.write(fd, `${to_block}\n`, null, 'UTF-8', () => {
|
|
57
57
|
fs.close(fd)
|
|
58
58
|
})
|
|
59
59
|
})
|
package/plugins/delay_deny.js
CHANGED
|
@@ -101,7 +101,7 @@ exports.hook_deny = function (next, connection, params) {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
exports.hook_rcpt_ok = function (next, connection
|
|
104
|
+
exports.hook_rcpt_ok = function (next, connection) {
|
|
105
105
|
const transaction = connection?.transaction
|
|
106
106
|
if (!transaction) return next()
|
|
107
107
|
|
|
@@ -87,7 +87,7 @@ exports.hook_queue = function (next, connection) {
|
|
|
87
87
|
}
|
|
88
88
|
plugin.loginfo('Message Stream sent to qmail. Now sending envelope')
|
|
89
89
|
const buf = plugin.build_envelope(connection.transaction)
|
|
90
|
-
qmail_queue.stdout.on('error', (
|
|
90
|
+
qmail_queue.stdout.on('error', () => {}) // stdout throws an error on close
|
|
91
91
|
qmail_queue.stdout.end(buf)
|
|
92
92
|
})
|
|
93
93
|
}
|
|
@@ -10,7 +10,7 @@ exports.register = function () {
|
|
|
10
10
|
this.register_hook('queue_outbound', 'quarantine')
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
exports.hook_init_master = function (next
|
|
13
|
+
exports.hook_init_master = function (next) {
|
|
14
14
|
this.init_quarantine_dir(() => {
|
|
15
15
|
this.clean_tmp_directory(next)
|
|
16
16
|
})
|
|
@@ -62,8 +62,8 @@ exports.init_quarantine_dir = function (done) {
|
|
|
62
62
|
const tmp_dir = path.join(this.get_base_dir(), 'tmp')
|
|
63
63
|
fs.promises
|
|
64
64
|
.mkdir(tmp_dir, { recursive: true })
|
|
65
|
-
.then((
|
|
66
|
-
.catch((
|
|
65
|
+
.then(() => this.loginfo(`created ${tmp_dir}`))
|
|
66
|
+
.catch(() => this.logerror(`Unable to create ${tmp_dir}`))
|
|
67
67
|
.finally(done)
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -98,11 +98,11 @@ exports.quarantine = function (next, connection) {
|
|
|
98
98
|
// final destination.
|
|
99
99
|
fs.promises
|
|
100
100
|
.mkdir(msg_dir, { recursive: true })
|
|
101
|
-
.catch((
|
|
101
|
+
.catch(() => {
|
|
102
102
|
connection.logerror(this, `Error creating directory: ${msg_dir}`)
|
|
103
103
|
next()
|
|
104
104
|
})
|
|
105
|
-
.then((
|
|
105
|
+
.then(() => {
|
|
106
106
|
const ws = fs.createWriteStream(tmp_path)
|
|
107
107
|
|
|
108
108
|
ws.on('error', (err) => {
|
|
@@ -21,7 +21,7 @@ exports.hook_data_post = (next, connection) => {
|
|
|
21
21
|
return next()
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
exports.hook_get_mx = function (next, hmail
|
|
24
|
+
exports.hook_get_mx = function (next, hmail) {
|
|
25
25
|
let priority = 10
|
|
26
26
|
if (this.cfg.main.priority) {
|
|
27
27
|
priority = this.cfg.main.priority
|
|
@@ -41,7 +41,7 @@ exports.load_smtp_proxy_ini = function () {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
exports.hook_mail = function (next, connection
|
|
44
|
+
exports.hook_mail = function (next, connection) {
|
|
45
45
|
const c = this.cfg.main
|
|
46
46
|
connection.loginfo(
|
|
47
47
|
this,
|
|
@@ -70,7 +70,7 @@ exports.hook_mail = function (next, connection, params) {
|
|
|
70
70
|
delete connection.notes.smtp_client
|
|
71
71
|
})
|
|
72
72
|
|
|
73
|
-
smtp_client.on('bad_code', (code
|
|
73
|
+
smtp_client.on('bad_code', (code) => {
|
|
74
74
|
smtp_client.call_next(code.match(/^4/) ? DENYSOFT : DENY, smtp_client.response.slice())
|
|
75
75
|
|
|
76
76
|
if (smtp_client.command !== 'rcpt') {
|
package/plugins/status.js
CHANGED
|
@@ -136,8 +136,8 @@ exports.queue_inspect = function (cb) {
|
|
|
136
136
|
exports.queue_discard = function (file, cb) {
|
|
137
137
|
try {
|
|
138
138
|
this.outbound.temp_fail_queue.discard(file)
|
|
139
|
-
} catch
|
|
140
|
-
//
|
|
139
|
+
} catch {
|
|
140
|
+
// ignore not found error
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
fs.unlink(path.join(this.queue_dir || '', file), () => {
|
package/plugins/toobusy.js
CHANGED
package/plugins.js
CHANGED
|
@@ -197,11 +197,12 @@ class Plugin {
|
|
|
197
197
|
__filename: pp,
|
|
198
198
|
__dirname: path.dirname(pp),
|
|
199
199
|
exports: this,
|
|
200
|
-
|
|
200
|
+
fetch,
|
|
201
201
|
clearTimeout,
|
|
202
|
-
setInterval,
|
|
203
202
|
clearInterval,
|
|
204
203
|
process,
|
|
204
|
+
setInterval,
|
|
205
|
+
setTimeout,
|
|
205
206
|
Buffer,
|
|
206
207
|
Math,
|
|
207
208
|
server: plugins.server,
|
|
@@ -585,7 +586,7 @@ function get_denyfn(object, hook, params, retval, msg, respond_method) {
|
|
|
585
586
|
switch (deny_retval) {
|
|
586
587
|
case constants.ok:
|
|
587
588
|
// Override rejection
|
|
588
|
-
object.loginfo(`deny(soft?)
|
|
589
|
+
object.loginfo(`deny(soft?) overridden by deny hook${deny_msg ? ': deny_msg' : ''}`)
|
|
589
590
|
// Restore hooks_to_run with saved copy so that
|
|
590
591
|
// any other plugins on this hook can also run.
|
|
591
592
|
if (object.saved_hooks_to_run.length > 0) {
|