Haraka 3.1.1 → 3.1.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.
Files changed (168) hide show
  1. package/.prettierignore +4 -0
  2. package/CONTRIBUTORS.md +5 -5
  3. package/Changes.md +72 -50
  4. package/Plugins.md +3 -1
  5. package/README.md +1 -1
  6. package/bin/haraka +475 -479
  7. package/config/connection.ini +10 -0
  8. package/config/outbound.ini +3 -0
  9. package/config/smtp.ini +0 -9
  10. package/connection.js +1072 -1108
  11. package/docs/Connection.md +29 -30
  12. package/docs/CoreConfig.md +38 -40
  13. package/docs/CustomReturnCodes.md +0 -1
  14. package/docs/HAProxy.md +2 -2
  15. package/docs/Header.md +1 -1
  16. package/docs/Logging.md +29 -5
  17. package/docs/Outbound.md +93 -78
  18. package/docs/Plugins.md +103 -108
  19. package/docs/Transaction.md +49 -51
  20. package/docs/Tutorial.md +127 -143
  21. package/docs/deprecated/access.md +0 -1
  22. package/docs/deprecated/backscatterer.md +2 -3
  23. package/docs/deprecated/connect.rdns_access.md +18 -27
  24. package/docs/deprecated/data.headers.md +0 -1
  25. package/docs/deprecated/data.nomsgid.md +1 -2
  26. package/docs/deprecated/data.noreceived.md +1 -2
  27. package/docs/deprecated/data.rfc5322_header_checks.md +1 -2
  28. package/docs/deprecated/dkim_sign.md +13 -17
  29. package/docs/deprecated/dkim_verify.md +9 -17
  30. package/docs/deprecated/dnsbl.md +36 -38
  31. package/docs/deprecated/dnswl.md +41 -43
  32. package/docs/deprecated/lookup_rdns.strict.md +21 -34
  33. package/docs/deprecated/mail_from.access.md +17 -25
  34. package/docs/deprecated/mail_from.blocklist.md +9 -12
  35. package/docs/deprecated/mail_from.nobounces.md +1 -2
  36. package/docs/deprecated/rcpt_to.access.md +20 -27
  37. package/docs/deprecated/rcpt_to.blocklist.md +10 -13
  38. package/docs/deprecated/rcpt_to.routes.md +0 -1
  39. package/docs/deprecated/rdns.regexp.md +13 -15
  40. package/docs/plugins/aliases.md +89 -89
  41. package/docs/plugins/auth/auth_bridge.md +5 -7
  42. package/docs/plugins/auth/auth_ldap.md +11 -14
  43. package/docs/plugins/auth/auth_proxy.md +10 -12
  44. package/docs/plugins/auth/auth_vpopmaild.md +5 -6
  45. package/docs/plugins/auth/flat_file.md +4 -4
  46. package/docs/plugins/block_me.md +3 -3
  47. package/docs/plugins/data.signatures.md +1 -2
  48. package/docs/plugins/delay_deny.md +3 -4
  49. package/docs/plugins/max_unrecognized_commands.md +4 -4
  50. package/docs/plugins/prevent_credential_leaks.md +6 -6
  51. package/docs/plugins/process_title.md +18 -18
  52. package/docs/plugins/queue/deliver.md +2 -3
  53. package/docs/plugins/queue/discard.md +4 -4
  54. package/docs/plugins/queue/lmtp.md +1 -3
  55. package/docs/plugins/queue/qmail-queue.md +7 -9
  56. package/docs/plugins/queue/quarantine.md +16 -21
  57. package/docs/plugins/queue/rabbitmq.md +8 -11
  58. package/docs/plugins/queue/rabbitmq_amqplib.md +43 -39
  59. package/docs/plugins/queue/smtp_bridge.md +7 -10
  60. package/docs/plugins/queue/smtp_forward.md +42 -34
  61. package/docs/plugins/queue/smtp_proxy.md +30 -29
  62. package/docs/plugins/queue/test.md +1 -3
  63. package/docs/plugins/rcpt_to.in_host_list.md +6 -6
  64. package/docs/plugins/rcpt_to.max_count.md +1 -1
  65. package/docs/plugins/record_envelope_addresses.md +3 -3
  66. package/docs/plugins/reseed_rng.md +6 -6
  67. package/docs/plugins/status.md +9 -8
  68. package/docs/plugins/tarpit.md +7 -11
  69. package/docs/plugins/tls.md +12 -17
  70. package/docs/plugins/toobusy.md +4 -4
  71. package/docs/plugins/xclient.md +3 -3
  72. package/docs/tutorials/Migrating_from_v1_to_v2.md +19 -41
  73. package/docs/tutorials/SettingUpOutbound.md +6 -9
  74. package/endpoint.js +35 -38
  75. package/eslint.config.mjs +22 -19
  76. package/haraka.js +42 -47
  77. package/host_pool.js +75 -79
  78. package/http/html/404.html +45 -49
  79. package/http/html/index.html +39 -28
  80. package/http/package.json +2 -4
  81. package/line_socket.js +27 -28
  82. package/logger.js +182 -201
  83. package/outbound/client_pool.js +33 -33
  84. package/outbound/config.js +64 -59
  85. package/outbound/fsync_writestream.js +24 -25
  86. package/outbound/hmail.js +888 -835
  87. package/outbound/index.js +194 -187
  88. package/outbound/qfile.js +49 -52
  89. package/outbound/queue.js +197 -190
  90. package/outbound/timer_queue.js +41 -43
  91. package/outbound/tls.js +68 -61
  92. package/outbound/todo.js +11 -11
  93. package/package.json +35 -36
  94. package/plugins/.eslintrc.yaml +0 -1
  95. package/plugins/auth/auth_base.js +123 -127
  96. package/plugins/auth/auth_bridge.js +7 -7
  97. package/plugins/auth/auth_proxy.js +121 -126
  98. package/plugins/auth/auth_vpopmaild.js +84 -85
  99. package/plugins/auth/flat_file.js +18 -17
  100. package/plugins/block_me.js +31 -31
  101. package/plugins/data.signatures.js +13 -13
  102. package/plugins/delay_deny.js +65 -61
  103. package/plugins/prevent_credential_leaks.js +23 -23
  104. package/plugins/process_title.js +125 -128
  105. package/plugins/profile.js +5 -5
  106. package/plugins/queue/deliver.js +3 -3
  107. package/plugins/queue/discard.js +13 -14
  108. package/plugins/queue/lmtp.js +16 -17
  109. package/plugins/queue/qmail-queue.js +54 -55
  110. package/plugins/queue/quarantine.js +68 -70
  111. package/plugins/queue/rabbitmq.js +80 -87
  112. package/plugins/queue/rabbitmq_amqplib.js +75 -54
  113. package/plugins/queue/smtp_bridge.js +16 -16
  114. package/plugins/queue/smtp_forward.js +175 -179
  115. package/plugins/queue/smtp_proxy.js +69 -71
  116. package/plugins/queue/test.js +9 -9
  117. package/plugins/rcpt_to.host_list_base.js +30 -34
  118. package/plugins/rcpt_to.in_host_list.js +19 -19
  119. package/plugins/record_envelope_addresses.js +4 -4
  120. package/plugins/reseed_rng.js +4 -4
  121. package/plugins/status.js +90 -97
  122. package/plugins/tarpit.js +25 -14
  123. package/plugins/tls.js +68 -68
  124. package/plugins/toobusy.js +21 -23
  125. package/plugins/xclient.js +51 -53
  126. package/plugins.js +276 -293
  127. package/rfc1869.js +30 -35
  128. package/server.js +308 -299
  129. package/smtp_client.js +244 -228
  130. package/test/.eslintrc.yaml +0 -1
  131. package/test/connection.js +127 -134
  132. package/test/endpoint.js +53 -47
  133. package/test/fixtures/line_socket.js +12 -12
  134. package/test/fixtures/util_hmailitem.js +89 -85
  135. package/test/host_pool.js +90 -92
  136. package/test/installation/plugins/base_plugin.js +2 -2
  137. package/test/installation/plugins/folder_plugin/index.js +2 -3
  138. package/test/installation/plugins/inherits.js +3 -3
  139. package/test/installation/plugins/load_first.js +2 -3
  140. package/test/installation/plugins/plugin.js +1 -3
  141. package/test/installation/plugins/tls.js +2 -4
  142. package/test/logger.js +135 -116
  143. package/test/outbound/hmail.js +49 -35
  144. package/test/outbound/index.js +118 -101
  145. package/test/outbound/qfile.js +51 -53
  146. package/test/outbound_bounce_net_errors.js +84 -69
  147. package/test/outbound_bounce_rfc3464.js +235 -165
  148. package/test/plugins/auth/auth_base.js +420 -279
  149. package/test/plugins/auth/auth_vpopmaild.js +38 -39
  150. package/test/plugins/queue/smtp_forward.js +126 -104
  151. package/test/plugins/rcpt_to.host_list_base.js +85 -67
  152. package/test/plugins/rcpt_to.in_host_list.js +159 -112
  153. package/test/plugins/status.js +71 -64
  154. package/test/plugins/tls.js +37 -34
  155. package/test/plugins.js +97 -92
  156. package/test/rfc1869.js +19 -26
  157. package/test/server.js +293 -272
  158. package/test/smtp_client.js +180 -176
  159. package/test/tls_socket.js +62 -66
  160. package/test/transaction.js +159 -160
  161. package/tls_socket.js +331 -333
  162. package/transaction.js +129 -137
  163. package/config/me +0 -1
  164. package/config/tls_cert.pem +0 -23
  165. package/config/tls_key.pem +0 -28
  166. package/test/queue/multibyte +0 -0
  167. package/test/queue/plain +0 -0
  168. package/test/test-queue/delete-me +0 -0
@@ -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