Haraka 3.1.1 → 3.1.3

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 (168) hide show
  1. package/.prettierignore +4 -0
  2. package/CONTRIBUTORS.md +5 -5
  3. package/Changes.md +72 -50
  4. package/Plugins.md +3 -1
  5. package/README.md +1 -1
  6. package/bin/haraka +475 -479
  7. package/config/connection.ini +10 -0
  8. package/config/outbound.ini +3 -0
  9. package/config/smtp.ini +0 -9
  10. package/connection.js +1072 -1108
  11. package/docs/Connection.md +29 -30
  12. package/docs/CoreConfig.md +38 -40
  13. package/docs/CustomReturnCodes.md +0 -1
  14. package/docs/HAProxy.md +2 -2
  15. package/docs/Header.md +1 -1
  16. package/docs/Logging.md +29 -5
  17. package/docs/Outbound.md +93 -78
  18. package/docs/Plugins.md +103 -108
  19. package/docs/Transaction.md +49 -51
  20. package/docs/Tutorial.md +127 -143
  21. package/docs/deprecated/access.md +0 -1
  22. package/docs/deprecated/backscatterer.md +2 -3
  23. package/docs/deprecated/connect.rdns_access.md +18 -27
  24. package/docs/deprecated/data.headers.md +0 -1
  25. package/docs/deprecated/data.nomsgid.md +1 -2
  26. package/docs/deprecated/data.noreceived.md +1 -2
  27. package/docs/deprecated/data.rfc5322_header_checks.md +1 -2
  28. package/docs/deprecated/dkim_sign.md +13 -17
  29. package/docs/deprecated/dkim_verify.md +9 -17
  30. package/docs/deprecated/dnsbl.md +36 -38
  31. package/docs/deprecated/dnswl.md +41 -43
  32. package/docs/deprecated/lookup_rdns.strict.md +21 -34
  33. package/docs/deprecated/mail_from.access.md +17 -25
  34. package/docs/deprecated/mail_from.blocklist.md +9 -12
  35. package/docs/deprecated/mail_from.nobounces.md +1 -2
  36. package/docs/deprecated/rcpt_to.access.md +20 -27
  37. package/docs/deprecated/rcpt_to.blocklist.md +10 -13
  38. package/docs/deprecated/rcpt_to.routes.md +0 -1
  39. package/docs/deprecated/rdns.regexp.md +13 -15
  40. package/docs/plugins/aliases.md +89 -89
  41. package/docs/plugins/auth/auth_bridge.md +5 -7
  42. package/docs/plugins/auth/auth_ldap.md +11 -14
  43. package/docs/plugins/auth/auth_proxy.md +10 -12
  44. package/docs/plugins/auth/auth_vpopmaild.md +5 -6
  45. package/docs/plugins/auth/flat_file.md +4 -4
  46. package/docs/plugins/block_me.md +3 -3
  47. package/docs/plugins/data.signatures.md +1 -2
  48. package/docs/plugins/delay_deny.md +3 -4
  49. package/docs/plugins/max_unrecognized_commands.md +4 -4
  50. package/docs/plugins/prevent_credential_leaks.md +6 -6
  51. package/docs/plugins/process_title.md +18 -18
  52. package/docs/plugins/queue/deliver.md +2 -3
  53. package/docs/plugins/queue/discard.md +4 -4
  54. package/docs/plugins/queue/lmtp.md +1 -3
  55. package/docs/plugins/queue/qmail-queue.md +7 -9
  56. package/docs/plugins/queue/quarantine.md +16 -21
  57. package/docs/plugins/queue/rabbitmq.md +8 -11
  58. package/docs/plugins/queue/rabbitmq_amqplib.md +43 -39
  59. package/docs/plugins/queue/smtp_bridge.md +7 -10
  60. package/docs/plugins/queue/smtp_forward.md +42 -34
  61. package/docs/plugins/queue/smtp_proxy.md +30 -29
  62. package/docs/plugins/queue/test.md +1 -3
  63. package/docs/plugins/rcpt_to.in_host_list.md +6 -6
  64. package/docs/plugins/rcpt_to.max_count.md +1 -1
  65. package/docs/plugins/record_envelope_addresses.md +3 -3
  66. package/docs/plugins/reseed_rng.md +6 -6
  67. package/docs/plugins/status.md +9 -8
  68. package/docs/plugins/tarpit.md +7 -11
  69. package/docs/plugins/tls.md +12 -17
  70. package/docs/plugins/toobusy.md +4 -4
  71. package/docs/plugins/xclient.md +3 -3
  72. package/docs/tutorials/Migrating_from_v1_to_v2.md +19 -41
  73. package/docs/tutorials/SettingUpOutbound.md +6 -9
  74. package/endpoint.js +35 -38
  75. package/eslint.config.mjs +22 -19
  76. package/haraka.js +42 -47
  77. package/host_pool.js +75 -79
  78. package/http/html/404.html +45 -49
  79. package/http/html/index.html +39 -28
  80. package/http/package.json +2 -4
  81. package/line_socket.js +27 -28
  82. package/logger.js +182 -201
  83. package/outbound/client_pool.js +33 -33
  84. package/outbound/config.js +64 -59
  85. package/outbound/fsync_writestream.js +24 -25
  86. package/outbound/hmail.js +888 -835
  87. package/outbound/index.js +194 -187
  88. package/outbound/qfile.js +49 -52
  89. package/outbound/queue.js +197 -190
  90. package/outbound/timer_queue.js +41 -43
  91. package/outbound/tls.js +68 -61
  92. package/outbound/todo.js +11 -11
  93. package/package.json +35 -36
  94. package/plugins/.eslintrc.yaml +0 -1
  95. package/plugins/auth/auth_base.js +123 -127
  96. package/plugins/auth/auth_bridge.js +7 -7
  97. package/plugins/auth/auth_proxy.js +121 -126
  98. package/plugins/auth/auth_vpopmaild.js +84 -85
  99. package/plugins/auth/flat_file.js +18 -17
  100. package/plugins/block_me.js +31 -31
  101. package/plugins/data.signatures.js +13 -13
  102. package/plugins/delay_deny.js +65 -61
  103. package/plugins/prevent_credential_leaks.js +23 -23
  104. package/plugins/process_title.js +125 -128
  105. package/plugins/profile.js +5 -5
  106. package/plugins/queue/deliver.js +3 -3
  107. package/plugins/queue/discard.js +13 -14
  108. package/plugins/queue/lmtp.js +16 -17
  109. package/plugins/queue/qmail-queue.js +54 -55
  110. package/plugins/queue/quarantine.js +68 -70
  111. package/plugins/queue/rabbitmq.js +80 -87
  112. package/plugins/queue/rabbitmq_amqplib.js +75 -54
  113. package/plugins/queue/smtp_bridge.js +16 -16
  114. package/plugins/queue/smtp_forward.js +175 -179
  115. package/plugins/queue/smtp_proxy.js +69 -71
  116. package/plugins/queue/test.js +9 -9
  117. package/plugins/rcpt_to.host_list_base.js +30 -34
  118. package/plugins/rcpt_to.in_host_list.js +19 -19
  119. package/plugins/record_envelope_addresses.js +4 -4
  120. package/plugins/reseed_rng.js +4 -4
  121. package/plugins/status.js +90 -97
  122. package/plugins/tarpit.js +25 -14
  123. package/plugins/tls.js +68 -68
  124. package/plugins/toobusy.js +21 -23
  125. package/plugins/xclient.js +51 -53
  126. package/plugins.js +276 -293
  127. package/rfc1869.js +30 -35
  128. package/server.js +308 -299
  129. package/smtp_client.js +244 -228
  130. package/test/.eslintrc.yaml +0 -1
  131. package/test/connection.js +127 -134
  132. package/test/endpoint.js +53 -47
  133. package/test/fixtures/line_socket.js +12 -12
  134. package/test/fixtures/util_hmailitem.js +89 -85
  135. package/test/host_pool.js +90 -92
  136. package/test/installation/plugins/base_plugin.js +2 -2
  137. package/test/installation/plugins/folder_plugin/index.js +2 -3
  138. package/test/installation/plugins/inherits.js +3 -3
  139. package/test/installation/plugins/load_first.js +2 -3
  140. package/test/installation/plugins/plugin.js +1 -3
  141. package/test/installation/plugins/tls.js +2 -4
  142. package/test/logger.js +135 -116
  143. package/test/outbound/hmail.js +49 -35
  144. package/test/outbound/index.js +118 -101
  145. package/test/outbound/qfile.js +51 -53
  146. package/test/outbound_bounce_net_errors.js +84 -69
  147. package/test/outbound_bounce_rfc3464.js +235 -165
  148. package/test/plugins/auth/auth_base.js +420 -279
  149. package/test/plugins/auth/auth_vpopmaild.js +38 -39
  150. package/test/plugins/queue/smtp_forward.js +126 -104
  151. package/test/plugins/rcpt_to.host_list_base.js +85 -67
  152. package/test/plugins/rcpt_to.in_host_list.js +159 -112
  153. package/test/plugins/status.js +71 -64
  154. package/test/plugins/tls.js +37 -34
  155. package/test/plugins.js +97 -92
  156. package/test/rfc1869.js +19 -26
  157. package/test/server.js +293 -272
  158. package/test/smtp_client.js +180 -176
  159. package/test/tls_socket.js +62 -66
  160. package/test/transaction.js +159 -160
  161. package/tls_socket.js +331 -333
  162. package/transaction.js +129 -137
  163. package/config/me +0 -1
  164. package/config/tls_cert.pem +0 -23
  165. package/config/tls_key.pem +0 -28
  166. package/test/queue/multibyte +0 -0
  167. package/test/queue/plain +0 -0
  168. package/test/test-queue/delete-me +0 -0
