Haraka 3.1.1 → 3.1.2

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 (160) hide show
  1. package/.prettierignore +4 -0
  2. package/CONTRIBUTORS.md +5 -5
  3. package/Changes.md +62 -50
  4. package/Plugins.md +3 -1
  5. package/README.md +1 -1
  6. package/bin/haraka +475 -479
  7. package/config/outbound.ini +3 -0
  8. package/connection.js +1072 -1108
  9. package/docs/Connection.md +29 -30
  10. package/docs/CoreConfig.md +38 -39
  11. package/docs/CustomReturnCodes.md +0 -1
  12. package/docs/HAProxy.md +2 -2
  13. package/docs/Header.md +1 -1
  14. package/docs/Logging.md +29 -5
  15. package/docs/Outbound.md +93 -78
  16. package/docs/Plugins.md +103 -108
  17. package/docs/Transaction.md +49 -51
  18. package/docs/Tutorial.md +127 -143
  19. package/docs/deprecated/access.md +0 -1
  20. package/docs/deprecated/backscatterer.md +2 -3
  21. package/docs/deprecated/connect.rdns_access.md +18 -27
  22. package/docs/deprecated/data.headers.md +0 -1
  23. package/docs/deprecated/data.nomsgid.md +1 -2
  24. package/docs/deprecated/data.noreceived.md +1 -2
  25. package/docs/deprecated/data.rfc5322_header_checks.md +1 -2
  26. package/docs/deprecated/dkim_sign.md +13 -17
  27. package/docs/deprecated/dkim_verify.md +9 -17
  28. package/docs/deprecated/dnsbl.md +36 -38
  29. package/docs/deprecated/dnswl.md +41 -43
  30. package/docs/deprecated/lookup_rdns.strict.md +21 -34
  31. package/docs/deprecated/mail_from.access.md +17 -25
  32. package/docs/deprecated/mail_from.blocklist.md +9 -12
  33. package/docs/deprecated/mail_from.nobounces.md +1 -2
  34. package/docs/deprecated/rcpt_to.access.md +20 -27
  35. package/docs/deprecated/rcpt_to.blocklist.md +10 -13
  36. package/docs/deprecated/rcpt_to.routes.md +0 -1
  37. package/docs/deprecated/rdns.regexp.md +13 -15
  38. package/docs/plugins/aliases.md +89 -89
  39. package/docs/plugins/auth/auth_bridge.md +5 -7
  40. package/docs/plugins/auth/auth_ldap.md +11 -14
  41. package/docs/plugins/auth/auth_proxy.md +10 -12
  42. package/docs/plugins/auth/auth_vpopmaild.md +5 -6
  43. package/docs/plugins/auth/flat_file.md +4 -4
  44. package/docs/plugins/block_me.md +3 -3
  45. package/docs/plugins/data.signatures.md +1 -2
  46. package/docs/plugins/delay_deny.md +3 -4
  47. package/docs/plugins/max_unrecognized_commands.md +4 -4
  48. package/docs/plugins/prevent_credential_leaks.md +6 -6
  49. package/docs/plugins/process_title.md +18 -18
  50. package/docs/plugins/queue/deliver.md +2 -3
  51. package/docs/plugins/queue/discard.md +4 -4
  52. package/docs/plugins/queue/lmtp.md +1 -3
  53. package/docs/plugins/queue/qmail-queue.md +7 -9
  54. package/docs/plugins/queue/quarantine.md +16 -21
  55. package/docs/plugins/queue/rabbitmq.md +8 -11
  56. package/docs/plugins/queue/rabbitmq_amqplib.md +43 -39
  57. package/docs/plugins/queue/smtp_bridge.md +7 -10
  58. package/docs/plugins/queue/smtp_forward.md +42 -34
  59. package/docs/plugins/queue/smtp_proxy.md +30 -29
  60. package/docs/plugins/queue/test.md +1 -3
  61. package/docs/plugins/rcpt_to.in_host_list.md +6 -6
  62. package/docs/plugins/rcpt_to.max_count.md +1 -1
  63. package/docs/plugins/record_envelope_addresses.md +3 -3
  64. package/docs/plugins/reseed_rng.md +6 -6
  65. package/docs/plugins/status.md +9 -8
  66. package/docs/plugins/tarpit.md +7 -11
  67. package/docs/plugins/tls.md +12 -17
  68. package/docs/plugins/toobusy.md +4 -4
  69. package/docs/plugins/xclient.md +3 -3
  70. package/docs/tutorials/Migrating_from_v1_to_v2.md +19 -41
  71. package/docs/tutorials/SettingUpOutbound.md +6 -9
  72. package/endpoint.js +35 -38
  73. package/eslint.config.mjs +22 -19
  74. package/haraka.js +42 -47
  75. package/host_pool.js +75 -79
  76. package/http/html/404.html +45 -49
  77. package/http/html/index.html +39 -28
  78. package/http/package.json +2 -4
  79. package/line_socket.js +27 -28
  80. package/logger.js +182 -201
  81. package/outbound/client_pool.js +33 -33
  82. package/outbound/config.js +64 -59
  83. package/outbound/fsync_writestream.js +24 -25
  84. package/outbound/hmail.js +888 -835
  85. package/outbound/index.js +194 -187
  86. package/outbound/qfile.js +49 -52
  87. package/outbound/queue.js +197 -190
  88. package/outbound/timer_queue.js +41 -43
  89. package/outbound/tls.js +68 -61
  90. package/outbound/todo.js +11 -11
  91. package/package.json +32 -32
  92. package/plugins/.eslintrc.yaml +0 -1
  93. package/plugins/auth/auth_base.js +123 -127
  94. package/plugins/auth/auth_bridge.js +7 -7
  95. package/plugins/auth/auth_proxy.js +121 -126
  96. package/plugins/auth/auth_vpopmaild.js +84 -85
  97. package/plugins/auth/flat_file.js +18 -17
  98. package/plugins/block_me.js +31 -31
  99. package/plugins/data.signatures.js +13 -13
  100. package/plugins/delay_deny.js +65 -61
  101. package/plugins/prevent_credential_leaks.js +23 -23
  102. package/plugins/process_title.js +125 -128
  103. package/plugins/profile.js +5 -5
  104. package/plugins/queue/deliver.js +3 -3
  105. package/plugins/queue/discard.js +13 -14
  106. package/plugins/queue/lmtp.js +16 -17
  107. package/plugins/queue/qmail-queue.js +54 -55
  108. package/plugins/queue/quarantine.js +68 -70
  109. package/plugins/queue/rabbitmq.js +80 -87
  110. package/plugins/queue/rabbitmq_amqplib.js +75 -54
  111. package/plugins/queue/smtp_bridge.js +16 -16
  112. package/plugins/queue/smtp_forward.js +175 -179
  113. package/plugins/queue/smtp_proxy.js +69 -71
  114. package/plugins/queue/test.js +9 -9
  115. package/plugins/rcpt_to.host_list_base.js +30 -34
  116. package/plugins/rcpt_to.in_host_list.js +19 -19
  117. package/plugins/record_envelope_addresses.js +4 -4
  118. package/plugins/reseed_rng.js +4 -4
  119. package/plugins/status.js +90 -97
  120. package/plugins/tarpit.js +25 -14
  121. package/plugins/tls.js +68 -68
  122. package/plugins/toobusy.js +21 -23
  123. package/plugins/xclient.js +51 -53
  124. package/plugins.js +276 -293
  125. package/rfc1869.js +30 -35
  126. package/server.js +308 -299
  127. package/smtp_client.js +244 -228
  128. package/test/.eslintrc.yaml +0 -1
  129. package/test/connection.js +127 -134
  130. package/test/endpoint.js +53 -47
  131. package/test/fixtures/line_socket.js +12 -12
  132. package/test/fixtures/util_hmailitem.js +89 -85
  133. package/test/host_pool.js +90 -92
  134. package/test/installation/plugins/base_plugin.js +2 -2
  135. package/test/installation/plugins/folder_plugin/index.js +2 -3
  136. package/test/installation/plugins/inherits.js +3 -3
  137. package/test/installation/plugins/load_first.js +2 -3
  138. package/test/installation/plugins/plugin.js +1 -3
  139. package/test/installation/plugins/tls.js +2 -4
  140. package/test/logger.js +135 -116
  141. package/test/outbound/hmail.js +49 -35
  142. package/test/outbound/index.js +118 -101
  143. package/test/outbound/qfile.js +51 -53
  144. package/test/outbound_bounce_net_errors.js +84 -69
  145. package/test/outbound_bounce_rfc3464.js +235 -165
  146. package/test/plugins/auth/auth_base.js +420 -279
  147. package/test/plugins/auth/auth_vpopmaild.js +38 -39
  148. package/test/plugins/queue/smtp_forward.js +126 -104
  149. package/test/plugins/rcpt_to.host_list_base.js +85 -67
  150. package/test/plugins/rcpt_to.in_host_list.js +159 -112
  151. package/test/plugins/status.js +71 -64
  152. package/test/plugins/tls.js +37 -34
  153. package/test/plugins.js +97 -92
  154. package/test/rfc1869.js +19 -26
  155. package/test/server.js +293 -272
  156. package/test/smtp_client.js +180 -176
  157. package/test/tls_socket.js +62 -66
  158. package/test/transaction.js +159 -160
  159. package/tls_socket.js +331 -333
  160. package/transaction.js +129 -137
