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
@@ -4,36 +4,36 @@ const path = require('node:path')
4
4
  const os = require('node:os')
5
5
 
6
6
  const _setup = (done) => {
7
- this.socket = require('../tls_socket');
7
+ this.socket = require('../tls_socket')
8
8
 
9
9
  // use test/config instead of ./config
10
- this.socket.config = this.socket.config.module_config(path.resolve('test'));
11
- done();
10
+ this.socket.config = this.socket.config.module_config(path.resolve('test'))
11
+ done()
12
12
  }
13
13
 
14
14
  describe('tls_socket', () => {
15
15
  beforeEach(_setup)
16
16
 
17
17
  it('loads', () => {
18
- assert.ok(this.socket);
18
+ assert.ok(this.socket)
19
19
  })
20
20
  it('exports createConnection', () => {
21
- assert.equal(typeof this.socket.createConnection, 'function');
21
+ assert.equal(typeof this.socket.createConnection, 'function')
22
22
  })
23
23
  it('exports createServer', () => {
24
24
  // console.log(this.socket);
25
- assert.equal(typeof this.socket.createServer, 'function');
25
+ assert.equal(typeof this.socket.createServer, 'function')
26
26
  })
27
27
  it('exports shutdown', () => {
28
28
  // console.log(this.socket);
29
- assert.equal(typeof this.socket.shutdown, 'function');
29
+ assert.equal(typeof this.socket.shutdown, 'function')
30
30
  })
31
31
 
32
32
  describe('createServer', () => {
33
33
  beforeEach(_setup)
34
34
 
35
35
  it('returns a net.Server', () => {
36
- const server = this.socket.createServer(sock => {
36
+ const server = this.socket.createServer((sock) => {
37
37
  // TODO: socket test?
38
38
  })
39
39
  assert.ok(server)
@@ -44,8 +44,8 @@ describe('tls_socket', () => {
44
44
  beforeEach(_setup)
45
45
 
46
46
  it('tls.ini loads', () => {
47
- assert.ok(this.socket.load_tls_ini().main !== undefined);
48
- assert.ok(this.socket.certsByHost['*'].key);
47
+ assert.ok(this.socket.load_tls_ini().main !== undefined)
48
+ assert.ok(this.socket.certsByHost['*'].key)
49
49
  // console.log(this.socket.cfg);
50
50
  // console.log(this.socket.certsByHost);
51
51
  })
@@ -55,10 +55,10 @@ describe('tls_socket', () => {
55
55
  beforeEach(_setup)
56
56
 
57
57
  it('loads certs from test/loud/config/tls', async () => {
58
- this.socket.config = this.socket.config.module_config(path.resolve('test', 'loud'));
58
+ this.socket.config = this.socket.config.module_config(path.resolve('test', 'loud'))
59
59
  this.socket.load_tls_ini()
60
60
  const certs = await this.socket.get_certs_dir('tls')
61
- assert.ok(certs);
61
+ assert.ok(certs)
62
62
  })
63
63
  })
64
64
 
@@ -66,7 +66,7 @@ describe('tls_socket', () => {
66
66
  beforeEach(_setup)
67
67
 
68
68
  it('loads certs from test/config/tls', async () => {
69
- this.socket.config = this.socket.config.module_config(path.resolve('test'));
69
+ this.socket.config = this.socket.config.module_config(path.resolve('test'))
70
70
  this.socket.load_tls_ini()
71
71
  try {
72
72
  const certs = await this.socket.get_certs_dir('tls')
@@ -74,9 +74,8 @@ describe('tls_socket', () => {
74
74
  assert.ok(certs['mail.haraka.io'])
75
75
  assert.ok(certs['haraka.local'])
76
76
  assert.ok(certs['*.example.com'])
77
- }
78
- catch (err) {
79
- assert.ifError(err);
77
+ } catch (err) {
78
+ assert.ifError(err)
80
79
  }
81
80
  })
82
81
  })
@@ -86,10 +85,10 @@ describe('tls_socket', () => {
86
85
 
87
86
  it('gets socket opts for *', async () => {
88
87
  const certs = await this.socket.get_certs_dir('tls')
89
- this.socket.getSocketOpts('*').then(opts => {
88
+ this.socket.getSocketOpts('*').then((opts) => {
90
89
  // console.log(opts);
91
- assert.ok(opts.key);
92
- assert.ok(opts.cert);
90
+ assert.ok(opts.key)
91
+ assert.ok(opts.cert)
93
92
  })
94
93
  })
95
94
  })
@@ -97,45 +96,44 @@ describe('tls_socket', () => {
97
96
  describe('ensureDhparams', () => {
98
97
  beforeEach(_setup)
99
98
  it('generates a missing dhparams file', () => {
100
- this.socket.load_tls_ini();
99
+ this.socket.load_tls_ini()
101
100
  this.socket.ensureDhparams((err, dhparams) => {
102
101
  // console.log(dhparams);
103
- assert.ifError(err);
104
- assert.ok(dhparams);
102
+ assert.ifError(err)
103
+ assert.ok(dhparams)
105
104
  })
106
105
  })
107
106
  })
108
107
 
109
108
  describe('load_tls_ini2', () => {
110
109
  beforeEach((done) => {
111
- this.socket = require('../tls_socket');
112
- delete process.env.HARAKA_TEST_DIR;
113
- done();
110
+ this.socket = require('../tls_socket')
111
+ delete process.env.HARAKA_TEST_DIR
112
+ done()
114
113
  })
115
114
 
116
115
  it('loads missing tls.ini default config', () => {
117
- this.socket.config = this.socket.config.module_config(path.resolve('non-exist'));
118
- assert.deepEqual(this.socket.load_tls_ini(),
119
- {
120
- main: {
121
- requestCert: true,
122
- rejectUnauthorized: false,
123
- honorCipherOrder: true,
124
- requestOCSP: false,
125
- // enableOCSPStapling: false,
126
- requireAuthorized: [],
127
- mutual_tls: false,
128
- no_starttls_ports: [],
129
- },
130
- redis: { disable_for_failed_hosts: false },
131
- no_tls_hosts: {},
132
- mutual_auth_hosts: {},
133
- mutual_auth_hosts_exclude: {},
134
- });
116
+ this.socket.config = this.socket.config.module_config(path.resolve('non-exist'))
117
+ assert.deepEqual(this.socket.load_tls_ini(), {
118
+ main: {
119
+ requestCert: true,
120
+ rejectUnauthorized: false,
121
+ honorCipherOrder: true,
122
+ requestOCSP: false,
123
+ // enableOCSPStapling: false,
124
+ requireAuthorized: [],
125
+ mutual_tls: false,
126
+ no_starttls_ports: [],
127
+ },
128
+ redis: { disable_for_failed_hosts: false },
129
+ no_tls_hosts: {},
130
+ mutual_auth_hosts: {},
131
+ mutual_auth_hosts_exclude: {},
132
+ })
135
133
  })
136
134
 
137
135
  it('loads tls.ini from test dir', () => {
138
- this.socket.config = this.socket.config.module_config(path.resolve('test'));
136
+ this.socket.config = this.socket.config.module_config(path.resolve('test'))
139
137
  assert.deepEqual(this.socket.load_tls_ini(), {
140
138
  main: {
141
139
  requestCert: true,
@@ -145,7 +143,8 @@ describe('tls_socket', () => {
145
143
  key: 'tls_key.pem',
146
144
  cert: 'tls_cert.pem',
147
145
  dhparam: 'dhparams.pem',
148
- ciphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384',
146
+ ciphers:
147
+ 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384',
149
148
  minVersion: 'TLSv1',
150
149
  requireAuthorized: [2465, 2587],
151
150
  mutual_tls: false,
@@ -169,7 +168,7 @@ describe('tls_socket', () => {
169
168
  honorCipherOrder: false,
170
169
  force_tls_hosts: ['first.example.com', 'second.example.net'],
171
170
  no_tls_hosts: ['127.0.0.2', '192.168.31.1/24'],
172
- }
171
+ },
173
172
  })
174
173
  })
175
174
  })
@@ -179,25 +178,21 @@ describe('tls_socket', () => {
179
178
 
180
179
  it('returns empty object on empty input', async () => {
181
180
  const res = await this.socket.parse_x509()
182
- assert.deepEqual(res, {});
181
+ assert.deepEqual(res, {})
183
182
  })
184
183
 
185
184
  it('returns key from BEGIN PRIVATE KEY block', async () => {
186
- const res = await this.socket.parse_x509('-BEGIN PRIVATE KEY-\nhello\n--END PRIVATE KEY--\n-its me-\n');
187
- assert.deepEqual(
188
- res.keys[0].toString(),
189
- '-BEGIN PRIVATE KEY-\nhello\n--END PRIVATE KEY--',
190
- );
191
- assert.deepEqual(res.cert, undefined);
185
+ const res = await this.socket.parse_x509('-BEGIN PRIVATE KEY-\nhello\n--END PRIVATE KEY--\n-its me-\n')
186
+ assert.deepEqual(res.keys[0].toString(), '-BEGIN PRIVATE KEY-\nhello\n--END PRIVATE KEY--')
187
+ assert.deepEqual(res.cert, undefined)
192
188
  })
193
189
 
194
190
  it('returns key from BEGIN RSA PRIVATE KEY block', async () => {
195
- const res = await this.socket.parse_x509('-BEGIN RSA PRIVATE KEY-\nhello\n--END RSA PRIVATE KEY--\n-its me-\n');
196
- assert.deepEqual(
197
- res.keys[0].toString(),
198
- '-BEGIN RSA PRIVATE KEY-\nhello\n--END RSA PRIVATE KEY--',
199
- );
200
- assert.deepEqual(res.cert, undefined);
191
+ const res = await this.socket.parse_x509(
192
+ '-BEGIN RSA PRIVATE KEY-\nhello\n--END RSA PRIVATE KEY--\n-its me-\n',
193
+ )
194
+ assert.deepEqual(res.keys[0].toString(), '-BEGIN RSA PRIVATE KEY-\nhello\n--END RSA PRIVATE KEY--')
195
+ assert.deepEqual(res.cert, undefined)
201
196
  })
202
197
 
203
198
  it.skip('returns a key and certificate chain', async () => {
@@ -239,13 +234,13 @@ WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
239
234
  he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
240
235
  Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
241
236
  -----END CERTIFICATE-----`
242
- const res = await this.socket.parse_x509(str);
243
- assert.deepEqual(res.key.length, 446);
244
- assert.deepEqual(res.cert.length, 1195);
237
+ const res = await this.socket.parse_x509(str)
238
+ assert.deepEqual(res.key.length, 446)
239
+ assert.deepEqual(res.cert.length, 1195)
245
240
  })
246
241
 
247
242
  it('returns cert and key from EC pem', async () => {
248
- const fp = await fs.readFile(path.join('test','config','tls','ec.pem'))
243
+ const fp = await fs.readFile(path.join('test', 'config', 'tls', 'ec.pem'))
249
244
  const res = await this.socket.parse_x509(fp.toString())
250
245
  assert.deepEqual(
251
246
  res.keys[0].toString().split(os.EOL).join('\n'),
@@ -253,8 +248,8 @@ Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
253
248
  MHcCAQEEIIDhiI5q6l7txfMJ6kIEYjK12EFcHLvDIkfWIwzdZBsloAoGCCqGSM49
254
249
  AwEHoUQDQgAEZg2nHEFy9nquFPF3DQyQE28e/ytjXeb4nD/8U+L4KHKFtglaX3R4
255
250
  uZ+5JcwfcDghpL4Z8h4ouUD/xqe957e2+g==
256
- -----END EC PRIVATE KEY-----`
257
- );
251
+ -----END EC PRIVATE KEY-----`,
252
+ )
258
253
  assert.deepEqual(
259
254
  res.chain[0].toString().split(os.EOL).join('\n'),
260
255
  `-----BEGIN CERTIFICATE-----
@@ -271,7 +266,8 @@ OCGkvhnyHii5QP/Gp73nt7b6o1MwUTAdBgNVHQ4EFgQU094ROMLHmLEspT4ZoCfX
271
266
  Rz0mR/YwHwYDVR0jBBgwFoAU094ROMLHmLEspT4ZoCfXRz0mR/YwDwYDVR0TAQH/
272
267
  BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEAsmshzvMDjmYDHyGRrKdMmsnnESFd
273
268
  GMtfRXYIv0AZe7ICIGD2Sta9LL0zZ44ARGXhh+sPjxd78I/+0FdIPsofr2I+
274
- -----END CERTIFICATE-----`);
269
+ -----END CERTIFICATE-----`,
270
+ )
275
271
  })
276
272
  })
277
273
  })