Haraka 2.8.28 → 3.0.0

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 (134) hide show
  1. package/.eslintrc.yaml +2 -10
  2. package/Changes.md +68 -2
  3. package/Dockerfile +1 -1
  4. package/Plugins.md +7 -4
  5. package/README.md +2 -6
  6. package/config/outbound.ini +0 -7
  7. package/config/plugins +1 -1
  8. package/config/smtp.ini +1 -1
  9. package/config/smtp_forward.ini +2 -8
  10. package/config/smtp_proxy.ini +0 -6
  11. package/connection.js +178 -204
  12. package/coverage/lcov.info +13863 -0
  13. package/coverage/tmp/coverage-42958-1658373250585-0.json +1 -0
  14. package/coverage/tmp/coverage-42961-1658373250529-0.json +1 -0
  15. package/dkim.js +65 -73
  16. package/docs/Body.md +1 -22
  17. package/docs/CoreConfig.md +2 -2
  18. package/docs/Header.md +1 -47
  19. package/docs/Outbound.md +8 -36
  20. package/endpoint.js +1 -1
  21. package/haraka.js +1 -1
  22. package/host_pool.js +8 -12
  23. package/logger.js +25 -32
  24. package/outbound/client_pool.js +11 -153
  25. package/outbound/config.js +5 -11
  26. package/outbound/hmail.js +109 -143
  27. package/outbound/index.js +13 -25
  28. package/outbound/mx_lookup.js +10 -7
  29. package/outbound/queue.js +8 -12
  30. package/outbound/timer_queue.js +2 -4
  31. package/outbound/tls.js +17 -18
  32. package/outbound/todo.js +1 -0
  33. package/package.json +42 -40
  34. package/plugins/auth/auth_base.js +39 -63
  35. package/plugins/auth/auth_bridge.js +3 -4
  36. package/plugins/auth/auth_proxy.js +16 -16
  37. package/plugins/auth/auth_vpopmaild.js +30 -37
  38. package/plugins/auth/flat_file.js +9 -13
  39. package/plugins/avg.js +9 -11
  40. package/plugins/backscatterer.js +1 -1
  41. package/plugins/block_me.js +2 -6
  42. package/plugins/bounce.js +106 -124
  43. package/plugins/clamd.js +59 -63
  44. package/plugins/data.signatures.js +6 -6
  45. package/plugins/data.uribl.js +1 -415
  46. package/plugins/delay_deny.js +19 -20
  47. package/plugins/dkim_sign.js +56 -62
  48. package/plugins/dkim_verify.js +9 -8
  49. package/plugins/dns_list_base.js +43 -42
  50. package/plugins/dnsbl.js +41 -46
  51. package/plugins/dnswl.js +23 -26
  52. package/plugins/early_talker.js +24 -28
  53. package/plugins/esets.js +8 -11
  54. package/plugins/greylist.js +161 -190
  55. package/plugins/helo.checks.js +175 -197
  56. package/plugins/mail_from.is_resolvable.js +38 -38
  57. package/plugins/messagesniffer.js +33 -40
  58. package/plugins/prevent_credential_leaks.js +7 -5
  59. package/plugins/process_title.js +16 -17
  60. package/plugins/queue/deliver.js +2 -2
  61. package/plugins/queue/lmtp.js +5 -6
  62. package/plugins/queue/qmail-queue.js +11 -13
  63. package/plugins/queue/quarantine.js +25 -34
  64. package/plugins/queue/rabbitmq.js +3 -2
  65. package/plugins/queue/rabbitmq_amqplib.js +9 -9
  66. package/plugins/queue/smtp_bridge.js +5 -4
  67. package/plugins/queue/smtp_forward.js +81 -89
  68. package/plugins/queue/smtp_proxy.js +21 -22
  69. package/plugins/queue/test.js +2 -1
  70. package/plugins/rcpt_to.host_list_base.js +20 -30
  71. package/plugins/rcpt_to.in_host_list.js +12 -14
  72. package/plugins/rcpt_to.max_count.js +7 -5
  73. package/plugins/record_envelope_addresses.js +4 -6
  74. package/plugins/relay.js +64 -74
  75. package/plugins/reseed_rng.js +1 -2
  76. package/plugins/spamassassin.js +56 -68
  77. package/plugins/status.js +2 -3
  78. package/plugins/tarpit.js +8 -11
  79. package/plugins/tls.js +14 -17
  80. package/plugins/toobusy.js +6 -8
  81. package/plugins/xclient.js +14 -25
  82. package/plugins.js +24 -29
  83. package/rfc1869.js +2 -2
  84. package/server.js +3 -13
  85. package/smtp_client.js +138 -215
  86. package/tests/config/smtp_forward.ini +0 -6
  87. package/tests/fixtures/line_socket.js +1 -1
  88. package/tests/fixtures/util_hmailitem.js +5 -7
  89. package/tests/fixtures/vm_harness.js +2 -2
  90. package/tests/host_pool.js +13 -14
  91. package/tests/installation/plugins/inherits.js +1 -2
  92. package/tests/logger.js +2 -2
  93. package/tests/plugins/bounce.js +6 -8
  94. package/tests/plugins/dkim_signer.js +7 -7
  95. package/tests/plugins/dns_list_base.js +7 -7
  96. package/tests/plugins/helo.checks.js +1 -1
  97. package/tests/plugins/mail_from.is_resolvable.js +10 -54
  98. package/tests/plugins/queue/smtp_forward.js +11 -11
  99. package/tests/plugins/rcpt_to.host_list_base.js +1 -1
  100. package/tests/plugins/rcpt_to.in_host_list.js +1 -1
  101. package/tests/plugins/spamassassin.js +1 -1
  102. package/tests/queue/multibyte +0 -0
  103. package/tests/queue/plain +0 -0
  104. package/tests/rfc1869.js +4 -1
  105. package/tests/server.js +15 -9
  106. package/tests/smtp_client/auth.js +4 -14
  107. package/tests/smtp_client/basic.js +5 -15
  108. package/tests/smtp_client.js +7 -3
  109. package/tests/transaction.js +72 -19
  110. package/tls_socket.js +75 -85
  111. package/transaction.js +7 -9
  112. package/attachment_stream.js +0 -118
  113. package/bin/spf +0 -48
  114. package/chunkemitter.js +0 -75
  115. package/config/data.uribl.excludes +0 -202
  116. package/config/data.uribl.ini +0 -37
  117. package/config/spf.ini +0 -1
  118. package/docs/plugins/attachment.md +0 -92
  119. package/docs/plugins/data.uribl.md +0 -120
  120. package/docs/plugins/spf.md +0 -142
  121. package/mailbody.js +0 -502
  122. package/mailheader.js +0 -304
  123. package/messagestream.js +0 -441
  124. package/plugins/aliases.js +0 -120
  125. package/plugins/attachment.js +0 -503
  126. package/plugins/connect.p0f.js +0 -5
  127. package/plugins/spf.js +0 -327
  128. package/spf.js +0 -689
  129. package/tests/mailbody.js +0 -348
  130. package/tests/mailheader.js +0 -138
  131. package/tests/messagestream.js +0 -34
  132. package/tests/plugins/aliases.js +0 -376
  133. package/tests/plugins/spf.js +0 -251
  134. 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++) {