Haraka 3.0.2 → 3.0.4

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 (267) hide show
  1. package/.eslintrc.yaml +5 -9
  2. package/.prettierrc.yml +1 -0
  3. package/CONTRIBUTORS.md +11 -0
  4. package/Changes.md +1393 -1211
  5. package/Dockerfile +3 -3
  6. package/Plugins.md +119 -106
  7. package/README.md +7 -16
  8. package/TODO +1 -24
  9. package/bin/haraka +197 -298
  10. package/config/auth_flat_file.ini +2 -0
  11. package/config/auth_vpopmaild.ini +4 -2
  12. package/config/dhparams.pem +8 -0
  13. package/config/mail_from.is_resolvable.ini +4 -2
  14. package/config/me +1 -0
  15. package/config/outbound.ini +0 -2
  16. package/config/plugins +36 -35
  17. package/config/rabbitmq_amqplib.ini +8 -1
  18. package/config/smtp.ini +0 -1
  19. package/config/smtp.json +17 -0
  20. package/config/tls_cert.pem +23 -0
  21. package/config/tls_key.pem +28 -0
  22. package/connection.js +46 -73
  23. package/contrib/bsd-rc.d/haraka +3 -1
  24. package/contrib/plugin2npm.sh +6 -36
  25. package/docs/Connection.md +1 -1
  26. package/docs/CoreConfig.md +2 -2
  27. package/docs/Logging.md +7 -21
  28. package/docs/Outbound.md +104 -210
  29. package/docs/Plugins.md +47 -40
  30. package/docs/Transaction.md +59 -82
  31. package/docs/{plugins → deprecated}/connect.rdns_access.md +1 -1
  32. package/docs/{plugins → deprecated}/mail_from.access.md +1 -1
  33. package/docs/{plugins → deprecated}/rcpt_to.access.md +1 -1
  34. package/docs/plugins/auth/auth_vpopmaild.md +15 -19
  35. package/docs/plugins/auth/flat_file.md +23 -30
  36. package/docs/plugins/queue/rabbitmq_amqplib.md +7 -0
  37. package/docs/plugins/queue/smtp_forward.md +1 -1
  38. package/docs/plugins/queue/smtp_proxy.md +5 -10
  39. package/docs/plugins/relay.md +2 -2
  40. package/docs/plugins/tls.md +29 -9
  41. package/endpoint.js +16 -13
  42. package/haraka.js +10 -14
  43. package/host_pool.js +5 -5
  44. package/line_socket.js +3 -4
  45. package/logger.js +44 -28
  46. package/outbound/client_pool.js +27 -23
  47. package/outbound/config.js +4 -6
  48. package/outbound/fsync_writestream.js +1 -1
  49. package/outbound/hmail.js +180 -220
  50. package/outbound/index.js +86 -99
  51. package/outbound/qfile.js +1 -1
  52. package/outbound/queue.js +55 -43
  53. package/outbound/timer_queue.js +3 -2
  54. package/outbound/tls.js +19 -7
  55. package/package.json +66 -55
  56. package/plugins/.eslintrc.yaml +0 -6
  57. package/plugins/auth/auth_base.js +30 -12
  58. package/plugins/auth/auth_proxy.js +14 -12
  59. package/plugins/auth/auth_vpopmaild.js +30 -20
  60. package/plugins/auth/flat_file.js +17 -12
  61. package/plugins/block_me.js +1 -1
  62. package/plugins/data.signatures.js +2 -4
  63. package/plugins/early_talker.js +2 -1
  64. package/plugins/mail_from.is_resolvable.js +65 -135
  65. package/plugins/queue/deliver.js +4 -5
  66. package/plugins/queue/lmtp.js +11 -14
  67. package/plugins/queue/qmail-queue.js +2 -2
  68. package/plugins/queue/quarantine.js +2 -2
  69. package/plugins/queue/rabbitmq.js +16 -17
  70. package/plugins/queue/rabbitmq_amqplib.js +1 -1
  71. package/plugins/queue/smtp_forward.js +6 -6
  72. package/plugins/queue/smtp_proxy.js +10 -1
  73. package/plugins/queue/test.js +2 -2
  74. package/plugins/rcpt_to.host_list_base.js +5 -5
  75. package/plugins/rcpt_to.in_host_list.js +2 -2
  76. package/plugins/relay.js +6 -7
  77. package/plugins/reseed_rng.js +1 -1
  78. package/plugins/status.js +37 -33
  79. package/plugins/tls.js +2 -2
  80. package/plugins/xclient.js +3 -2
  81. package/plugins.js +51 -54
  82. package/run_tests +3 -30
  83. package/server.js +190 -190
  84. package/smtp_client.js +30 -23
  85. package/{tests → test}/config/plugins +0 -2
  86. package/{tests → test}/config/smtp.ini +1 -1
  87. package/test/config/tls/example.com/_.example.com.key +28 -0
  88. package/test/config/tls/example.com/example.com.crt +25 -0
  89. package/test/connection.js +302 -0
  90. package/test/endpoint.js +94 -0
  91. package/{tests → test}/fixtures/line_socket.js +1 -1
  92. package/{tests → test}/fixtures/util_hmailitem.js +19 -25
  93. package/{tests → test}/host_pool.js +42 -57
  94. package/test/logger.js +258 -0
  95. package/test/outbound/hmail.js +141 -0
  96. package/test/outbound/index.js +220 -0
  97. package/test/outbound/qfile.js +126 -0
  98. package/test/outbound_bounce_net_errors.js +142 -0
  99. package/{tests → test}/outbound_bounce_rfc3464.js +110 -122
  100. package/test/plugins/auth/auth_base.js +484 -0
  101. package/test/plugins/auth/auth_vpopmaild.js +83 -0
  102. package/test/plugins/early_talker.js +104 -0
  103. package/test/plugins/mail_from.is_resolvable.js +35 -0
  104. package/test/plugins/queue/smtp_forward.js +206 -0
  105. package/test/plugins/rcpt_to.host_list_base.js +122 -0
  106. package/test/plugins/rcpt_to.in_host_list.js +193 -0
  107. package/test/plugins/relay.js +303 -0
  108. package/test/plugins/status.js +130 -0
  109. package/test/plugins/tls.js +70 -0
  110. package/test/plugins.js +228 -0
  111. package/{tests → test}/queue/multibyte +0 -0
  112. package/{tests → test}/queue/plain +0 -0
  113. package/test/rfc1869.js +73 -0
  114. package/test/server.js +491 -0
  115. package/test/smtp_client.js +299 -0
  116. package/test/tls_socket.js +273 -0
  117. package/test/transaction.js +270 -0
  118. package/tls_socket.js +202 -252
  119. package/transaction.js +9 -24
  120. package/CONTRIBUTING.md +0 -1
  121. package/bin/dkimverify +0 -40
  122. package/config/access.domains +0 -13
  123. package/config/attachment.ctype.regex +0 -2
  124. package/config/attachment.filename.regex +0 -1
  125. package/config/avg.ini +0 -5
  126. package/config/bounce.ini +0 -15
  127. package/config/data.headers.ini +0 -61
  128. package/config/dkim/dkim_key_gen.sh +0 -78
  129. package/config/dkim_sign.ini +0 -4
  130. package/config/dkim_verify.ini +0 -7
  131. package/config/dnsbl.ini +0 -23
  132. package/config/greylist.ini +0 -43
  133. package/config/helo.checks.ini +0 -52
  134. package/config/lookup_rdns.strict.ini +0 -12
  135. package/config/lookup_rdns.strict.timeout +0 -1
  136. package/config/lookup_rdns.strict.whitelist +0 -1
  137. package/config/lookup_rdns.strict.whitelist_regex +0 -5
  138. package/config/messagesniffer.ini +0 -18
  139. package/config/rcpt_to.blocklist +0 -1
  140. package/config/rdns.allow_regexps +0 -0
  141. package/config/rdns.deny_regexps +0 -0
  142. package/config/spamassassin.ini +0 -56
  143. package/config.js +0 -6
  144. package/dkim.js +0 -614
  145. package/docs/plugins/avg.md +0 -35
  146. package/docs/plugins/bounce.md +0 -69
  147. package/docs/plugins/clamd.md +0 -147
  148. package/docs/plugins/esets.md +0 -8
  149. package/docs/plugins/greylist.md +0 -90
  150. package/docs/plugins/helo.checks.md +0 -135
  151. package/docs/plugins/messagesniffer.md +0 -163
  152. package/docs/plugins/relay_acl.md +0 -29
  153. package/docs/plugins/relay_all.md +0 -15
  154. package/docs/plugins/relay_force_routing.md +0 -33
  155. package/docs/plugins/spamassassin.md +0 -180
  156. package/outbound/mx_lookup.js +0 -70
  157. package/plugins/auth/auth_ldap.js +0 -3
  158. package/plugins/avg.js +0 -162
  159. package/plugins/backscatterer.js +0 -25
  160. package/plugins/bounce.js +0 -381
  161. package/plugins/clamd.js +0 -381
  162. package/plugins/data.headers.js +0 -4
  163. package/plugins/data.uribl.js +0 -4
  164. package/plugins/dkim_sign.js +0 -395
  165. package/plugins/dkim_verify.js +0 -62
  166. package/plugins/dns_list_base.js +0 -221
  167. package/plugins/dnsbl.js +0 -146
  168. package/plugins/dnswl.js +0 -58
  169. package/plugins/esets.js +0 -71
  170. package/plugins/graph.js +0 -5
  171. package/plugins/greylist.js +0 -645
  172. package/plugins/helo.checks.js +0 -533
  173. package/plugins/messagesniffer.js +0 -381
  174. package/plugins/rcpt_to.ldap.js +0 -3
  175. package/plugins/rcpt_to.max_count.js +0 -24
  176. package/plugins/relay_all.js +0 -13
  177. package/plugins/spamassassin.js +0 -384
  178. package/tests/config/dkim/example.com/dns +0 -29
  179. package/tests/config/dkim/example.com/private +0 -6
  180. package/tests/config/dkim/example.com/public +0 -4
  181. package/tests/config/dkim/example.com/selector +0 -1
  182. package/tests/config/dkim.private.key +0 -6
  183. package/tests/config/dkim_sign.ini +0 -4
  184. package/tests/config/helo.checks.ini +0 -52
  185. package/tests/connection.js +0 -327
  186. package/tests/endpoint.js +0 -128
  187. package/tests/fixtures/vm_harness.js +0 -59
  188. package/tests/logger.js +0 -327
  189. package/tests/outbound/hmail.js +0 -112
  190. package/tests/outbound/index.js +0 -324
  191. package/tests/outbound/qfile.js +0 -67
  192. package/tests/outbound_bounce_net_errors.js +0 -173
  193. package/tests/plugins/auth/auth_base.js +0 -463
  194. package/tests/plugins/auth/auth_vpopmaild.js +0 -91
  195. package/tests/plugins/bounce.js +0 -307
  196. package/tests/plugins/clamd.js +0 -224
  197. package/tests/plugins/deprecated/relay_acl.js +0 -140
  198. package/tests/plugins/deprecated/relay_all.js +0 -59
  199. package/tests/plugins/dkim_sign.js +0 -315
  200. package/tests/plugins/dkim_signer.js +0 -108
  201. package/tests/plugins/dns_list_base.js +0 -259
  202. package/tests/plugins/dnsbl.js +0 -101
  203. package/tests/plugins/early_talker.js +0 -115
  204. package/tests/plugins/greylist.js +0 -58
  205. package/tests/plugins/helo.checks.js +0 -525
  206. package/tests/plugins/mail_from.is_resolvable.js +0 -116
  207. package/tests/plugins/queue/smtp_forward.js +0 -221
  208. package/tests/plugins/rcpt_to.host_list_base.js +0 -132
  209. package/tests/plugins/rcpt_to.in_host_list.js +0 -218
  210. package/tests/plugins/relay.js +0 -339
  211. package/tests/plugins/spamassassin.js +0 -171
  212. package/tests/plugins/status.js +0 -138
  213. package/tests/plugins/tls.js +0 -84
  214. package/tests/plugins.js +0 -247
  215. package/tests/rfc1869.js +0 -61
  216. package/tests/server.js +0 -510
  217. package/tests/smtp_client/auth.js +0 -105
  218. package/tests/smtp_client/basic.js +0 -101
  219. package/tests/smtp_client.js +0 -80
  220. package/tests/tls_socket.js +0 -333
  221. package/tests/transaction.js +0 -284
  222. /package/docs/{plugins → deprecated}/dkim_sign.md +0 -0
  223. /package/docs/{plugins → deprecated}/dkim_verify.md +0 -0
  224. /package/docs/{plugins → deprecated}/dnsbl.md +0 -0
  225. /package/docs/{plugins → deprecated}/dnswl.md +0 -0
  226. /package/docs/{plugins → deprecated}/rcpt_to.routes.md +0 -0
  227. /package/{tests → test}/.eslintrc.yaml +0 -0
  228. /package/{tests → test}/config/auth_flat_file.ini +0 -0
  229. /package/{tests → test}/config/dhparams.pem +0 -0
  230. /package/{tests → test}/config/host_list +0 -0
  231. /package/{tests → test}/config/outbound_tls_cert.pem +0 -0
  232. /package/{tests → test}/config/outbound_tls_key.pem +0 -0
  233. /package/{tests → test}/config/smtp_forward.ini +0 -0
  234. /package/{tests → test}/config/tls/ec.pem +0 -0
  235. /package/{tests → test}/config/tls/haraka.local.pem +0 -0
  236. /package/{tests → test}/config/tls/mismatched.pem +0 -0
  237. /package/{tests → test}/config/tls.ini +0 -0
  238. /package/{tests → test}/config/tls_cert.pem +0 -0
  239. /package/{tests → test}/config/tls_key.pem +0 -0
  240. /package/{tests → test}/fixtures/todo_qfile.txt +0 -0
  241. /package/{tests → test}/installation/config/test-plugin-flat +0 -0
  242. /package/{tests → test}/installation/config/test-plugin.ini +0 -0
  243. /package/{tests → test}/installation/config/tls.ini +0 -0
  244. /package/{tests → test}/installation/node_modules/load_first/index.js +0 -0
  245. /package/{tests → test}/installation/node_modules/load_first/package.json +0 -0
  246. /package/{tests → test}/installation/node_modules/test-plugin/config/test-plugin-flat +0 -0
  247. /package/{tests → test}/installation/node_modules/test-plugin/config/test-plugin.ini +0 -0
  248. /package/{tests → test}/installation/node_modules/test-plugin/package.json +0 -0
  249. /package/{tests → test}/installation/node_modules/test-plugin/test-plugin.js +0 -0
  250. /package/{tests → test}/installation/plugins/base_plugin.js +0 -0
  251. /package/{tests → test}/installation/plugins/folder_plugin/index.js +0 -0
  252. /package/{tests → test}/installation/plugins/folder_plugin/package.json +0 -0
  253. /package/{tests → test}/installation/plugins/inherits.js +0 -0
  254. /package/{tests → test}/installation/plugins/load_first.js +0 -0
  255. /package/{tests → test}/installation/plugins/plugin.js +0 -0
  256. /package/{tests → test}/installation/plugins/tls.js +0 -0
  257. /package/{tests → test}/loud/config/dhparams.pem +0 -0
  258. /package/{tests → test}/loud/config/tls/goobered.pem +0 -0
  259. /package/{tests → test}/loud/config/tls.ini +0 -0
  260. /package/{tests → test}/mail_specimen/base64-root-part.txt +0 -0
  261. /package/{tests → test}/mail_specimen/varied-fold-lengths-preserve-data.txt +0 -0
  262. /package/{tests → test}/queue/1507509981169_1507509981169_0_61403_e0Y0Ym_1_fixed +0 -0
  263. /package/{tests → test}/queue/1507509981169_1507509981169_0_61403_e0Y0Ym_1_haraka +0 -0
  264. /package/{tests → test}/queue/1508269674999_1508269674999_0_34002_socVUF_1_haraka +0 -0
  265. /package/{tests → test}/queue/1508455115683_1508455115683_0_90253_9Q4o4V_1_haraka +0 -0
  266. /package/{tests → test}/queue/zero-length +0 -0
  267. /package/{tests → test}/test-queue/delete-me +0 -0
