Haraka 3.1.1 → 3.1.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.
Files changed (160) hide show
  1. package/.prettierignore +4 -0
  2. package/CONTRIBUTORS.md +5 -5
  3. package/Changes.md +62 -50
  4. package/Plugins.md +3 -1
  5. package/README.md +1 -1
  6. package/bin/haraka +475 -479
  7. package/config/outbound.ini +3 -0
  8. package/connection.js +1072 -1108
  9. package/docs/Connection.md +29 -30
  10. package/docs/CoreConfig.md +38 -39
  11. package/docs/CustomReturnCodes.md +0 -1
  12. package/docs/HAProxy.md +2 -2
  13. package/docs/Header.md +1 -1
  14. package/docs/Logging.md +29 -5
  15. package/docs/Outbound.md +93 -78
  16. package/docs/Plugins.md +103 -108
  17. package/docs/Transaction.md +49 -51
  18. package/docs/Tutorial.md +127 -143
  19. package/docs/deprecated/access.md +0 -1
  20. package/docs/deprecated/backscatterer.md +2 -3
  21. package/docs/deprecated/connect.rdns_access.md +18 -27
  22. package/docs/deprecated/data.headers.md +0 -1
  23. package/docs/deprecated/data.nomsgid.md +1 -2
  24. package/docs/deprecated/data.noreceived.md +1 -2
  25. package/docs/deprecated/data.rfc5322_header_checks.md +1 -2
  26. package/docs/deprecated/dkim_sign.md +13 -17
  27. package/docs/deprecated/dkim_verify.md +9 -17
  28. package/docs/deprecated/dnsbl.md +36 -38
  29. package/docs/deprecated/dnswl.md +41 -43
  30. package/docs/deprecated/lookup_rdns.strict.md +21 -34
  31. package/docs/deprecated/mail_from.access.md +17 -25
  32. package/docs/deprecated/mail_from.blocklist.md +9 -12
  33. package/docs/deprecated/mail_from.nobounces.md +1 -2
  34. package/docs/deprecated/rcpt_to.access.md +20 -27
  35. package/docs/deprecated/rcpt_to.blocklist.md +10 -13
  36. package/docs/deprecated/rcpt_to.routes.md +0 -1
  37. package/docs/deprecated/rdns.regexp.md +13 -15
  38. package/docs/plugins/aliases.md +89 -89
  39. package/docs/plugins/auth/auth_bridge.md +5 -7
  40. package/docs/plugins/auth/auth_ldap.md +11 -14
  41. package/docs/plugins/auth/auth_proxy.md +10 -12
  42. package/docs/plugins/auth/auth_vpopmaild.md +5 -6
  43. package/docs/plugins/auth/flat_file.md +4 -4
  44. package/docs/plugins/block_me.md +3 -3
  45. package/docs/plugins/data.signatures.md +1 -2
  46. package/docs/plugins/delay_deny.md +3 -4
  47. package/docs/plugins/max_unrecognized_commands.md +4 -4
  48. package/docs/plugins/prevent_credential_leaks.md +6 -6
  49. package/docs/plugins/process_title.md +18 -18
  50. package/docs/plugins/queue/deliver.md +2 -3
  51. package/docs/plugins/queue/discard.md +4 -4
  52. package/docs/plugins/queue/lmtp.md +1 -3
  53. package/docs/plugins/queue/qmail-queue.md +7 -9
  54. package/docs/plugins/queue/quarantine.md +16 -21
  55. package/docs/plugins/queue/rabbitmq.md +8 -11
  56. package/docs/plugins/queue/rabbitmq_amqplib.md +43 -39
  57. package/docs/plugins/queue/smtp_bridge.md +7 -10
  58. package/docs/plugins/queue/smtp_forward.md +42 -34
  59. package/docs/plugins/queue/smtp_proxy.md +30 -29
  60. package/docs/plugins/queue/test.md +1 -3
  61. package/docs/plugins/rcpt_to.in_host_list.md +6 -6
  62. package/docs/plugins/rcpt_to.max_count.md +1 -1
  63. package/docs/plugins/record_envelope_addresses.md +3 -3
  64. package/docs/plugins/reseed_rng.md +6 -6
  65. package/docs/plugins/status.md +9 -8
  66. package/docs/plugins/tarpit.md +7 -11
  67. package/docs/plugins/tls.md +12 -17
  68. package/docs/plugins/toobusy.md +4 -4
  69. package/docs/plugins/xclient.md +3 -3
  70. package/docs/tutorials/Migrating_from_v1_to_v2.md +19 -41
  71. package/docs/tutorials/SettingUpOutbound.md +6 -9
  72. package/endpoint.js +35 -38
  73. package/eslint.config.mjs +22 -19
  74. package/haraka.js +42 -47
  75. package/host_pool.js +75 -79
  76. package/http/html/404.html +45 -49
  77. package/http/html/index.html +39 -28
  78. package/http/package.json +2 -4
  79. package/line_socket.js +27 -28
  80. package/logger.js +182 -201
  81. package/outbound/client_pool.js +33 -33
  82. package/outbound/config.js +64 -59
  83. package/outbound/fsync_writestream.js +24 -25
  84. package/outbound/hmail.js +888 -835
  85. package/outbound/index.js +194 -187
  86. package/outbound/qfile.js +49 -52
  87. package/outbound/queue.js +197 -190
  88. package/outbound/timer_queue.js +41 -43
  89. package/outbound/tls.js +68 -61
  90. package/outbound/todo.js +11 -11
  91. package/package.json +32 -32
  92. package/plugins/.eslintrc.yaml +0 -1
  93. package/plugins/auth/auth_base.js +123 -127
  94. package/plugins/auth/auth_bridge.js +7 -7
  95. package/plugins/auth/auth_proxy.js +121 -126
  96. package/plugins/auth/auth_vpopmaild.js +84 -85
  97. package/plugins/auth/flat_file.js +18 -17
  98. package/plugins/block_me.js +31 -31
  99. package/plugins/data.signatures.js +13 -13
  100. package/plugins/delay_deny.js +65 -61
  101. package/plugins/prevent_credential_leaks.js +23 -23
  102. package/plugins/process_title.js +125 -128
  103. package/plugins/profile.js +5 -5
  104. package/plugins/queue/deliver.js +3 -3
  105. package/plugins/queue/discard.js +13 -14
  106. package/plugins/queue/lmtp.js +16 -17
  107. package/plugins/queue/qmail-queue.js +54 -55
  108. package/plugins/queue/quarantine.js +68 -70
  109. package/plugins/queue/rabbitmq.js +80 -87
  110. package/plugins/queue/rabbitmq_amqplib.js +75 -54
  111. package/plugins/queue/smtp_bridge.js +16 -16
  112. package/plugins/queue/smtp_forward.js +175 -179
  113. package/plugins/queue/smtp_proxy.js +69 -71
  114. package/plugins/queue/test.js +9 -9
  115. package/plugins/rcpt_to.host_list_base.js +30 -34
  116. package/plugins/rcpt_to.in_host_list.js +19 -19
  117. package/plugins/record_envelope_addresses.js +4 -4
  118. package/plugins/reseed_rng.js +4 -4
  119. package/plugins/status.js +90 -97
  120. package/plugins/tarpit.js +25 -14
  121. package/plugins/tls.js +68 -68
  122. package/plugins/toobusy.js +21 -23
  123. package/plugins/xclient.js +51 -53
  124. package/plugins.js +276 -293
  125. package/rfc1869.js +30 -35
  126. package/server.js +308 -299
  127. package/smtp_client.js +244 -228
  128. package/test/.eslintrc.yaml +0 -1
  129. package/test/connection.js +127 -134
  130. package/test/endpoint.js +53 -47
  131. package/test/fixtures/line_socket.js +12 -12
  132. package/test/fixtures/util_hmailitem.js +89 -85
  133. package/test/host_pool.js +90 -92
  134. package/test/installation/plugins/base_plugin.js +2 -2
  135. package/test/installation/plugins/folder_plugin/index.js +2 -3
  136. package/test/installation/plugins/inherits.js +3 -3
  137. package/test/installation/plugins/load_first.js +2 -3
  138. package/test/installation/plugins/plugin.js +1 -3
  139. package/test/installation/plugins/tls.js +2 -4
  140. package/test/logger.js +135 -116
  141. package/test/outbound/hmail.js +49 -35
  142. package/test/outbound/index.js +118 -101
  143. package/test/outbound/qfile.js +51 -53
  144. package/test/outbound_bounce_net_errors.js +84 -69
  145. package/test/outbound_bounce_rfc3464.js +235 -165
  146. package/test/plugins/auth/auth_base.js +420 -279
  147. package/test/plugins/auth/auth_vpopmaild.js +38 -39
  148. package/test/plugins/queue/smtp_forward.js +126 -104
  149. package/test/plugins/rcpt_to.host_list_base.js +85 -67
  150. package/test/plugins/rcpt_to.in_host_list.js +159 -112
  151. package/test/plugins/status.js +71 -64
  152. package/test/plugins/tls.js +37 -34
  153. package/test/plugins.js +97 -92
  154. package/test/rfc1869.js +19 -26
  155. package/test/server.js +293 -272
  156. package/test/smtp_client.js +180 -176
  157. package/test/tls_socket.js +62 -66
  158. package/test/transaction.js +159 -160
  159. package/tls_socket.js +331 -333
  160. package/transaction.js +129 -137
