Haraka 2.8.28 → 3.0.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.
Files changed (135) hide show
  1. package/.eslintrc.yaml +2 -10
  2. package/Changes.md +84 -2
  3. package/Dockerfile +1 -1
  4. package/Plugins.md +9 -4
  5. package/README.md +2 -6
  6. package/bin/haraka +5 -4
  7. package/config/outbound.ini +0 -7
  8. package/config/plugins +1 -1
  9. package/config/smtp.ini +1 -1
  10. package/config/smtp_forward.ini +2 -8
  11. package/config/smtp_proxy.ini +0 -6
  12. package/connection.js +178 -204
  13. package/coverage/lcov.info +13863 -0
  14. package/coverage/tmp/coverage-42958-1658373250585-0.json +1 -0
  15. package/coverage/tmp/coverage-42961-1658373250529-0.json +1 -0
  16. package/dkim.js +66 -73
  17. package/docs/Body.md +1 -22
  18. package/docs/CoreConfig.md +2 -2
  19. package/docs/Header.md +1 -47
  20. package/docs/Outbound.md +8 -36
  21. package/endpoint.js +1 -1
  22. package/haraka.js +1 -1
  23. package/host_pool.js +8 -12
  24. package/logger.js +25 -32
  25. package/outbound/client_pool.js +11 -153
  26. package/outbound/config.js +5 -11
  27. package/outbound/hmail.js +109 -143
  28. package/outbound/index.js +13 -25
  29. package/outbound/mx_lookup.js +10 -7
  30. package/outbound/queue.js +8 -12
  31. package/outbound/timer_queue.js +2 -4
  32. package/outbound/tls.js +17 -18
  33. package/outbound/todo.js +1 -0
  34. package/package.json +57 -55
  35. package/plugins/auth/auth_base.js +39 -63
  36. package/plugins/auth/auth_bridge.js +3 -4
  37. package/plugins/auth/auth_proxy.js +16 -16
  38. package/plugins/auth/auth_vpopmaild.js +30 -37
  39. package/plugins/auth/flat_file.js +9 -13
  40. package/plugins/avg.js +9 -11
  41. package/plugins/backscatterer.js +1 -1
  42. package/plugins/block_me.js +2 -6
  43. package/plugins/bounce.js +106 -124
  44. package/plugins/clamd.js +59 -63
  45. package/plugins/data.signatures.js +6 -6
  46. package/plugins/data.uribl.js +1 -415
  47. package/plugins/delay_deny.js +19 -20
  48. package/plugins/dkim_sign.js +56 -62
  49. package/plugins/dkim_verify.js +9 -8
  50. package/plugins/dns_list_base.js +43 -42
  51. package/plugins/dnsbl.js +41 -46
  52. package/plugins/dnswl.js +23 -26
  53. package/plugins/early_talker.js +24 -28
  54. package/plugins/esets.js +8 -11
  55. package/plugins/greylist.js +161 -190
  56. package/plugins/helo.checks.js +175 -197
  57. package/plugins/mail_from.is_resolvable.js +38 -38
  58. package/plugins/messagesniffer.js +33 -40
  59. package/plugins/prevent_credential_leaks.js +7 -5
  60. package/plugins/process_title.js +16 -17
  61. package/plugins/queue/deliver.js +2 -2
  62. package/plugins/queue/lmtp.js +5 -6
  63. package/plugins/queue/qmail-queue.js +11 -13
  64. package/plugins/queue/quarantine.js +25 -34
  65. package/plugins/queue/rabbitmq.js +3 -2
  66. package/plugins/queue/rabbitmq_amqplib.js +9 -9
  67. package/plugins/queue/smtp_bridge.js +5 -4
  68. package/plugins/queue/smtp_forward.js +81 -89
  69. package/plugins/queue/smtp_proxy.js +21 -22
  70. package/plugins/queue/test.js +2 -1
  71. package/plugins/rcpt_to.host_list_base.js +20 -30
  72. package/plugins/rcpt_to.in_host_list.js +12 -14
  73. package/plugins/rcpt_to.max_count.js +7 -5
  74. package/plugins/record_envelope_addresses.js +4 -6
  75. package/plugins/relay.js +64 -74
  76. package/plugins/reseed_rng.js +1 -2
  77. package/plugins/spamassassin.js +56 -68
  78. package/plugins/status.js +2 -3
  79. package/plugins/tarpit.js +8 -11
  80. package/plugins/tls.js +14 -17
  81. package/plugins/toobusy.js +6 -8
  82. package/plugins/xclient.js +14 -25
  83. package/plugins.js +24 -29
  84. package/rfc1869.js +2 -2
  85. package/server.js +3 -13
  86. package/smtp_client.js +138 -215
  87. package/tests/config/smtp_forward.ini +0 -6
  88. package/tests/fixtures/line_socket.js +1 -1
  89. package/tests/fixtures/util_hmailitem.js +5 -7
  90. package/tests/fixtures/vm_harness.js +2 -2
  91. package/tests/host_pool.js +13 -14
  92. package/tests/installation/plugins/inherits.js +1 -2
  93. package/tests/logger.js +2 -2
  94. package/tests/plugins/bounce.js +6 -8
  95. package/tests/plugins/dkim_signer.js +7 -7
  96. package/tests/plugins/dns_list_base.js +7 -7
  97. package/tests/plugins/helo.checks.js +1 -1
  98. package/tests/plugins/mail_from.is_resolvable.js +10 -54
  99. package/tests/plugins/queue/smtp_forward.js +11 -11
  100. package/tests/plugins/rcpt_to.host_list_base.js +1 -1
  101. package/tests/plugins/rcpt_to.in_host_list.js +1 -1
  102. package/tests/plugins/spamassassin.js +1 -1
  103. package/tests/queue/multibyte +0 -0
  104. package/tests/queue/plain +0 -0
  105. package/tests/rfc1869.js +4 -1
  106. package/tests/server.js +15 -9
  107. package/tests/smtp_client/auth.js +4 -14
  108. package/tests/smtp_client/basic.js +5 -15
  109. package/tests/smtp_client.js +7 -3
  110. package/tests/transaction.js +72 -19
  111. package/tls_socket.js +75 -85
  112. package/transaction.js +7 -9
  113. package/attachment_stream.js +0 -118
  114. package/bin/spf +0 -48
  115. package/chunkemitter.js +0 -75
  116. package/config/data.uribl.excludes +0 -202
  117. package/config/data.uribl.ini +0 -37
  118. package/config/spf.ini +0 -1
  119. package/docs/plugins/attachment.md +0 -92
  120. package/docs/plugins/data.uribl.md +0 -120
  121. package/docs/plugins/spf.md +0 -142
  122. package/mailbody.js +0 -502
  123. package/mailheader.js +0 -304
  124. package/messagestream.js +0 -441
  125. package/plugins/aliases.js +0 -120
  126. package/plugins/attachment.js +0 -503
  127. package/plugins/connect.p0f.js +0 -5
  128. package/plugins/spf.js +0 -327
  129. package/spf.js +0 -689
  130. package/tests/mailbody.js +0 -348
  131. package/tests/mailheader.js +0 -138
  132. package/tests/messagestream.js +0 -34
  133. package/tests/plugins/aliases.js +0 -376
  134. package/tests/plugins/spf.js +0 -251
  135. package/tests/spf.js +0 -96