@@ -1,49 +1,47 @@
1
1
  // Stop accepting new connections when we are too busy
2
2
 
3
- let toobusy;
4
- let was_busy = false;
3
+ let toobusy
4
+ let was_busy = false
5
5
 
6
6
  exports.register = function () {
7
-
8
7
  try {
9
- toobusy = require('toobusy-js');
10
- }
11
- catch (e) {
12
- this.logerror(e);
13
- this.logerror("try: 'npm install -g toobusy-js'");
14
- return;
8
+ toobusy = require('toobusy-js')
9
+ } catch (e) {
10
+ this.logerror(e)
11
+ this.logerror("try: 'npm install -g toobusy-js'")
12
+ return
15
13
  }
16
14
 
17
- this.loadConfig();
15
+ this.loadConfig()
18
16
 
19
- this.register_hook('connect', 'check_busy', -100);
17
+ this.register_hook('connect', 'check_busy', -100)
20
18
  }
21
19
 
22
20
  exports.loadConfig = function () {
23
- let maxLag = this.config.get('toobusy.maxlag','value', () => {
24
- this.loadConfig();
25
- });
21
+ let maxLag = this.config.get('toobusy.maxlag', 'value', () => {
22
+ this.loadConfig()
23
+ })
26
24
 
27
- maxLag = parseInt(maxLag);
25
+ maxLag = parseInt(maxLag)
28
26
  if (maxLag) {
29
27
  // This will throw an exception on error
30
- toobusy.maxLag(maxLag);
28
+ toobusy.maxLag(maxLag)
31
29
  }
32
30
  }