@@ -1,46 +1,51 @@
1
- 'use strict';
1
+ 'use strict'
2
2
 
3
- const config = require('haraka-config');
4
- const logger = require('../logger');
3
+ const config = require('haraka-config')
4
+ const logger = require('../logger')
5
5
 
6
6
  exports.name = 'outbound/config'
7
7
 
8
- function load_config () {
9
- const cfg = exports.cfg = config.get('outbound.ini', {
10
- booleans: [
11
- '-disabled',
12
- '-always_split',
13
- '+enable_tls',
14
- '-local_mx_ok',
15
- ],
16
- }, () => {
17
- load_config();
18
- }).main;
8
+ function load_config() {
9
+ const cfg = (exports.cfg = config.get(
10
+ 'outbound.ini',
11
+ {
12
+ booleans: ['-disabled', '-always_split', '+enable_tls', '-local_mx_ok'],
13
+ },
14
+ () => {
15
+ load_config()
16
+ },
17
+ ).main)
18
+
19
+ if (!cfg.inet_prefer) cfg.inet_prefer = 'default'
20
+ if (!cfg.inet_prefer.match(/^(v4|v6|default)$/)) {
21
+ logger.warn(exports, `inet_prefer is set to an invalid value: ${cfg.inet_prefer}`)
22
+ cfg.inet_prefer = 'default'
23
+ }
19
24
 
20
25
  // legacy config file support. Remove in Haraka 4.0
21
26
  if (!cfg.disabled && config.get('outbound.disabled')) {
22
- cfg.disabled = true;
27
+ cfg.disabled = true
23
28
  }
24
29
  if (!cfg.enable_tls && config.get('outbound.enable_tls')) {
25
- cfg.enable_tls = true;
30
+ cfg.enable_tls = true
26
31
  }
27
32
  if (!cfg.temp_fail_intervals) {
28
- cfg.temp_fail_intervals = config.get('outbound.temp_fail_intervals');
33
+ cfg.temp_fail_intervals = config.get('outbound.temp_fail_intervals')
29
34
  }
30
35
  if (!cfg.maxTempFailures) {
31
- cfg.maxTempFailures = config.get('outbound.maxTempFailures') || 13;
36
+ cfg.maxTempFailures = config.get('outbound.maxTempFailures') || 13
32
37
  }
33
38
  if (!cfg.concurrency_max) {
34
- cfg.concurrency_max = config.get('outbound.concurrency_max') || 10000;
39
+ cfg.concurrency_max = config.get('outbound.concurrency_max') || 10000
35
40
  }
36
41
  if (!cfg.connect_timeout) {
37
- cfg.connect_timeout = 30;
42
+ cfg.connect_timeout = 30
38
43
  }
39
44
  if (!cfg.received_header) {
40
- cfg.received_header = config.get('outbound.received_header') || 'Haraka outbound';
45
+ cfg.received_header = config.get('outbound.received_header') || 'Haraka outbound'
41
46
  }
42
47
 
43
- exports.set_temp_fail_intervals();
48
+ exports.set_temp_fail_intervals()
44
49
  }
45
50
 
46
51
  exports.set_temp_fail_intervals = function () {
@@ -50,80 +55,80 @@ exports.set_temp_fail_intervals = function () {
50
55
  // it with the equivalent times of maxTempFailures using the original 2^N formula
51
56
  // 3) the word "none" can be specified if you do not want to retry a temp failure,
52
57
  // equivalent behavior of specifying maxTempFailures=1
53
- const { cfg } = this;
58
+ const { cfg } = this
54
59
 
55
60
  // Fallback function to create an array of the original retry times
56
- function set_old_defaults () {
57
- cfg.temp_fail_intervals = [];
58
- for (let i=1; i<cfg.maxTempFailures; i++) {
59
- cfg.temp_fail_intervals.push(2 ** (i + 5));
61
+ function set_old_defaults() {
62
+ cfg.temp_fail_intervals = []
63
+ for (let i = 1; i < cfg.maxTempFailures; i++) {
64
+ cfg.temp_fail_intervals.push(2 ** (i + 5))
60
65
  }
61
66
  }
62
67
 
63
68
  // Helpful error function in case of parsing failure
64
- function error (i, msg) {
65
- logger.error(exports, `temp_fail_intervals syntax error parsing element ${i}: ${msg}`);
66
- logger.warn(exports, 'Setting outbound temp_fail_intervals to old defaults');
67
- set_old_defaults();
69
+ function error(i, msg) {
70
+ logger.error(exports, `temp_fail_intervals syntax error parsing element ${i}: ${msg}`)
71
+ logger.warn(exports, 'Setting outbound temp_fail_intervals to old defaults')
72
+ set_old_defaults()
68
73
  }
69
74
 
70
75
  // If the new value isn't specified, then create the old defaults
71
76
  if (!cfg.temp_fail_intervals) {
72
- return set_old_defaults();
77
+ return set_old_defaults()
73
78
  }
74
79
 
75
80
  // If here then turn the text input into an expanded array of intervals (in seconds)
76
81
  // i.e, turn "1m,5m*2,1h*3" into [60,300,300,3600,3600,3600]
77
82
  // Parse manually to do better syntax checking and provide better failure messages
78
- const times = [];
79
- let input = cfg.temp_fail_intervals.replace(/\s+/g, '').toLowerCase();
80
- if (input.length === 0) return error(0, 'nothing specified');
83
+ const times = []
84
+ let input = cfg.temp_fail_intervals.replace(/\s+/g, '').toLowerCase()
85
+ if (input.length === 0) return error(0, 'nothing specified')
81
86
  if (input === 'none') {
82
- cfg.temp_fail_intervals = [];
83
- return;
87
+ cfg.temp_fail_intervals = []
88
+ return
84
89
  }
85
90
  input = input.split(',')
86
91
 
87
- for (let i=0; i<input.length; i++) {
88
- const delay = input[i].split('*');
89
- if (delay.length === 1) delay.push(1);
90
- else if (delay.length === 2) delay[1] = Number(delay[1]);
91
- else return error(i, 'too many *');
92
- if (!Number.isInteger(delay[1])) return error(i, 'multiplier is not an integer');
92
+ for (let i = 0; i < input.length; i++) {
93
+ const delay = input[i].split('*')
94
+ if (delay.length === 1) delay.push(1)
95
+ else if (delay.length === 2) delay[1] = Number(delay[1])
96
+ else return error(i, 'too many *')
97
+ if (!Number.isInteger(delay[1])) return error(i, 'multiplier is not an integer')
93
98
 
94
- if (delay[0].length < 2) error(i, 'invalid time span');
95
- const symbol = delay[0].charAt(delay[0].length - 1);
96
- let num = Number(delay[0].slice(0, -1));
97
- if (isNaN(num)) return error(i, 'invalid number or symbol');
99
+ if (delay[0].length < 2) error(i, 'invalid time span')
100
+ const symbol = delay[0].charAt(delay[0].length - 1)
101
+ let num = Number(delay[0].slice(0, -1))
102
+ if (isNaN(num)) return error(i, 'invalid number or symbol')
98
103
 
99
104
  switch (symbol) {
100
105
  case 's':
101
106
  // do nothing, this is the base unit
102
- break;
107
+ break
103
108
  case 'm':
104
- num *= 60;
105
- break;
109
+ num *= 60
110
+ break
106
111
  case 'h':
107
- num *= 3600;
108
- break;
112
+ num *= 3600
113
+ break
109
114
  case 'd':
110
- num *= 86400;
111
- break;
115
+ num *= 86400
116
+ break
112
117
  default:
113
- return error(i, 'invalid time span symbol');
118
+ return error(i, 'invalid time span symbol')
114
119
  }
115
120
  // Sanity check (what should this number be?)
116
121
  if (num < 5) return error(i, 'delay time too small, should be >=5 seconds')
117
122
  for (let j = 0; j < delay[1]; j++) {
118
- times.push(num);
123
+ times.push(num)
119
124
  }
120
125
  }
121
126
 
122
127
  // One last check, just in case...should never be true
123
- if (times.length === 0) return error(0, 'unexpected parsing result');
128
+ if (times.length === 0) return error(0, 'unexpected parsing result')
124
129
 
125
130
  // If here, success, so actually store the calculated array in the config
126
- cfg.temp_fail_intervals = times;
131
+ cfg.temp_fail_intervals = times
127
132
  }
128
133
 
129
- load_config();
134
+ load_config()
@@ -1,45 +1,44 @@
1
- 'use strict';
1
+ 'use strict'
2
2
 
3
- const fs = require('node:fs');
3
+ const fs = require('node:fs')
4
4
 
5
5
  class FsyncWriteStream extends fs.WriteStream {
6
- constructor (path, options) {
7
- super(path, options);
6
+ constructor(path, options) {
7
+ super(path, options)
8
8
  }
9
9
 
10
- close (cb) {
11
- const self = this;
12
- if (cb) this.once('close', cb);
10
+ close(cb) {
11
+ const self = this
12
+ if (cb) this.once('close', cb)
13
13
 
14
14
  if (this.closed || 'number' !== typeof this.fd) {
15
15
  if ('number' !== typeof this.fd) {
16
- this.once('open', close);
17
- return;
16
+ this.once('open', close)
17
+ return
18
18
  }
19
- return setImmediate(this.emit.bind(this, 'close'));
19
+ return setImmediate(this.emit.bind(this, 'close'))
20
20
  }
21
- this.closed = true;
22
- close();
21
+ this.closed = true
22
+ close()
23
23
 
24
- function close (fd) {
25
- fs.fsync(fd || self.fd, er => {
24
+ function close(fd) {
25
+ fs.fsync(fd || self.fd, (er) => {
26
26
  if (er) {
27
- self.emit('error', er);
28
- return;
27
+ self.emit('error', er)
28
+ return
29
29
  }
30
30
 
31
- fs.close(fd || self.fd, err => {
31
+ fs.close(fd || self.fd, (err) => {
32
32
  if (err) {
33
- self.emit('error', err);
33
+ self.emit('error', err)
34
+ } else {
35
+ self.emit('close')
34
36
  }
35
- else {
36
- self.emit('close');
37
- }
38
- });
39
- self.fd = null;
40
- });
37
+ })
38
+ self.fd = null
39
+ })
41
40
  }
42
41
  }
43
42
  }
44
43
 
45
- module.exports = FsyncWriteStream;
44
+ module.exports = FsyncWriteStream