@@ -1,14 +1,13 @@
1
1
  # tarpit
2
2
 
3
3
  This plugin is designed to introduce deliberate delays on the response
4
- of every hook in order to slow down a connection. It has no
4
+ of every hook in order to slow down a connection. It has no
5
5
  configuration and is designed to be used only by other plugins.
6
6
 
7
7
  It must be loaded early in config/plugins (e.g. before any plugins
8
- that accept recipients or that return OK) but must be loaded *after*
8
+ that accept recipients or that return OK) but must be loaded _after_
9
9
  any plugins that wish to use it.
10
10
 
11
-
12
11
  ## Usage
13
12
 
14
13
  To use this plugin in another plugin set:
@@ -19,26 +18,24 @@ or
19
18
 
20
19
  connection.transaction.notes.tarpit = <seconds to delay>;
21
20
 
22
-
23
21
  ## Configuration
24
22
 
25
23
  The configuration file for tarpit is config/tarpit.ini.
26
24
 
27
- * hooks\_to\_delay - a list of hooks to delay at. This setting can be used to
25
+ - hooks_to_delay - a list of hooks to delay at. This setting can be used to
28
26
  override the default list in the plugin. For example, if you notice that
29
- malware is disconnecting after delaying rcpt\_ok, you can remove just that
27
+ malware is disconnecting after delaying rcpt_ok, you can remove just that
30
28
  hook from the list:
31
29
 
32
- hooks\_to\_delay=connect,helo,ehlo,mail,rcpt,data,data\_post,queue,unrecognized\_command,vrfy,noop,rset,quit
33
-
30
+ hooks_to_delay=connect,helo,ehlo,mail,rcpt,data,data_post,queue,unrecognized_command,vrfy,noop,rset,quit
34
31
 
35
32
  ## Plugin Timeout
36
33
 
37
34
  config/tarpit.timeout (Default: 0)
38
35
 
39
- All Haraka plugins can configure a *name*.timeout file. The timeout specifies
36
+ All Haraka plugins can configure a _name_.timeout file. The timeout specifies
40
37
  how long Haraka lets the plugin do nothing before it times out. When zero,
41
- there is no timeout. When non-zero and *seconds to delay* is longer than
38
+ there is no timeout. When non-zero and _seconds to delay_ is longer than
42
39
  tarpit.timeout (default: 1s), you'll get errors like this in your log files:
43
40
 
44
41
  [core] Plugin tarpit timed out on hook rcpt - make sure it calls the callback
@@ -47,7 +44,6 @@ tarpit.timeout (default: 1s), you'll get errors like this in your log files:
47
44
  The solution is to set the contents of config/tarpit.timeout to zero or
48
45
  **seconds to delay** + 1.
49
46
 
50
-
51
47
  ## Logging
52
48
 
53
49
  When tarpitting a command it will log 'tarpitting response for Ns' to