package/plugins/status.js CHANGED
@@ -1,8 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const fs = require('fs');
4
- const path = require('path');
5
- const async = require('async');
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
6
5
 
7
6
  exports.register = function () {
8
7
  this.outbound = require('../outbound');
@@ -81,38 +80,36 @@ exports.pool_list = cb => {
81
80
  const result = {};
82
81
 
83
82
  if (server.notes.pool) {
84
- Object.keys(server.notes.pool).forEach(name => {
83
+ for (const name of Object.keys(server.notes.pool)) {
85
84
  const instance = server.notes.pool[name];
86
85
 
87
86
  result[name] = {
88
87
  inUse: instance.inUseObjectsCount(),
89
88
  size: instance.getPoolSize()
90
89
  };
91
- });
90
+ }
92
91
  }
93
92
 
94
93
  cb(null, result);
95
94
  }
96
95
 
97
96
  exports.queue_list = function (cb) {
98
- this.outbound.list_queue((err, qlist) => {
99
- if (err) cb(err);
100
-
97
+ this.outbound.list_queue((err, qlist = []) => {
101
98
  const result = [];
102
99
 
103
- if (qlist) {
104
- qlist.forEach((todo) => result.push({
100
+ for (const todo of qlist) {
101
+ result.push({
105
102
  file: todo.file,
106
103
  uuid: todo.uuid,
107
104
  queue_time: todo.queue_time,
108
105
  domain: todo.domain,
109
106
  from: todo.mail_from.toString(),
110
107
  to: todo.rcpt_to.map((r) => r.toString())
111
- }));
108
+ })
112
109
  }
113
110
 
114
111
  cb(err, result);
115
- });
112
+ })
116
113
  }
117
114
 
118
115
  exports.queue_stats = function (cb) {
@@ -165,14 +162,14 @@ exports.queue_push = function (file, cb) {
165
162
  // cluster IPC
166
163
 
167
164
  exports.hook_init_master = function (next) {
168
- const self = this;
165
+ const plugin = this;
169
166
 
170
167
  if (!server.cluster) return next();
171
168
 
172
169
  function message_handler (sender, msg) {
173
170
  if (msg.event !== 'status.request') return;
174
171
 
175
- self.call_workers(msg, (err, response) => {
172
+ plugin.call_workers(msg, (response) => {
176
173
  msg.result = response.filter((el) => el != null);
177
174
  msg.event = 'status.result';
178
175
  sender.send(msg);
@@ -214,32 +211,39 @@ exports.call_master = (cmd, cb) => {
214
211
  }
215
212
 
216
213
  exports.call_workers = function (cmd, cb) {
217
-
218
- async.map(server.cluster.workers, (w, done) => {
219
- this.call_worker(w, cmd, done);
220
- }, cb);
214
+ Promise.allSettled(
215
+ Object.values(server.cluster.workers).map(w => this.call_worker(w, cmd))
216
+ )
217
+ .then(r => {
218
+ cb(
219
+ // r.filter(s => s.status === 'rejected').flatMap(s => s.reason),
220
+ r.filter(s => s.status === 'fulfilled').flatMap(s => s.value),
221
+ )
222
+ })
221
223
  }
222
224
 
223
225
  // sends command to worker and then wait for response or timeout
224
- exports.call_worker = (worker, cmd, cb) => {
225
- let timeout;
226
+ exports.call_worker = (worker, cmd) => {
227
+ return new Promise((resolve) => {
228
+ let timeout;
226
229
 
227
- function message_handler (sender, msg) {
228
- if (sender.id !== worker.id) return;
229
- if (msg.event !== 'status.response') return;
230
+ function message_handler (sender, msg) {
231
+ if (sender.id !== worker.id) return;
232
+ if (msg.event !== 'status.response') return;
230
233
 
231
- clearTimeout(timeout);
232
- server.cluster.removeListener('message', message_handler);
234
+ clearTimeout(timeout);
235
+ server.cluster.removeListener('message', message_handler);
233
236
 
234
- cb(null, msg.result);
235
- }
237
+ resolve(msg.result);
238
+ }
236
239
 
237
- timeout = setTimeout(() => {
238
- server.cluster.removeListener('message', message_handler);
239
- cb();
240
- }, 1000);
240
+ timeout = setTimeout(() => {
241
+ server.cluster.removeListener('message', message_handler);
242
+ resolve();
243
+ }, 1000);
241
244
 
242
245
 
243
- server.cluster.on('message', message_handler);
244
- worker.send(cmd);
246
+ server.cluster.on('message', message_handler);
247
+ worker.send(cmd);
248
+ })
245
249
  }
package/plugins/tls.js CHANGED
@@ -123,7 +123,7 @@ exports.upgrade_connection = function (next, connection, params) {
123
123
 
124
124
  connection.results.add(plugin, connection.tls);
125
125
  plugin.emit_upgrade_msg(connection, verified, verifyErr, cert, cipher);
126
- return next(OK); // Return OK as we responded to the client
126
+ next(OK);
127
127
  })
128
128
  })
129
129
  }
@@ -132,7 +132,7 @@ exports.hook_disconnect = (next, connection) => {
132
132
  if (connection.notes.cleanUpDisconnect) {
133
133
  connection.notes.cleanUpDisconnect(true);
134
134
  }
135
- return next();
135
+ next();
136
136
  }
137
137
 
138
138
  exports.emit_upgrade_msg = function (conn, verified, verifyErr, cert, cipher) {
@@ -1,9 +1,10 @@
1
1
  // Implementation of XCLIENT protocol
2
2
  // See http://www.postfix.org/XCLIENT_README.html
3
3
 
4
+ const net = require('node:net');
5
+
4
6
  const utils = require('haraka-utils');
5
7
  const DSN = require('haraka-dsn');
6
- const net = require('net');
7
8
  let allowed_hosts = {};
8
9
 
9
10
  exports.register = function () {
@@ -119,5 +120,5 @@ exports.hook_unrecognized_command = function (next, connection, params) {
119
120
  connection.xclient = true;
120
121
  if (!xclient.name) return next(NEXT_HOOK, 'lookup_rdns');
121
122
 
122
- return next(NEXT_HOOK, 'connect');
123
+ next(NEXT_HOOK, 'connect');
123
124
  }
package/plugins.js CHANGED
@@ -2,9 +2,9 @@
2
2
  // load all defined plugins
3
3
 
4
4
  // node built-ins
5
- const fs = require('fs');
6
- const path = require('path');
7
- const vm = require('vm');
5
+ const fs = require('node:fs');
6
+ const path = require('node:path');
7
+ const vm = require('node:vm');
8
8
 
9
9
  // npm modules
10
10
  exports.config = require('haraka-config');
@@ -74,8 +74,8 @@ class Plugin {
74
74
 
75
75
  // development mode
76
76
  paths = paths.concat(plugin_search_paths(__dirname, name));
77
- paths.forEach(pp => {
78
- if (this.plugin_path) return;
77
+ for (const pp of paths) {
78
+ if (this.plugin_path) continue;
79
79
  try {
80
80
  fs.statSync(pp);
81
81
  this.plugin_path = pp;
@@ -84,7 +84,7 @@ class Plugin {
84
84
  }
85
85
  }
86
86
  catch (ignore) {}
87
- });
87
+ }
88
88
  }
89
89
 
90
90
  _get_config () {
@@ -128,8 +128,7 @@ class Plugin {
128
128
  this.hooks[hook_name] = this.hooks[hook_name] || [];
129
129
  this.hooks[hook_name].push(method_name);
130
130
 
131
- logger.logdebug(`registered hook ${hook_name} to ${this.name}.` +
132
- `${method_name} priority ${priority}`);
131
+ plugins.logdebug(`registered hook ${hook_name} to ${this.name}.${method_name} priority ${priority}`);
133
132
  }
134
133
 
135
134
  register () {} // noop
@@ -140,12 +139,6 @@ class Plugin {
140
139
  if (!this[method]) {
141
140
  this[method] = parent_plugin[method];
142
141
  }
143
- // else if (method == 'shutdown') {
144
- // Method is in this module, so it exists in the plugin
145
- // if (!this.hasOwnProperty('shutdown')) {
146
- // this[method] = parent_plugin[method];
147
- // }
148
- // }
149
142
  }
150
143
  if (parent_plugin.register) {
151
144
  parent_plugin.register.call(this);
@@ -195,7 +188,7 @@ class Plugin {
195
188
  }
196
189
  catch (err) {
197
190
  if (exports.config.get('smtp.ini').main.ignore_bad_plugins) {
198
- logger.logcrit(`Loading plugin ${this.name} failed: ${err}`);
191
+ plugins.logcrit(`Loading ${this.name} failed: ${err}`);
199
192
  return;
200
193
  }
201
194
  throw `Loading plugin ${this.name} failed: ${err}`;
@@ -231,16 +224,13 @@ class Plugin {
231
224
  vm.runInNewContext(code, sandbox, pp);
232
225
  }
233
226
  catch (err) {
234
- logger.logcrit(`Compiling plugin: ${this.name} failed`);
227
+ plugins.logcrit(`compiling '${this.name}' failed`);
235
228
  if (exports.config.get('smtp.ini').main.ignore_bad_plugins) {
236
- logger.logcrit(`Loading plugin ${this.name} failed: `,
237
- `${err.message} - will skip this plugin and continue`);
229
+ plugins.logcrit(`Loading '${this.name}' failed: ${err.message} - skipping`);
238
230
  return;
239
231
  }
240
232
  throw err; // default is to re-throw and stop Haraka
241
233
  }
242
-
243
- return this;
244
234
  }
245
235
  }
246
236
 
@@ -254,7 +244,7 @@ exports.shutdown_plugins = () => {
254
244
 
255
245
  process.on('message', msg => {
256
246
  if (msg.event && msg.event == 'plugins.shutdown') {
257
- logger.loginfo("[plugins] Shutting down plugins");
247
+ plugins.loginfo("Shutting down");
258
248
  exports.shutdown_plugins();
259
249
  }
260
250
  });
@@ -270,39 +260,28 @@ function plugin_search_paths (prefix, name) {
270
260
  function get_timeout (name) {
271
261
  let timeout = parseFloat((exports.config.get(`${name}.timeout`)));
272
262
  if (isNaN(timeout)) {
273
- logger.logdebug(`no timeout in ${name}.timeout`);
263
+ plugins.logdebug(`no timeout in ${name}.timeout`);
274
264
  timeout = parseFloat(exports.config.get('plugin_timeout'));
275
265
  }
276
266
  if (isNaN(timeout)) {
277
- logger.logdebug('no timeout in plugin_timeout');
267
+ plugins.logdebug('no timeout in plugin_timeout');
278
268
  timeout = 30;
279
269
  }
280
270
 
281
- logger.logdebug(`plugin ${name} timeout is: ${timeout}s`);
271
+ plugins.logdebug(`plugin ${name} timeout is: ${timeout}s`);
282
272
  return timeout;
283
273
  }
284
274
 
285
- // copy logger methods into Plugin:
286
- for (const key in logger) {
287
- if (!/^log\w/.test(key)) continue;
288
- // console.log(`adding Plugin.${key} method`);
289
- Plugin.prototype[key] = (function (lev) {
290
- return function () {
291
- const args = [this];
292
- for (let i=0, l=arguments.length; i<l; i++) {
293
- args.push(arguments[i]);
294
- }
295
- logger[lev].apply(logger, args);
296
- };
297
- })(key);
298
- }
275
+ logger.add_log_methods(Plugin)
299
276
 
300
277
  const plugins = exports;
301
278
 
279
+ logger.add_log_methods(plugins, 'plugins')
280
+
302
281
  plugins.Plugin = Plugin;
303
282
 
304
283
  plugins.load_plugins = override => {
305
- logger.loginfo('Loading plugins');
284
+ plugins.logdebug('Loading');
306
285
  let plugin_list;
307
286
  if (override) {
308
287
  if (!Array.isArray(override)) override = [ override ];
@@ -312,22 +291,21 @@ plugins.load_plugins = override => {
312
291
  plugin_list = exports.config.get('plugins', 'list');
313
292
  }
314
293
 
315
- plugin_list.forEach(plugin => {
294
+ for (let plugin of plugin_list) {
316
295
  if (plugin.startsWith('haraka-plugin-')) plugin = plugin.substr(14)
317
296
  if (plugins.deprecated[plugin]) {
318
- logger.lognotice(`the plugin ${plugin} has been replaced by '${plugins.deprecated[plugin]}'. Please update config/plugins`)
297
+ plugins.lognotice(`${plugin} has been replaced by '${plugins.deprecated[plugin]}'. Please update config/plugins`)
319
298
  plugins.load_plugin(plugins.deprecated[plugin]);
320
299
  }
321
300
  else {
322
301
  plugins.load_plugin(plugin);
323
302
  }
324
- });
303
+ }
325
304
 
326
305
  plugins.plugin_list = Object.keys(plugins.registered_plugins);
327
306
 
328
307
  // Sort registered_hooks by priority
329
- const hooks = Object.keys(plugins.registered_hooks);
330
- for (const hook of hooks) {
308
+ for (const hook of Object.keys(plugins.registered_hooks)) {
331
309
  plugins.registered_hooks[hook].sort((a, b) => {
332
310
  if (a.priority < b.priority) return -1;
333
311
  if (a.priority > b.priority) return 1;
@@ -343,6 +321,8 @@ plugins.load_plugins = override => {
343
321
  }
344
322
 
345
323
  plugins.deprecated = {
324
+ 'auth/auth_ldap' : 'auth-ldap',
325
+ 'backscatterer' : 'dns-list',
346
326
  'connect.asn' : 'asn',
347
327
  'connect.fcrdns' : 'fcrdns',
348
328
  'connect.geoip' : 'geoip',
@@ -352,6 +332,11 @@ plugins.deprecated = {
352
332
  'data.noreceived' : 'headers',
353
333
  'data.rfc5322_header_checks': 'headers',
354
334
  'data.headers' : 'headers',
335
+ 'dkim_sign' : 'dkim',
336
+ 'dkim_verify' : 'dkim',
337
+ 'data.uribl' : 'uribl',
338
+ 'dnsbl' : 'dns-list',
339
+ 'dnswl' : 'dns-list',
355
340
  'log.syslog' : 'syslog',
356
341
  'mail_from.access' : 'access',
357
342
  'mail_from.blocklist' : 'access',
@@ -360,14 +345,17 @@ plugins.deprecated = {
360
345
  'rate_limit' : 'limit',
361
346
  'rcpt_to.access' : 'access',
362
347
  'rcpt_to.blocklist' : 'access',
348
+ 'rcpt_to.ldap' : 'rcpt-ldap',
349
+ 'rcpt_to.max_count' : 'limit',
363
350
  'rcpt_to.qmail_deliverable' : 'qmail-deliverable',
364
351
  'rdns.regexp' : 'access',
365
352
  'relay_acl' : 'relay',
353
+ 'relay_all' : 'relay',
366
354
  'relay_force_routing' : 'relay',
367
355
  }
368
356
 
369
357
  plugins.load_plugin = name => {
370
- logger.loginfo(`Loading plugin: ${name}`);
358
+ plugins.loginfo(`loading ${name}`);
371
359
 
372
360
  const plugin = plugins._load_and_compile_plugin(name);
373
361
  if (plugin) {
@@ -375,7 +363,6 @@ plugins.load_plugin = name => {
375
363
  }
376
364
 
377
365
  plugins.registered_plugins[name] = plugin;
378
- return plugin;
379
366
  }
380
367
 
381
368
  // Set in server.js; initialized to empty object
@@ -387,7 +374,7 @@ plugins._load_and_compile_plugin = name => {
387
374
  if (!plugin.plugin_path) {
388
375
  const err = `Loading plugin ${plugin.name} failed: No plugin with this name found`;
389
376
  if (exports.config.get('smtp.ini').main.ignore_bad_plugins) {
390
- logger.logcrit(err);
377
+ plugins.logcrit(err);
391
378
  return;
392
379
  }
393
380
  throw err;
@@ -406,8 +393,6 @@ plugins._register_plugin = plugin => {
406
393
  plugin.register_hook(result[1], method);
407
394
  }
408
395
  }
409
-
410
- return plugin;
411
396
  }
412
397
 
413
398
  plugins.run_hooks = (hook, object, params) => {
@@ -495,10 +480,8 @@ plugins.run_next_hook = (hook, object, params) => {
495
480
 
496
481
  const respond_method = `${hook}_respond`;
497
482
  if (item && is_deny_retval(retval) && hook.substr(0,5) !== 'init_') {
498
- object.deny_respond =
499
- get_denyfn(object, hook, params, retval, msg, respond_method);
500
- plugins.run_hooks('deny', object,
501
- [retval, msg, item[0].name, item[1], params, hook]);
483
+ object.deny_respond = get_denyfn(object, hook, params, retval, msg, respond_method);
484
+ plugins.run_hooks('deny', object, [retval, msg, item[0].name, item[1], params, hook]);
502
485
  }
503
486
  else {
504
487
  object.hooks_to_run = [];
@@ -578,11 +561,25 @@ function log_run_item (item, hook, retval, object, params, msg) {
578
561
  'function' : item[1],
579
562
  'params' : ((params) ? ((typeof params === 'string') ? params : params[0]) : ''),
580
563
  'retval' : constants.translate(retval),
581
- 'msg' : ((msg) ? msg : ''),
564
+ 'msg' : sanitize(msg),
582
565
  });
583
566
  }
584
567
  }
585
568
 
569
+ function sanitize (msg) {
570
+ if (!msg) return ''
571
+ if (typeof msg === 'string') return msg
572
+ if (typeof msg === 'object') {
573
+ if (msg.constructor.name === 'DSN') return msg.reply
574
+ const sanitized = { ...msg }; // copy the message
575
+ for (const priv of ['password','auth_pass']) {
576
+ delete sanitized[priv]
577
+ }
578
+ return JSON.stringify(sanitized)
579
+ }
580
+ logger.logerror(`what is ${msg} (typeof ${typeof msg})?`)
581
+ }
582
+
586
583
  function is_deny_retval (val) {
587
584
  switch (val) {
588
585
  case constants.deny:
package/run_tests CHANGED
@@ -1,32 +1,5 @@
1
- #!/usr/bin/env node
1
+ #!/bin/sh
2
2
 
3
- 'use strict';
3
+ TESTS=${1:-"test test/outbound test/plugins/auth test/plugins/queue test/plugins"}
4
4
 
5
- let reporter;
6
- try {
7
- reporter = require('nodeunit-x').reporters.default;
8
- }
9
- catch (e) {
10
- console.log(`Error: ${e.message}
11
-
12
- Cannot find nodeunit module. Please run the following:
13
-
14
- npm install\n`);
15
-
16
- process.exit();
17
- }
18
-
19
- process.chdir(__dirname);
20
-
21
- let tests = [
22
- 'tests', 'tests/outbound', 'tests/plugins',
23
- 'tests/plugins/auth', 'tests/plugins/queue'
24
- ];
25
-
26
- if (process.argv[2]) {
27
- console.log("Running tests: ", process.argv.slice(2));
28
- tests = process.argv.slice(2);
29
- }
30
- reporter.run(tests, undefined, function (err) {
31
- process.exit(((err) ? 1 : 0));
32
- });
5
+ npx mocha --exit $TESTS