package/plugins.js CHANGED
@@ -39,7 +39,6 @@ class Plugin {
39
39
  }
40
40
 
41
41
  _get_plugin_path () {
42
- const plugin = this;
43
42
  /* From https://github.com/haraka/Haraka/pull/1278#issuecomment-168856528
44
43
  In Development mode, or install via a plain "git clone":
45
44
 
@@ -57,9 +56,9 @@ class Plugin {
57
56
  Plugin in <core_haraka_dir>/node_modules.
58
57
  */
59
58
 
60
- plugin.hasPackageJson = false;
61
- const name = plugin.name.startsWith('haraka-plugin-') ? plugin.name.substr(14) : plugin.name;
62
- if (plugin.name !== name) plugin.name = name;
59
+ this.hasPackageJson = false;
60
+ const name = this.name.startsWith('haraka-plugin-') ? this.name.substr(14) : this.name;
61
+ if (this.name !== name) this.name = name;
63
62
 
64
63
  let paths = [];
65
64
  if (process.env.HARAKA) {
@@ -76,12 +75,12 @@ class Plugin {
76
75
  // development mode
77
76
  paths = paths.concat(plugin_search_paths(__dirname, name));
78
77
  paths.forEach(pp => {
79
- if (plugin.plugin_path) return;
78
+ if (this.plugin_path) return;
80
79
  try {
81
80
  fs.statSync(pp);
82
- plugin.plugin_path = pp;
81
+ this.plugin_path = pp;
83
82
  if (path.basename(pp) === 'package.json') {
84
- plugin.hasPackageJson = true;
83
+ this.hasPackageJson = true;
85
84
  }
86
85
  }
87
86
  catch (ignore) {}
@@ -155,9 +154,8 @@ class Plugin {
155
154
  }
156
155
 
157
156
  _make_custom_require () {
158
- const plugin = this;
159
157
  return module => {
160
- if (plugin.hasPackageJson) {
158
+ if (this.hasPackageJson) {
161
159
  const mod = require(module);
162
160
  constants.import(global);
163
161
  global.server = plugins.server;
@@ -165,7 +163,7 @@ class Plugin {
165
163
  }
166
164
 
167
165
  if (module === './config') {
168
- return plugin.config;
166
+ return this.config;
169
167
  }
170
168
 
171
169
  if (!/^\./.test(module)) {
@@ -177,14 +175,13 @@ class Plugin {
177
175
  return require(module);
178
176
  }
179
177
 
180
- return require(path.join(path.dirname(plugin.plugin_path), module));
178
+ return require(path.join(path.dirname(this.plugin_path), module));
181
179
  };
182
180
  }
183
181
 
184
182
  _get_code (pp) {
185
- const plugin = this;
186
183
 
187
- if (plugin.hasPackageJson) {
184
+ if (this.hasPackageJson) {
188
185
  let packageDir = path.dirname(pp);
189
186
  if (/^win(32|64)/.test(process.platform)) {
190
187
  // escape the c:\path\back\slashes else they disappear
@@ -198,25 +195,24 @@ class Plugin {
198
195
  }
199
196
  catch (err) {
200
197
  if (exports.config.get('smtp.ini').main.ignore_bad_plugins) {
201
- logger.logcrit(`Loading plugin ${plugin.name} failed: ${err}`);
198
+ logger.logcrit(`Loading plugin ${this.name} failed: ${err}`);
202
199
  return;
203
200
  }
204
- throw `Loading plugin ${plugin.name} failed: ${err}`;
201
+ throw `Loading plugin ${this.name} failed: ${err}`;
205
202
  }
206
203
  }
207
204
 
208
205
  _compile () {
209
- const plugin = this;
210
206
 
211
- const pp = plugin.plugin_path;
212
- const code = plugin._get_code(pp);
207
+ const pp = this.plugin_path;
208
+ const code = this._get_code(pp);
213
209
  if (!code) return;
214
210
 
215
211
  const sandbox = {
216
- require: plugin._make_custom_require(),
212
+ require: this._make_custom_require(),
217
213
  __filename: pp,
218
214
  __dirname: path.dirname(pp),
219
- exports: plugin,
215
+ exports: this,
220
216
  setTimeout,
221
217
  clearTimeout,
222
218
  setInterval,
@@ -227,7 +223,7 @@ class Plugin {
227
223
  server: plugins.server,
228
224
  setImmediate
229
225
  };
230
- if (plugin.hasPackageJson) {
226
+ if (this.hasPackageJson) {
231
227
  delete sandbox.__filename;
232
228
  }
233
229
  constants.import(sandbox);
@@ -235,16 +231,16 @@ class Plugin {
235
231
  vm.runInNewContext(code, sandbox, pp);
236
232
  }
237
233
  catch (err) {
238
- logger.logcrit(`Compiling plugin: ${plugin.name} failed`);
234
+ logger.logcrit(`Compiling plugin: ${this.name} failed`);
239
235
  if (exports.config.get('smtp.ini').main.ignore_bad_plugins) {
240
- logger.logcrit(`Loading plugin ${plugin.name} failed: `,
236
+ logger.logcrit(`Loading plugin ${this.name} failed: `,
241
237
  `${err.message} - will skip this plugin and continue`);
242
238
  return;
243
239
  }
244
240
  throw err; // default is to re-throw and stop Haraka
245
241
  }
246
242
 
247
- return plugin;
243
+ return this;
248
244
  }
249
245
  }
250
246
 
@@ -331,8 +327,7 @@ plugins.load_plugins = override => {
331
327
 
332
328
  // Sort registered_hooks by priority
333
329
  const hooks = Object.keys(plugins.registered_hooks);
334
- for (let h=0; h<hooks.length; h++) {
335
- const hook = hooks[h];
330
+ for (const hook of hooks) {
336
331
  plugins.registered_hooks[hook].sort((a, b) => {
337
332
  if (a.priority < b.priority) return -1;
338
333
  if (a.priority > b.priority) return 1;
@@ -351,6 +346,7 @@ plugins.deprecated = {
351
346
  'connect.asn' : 'asn',
352
347
  'connect.fcrdns' : 'fcrdns',
353
348
  'connect.geoip' : 'geoip',
349
+ 'connect.p0f' : 'p0f',
354
350
  'connect.rdns_access' : 'access',
355
351
  'data.nomsgid' : 'headers',
356
352
  'data.noreceived' : 'headers',
@@ -439,8 +435,7 @@ plugins.run_hooks = (hook, object, params) => {
439
435
  object.hooks_to_run = [];
440
436
 
441
437
  if (plugins.registered_hooks[hook]) {
442
- for (let i=0; i<plugins.registered_hooks[hook].length; i++) {
443
- const item = plugins.registered_hooks[hook][i];
438
+ for (const item of plugins.registered_hooks[hook]) {
444
439
  const plugin = plugins.registered_plugins[item.plugin];
445
440
  object.hooks_to_run.push([plugin, item.method]);
446
441
  }
@@ -529,7 +524,7 @@ plugins.run_next_hook = (hook, object, params) => {
529
524
  object.logdebug(`running ${hook} hook in ${item[0].name} plugin`);
530
525
  }
531
526
 
532
- if (object.transaction && object.transaction.notes.skip_plugins.includes(item[0].name)) {
527
+ if (object.transaction?.notes.skip_plugins.includes(item[0].name)) {
533
528
  object.logdebug(`skipping ${item[0].name}_${hook} by request in notes`);
534
529
  return callback();
535
530
  }
package/rfc1869.js CHANGED
@@ -86,8 +86,8 @@ exports.parse = (type, line, strict) => {
86
86
  else if (line.match(/@/)) {
87
87
  if (!line.match(/^<.*>$/)) line = `<${line}>`;
88
88
  }
89
- else if (!line.match(/^(postmaster|abuse)$/i)) {
90
- throw new Error('Syntax error in address');
89
+ else if (!line.match(/^<(postmaster|abuse)>$/i)) {
90
+ throw new Error(`Syntax error in address: ${line}`);
91
91
  }
92
92
  }
93
93
  }
package/server.js CHANGED
@@ -22,7 +22,7 @@ Server.config = require('haraka-config');
22
22
  Server.plugins = require('./plugins');
23
23
  Server.notes = {};
24
24
 
25
- const logger = Server.logger;
25
+ const { logger } = Server;
26
26
 
27
27
  // Need these here so we can run hooks
28
28
  logger.add_log_methods(Server, 'server');
@@ -233,16 +233,6 @@ Server._graceful = shutdown => {
233
233
  });
234
234
  }
235
235
 
236
- Server.drainPools = () => {
237
- if (!Server.cluster) {
238
- return outbound.drain_pools();
239
- }
240
-
241
- for (const id in cluster.workers) {
242
- cluster.workers[id].send({event: 'outbound.drain_pools'});
243
- }
244
- }
245
-
246
236
  Server.sendToMaster = (command, params) => {
247
237
  // console.log("Send to master: ", command);
248
238
  if (Server.cluster) {
@@ -274,7 +264,7 @@ function messageHandler (worker, msg, handle) {
274
264
  worker = undefined;
275
265
  }
276
266
  // console.log("received cmd: ", msg);
277
- if (msg && msg.cmd) {
267
+ if (msg?.cmd) {
278
268
  Server.receiveAsMaster(msg.cmd, msg.params);
279
269
  }
280
270
  }
@@ -282,7 +272,7 @@ function messageHandler (worker, msg, handle) {
282
272
  Server.get_listen_addrs = (cfg, port) => {
283
273
  if (!port) port = 25;
284
274
  let listeners = [];
285
- if (cfg && cfg.listen) {
275
+ if (cfg?.listen) {
286
276
  listeners = cfg.listen.split(/\s*,\s*/);
287
277
  if (listeners[0] === '') listeners = [];
288
278
  for (let i=0; i < listeners.length; i++) {