@@ -32,21 +32,21 @@ An example [acme.sh](https://acme.sh) deployment [script](https://github.com/msi
32
32
 
33
33
  ### Wild Wild West
34
34
 
35
- PEM encoded TLS certificates and keys can be stored in files in `config/tls`. The certificate loader is recursive, so TLS files can be in subdirs like `config/tls/mx1.example.com`. The certificate names are parsed from the 1st cert in each file and indexed by the certs Common Name(s). Subject Alternate Names are supported. The file name containing the certificates does *not* matter. Additional certificates within each file are presumed to be CA chain (intermediate) certificates.
35
+ PEM encoded TLS certificates and keys can be stored in files in `config/tls`. The certificate loader is recursive, so TLS files can be in subdirs like `config/tls/mx1.example.com`. The certificate names are parsed from the 1st cert in each file and indexed by the certs Common Name(s). Subject Alternate Names are supported. The file name containing the certificates does _not_ matter. Additional certificates within each file are presumed to be CA chain (intermediate) certificates.
36
36
 
37
37
  If the TLS key is stored in the same file as the matching certificate, then the name of the file does not matter. If the TLS key is alone in a file, the file MUST be named with the keys Common Name. The file extension does not matter, `.pem` and `.key` are common. If the key is used for multiple CNs, the key must be stored in a file name matching each CN. Examples of working TLS key/cert file pairs for the Common Name mx1.example.com:
38
38
 
39
39
  1. certificate bundle (see above), key & cert in same file
40
- - config/tls/mx1.example.com.pem (recommended)
41
- - config/tls/any-unique-name.pem (CN is extracted from 1st cert)
40
+ - config/tls/mx1.example.com.pem (recommended)
41
+ - config/tls/any-unique-name.pem (CN is extracted from 1st cert)
42
42
  2. files in TLS dir
43
- - config/tls/mx1.example.com.crt
44
- - config/tls/mx1.example.com.key
43
+ - config/tls/mx1.example.com.crt
44
+ - config/tls/mx1.example.com.key
45
45
  3. files in subdir
46
- - config/tls/example.com/mx1.cert
47
- - config/tls/example.com/mx1.example.com.key
48
- 4. wildcard bundle on Windows platform (* is not allowed in file names)
49
- - config/tls/_.example.com.pem
46
+ - config/tls/example.com/mx1.cert
47
+ - config/tls/example.com/mx1.example.com.key
48
+ 4. wildcard bundle on Windows platform (\* is not allowed in file names)
49
+ - config/tls/\_.example.com.pem
50
50
 
51
51
  ## Purchased Certificate
52
52
 
@@ -129,7 +129,7 @@ no_starttls_ports[]=2525
129
129
 
130
130
  ### force_tls_hosts
131
131
 
132
- For known good TLS hosts, it's possible to force that the outbound mailer will only connect via secure sockets. This makes Haraka use *forced TLS* instead of *opportunistic TLS*. For forced TLS, the STARTTLS upgrade must succeed with a valid certificate (overriding `rejectUnauthorized`). The list is matched both against the host (MX record or `nexthop` in `relay_dest_domains.ini`), and the domain name of the email address.
132
+ For known good TLS hosts, it's possible to force that the outbound mailer will only connect via secure sockets. This makes Haraka use _forced TLS_ instead of _opportunistic TLS_. For forced TLS, the STARTTLS upgrade must succeed with a valid certificate (overriding `rejectUnauthorized`). The list is matched both against the host (MX record or `nexthop` in `relay_dest_domains.ini`), and the domain name of the email address.
133
133
 
134
134
  Note: unlike `no_tls_hosts`, this feature is implemented as an array:
135
135
 
@@ -153,11 +153,11 @@ See also: [Mozilla SSL configuration generator](https://ssl-config.mozilla.org/)
153
153
 
154
154
  Specifies minimum allowable TLS protocol version to use. Example:
155
155
 
156
- minVersion=TLSv1.1
156
+ minVersion=TLSv1.1
157
157
 
158
158
  If unset, the default is node's tls.DEFAULT_MIN_VERSION constant.
159
159
 
160
- (**Node.js 11.4+ required**, for older instances you can use *secureProtocol* settings)
160
+ (**Node.js 11.4+ required**, for older instances you can use _secureProtocol_ settings)
161
161
 
162
162
  ### honorCipherOrder
163
163
 
@@ -178,14 +178,12 @@ Whether Haraka should request a certificate from a connecting client.
178
178
 
179
179
  requestCert=[true|false] (default: true)
180
180
 
181
-
182
181
  ### rejectUnauthorized
183
182
 
184
183
  Reject connections from clients without a CA validated TLS certificate.
185
184
 
186
185
  rejectUnauthorized=[true|false] (default: false)
187
186
 
188
-
189
187
  ### requireAuthorized
190
188
 
191
189
  When `rejectUnauthorized=false`, require validated TLS certificates on just the specified ports.
@@ -195,7 +193,6 @@ requireAuthorized[]=465
195
193
  ;requireAuthorized[]=587
196
194
  ```
197
195
 
198
-
199
196
  ### secureProtocol
200
197
 
201
198
  Specifies the OpenSSL API function used for handling the TLS session. Choose
@@ -203,7 +200,6 @@ one of the methods described at the
203
200
  [OpenSSL API page](https://www.openssl.org/docs/manmaster/ssl/ssl.html).
204
201
  The default is `SSLv23_method`.
205
202
 
206
-
207
203
  ### requestOCSP
208
204
 
209
205
  Specifies that OCSP Stapling should be enabled, according to RFC 6066.
@@ -218,7 +214,6 @@ they are valid, and get refreshed after that time. A server restart
218
214
  requires the OCSP responses to be fetched again upon the first client
219
215
  connection.
220
216
 
221
-
222
217
  ## Inbound Specific Configuration
223
218
 
224
219
  By default the above options are shared with outbound mail (either
@@ -1,6 +1,6 @@
1
1
  # toobusy
2
2
 
3
- This plugin will stop Haraka accepting new connections when the event loop
3
+ This plugin will stop Haraka accepting new connections when the event loop
4
4
  latency is too high.
5
5
 
6
6
  See https://github.com/STRML/node-toobusy for details.
@@ -8,13 +8,13 @@ See https://github.com/STRML/node-toobusy for details.
8
8
  To use this plugin you have to install the 'toobusy-js' module by running
9
9
  'npm install toobusy-js' in your Haraka configuration directory.
10
10
 
11
- This plugin should be listed at the top of your config/plugins file so that
12
- it runs before any other plugin that hooks lookup\_rdns.
11
+ This plugin should be listed at the top of your config/plugins file so that
12
+ it runs before any other plugin that hooks lookup_rdns.
13
13
 
14
14
  ## Configuration
15
15
 
16
16
  If you wish to override the default maxLag value of 70ms then add the desired
17
- value to config/toobusy.maxlag. This can be set and changed at runtime and
17
+ value to config/toobusy.maxlag. This can be set and changed at runtime and
18
18
  no restart is required.
19
19
 
20
20
  Note that if you set the maxLag value to <10 then this will cause the toobusy
@@ -4,7 +4,7 @@ Implements the [XCLIENT](http://www.postfix.org/XCLIENT_README.html) protocol.
4
4
 
5
5
  ## configuration
6
6
 
7
- * xclient.hosts
7
+ - xclient.hosts
8
8
 
9
- A list of IP addresses, one per line that should be allowed to use the
10
- XCLIENT protocol. Localhost (127.0.0.1 or ::1) is allowed implicitly.
9
+ A list of IP addresses, one per line that should be allowed to use the
10
+ XCLIENT protocol. Localhost (127.0.0.1 or ::1) is allowed implicitly.
@@ -1,47 +1,26 @@
1
- Migrating from Haraka v1.x to v2.x
2
- ==================================
1
+ # Migrating from Haraka v1.x to v2.x
3
2
 
4
- Haraka v2.x contains two significant changes to the v1.x API related to
5
- streams.
3
+ Haraka v2.x contains two significant changes to the v1.x API related to streams.
6
4
 
7
- Streams are an abstraction over a data flow that is provided by Node core
8
- and is used throughout node to "pipe" data between two places or more. This
9
- makes programming very easy, and is hence why we started using them in Haraka
10
- starting with version 2.0.0.
5
+ Streams are an abstraction over a data flow that is provided by Node core and is used throughout node to "pipe" data between two places or more. This makes programming very easy, and is hence why we started using them in Haraka starting with version 2.0.0.
11
6
 
12
- For more information about the Stream API, see
13
- http://nodejs.org/api/stream.html
7
+ For more information about the Stream API, see http://nodejs.org/api/stream.html
14
8
 
15
- It's important to note that if you are using standard Haraka plugins then
16
- it's very unlikely you will need to change anything. Though you may want
17
- to configure `spool_dir` and `spool_after` in `config/smtp.ini`. However if
18
- you have written custom plugins, continue reading.
9
+ Note that when using bundled Haraka plugins, it's very unlikely you will need to change anything. Though you may want to configure `spool_dir` and `spool_after` in `config/smtp.ini`. If you have custom plugins, continue reading.
19
10
 
20
- Changes To Look For
21
- -------------------
11
+ ## Changes To Look For
22
12
 
23
- Firstly, the incoming data in an email (the email body) is now stored in an
24
- object which you can treat as a ReadableStream. To find if this is relevant
25
- for you, look for instances of `data_lines` in your plugins.
13
+ Firstly, the incoming data in an email (the email body) is now stored in an object which you can treat as a ReadableStream. To find if this is relevant for you, look for instances of `data_lines` in your plugins.
26
14
 
27
- Secondly, if you parse the mail body, attachments are now provided as a
28
- stream, rather than custom start/data/end events. To find if this is relevant
29
- for you, look for instances of `attachment_hooks` in your plugins.
15
+ Secondly, if you parse the mail body, attachments are now provided as a stream, rather than custom start/data/end events. To find if this is relevant for you, look for instances of `attachment_hooks` in your plugins.
30
16
 
31
- Fixing data\_lines plugins
32
- -------------------------
17
+ ## Fixing data_lines plugins
33
18
 
34
- Any plugins now working on each line of data will need to change to using a
35
- stream. The stream is called `transaction.message_stream`.
19
+ Any plugins now working on each line of data will need to change to using a stream. The stream is called `transaction.message_stream`.
36
20
 
37
- These changes may be complicated if you are iterating over each line and
38
- doing something with the strings therein. However if you are piping the data
39
- to an application or over a network, your code will become significantly
40
- simpler (and a lot faster).
21
+ These changes may be complicated if you are iterating over each line and doing something with the strings therein. However if you are piping the data to an application or over a network, your code will become significantly simpler (and a lot faster).
41
22
 
42
- In v1.x Haraka populated the `transaction.data_lines` array for each line of
43
- data received. If you were writing the data to a socket then you had to handle backpressure manually by checking the return of `write()` and adding
44
- `on('drain')` handlers like so:
23
+ In v1.x Haraka populated the `transaction.data_lines` array for each line of data received. If you were writing the data to a socket then you had to handle backpressure manually by checking the return of `write()` and adding `on('drain')` handlers like so:
45
24
 
46
25
  var data_marker = 0;
47
26
  var in_data = false;
@@ -70,18 +49,17 @@ data received. If you were writing the data to a socket then you had to handle
70
49
 
71
50
  In v2.x this now becomes:
72
51
 
73
- connection.transaction.message_stream.pipe(socket, {dot_stuffing: true, ending_dot: true});
52
+ connection.transaction.message_stream.pipe(socket, {ending_dot: true});
74
53
 
75
- This automatically chunks the data, handles backpressure and will apply any
76
- necessary format changes. See `docs/Transaction.md` for the full details.
54
+ This automatically chunks the data, handles backpressure and will apply any
55
+ necessary format changes. See `docs/Transaction.md` for the full details.
77
56
 
78
- If you need to handle the input data by line, then you will need to create
79
- your own writable stream and then pipe the message to the stream and then
80
- extract the lines from the stream of data. See `plugins/dkim_sign.js` for
57
+ If you need to handle the input data by line, then you will need to create
58
+ your own writable stream and then pipe the message to the stream and then
59
+ extract the lines from the stream of data. See the `dkim` plugin for
81
60
  an example.
82
61
 
83
- Fixing attachment\_hooks plugins
84
- -------------------------------
62
+ ## Fixing attachment_hooks plugins
85
63
 
86
64
  For v1.x you passed in functions to `transaction.attachment_hooks()` as
87
65
  follows:
@@ -1,19 +1,17 @@
1
- Configuring Haraka For Outbound Email
2
- =====================================
1
+ # Configuring Haraka For Outbound Email
3
2
 
4
3
  It is trivially easy to configure Haraka as an outbound email server. But
5
4
  first there are external things you may want to sort out:
6
5
 
7
- * Get your DNS PTR record working - make sure it matches the A record of the
6
+ - Get your DNS PTR record working - make sure it matches the A record of the
8
7
  host you are sending from.
9
- * Consider implementing an SPF record. I don't personally do this, but some
8
+ - Consider implementing an SPF record. I don't personally do this, but some
10
9
  people seem to think it helps.
11
10
 
12
11
  There's lots of information elsewhere on the internet about getting these
13
12
  things working, and they are specific to your network and your DNS hosting.
14
13
 
15
- First Some Background
16
- ---------------------
14
+ ## First Some Background
17
15
 
18
16
  Sending outbound mail through Haraka is called "relaying", and that is the
19
17
  term the internals use. The process is simple - if a plugin in Haraka tells
@@ -25,8 +23,7 @@ address used when connecting to Haraka. If that address also bounces then
25
23
  it is considered a "double bounce" and Haraka will log an error and drop it
26
24
  on the floor.
27
25
 
28
- The Setup
29
- ---------
26
+ ## The Setup
30
27
 
31
28
  Outbound mail servers should run on port 587 and enforce authentication. This
32
29
  is slightly different from the "old" model where there would simply be a
@@ -52,7 +49,7 @@ and password:
52
49
 
53
50
  vi config/auth_flat_file.ini
54
51
 
55
- See the documentation in docs/plugins/auth/flat\_file.md for information about
52
+ See the documentation in docs/plugins/auth/flat_file.md for information about
56
53
  what can go in that file.
57
54
 
58
55
  Now you can start Haraka. That's all the configuration you need.
package/endpoint.js CHANGED
@@ -1,69 +1,66 @@
1
- 'use strict';
1
+ 'use strict'
2
2
  // Socket address parser/formatter and server binding helper
3
3
 
4
- const fs = require('node:fs/promises');
5
- const sockaddr = require('sockaddr');
4
+ const fs = require('node:fs/promises')
5
+ const sockaddr = require('sockaddr')
6
6
 
7
- module.exports = function endpoint (addr, defaultPort) {
7
+ module.exports = function endpoint(addr, defaultPort) {
8
8
  try {
9
9
  if ('string' === typeof addr || 'number' === typeof addr) {
10
- addr = sockaddr(addr, {defaultPort});
11
- const match = /^(.*):([0-7]{3})$/.exec(addr.path || '');
10
+ addr = sockaddr(addr, { defaultPort })
11
+ const match = /^(.*):([0-7]{3})$/.exec(addr.path || '')
12
12
  if (match) {
13
- addr.path = match[1];
14
- addr.mode = match[2];
13
+ addr.path = match[1]
14
+ addr.mode = match[2]
15
15
  }
16
16
  }
17
- }
18
- catch (err) {
17
+ } catch (err) {
19
18
  // Return the parse exception instead of throwing it
20
- return err;
19
+ return err
21
20
  }
22
- return new Endpoint(addr);
21
+ return new Endpoint(addr)
23
22
  }
24
23
 
25
24
  class Endpoint {
26
-
27
- constructor (addr) {
25
+ constructor(addr) {
28
26
  if (addr.path) {
29
- this.path = addr.path;
30
- if (addr.mode) this.mode = addr.mode;
31
- }
32
- else {
27
+ this.path = addr.path
28
+ if (addr.mode) this.mode = addr.mode
29
+ } else {
33
30
  // Handle server.address() return as well as parsed host/port
34
- const host = addr.address || addr.host || '::0';
31
+ const host = addr.address || addr.host || '::0'
35
32
  // Normalize '::' to '::0'
36
- this.host = ('::' === host) ? '::0' : host ;
37
- this.port = parseInt(addr.port, 10);
33
+ this.host = '::' === host ? '::0' : host
34
+ this.port = parseInt(addr.port, 10)
38
35
  }
39
36
  }
40
37
 
41
- toString () {
42
- if (this.mode) return `${this.path}:${this.mode}`;
43
- if (this.path) return this.path;
44
- if (this.host.includes(':')) return `[${this.host}]:${this.port}`;
45
- return `${this.host}:${this.port}`;
38
+ toString() {
39
+ if (this.mode) return `${this.path}:${this.mode}`
40
+ if (this.path) return this.path
41
+ if (this.host.includes(':')) return `[${this.host}]:${this.port}`
42
+ return `${this.host}:${this.port}`
46
43
  }
47
44
 
48
45
  // Make server listen on this endpoint, w/optional options
49
- async bind (server, opts) {
50
- opts = {...opts};
46
+ async bind(server, opts) {
47
+ opts = { ...opts }
51
48
 
52
- const mode = this.mode ? parseInt(this.mode, 8) : false;
49
+ const mode = this.mode ? parseInt(this.mode, 8) : false
53
50
  if (this.path) {
54
- opts.path = this.path;
55
- await fs.rm(this.path, { force: true }); // errors are ignored when force is true
51
+ opts.path = this.path
52
+ await fs.rm(this.path, { force: true }) // errors are ignored when force is true
56
53
  } else {
57
- opts.host = this.host;
58
- opts.port = this.port;
54
+ opts.host = this.host
55
+ opts.port = this.port
59
56
  }
60
-
57
+
61
58
  return new Promise((resolve, reject) => {
62
59
  server.listen(opts, async (err) => {
63
- if(err) return reject(err);
64
- if (mode) await fs.chmod(opts.path, mode);
60
+ if (err) return reject(err)
61
+ if (mode) await fs.chmod(opts.path, mode)
65
62
  resolve()
66
- });
67
- });
63
+ })
64
+ })
68
65
  }
69
66
  }
package/eslint.config.mjs CHANGED
@@ -1,27 +1,30 @@
1
- import globals from "globals";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import js from "@eslint/js";
5
- import { FlatCompat } from "@eslint/eslintrc";
1
+ import globals from 'globals'
2
+ import path from 'node:path'
3
+ import { fileURLToPath } from 'node:url'
4
+ import js from '@eslint/js'
5
+ import { FlatCompat } from '@eslint/eslintrc'
6
6
 
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = path.dirname(__filename);
7
+ const __filename = fileURLToPath(import.meta.url)
8
+ const __dirname = path.dirname(__filename)
9
9
  const compat = new FlatCompat({
10
- baseDirectory: __dirname,
11
- recommendedConfig: js.configs.recommended,
12
- allConfig: js.configs.all
13
- });
10
+ baseDirectory: __dirname,
11
+ recommendedConfig: js.configs.recommended,
12
+ allConfig: js.configs.all,
13
+ })
14
14
 
15
- export default [...compat.extends("@haraka"), {
15
+ export default [
16
+ ...compat.extends('@haraka'),
17
+ {
16
18
  languageOptions: {
17
- globals: {
18
- ...globals.node,
19
- },
19
+ globals: {
20
+ ...globals.node,
21
+ },
20
22
  },
21
23
 
22
24
  rules: {
23
- "prefer-template": "warn",
24
- "no-unneeded-ternary": 1,
25
- "no-unused-vars": 0,
25
+ 'prefer-template': 'warn',
26
+ 'no-unneeded-ternary': 1,
27
+ 'no-unused-vars': 0,
26
28
  },
27
- }];
29
+ },
30
+ ]
package/haraka.js CHANGED
@@ -1,79 +1,74 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- 'use strict';
4
- const path = require('path');
5
- const makePathJoin = () => path.join(process.env.HARAKA, 'node_modules');
3
+ 'use strict'
4
+ const path = require('path')
5
+ const makePathJoin = () => path.join(process.env.HARAKA, 'node_modules')
6
6
 
7
7
  if (!process.env.HARAKA) {
8
- console.warn("WARNING: Not running installed Haraka - command line arguments ignored")
8
+ console.warn('WARNING: Not running installed Haraka - command line arguments ignored')
9
9
  }
10
10
 
11
11
  // this must be set before "server.js" is loaded
12
- process.env.HARAKA = process.env.HARAKA || path.resolve('.');
12
+ process.env.HARAKA = process.env.HARAKA || path.resolve('.')
13
13
  try {
14
- require.paths.push(makePathJoin());
15
- }
16
- catch (e) {
17
- process.env.NODE_PATH = process.env.NODE_PATH ?
18
- (`${process.env.NODE_PATH}:${makePathJoin()}`) :
19
- (makePathJoin());
20
- require('module')._initPaths(); // Horrible hack
14
+ require.paths.push(makePathJoin())
15
+ } catch (e) {
16
+ process.env.NODE_PATH = process.env.NODE_PATH ? `${process.env.NODE_PATH}:${makePathJoin()}` : makePathJoin()
17
+ require('module')._initPaths() // Horrible hack
21
18
  }
22
19
 
23
- const utils = require('haraka-utils');
24
- const logger = require('./logger');
25
- const server = require('./server');
20
+ const utils = require('haraka-utils')
21
+ const logger = require('./logger')
22
+ const server = require('./server')
26
23
 
27
24
  exports.version = utils.getVersion(__dirname)
28
25
 
29
- process.on('uncaughtException', err => {
26
+ process.on('uncaughtException', (err) => {
30
27
  if (err.stack) {
31
- err.stack.split("\n").forEach(line => logger.crit(line));
32
- }
33
- else {
34
- logger.crit(`Caught exception: ${JSON.stringify(err)}`);
28
+ err.stack.split('\n').forEach((line) => logger.crit(line))
29
+ } else {
30
+ logger.crit(`Caught exception: ${JSON.stringify(err)}`)
35
31
  }
36
- logger.dump_and_exit(1);
37
- });
32
+ logger.dump_and_exit(1)
33
+ })
38
34
 
39
- let shutting_down = false;
40
- const signals = ['SIGINT'];
35
+ let shutting_down = false
36
+ const signals = ['SIGINT']
41
37
 
42
38
  if (process.pid === 1) signals.push('SIGTERM')
43
39
 
44
40
  for (const sig of signals) {
45
41
  process.on(sig, () => {
46
- if (shutting_down) return process.exit(1);
47
- shutting_down = true;
48
- const [, filename] = process.argv;
49
- process.title = path.basename(filename, '.js');
42
+ if (shutting_down) return process.exit(1)
43
+ shutting_down = true
44
+ const [, filename] = process.argv
45
+ process.title = path.basename(filename, '.js')
50
46
 
51
- logger.notice(`${sig} received`);
47
+ logger.notice(`${sig} received`)
52
48
  logger.dump_and_exit(() => {
53
49
  if (server.cluster?.isMaster) {
54
- server.performShutdown();
55
- }
56
- else if (!server.cluster) {
57
- server.performShutdown();
50
+ server.performShutdown()
51
+ } else if (!server.cluster) {
52
+ server.performShutdown()
58
53
  }
59
- });
60
- });
54
+ })
55
+ })
61
56
  }
62
57
 
63
58
  process.on('SIGHUP', () => {
64
- logger.notice('Flushing the temp fail queue');
65
- server.flushQueue();
66
- });
59
+ logger.notice('Flushing the temp fail queue')
60
+ server.flushQueue()
61
+ })
67
62
 
68
- process.on('exit', code => {
69
- if (shutting_down) return;
70
- const [, filename] = process.argv;
71
- process.title = path.basename(filename, '.js');
63
+ process.on('exit', (code) => {
64
+ if (shutting_down) return
65
+ const [, filename] = process.argv
66
+ process.title = path.basename(filename, '.js')
72
67
 
73
- logger.notice('Shutting down');
74
- logger.dump_logs();
75
- });
68
+ logger.notice('Shutting down')
69
+ logger.dump_logs()
70
+ })
76
71
 
77
- logger.log('NOTICE', `Starting up Haraka version ${exports.version}`);
72
+ logger.log('NOTICE', `Starting up Haraka version ${exports.version}`)
78
73
 
79
- server.createServer();
74
+ server.createServer()