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/dnsbl.js CHANGED
@@ -1,85 +1,81 @@
1
1
  // dnsbl plugin
2
2
 
3
3
  exports.register = function () {
4
- const plugin = this;
5
- plugin.inherits('dns_list_base');
4
+ this.inherits('dns_list_base');
6
5
 
7
- plugin.load_config();
6
+ this.load_config();
8
7
 
9
- if (plugin.cfg.main.periodic_checks) {
10
- plugin.check_zones(plugin.cfg.main.periodic_checks);
8
+ if (this.cfg.main.periodic_checks) {
9
+ this.check_zones(this.cfg.main.periodic_checks);
11
10
  }
12
11
 
13
- if (plugin.cfg.main.search === 'all') {
14
- plugin.register_hook('connect', 'connect_multi');
12
+ if (this.cfg.main.search === 'all') {
13
+ this.register_hook('connect', 'connect_multi');
15
14
  }
16
15
  else {
17
- plugin.register_hook('connect', 'connect_first');
16
+ this.register_hook('connect', 'connect_first');
18
17
  }
19
18
  }
20
19
 
21
20
  exports.load_config = function () {
22
- const plugin = this;
23
21
 
24
- plugin.cfg = plugin.config.get('dnsbl.ini', {
22
+ this.cfg = this.config.get('dnsbl.ini', {
25
23
  booleans: ['+main.reject', '-main.enable_stats'],
26
24
  }, () => {
27
- plugin.load_config();
25
+ this.load_config();
28
26
  });
29
27
 
30
- if (plugin.cfg.main.enable_stats && !plugin.enable_stats) {
31
- plugin.loginfo('stats reporting enabled');
32
- plugin.enable_stats = true;
28
+ if (this.cfg.main.enable_stats && !this.enable_stats) {
29
+ this.loginfo('stats reporting enabled');
30
+ this.enable_stats = true;
33
31
  }
34
- if (!plugin.cfg.main.enable_stats && plugin.enable_stats) {
35
- plugin.loginfo('stats reporting disabled');
36
- plugin.enable_stats = false;
32
+ if (!this.cfg.main.enable_stats && this.enable_stats) {
33
+ this.loginfo('stats reporting disabled');
34
+ this.enable_stats = false;
37
35
  }
38
36
 
39
- if (plugin.cfg.main.stats_redis_host &&
40
- plugin.cfg.main.stats_redis_host !== plugin.redis_host) {
41
- plugin.redis_host = plugin.cfg.main.stats_redis_host;
42
- plugin.loginfo(`set stats redis host to: ${plugin.redis_host}`);
37
+ if (this.cfg.main.stats_redis_host &&
38
+ this.cfg.main.stats_redis_host !== this.redis_host) {
39
+ this.redis_host = this.cfg.main.stats_redis_host;
40
+ this.loginfo(`set stats redis host to: ${this.redis_host}`);
43
41
  }
44
42
 
45
- plugin.get_uniq_zones();
43
+ this.get_uniq_zones();
46
44
  }
47
45
 
48
46
  exports.get_uniq_zones = function () {
49
- const plugin = this;
50
- plugin.zones = [];
47
+ this.zones = [];
51
48
 
52
49
  const unique_zones = {};
53
50
 
54
51
  // Compatibility with old plugin
55
- const legacy_zones = plugin.config.get('dnsbl.zones', 'list');
56
- for (let i=0; i < legacy_zones.length; i++) {
57
- unique_zones[legacy_zones[i]] = true;
52
+ const legacy_zones = this.config.get('dnsbl.zones', 'list');
53
+ for (const legacyZone of legacy_zones) {
54
+ unique_zones[legacyZone] = true;
58
55
  }
59
56
 
60
- if (plugin.cfg.main.zones) {
61
- const new_zones = plugin.cfg.main.zones.split(/[\s,;]+/);
62
- for (let h=0; h < new_zones.length; h++) {
63
- unique_zones[new_zones[h]] = true;
57
+ if (this.cfg.main.zones) {
58
+ const new_zones = this.cfg.main.zones.split(/[\s,;]+/);
59
+ for (const newZone of new_zones) {
60
+ unique_zones[newZone] = true;
64
61
  }
65
62
  }
66
63
 
67
- for (const key in unique_zones) { plugin.zones.push(key); }
68
- return plugin.zones;
64
+ for (const key in unique_zones) { this.zones.push(key); }
65
+ return this.zones;
69
66
  }
70
67
 
71
68
  exports.should_skip = function (connection) {
72
- const plugin = this;
73
69
 
74
70
  if (!connection) { return true; }
75
71
 
76
72
  if (connection.remote.is_private) {
77
- connection.logdebug(plugin, `skip private: ${connection.remote.ip}`);
73
+ connection.logdebug(this, `skip private: ${connection.remote.ip}`);
78
74
  return true;
79
75
  }
80
76
 
81
- if (!plugin.zones || !plugin.zones.length) {
82
- connection.logerror(plugin, "no zones");
77
+ if (!this.zones || !this.zones.length) {
78
+ connection.logerror(this, "no zones");
83
79
  return true;
84
80
  }
85
81
 
@@ -112,21 +108,20 @@ exports.connect_first = function (next, connection) {
112
108
  }
113
109
 
114
110
  exports.connect_multi = function (next, connection) {
115
- const plugin = this;
116
111
  const remote_ip = connection.remote.ip;
117
112
 
118
- if (plugin.should_skip(connection)) { return next(); }
113
+ if (this.should_skip(connection)) { return next(); }
119
114
 
120
115
  const hits = [];
121
116
  function get_deny_msg () {
122
117
  return `host [${remote_ip}] is blacklisted by ${hits.join(', ')}`;
123
118
  }
124
119
 
125
- plugin.multi(remote_ip, plugin.zones, (err, zone, a, pending) => {
120
+ this.multi(remote_ip, this.zones, (err, zone, a, pending) => {
126
121
  if (err) {
127
- connection.results.add(plugin, {err: err.message});
122
+ connection.results.add(this, {err: err.message});
128
123
  if (pending) return;
129
- if (plugin.cfg.main.reject && hits.length) {
124
+ if (this.cfg.main.reject && hits.length) {
130
125
  return next(DENY, get_deny_msg());
131
126
  }
132
127
  return next();
@@ -134,16 +129,16 @@ exports.connect_multi = function (next, connection) {
134
129
 
135
130
  if (a) {
136
131
  hits.push(zone);
137
- connection.results.add(plugin, {fail: zone});
132
+ connection.results.add(this, {fail: zone});
138
133
  }
139
134
  else {
140
- if (zone) connection.results.add(plugin, {pass: zone});
135
+ if (zone) connection.results.add(this, {pass: zone});
141
136
  }
142
137
 
143
138
  if (pending) return;
144
- connection.results.add(plugin, {emit: true});
139
+ connection.results.add(this, {emit: true});
145
140
 
146
- if (plugin.cfg.main.reject && hits.length) {
141
+ if (this.cfg.main.reject && hits.length) {
147
142
  return next(DENY, get_deny_msg());
148
143
  }
149
144
  return next();
package/plugins/dnswl.js CHANGED
@@ -2,59 +2,56 @@
2
2
  // dnswl plugin
3
3
 
4
4
  exports.register = function () {
5
- const plugin = this;
6
- plugin.inherits('dns_list_base');
5
+ this.inherits('dns_list_base');
7
6
 
8
- plugin.load_dnswl_ini();
7
+ this.load_dnswl_ini();
9
8
 
10
9
  // IMPORTANT: don't run this on hook_rcpt otherwise we're an open relay...
11
10
  ['ehlo','helo','mail'].forEach(hook => {
12
- plugin.register_hook(hook, 'check_dnswl');
11
+ this.register_hook(hook, 'check_dnswl');
13
12
  });
14
13
  }
15
14
 
16
15
  exports.load_dnswl_ini = function () {
17
- const plugin = this;
18
- plugin.cfg = plugin.config.get('dnswl.ini', () => {
19
- plugin.load_dnswl_ini();
16
+ this.cfg = this.config.get('dnswl.ini', () => {
17
+ this.load_dnswl_ini();
20
18
  });
21
19
 
22
- if (plugin.cfg.main.enable_stats) {
23
- plugin.logdebug('stats reporting enabled');
24
- plugin.enable_stats = true;
20
+ if (this.cfg.main.enable_stats) {
21
+ this.logdebug('stats reporting enabled');
22
+ this.enable_stats = true;
25
23
  }
26
24
 
27
- if (plugin.cfg.main.stats_redis_host) {
28
- plugin.redis_host = plugin.cfg.main.stats_redis_host;
29
- plugin.logdebug(`set stats redis host to: ${plugin.redis_host}`);
25
+ if (this.cfg.main.stats_redis_host) {
26
+ this.redis_host = this.cfg.main.stats_redis_host;
27
+ this.logdebug(`set stats redis host to: ${this.redis_host}`);
30
28
  }
31
29
 
32
- plugin.zones = [];
30
+ this.zones = [];
33
31
  // Compatibility with old-plugin
34
- plugin.zones = plugin.zones.concat(
35
- plugin.config.get('dnswl.zones', 'list')
32
+ this.zones = this.zones.concat(
33
+ this.config.get('dnswl.zones', 'list')
36
34
  );
37
- if (plugin.cfg.main.zones) {
38
- plugin.zones = plugin.zones.concat(
39
- plugin.cfg.main.zones.replace(/\s+/g,'').split(/[;,]/));
35
+ if (this.cfg.main.zones) {
36
+ this.zones = this.zones.concat(
37
+ this.cfg.main.zones.replace(/\s+/g,'').split(/[;,]/));
40
38
  }
41
39
 
42
- if (plugin.cfg.main.periodic_checks) {
43
- plugin.check_zones(plugin.cfg.main.periodic_checks);
40
+ if (this.cfg.main.periodic_checks) {
41
+ this.check_zones(this.cfg.main.periodic_checks);
44
42
  }
45
43
  }
46
44
 
47
45
  exports.check_dnswl = (next, connection) => connection.notes.dnswl ? next(OK) : next()
48
46
 
49
47
  exports.hook_connect = function (next, connection) {
50
- const plugin = this;
51
- if (!plugin.zones || !plugin.zones.length) {
52
- connection.logerror(plugin, 'no zones');
48
+ if (!this.zones || !this.zones.length) {
49
+ connection.logerror(this, 'no zones');
53
50
  return next();
54
51
  }
55
- plugin.first(connection.remote.ip, plugin.zones, (err, zone, a) => {
52
+ this.first(connection.remote.ip, this.zones, (err, zone, a) => {
56
53
  if (!a) return next();
57
- connection.loginfo(plugin, `${connection.remote.ip} is whitelisted by ${zone}: ${a}`);
54
+ connection.loginfo(this, `${connection.remote.ip} is whitelisted by ${zone}: ${a}`);
58
55
  connection.notes.dnswl = true;
59
56
  return next(OK);
60
57
  });
@@ -1,38 +1,36 @@
1
1
  // This plugin checks for clients that talk before we sent a response
2
2
 
3
3
  const ipaddr = require('ipaddr.js');
4
- const isIPv6 = require('net').isIPv6;
4
+ const { isIPv6 } = require('net');
5
5
 
6
6
  exports.register = function () {
7
- const plugin = this;
8
- plugin.load_config();
9
- plugin.register_hook('connect_init', 'early_talker');
10
- plugin.register_hook('data', 'early_talker');
7
+ this.load_config();
8
+ this.register_hook('connect_init', 'early_talker');
9
+ this.register_hook('data', 'early_talker');
11
10
  }
12
11
 
13
12
  exports.load_config = function () {
14
- const plugin = this;
15
13
 
16
- plugin.cfg = plugin.config.get('early_talker.ini', {
14
+ this.cfg = this.config.get('early_talker.ini', {
17
15
  booleans: [
18
16
  '+main.reject'
19
17
  ]
20
18
  },
21
19
  () => {
22
- plugin.load_config();
20
+ this.load_config();
23
21
  });
24
22
 
25
23
  // Generate a white list of IP addresses
26
- plugin.whitelist = plugin.load_ip_list(Object.keys(plugin.cfg.ip_whitelist));
24
+ this.whitelist = this.load_ip_list(Object.keys(this.cfg.ip_whitelist));
27
25
 
28
- if (plugin.cfg.main && plugin.cfg.main.pause) {
29
- plugin.pause = plugin.cfg.main.pause * 1000;
26
+ if (this.cfg.main?.pause) {
27
+ this.pause = this.cfg.main.pause * 1000;
30
28
  return;
31
29
  }
32
30
 
33
31
  // config/early_talker.pause is in milliseconds
34
- plugin.pause = plugin.config.get('early_talker.pause', () => {
35
- plugin.load_config();
32
+ this.pause = this.config.get('early_talker.pause', () => {
33
+ this.load_config();
36
34
  });
37
35
  }
38
36
 
@@ -52,7 +50,7 @@ exports.early_talker = function (next, connection) {
52
50
  return next(DENYDISCONNECT, "You talk too soon");
53
51
  }
54
52
 
55
- let pause = plugin.pause;
53
+ let { pause } = plugin;
56
54
  if (plugin.hook === 'connect_init') {
57
55
  const elapsed = (Date.now() - connection.start_time);
58
56
  if (elapsed > plugin.pause) {
@@ -73,15 +71,14 @@ exports.early_talker = function (next, connection) {
73
71
  * @return {Boolean} True if is whitelisted
74
72
  */
75
73
  exports.ip_in_list = function (ip) {
76
- const plugin = this;
77
74
 
78
- if (!plugin.whitelist) return false;
75
+ if (!this.whitelist) return false;
79
76
 
80
77
  const ipobj = ipaddr.parse(ip);
81
78
 
82
- for (let i = 0; i < plugin.whitelist.length; i++) {
79
+ for (const element of this.whitelist) {
83
80
  try {
84
- if (ipobj.match(plugin.whitelist[i])) {
81
+ if (ipobj.match(element)) {
85
82
  return true;
86
83
  }
87
84
  }
@@ -101,9 +98,9 @@ exports.ip_in_list = function (ip) {
101
98
  exports.load_ip_list = list => {
102
99
  const whitelist = [];
103
100
 
104
- for (let i = 0; i < list.length; i++) {
101
+ for (const element of list) {
105
102
  try {
106
- let addr = list[i];
103
+ let addr = element;
107
104
  if (addr.match(/\/\d+$/)) {
108
105
  addr = ipaddr.parseCIDR(addr);
109
106
  }
@@ -120,37 +117,36 @@ exports.load_ip_list = list => {
120
117
  }
121
118
 
122
119
  exports.should_check = function (connection) {
123
- const plugin = this;
124
120
  // Skip delays for privileged senders
125
121
 
126
122
  if (connection.notes.auth_user) {
127
- connection.results.add(plugin, { skip: 'authed'});
123
+ connection.results.add(this, { skip: 'authed'});
128
124
  return false;
129
125
  }
130
126
 
131
127
  if (connection.relaying) {
132
- connection.results.add(plugin, { skip: 'relay'});
128
+ connection.results.add(this, { skip: 'relay'});
133
129
  return false;
134
130
  }
135
131
 
136
- if (plugin.ip_in_list(connection.remote.ip)) {
137
- connection.results.add(plugin, { skip: 'whitelist' });
132
+ if (this.ip_in_list(connection.remote.ip)) {
133
+ connection.results.add(this, { skip: 'whitelist' });
138
134
  return false;
139
135
  }
140
136
 
141
137
  const karma = connection.results.get('karma');
142
138
  if (karma && karma.good > 0) {
143
- connection.results.add(plugin, { skip: '+karma' });
139
+ connection.results.add(this, { skip: '+karma' });
144
140
  return false;
145
141
  }
146
142
 
147
143
  if (connection.remote.is_local) {
148
- connection.results.add(plugin, { skip: 'local_ip'});
144
+ connection.results.add(this, { skip: 'local_ip'});
149
145
  return false;
150
146
  }
151
147
 
152
148
  if (connection.remote.is_private) {
153
- connection.results.add(plugin, { skip: 'private_ip'});
149
+ connection.results.add(this, { skip: 'private_ip'});
154
150
  return false;
155
151
  }
156
152
 
package/plugins/esets.js CHANGED
@@ -5,17 +5,16 @@ const virus_re = new RegExp('virus="([^"]+)"');
5
5
 
6
6
  exports.hook_data_post = function (next, connection) {
7
7
  const plugin = this;
8
- const txn = connection.transaction;
9
8
  const cfg = this.config.get('esets.ini');
10
9
 
11
10
  // Write message to temporary file
12
11
  const tmpdir = cfg.main.tmpdir || '/tmp';
13
- const tmpfile = `${tmpdir}/${txn.uuid}.esets`;
12
+ const tmpfile = `${tmpdir}/${connection?.transaction?.uuid}.esets`;
14
13
  const ws = fs.createWriteStream(tmpfile);
15
14
 
16
15
  ws.once('error', err => {
17
16
  connection.logerror(plugin, `Error writing temporary file: ${err.message}`);
18
- return next();
17
+ next();
19
18
  });
20
19
 
21
20
  let start_time;
@@ -32,17 +31,15 @@ exports.hook_data_post = function (next, connection) {
32
31
  [stdout, stderr].forEach(channel => {
33
32
  if (channel) {
34
33
  const lines = channel.split('\n');
35
- for (let i=0; i<lines.length; i++) {
36
- if (lines[i]) connection.logdebug(plugin, `recv: ${lines[i]}`);
34
+ for (const line of lines) {
35
+ if (line) connection.logdebug(plugin, `recv: ${line}`);
37
36
  }
38
37
  }
39
38
  });
40
39
 
41
40
  // Get virus name
42
- let virus;
43
- if ((virus = virus_re.exec(stdout))) {
44
- virus = virus[1];
45
- }
41
+ let virus = virus_re.exec(stdout)
42
+ if (virus) virus = virus[1];
46
43
 
47
44
  // Log a summary
48
45
  const exit_code = parseInt((error) ? error.code : 0)
@@ -60,7 +57,7 @@ exports.hook_data_post = function (next, connection) {
60
57
  return next(DENYSOFT, 'Virus scanner error');
61
58
  }
62
59
  }
63
- return next();
60
+ next();
64
61
  }
65
62
 
66
63
  ws.once('close', () => {
@@ -70,5 +67,5 @@ exports.hook_data_post = function (next, connection) {
70
67
  wsOnClose);
71
68
  });
72
69
 
73
- txn.message_stream.pipe(ws, { line_endings: '\r\n' });
70
+ connection.transaction.message_stream.pipe(ws, { line_endings: '\r\n' });
74
71
  }