33
31
 
34
32
  exports.check_busy = function (next, connection) {
35
33
  if (!toobusy()) {
36
- was_busy = false;
37
- return next();
34
+ was_busy = false
35
+ return next()
38
36
  }
39
37
 
40
38
  if (!was_busy) {
41
- was_busy = true;
39
+ was_busy = true
42
40
  // Log a CRIT error at the first occurrence
43
- const currentLag = toobusy.lag();
44
- const maxLag = toobusy.maxLag();
45
- this.logcrit(`deferring connections: lag=${currentLag} max=${maxLag}`);
41
+ const currentLag = toobusy.lag()
42
+ const maxLag = toobusy.maxLag()
43
+ this.logcrit(`deferring connections: lag=${currentLag} max=${maxLag}`)
46
44
  }
47
45
 
48
- return next(DENYSOFTDISCONNECT, 'Too busy; please try again later');
46
+ return next(DENYSOFTDISCONNECT, 'Too busy; please try again later')
49
47
  }
@@ -1,124 +1,122 @@
1
1
  // Implementation of XCLIENT protocol
2
2
  // See http://www.postfix.org/XCLIENT_README.html
3
3
 
4
- const net = require('node:net');
4
+ const net = require('node:net')
5
5
 
6
- const utils = require('haraka-utils');
7
- const DSN = require('haraka-dsn');
8
- let allowed_hosts = {};
6
+ const utils = require('haraka-utils')
7
+ const DSN = require('haraka-dsn')
8
+ let allowed_hosts = {}
9
9
 
10
10
  exports.register = function () {
11
- this.load_xclient_hosts();
11
+ this.load_xclient_hosts()
12
12
  }
13
13
 
14
14
  exports.load_xclient_hosts = function () {
15
15
  const cfg = this.config.get('xclient.hosts', 'list', () => {
16
- this.load_xclient_hosts();
17
- });
18
- const ah = {};
16
+ this.load_xclient_hosts()
17
+ })
18
+ const ah = {}
19
19
  for (const i in cfg) {
20
- ah[cfg[i]] = true;
20
+ ah[cfg[i]] = true
21
21
  }
22
- allowed_hosts = ah;
22
+ allowed_hosts = ah
23
23
  }
24
24
 
25
- function xclient_allowed (ip) {
26
- return !!(ip === '127.0.0.1' || ip === '::1' || allowed_hosts[ip]);
25
+ function xclient_allowed(ip) {
26
+ return !!(ip === '127.0.0.1' || ip === '::1' || allowed_hosts[ip])
27
27
  }
28
28
 
29
29
  exports.hook_capabilities = (next, connection) => {
30
30
  if (xclient_allowed(connection.remote.ip)) {
31
- connection.capabilities.push('XCLIENT NAME ADDR PROTO HELO LOGIN');
31
+ connection.capabilities.push('XCLIENT NAME ADDR PROTO HELO LOGIN')
32
32
  }
33
- next();
33
+ next()
34
34
  }
35
35
 
36
36
  exports.hook_unrecognized_command = function (next, connection, params) {
37
- if (params[0] !== 'XCLIENT') return next();
37
+ if (params[0] !== 'XCLIENT') return next()
38
38
 
39
39
  // XCLIENT is not allowed after transaction start
40
40
  if (connection?.transaction) {
41
- return next(DENY, DSN.proto_unspecified('Mail transaction in progress', 503));
41
+ return next(DENY, DSN.proto_unspecified('Mail transaction in progress', 503))
42
42
  }
43
43
 
44
- if (!(xclient_allowed(connection?.remote?.ip))) {
45
- return next(DENY, DSN.proto_unspecified('Not authorized', 550));
44
+ if (!xclient_allowed(connection?.remote?.ip)) {
45
+ return next(DENY, DSN.proto_unspecified('Not authorized', 550))
46
46
  }
47
47
 
48
48
  // If we get here - the client is allowed to use XCLIENT
49
49
  // Process arguments
50
- const args = (new String(params[1])).toLowerCase().split(/ /);
51
- const xclient = {};
50
+ const args = new String(params[1]).toLowerCase().split(/ /)
51
+ const xclient = {}
52
52
  for (const arg of args) {
53
- const match = /^([^=]+)=([^ ]+)/.exec(arg);
53
+ const match = /^([^=]+)=([^ ]+)/.exec(arg)
54
54
  if (match) {
55
- connection.logdebug(this, `found key=${match[1]} value=${match[2]}`);
55
+ connection.logdebug(this, `found key=${match[1]} value=${match[2]}`)
56
56
  switch (match[1]) {
57
57
  case 'destaddr':
58
58
  case 'addr': {
59
59
  // IPv6 is prefixed in the XCLIENT protocol
60
- let ipv6;
60
+ let ipv6
61
61
  if ((ipv6 = /^IPV6:(.+)$/i.exec(match[2]))) {
62
62
  // Validate
63
63
  if (net.isIPv6(ipv6[1])) {
64
- xclient[match[1]] = ipv6[1];
64
+ xclient[match[1]] = ipv6[1]
65
65
  }
66
- }
67
- else if (!/\[UNAVAILABLE\]/i.test(match[2])) {
66
+ } else if (!/\[UNAVAILABLE\]/i.test(match[2])) {
68
67
  // IPv4
69
68
  if (net.isIPv4(match[2])) {
70
- xclient[match[1]] = match[2];
69
+ xclient[match[1]] = match[2]
71
70
  }
72
71
  }
73
- break;
72
+ break
74
73
  }
75
74
  case 'proto':
76
75
  // SMTP or ESMTP
77
76
  if (/^e?smtp/i.test(match[2])) {
78
- xclient[match[1]] = match[2];
77
+ xclient[match[1]] = match[2]
79
78
  }
80
- break;
79
+ break
81
80
  case 'name':
82
81
  case 'port':
83
82
  case 'helo':
84
83
  case 'login':
85
84
  case 'destport':
86
85
  if (!/\[(UNAVAILABLE|TEMPUNAVAIL)\]/i.test(match[2])) {
87
- xclient[match[1]] = match[2];
86
+ xclient[match[1]] = match[2]
88
87
  }
89
- break;
88
+ break
90
89
  default:
91
- connection.logwarn(this, `unknown argument: ${arg}`);
90
+ connection.logwarn(this, `unknown argument: ${arg}`)
92
91
  }
93
- }
94
- else {
95
- connection.logwarn(this, `unknown argument: ${arg}`);
92
+ } else {
93
+ connection.logwarn(this, `unknown argument: ${arg}`)
96
94
  }
97
95
  }
98
96
 
99
97
  // Abort if we don't have a valid IP address
100
98
  if (!xclient.addr) {
101
- return next(DENY, DSN.proto_invalid_cmd_args('No valid IP address found', 501));
99
+ return next(DENY, DSN.proto_invalid_cmd_args('No valid IP address found', 501))
102
100
  }
103
101
 
104
102
  // Apply changes
105
- const new_uuid = utils.uuid();
106
- connection.loginfo(this, `new uuid=${new_uuid}`);
107
- connection.uuid = new_uuid;
108
- connection.reset_transaction();
109
- connection.relaying = false;
110
- connection.set('remote.ip', xclient.addr);
111
- connection.set('remote.host', ((xclient.name) ? xclient.name : undefined));
112
- connection.set('remote.login', ((xclient.login) ? xclient.login : undefined));
113
- connection.set('hello.host', ((xclient.helo) ? xclient.helo : undefined));
114
- connection.set('local.ip', ((xclient.destaddr) ? xclient.destaddr : undefined));
115
- connection.set('local.port', ((xclient.destport) ? xclient.destport: undefined));
103
+ const new_uuid = utils.uuid()
104
+ connection.loginfo(this, `new uuid=${new_uuid}`)
105
+ connection.uuid = new_uuid
106
+ connection.reset_transaction()
107
+ connection.relaying = false
108
+ connection.set('remote.ip', xclient.addr)
109
+ connection.set('remote.host', xclient.name ? xclient.name : undefined)
110
+ connection.set('remote.login', xclient.login ? xclient.login : undefined)
111
+ connection.set('hello.host', xclient.helo ? xclient.helo : undefined)
112
+ connection.set('local.ip', xclient.destaddr ? xclient.destaddr : undefined)
113
+ connection.set('local.port', xclient.destport ? xclient.destport : undefined)
116
114
  if (xclient.proto) {
117
- connection.set('hello', 'verb', ((xclient.proto === 'esmtp') ? 'EHLO' : 'HELO'));
115
+ connection.set('hello', 'verb', xclient.proto === 'esmtp' ? 'EHLO' : 'HELO')
118
116
  }
119
- connection.esmtp = (xclient.proto === 'esmtp');
120
- connection.xclient = true;
121
- if (!xclient.name) return next(NEXT_HOOK, 'lookup_rdns');
117
+ connection.esmtp = xclient.proto === 'esmtp'
118
+ connection.xclient = true
119
+ if (!xclient.name) return next(NEXT_HOOK, 'lookup_rdns')
122
120
 
123
- next(NEXT_HOOK, 'connect');
121
+ next(NEXT_HOOK, 'connect')
124
122
  }