Haraka 3.1.5 → 3.1.7

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 (79) hide show
  1. package/.prettierignore +1 -1
  2. package/{Changes.md → CHANGELOG.md} +54 -3
  3. package/CONTRIBUTORS.md +26 -26
  4. package/Plugins.md +99 -99
  5. package/README.md +68 -93
  6. package/SECURITY.md +178 -0
  7. package/bin/haraka +7 -14
  8. package/config/plugins +0 -3
  9. package/config/smtp_forward.ini +10 -0
  10. package/config/smtp_proxy.ini +10 -0
  11. package/connection.js +25 -8
  12. package/docs/Connection.md +126 -39
  13. package/docs/CoreConfig.md +92 -74
  14. package/docs/HAProxy.md +41 -25
  15. package/docs/Logging.md +68 -38
  16. package/docs/Outbound.md +124 -179
  17. package/docs/Plugins.md +38 -59
  18. package/docs/Transaction.md +78 -83
  19. package/docs/Tutorial.md +122 -209
  20. package/docs/plugins/aliases.md +1 -141
  21. package/docs/plugins/auth/auth_ldap.md +2 -39
  22. package/docs/plugins/max_unrecognized_commands.md +4 -18
  23. package/docs/plugins/process_title.md +3 -3
  24. package/docs/plugins/queue/smtp_forward.md +19 -3
  25. package/docs/plugins/queue/smtp_proxy.md +10 -2
  26. package/docs/plugins/reseed_rng.md +11 -13
  27. package/docs/plugins/tls.md +7 -7
  28. package/docs/plugins/toobusy.md +10 -4
  29. package/docs/tutorials/SettingUpOutbound.md +40 -48
  30. package/endpoint.js +32 -2
  31. package/haraka.js +1 -1
  32. package/outbound/hmail.js +42 -41
  33. package/outbound/index.js +7 -4
  34. package/outbound/tls.js +2 -43
  35. package/package.json +51 -61
  36. package/plugins/auth/auth_base.js +9 -3
  37. package/plugins/auth/auth_proxy.js +14 -11
  38. package/plugins/block_me.js +4 -2
  39. package/plugins/prevent_credential_leaks.js +3 -1
  40. package/plugins/process_title.js +6 -6
  41. package/plugins/queue/qmail-queue.js +15 -19
  42. package/plugins/queue/smtp_forward.js +12 -4
  43. package/plugins/queue/smtp_proxy.js +14 -3
  44. package/plugins/tls.js +13 -5
  45. package/plugins/xclient.js +3 -1
  46. package/server.js +22 -10
  47. package/smtp_client.js +20 -11
  48. package/test/config/block_me.recipient +1 -0
  49. package/test/config/block_me.senders +1 -0
  50. package/test/connection.js +258 -0
  51. package/test/endpoint.js +27 -0
  52. package/test/outbound/bounce_net_errors.js +3 -2
  53. package/test/outbound/hmail.js +19 -0
  54. package/test/outbound/index.js +189 -0
  55. package/test/outbound/queue.js +92 -0
  56. package/test/plugins/auth/auth_bridge.js +80 -0
  57. package/test/plugins/auth/flat_file.js +128 -0
  58. package/test/plugins/block_me.js +157 -0
  59. package/test/plugins/data.signatures.js +114 -0
  60. package/test/plugins/delay_deny.js +263 -0
  61. package/test/plugins/prevent_credential_leaks.js +178 -0
  62. package/test/plugins/process_title.js +135 -0
  63. package/test/plugins/queue/deliver.js +99 -0
  64. package/test/plugins/queue/discard.js +79 -0
  65. package/test/plugins/queue/lmtp.js +138 -0
  66. package/test/plugins/queue/qmail-queue.js +99 -0
  67. package/test/plugins/queue/quarantine.js +81 -0
  68. package/test/plugins/queue/smtp_bridge.js +154 -0
  69. package/test/plugins/queue/smtp_forward.js +42 -6
  70. package/test/plugins/queue/smtp_proxy.js +139 -0
  71. package/test/plugins/reseed_rng.js +34 -0
  72. package/test/plugins/tarpit.js +91 -0
  73. package/test/plugins/tls.js +25 -0
  74. package/test/plugins/toobusy.js +21 -0
  75. package/test/plugins/xclient.js +14 -0
  76. package/test/server.js +231 -0
  77. package/test/smtp_client.js +45 -12
  78. package/test/tls_socket.js +220 -0
  79. package/tls_socket.js +52 -2
package/docs/Tutorial.md CHANGED
@@ -1,270 +1,183 @@
1
1
  # Writing Haraka Plugins
2
2
 
3
- Part of the joy of using Haraka as your main mail server is having a strong
4
- plugin based system which means you control all aspects of how your mail is
5
- processed, accepted, and delivered.
3
+ Part of the joy of using Haraka as your main mail server is having a strong plugin system: you control every aspect of how mail is processed, accepted, and delivered.
6
4
 
7
- Of course in order to control this you may at some point need to edit some
8
- sort of plugin file of your own to customise how things work. The good news
9
- is that writing plugins in Haraka is simple, even for novice coders. You
10
- just need a little knowledge of Javascript (and maybe some understanding of
11
- Node.js) and the world is your oyster.
5
+ This tutorial walks through a small plugin that supports *disposable addresses*: an email like `user-20271231@example.com` is accepted up until 31 December 2027, after which delivery is rejected. Mail that is still within the validity window is rewritten back to `user@example.com` before it is forwarded on.
12
6
 
13
- This tutorial will run through a simple plugin which allows you to have
14
- email addresses that expire in a short period of time. This is handy if you
15
- want a _disposable email address_ to use to sign up for a web site that you
16
- don't wish to continually receive communication from.
7
+ ## What You'll Need
17
8
 
18
- ## The Design
19
-
20
- In order to make this simple, we are going to simply let you have tagged
21
- email addresses such as `user-20120515@domain.com` which will expire on the
22
- 15th May, 2012. Haraka will then check the email has yet to expire, and
23
- reject mails to that address after the expiry date. If the address hasn't
24
- expired yet it will re-write the address to `user@domain.com` before onward
25
- delivery.
26
-
27
- ## What You Will Need
28
-
29
- - Node.js and npm
9
+ - Node.js (an active LTS release) and npm
30
10
  - Haraka
31
11
  - A text editor
32
- - [swaks][1]
33
- - A screwdriver
34
-
35
- [1]: http://jetmore.org/john/code/swaks/
12
+ - [swaks][swaks] for sending test mail
36
13
 
37
14
  ## Getting Started
38
15
 
39
- First install Haraka via npm if you haven't already:
16
+ Install Haraka and create a project:
40
17
 
41
- $ sudo npm -g install Haraka
18
+ ```sh
19
+ sudo npm install -g Haraka
20
+ haraka -i /path/to/new_project
21
+ ```
42
22
 
43
- Now we can create our project directory to get started with:
23
+ Use a directory that does not yet exist. Now scaffold a plugin:
44
24
 
45
- $ haraka -i /path/to/new_project
25
+ ```sh
26
+ haraka -c /path/to/new_project -p rcpt_to.disposable
27
+ ```
46
28
 
47
- Make sure you use a directory that doesn't exist for your project.
29
+ `haraka -p` reports the files it created:
48
30
 
49
- Next, let's create a new plugin:
31
+ ```
32
+ Plugin rcpt_to.disposable created
33
+ Now edit javascript in: /path/to/new_project/plugins/rcpt_to.disposable.js
34
+ Add the plugin to config: /path/to/new_project/config/plugins
35
+ And edit documentation in: /path/to/new_project/docs/plugins/rcpt_to.disposable.md
36
+ ```
50
37
 
51
- $ haraka -c /path/to/new_project -p rcpt_to.disposable
38
+ Edit `config/plugins` so the only enabled lines are:
52
39
 
53
- This should output a bunch of information about files it has created:
40
+ ```
41
+ rcpt_to.disposable
42
+ rcpt_to.in_host_list
43
+ queue/test
44
+ ```
54
45
 
55
- Plugin rcpt_to.disposable created
56
- Now edit javascript in: /path/to/new_project/plugins/rcpt_to.disposable.js
57
- Add the plugin to config: /path/to/new_project/config/plugins
58
- And edit documentation in: /path/to/new_project/docs/plugins/rcpt_to.disposable.md
46
+ The ordering matters — the disposable plugin must run *before* `rcpt_to.in_host_list`, which accepts mail for domains listed in `config/host_list`. `queue/test` writes accepted mail to a `.eml` file in `os.tmpdir()` so you can confirm delivery.
59
47
 
60
- So let's do the second part now - load up the `config/plugins` file and
61
- set it up to test. Comment out most of the plugins, except for
62
- `rcpt_to.in_host_list` and add in our new plugin, and change the queue
63
- plugin to `test_queue`. The final file should look like this:
48
+ Open `plugins/rcpt_to.disposable.js` and start with:
64
49
 
65
- # default list of plugins
50
+ ```js
51
+ exports.hook_rcpt = (next, connection, params) => {
52
+ const rcpt = params[0]
53
+ connection.loginfo(`got recipient: ${rcpt}`)
54
+ next()
55
+ }
56
+ ```
66
57
 
67
- #dns-lists
68
- #data.signatures
58
+ Verify it works. In one terminal:
69
59
 
70
- # block mail from some known bad HELOs - see config/helo.checks.ini for configuration
71
- #helo.checks
60
+ ```sh
61
+ echo LOGDEBUG > config/loglevel
62
+ echo myserver.com >> config/host_list
63
+ sudo haraka -c /path/to/new_project
64
+ ```
72
65
 
73
- # Only accept mail where the MAIL FROM domain is resolvable to an MX record
74
- #mail_from.is_resolvable
66
+ In another:
75
67
 
76
- # Allow dated tagged addresses
77
- rcpt_to.disposable
68
+ ```sh
69
+ swaks -h example.com -t booya@myserver.com -f sender@example.com -s localhost -p 25
70
+ ```
78
71
 
79
- # Only accept mail for your personal list of hosts
80
- rcpt_to.in_host_list
72
+ You should see something like this in the Haraka log:
81
73
 
82
- # Queue mail via qmail-queue
83
- #queue/qmail-queue
74
+ ```
75
+ [INFO] [<uuid>] [rcpt_to.disposable] got recipient: <booya@myserver.com>
76
+ ```
84
77
 
85
- test_queue
86
-
87
- The ordering here is important - our new plugin has to come before `rcpt_to.in_host_list`.
88
-
89
- Fire up your favourite editor and put the following into the `plugins/rcpt_to.disposable.js` file:
90
-
91
- exports.hook_rcpt = function (next, connection, params) {
92
- const rcpt = params[0];
93
- this.loginfo("Got recipient: " + rcpt);
94
- next();
95
- }
78
+ …and a `.eml` file in your system temp directory containing the message.
96
79
 
97
- Here we log that we got the recipient.
80
+ ## Parsing Out the Date
98
81
 
99
- Check this works. You'll need two terminal windows. In window 1:
82
+ Detect addresses of the form `user-YYYYMMDD` and parse the date:
100
83
 
101
- $ echo LOGDEBUG > config/loglevel
102
- $ echo myserver.com >> config/host_list
103
- $ sudo haraka -c /path/to/new_project
84
+ ```js
85
+ exports.hook_rcpt = (next, connection, params) => {
86
+ const rcpt = params[0]
87
+ connection.loginfo(`got recipient: ${rcpt}`)
104
88
 
105
- And in window 2:
89
+ const match = /^(.*)-(\d{4})(\d{2})(\d{2})$/.exec(rcpt.user)
90
+ if (!match) return next()
106
91
 
107
- $ swaks -h domain.com -t booya@myserver.com -f somewhere@example.com \
108
- -s localhost -p 25
92
+ // Date constructor uses zero-indexed months (Dec === 11)
93
+ const expiry = new Date(match[2], match[3] - 1, match[4])
94
+ connection.loginfo(`expires on: ${expiry.toISOString()}`)
109
95
 
110
- In the logs you should see:
96
+ next()
97
+ }
98
+ ```
111
99
 
112
- [INFO] [rcpt_to.disposable] Got recipient: <booya@myserver.com>
100
+ Restart Haraka and send:
113
101
 
114
- Which indicates everything is working. You should also have a file
115
- `/tmp/mail.eml` containing the email that swaks sent.
102
+ ```sh
103
+ swaks -h example.com -t booya-20271231@myserver.com \
104
+ -f sender@example.com -s localhost -p 25
105
+ ```
116
106
 
117
- ## Parsing Out The Date
107
+ Logs:
118
108
 
119
- Now check for emails with an expire date in them and turn them into
120
- `Date` objects. Edit your plugin file as follows:
109
+ ```
110
+ [INFO] [rcpt_to.disposable] got recipient: <booya-20271231@myserver.com>
111
+ [INFO] [rcpt_to.disposable] expires on: 2027-12-31T00:00:00.000Z
112
+ ```
121
113
 
122
- exports.hook_rcpt = function (next, connection, params) {
123
- var rcpt = params[0];
124
- this.loginfo("Got recipient: " + rcpt);
114
+ ## Rejecting Expired Addresses
125
115
 
126
- // Check user matches regex 'user-YYYYMMDD':
127
- var match = /^(.*)-(\d{4})(\d{2})(\d{2})$/.exec(rcpt.user);
128
- if (!match) {
129
- return next();
130
- }
116
+ Compare the parsed date to today and reject if it has already passed:
131
117
 
132
- // get date - note Date constructor takes month-1 (i.e. Dec == 11).
133
- var expiry_date = new Date(match[2], match[3]-1, match[4]);
118
+ ```js
119
+ exports.hook_rcpt = (next, connection, params) => {
120
+ const rcpt = params[0]
134
121
 
135
- this.loginfo("Email expires on: " + expiry_date);
122
+ const match = /^(.*)-(\d{4})(\d{2})(\d{2})$/.exec(rcpt.user)
123
+ if (!match) return next()
136
124
 
137
- next();
125
+ const expiry = new Date(match[2], match[3] - 1, match[4])
126
+ if (expiry < new Date()) {
127
+ return next(DENY, 'Expired email address')
138
128
  }
139
129
 
140
- Start haraka again and pass it the following email via swaks:
130
+ next()
131
+ }
132
+ ```
141
133
 
142
- $ swaks -h domain.com -t booya-20120101@myserver.com \
143
- -f somewhere@example.com -s localhost -p 25
134
+ Send mail to an expired address:
144
135
 
145
- And you should see now in the logs:
136
+ ```sh
137
+ swaks -h example.com -t booya-20200101@myserver.com \
138
+ -f sender@example.com -s localhost -p 25
139
+ ```
146
140
 
147
- [INFO] [rcpt_to.disposable] Got recipient: <booya-20120101@myserver.com>
148
- [INFO] [rcpt_to.disposable] Email expires on: Sun, 01 Jan 2012 05:00:00 GMT
141
+ The remote end sees:
149
142
 
150
- The exact time may vary depending on your timezone, but it should be obvious
151
- we now have a date object, which we can now compare to the current date.
143
+ ```
144
+ <** 550 Expired email address
145
+ ```
152
146
 
153
- ## Rejecting Expired Emails
147
+ ## Rewriting Live Addresses
154
148
 
155
- The next edit we have to do is to add in code to compare to the current date
156
- and reject expired emails. Again, this is very simple:
149
+ When the address is still valid, strip the date tag so the downstream mail store receives plain `user@domain`:
157
150
 
158
- exports.hook_rcpt = function (next, connection, params) {
159
- var rcpt = params[0];
160
- this.loginfo("Got recipient: " + rcpt);
151
+ ```js
152
+ exports.hook_rcpt = (next, connection, params) => {
153
+ const rcpt = params[0]
161
154
 
162
- // Check user matches regex 'user-YYYYMMDD':
163
- var match = /^(.*)-(\d{4})(\d{2})(\d{2})$/.exec(rcpt.user);
164
- if (!match) {
165
- return next();
166
- }
155
+ const match = /^(.*)-(\d{4})(\d{2})(\d{2})$/.exec(rcpt.user)
156
+ if (!match) return next()
167
157
 
168
- // get date - note Date constructor takes month-1 (i.e. Dec == 11).
169
- var expiry_date = new Date(match[2], match[3]-1, match[4]);
170
-
171
- this.loginfo("Email expires on: " + expiry_date);
172
-
173
- var today = new Date();
174
-
175
- if (expiry_date < today) {
176
- // If we get here, the email address has expired
177
- return next(DENY, "Expired email address");
178
- }
179
-
180
- next();
158
+ const expiry = new Date(match[2], match[3] - 1, match[4])
159
+ if (expiry < new Date()) {
160
+ return next(DENY, 'Expired email address')
181
161
  }
182
162
 
183
- And we can easily check that with swaks (remember to restart Haraka):
184
-
185
- $ swaks -h foo.com -t booya-20110101@haraka.local -f somewhere@example.com \
186
- -s localhost -p 25
187
- === Trying localhost:25...
188
- === Connected to localhost.
189
- <- 220 sergeant.org ESMTP Haraka 0.3 ready
190
- -> EHLO foo.com
191
- <- 250-Haraka says hi Unknown [127.0.0.1]
192
- <- 250-PIPELINING
193
- <- 250-8BITMIME
194
- <- 250 SIZE 500000
195
- -> MAIL FROM:<somewhere@example.com>
196
- <- 250 From address is OK
197
- -> RCPT TO:<booya-20110101@haraka.local>
198
- <** 550 Expired email address
199
- -> QUIT
200
- <- 221 closing connection. Have a jolly good day.
201
- === Connection closed with remote host.
202
-
203
- Now we need to do one more thing...
204
-
205
- ## Fixing Up Unexpired Emails
206
-
207
- The last thing we need to do, is if we have an email that isn't expired, we
208
- need to normalise it back to the real email address, because wherever we
209
- deliver this to is unlikely to recognise these new email addresses.
210
-
211
- Here's how our final plugin will look:
212
-
213
- exports.hook_rcpt = function (next, connection, params) {
214
- var rcpt = params[0];
215
- this.loginfo("Got recipient: " + rcpt);
216
-
217
- // Check user matches regex 'user-YYYYMMDD':
218
- var match = /^(.*)-(\d{4})(\d{2})(\d{2})$/.exec(rcpt.user);
219
- if (!match) {
220
- return next();
221
- }
222
-
223
- // get date - note Date constructor takes month-1 (i.e. Dec == 11).
224
- var expiry_date = new Date(match[2], match[3]-1, match[4]);
225
-
226
- this.loginfo("Email expires on: " + expiry_date);
227
-
228
- var today = new Date();
229
-
230
- if (expiry_date < today) {
231
- // If we get here, the email address has expired
232
- return next(DENY, "Expired email address");
233
- }
234
-
235
- // now get rid of the extension:
236
- rcpt.user = match[1];
237
- this.loginfo("Email address now: " + rcpt);
238
-
239
- next();
240
- }
241
-
242
- And when we test this with an unexpired address via swaks:
243
-
244
- $ swaks -h foo.com -t booya-20120101@haraka.local \
245
- -f somewhere@example.com -s localhost -p 25
246
-
247
- We get in the logs:
163
+ rcpt.user = match[1]
164
+ connection.loginfo(`rewrote recipient to: ${rcpt}`)
165
+ next()
166
+ }
167
+ ```
248
168
 
249
- [INFO] [rcpt_to.disposable] Got recipient: <booya-20120101@haraka.local>
250
- [INFO] [rcpt_to.disposable] Email expires on: Sun Jan 01 2012 00:00:00 GMT-0500 (EST)
251
- [INFO] [rcpt_to.disposable] Email address now: <booya@haraka.local>
169
+ Send to a live tagged address and watch the log:
252
170
 
253
- Which indicates that we have successfully modified the email address.
171
+ ```
172
+ [INFO] [rcpt_to.disposable] rewrote recipient to: <booya@myserver.com>
173
+ ```
254
174
 
255
- # Further Reading
175
+ ## Further Reading
256
176
 
257
- There are many more features of the Haraka API to explore, including access
258
- to the body of the email and the headers, access to the HELO string, and
259
- implementing ESMTP extensions, among many others.
177
+ The Haraka API offers much more body and header access, ESMTP extension hooks, the outbound delivery hooks, structured results, attachments, and so on. Two good starting points:
260
178
 
261
- There are two good places to read up on these. Firstly is the documentation
262
- in the Haraka "docs" directory. Start with the `Plugins.md` file, and work
263
- your way through the API from there.
179
+ - The [Plugins guide](Plugins.md) and the rest of the `docs/` directory.
180
+ - The [Plugin registry](https://github.com/haraka/Haraka/blob/master/PLUGINS.md) for an inventory of real-world plugins.
181
+ - The plugins shipped in the [`plugins/`](../plugins/) directory. Even the most elaborate are under 200 lines; many are under 20.
264
182
 
265
- The second place is simply reading the source code for the plugins themselves.
266
- The plugins that Haraka ships with use almost all parts of the API and so
267
- should give you a good starting point if you want to implement a particular
268
- piece of functionality. Even the most complicated plugins are under 200 lines
269
- of code, so don't be intimidated by them! The simplest one is a mere 5 lines
270
- of code.
183
+ [swaks]: https://www.jetmore.org/john/code/swaks/
@@ -1,143 +1,3 @@
1
1
  # aliases
2
2
 
3
- This plugin allows one to configure aliases that may perform an action or
4
- change the RCPT address in a number of ways. All aliases are specified in
5
- a JSON formatted configuration file, and must have at very least an action.
6
- Any syntax error found in the JSON format config file will stop the server
7
- from running.
8
-
9
- IMPORTANT: this plugin must appear in `config/plugins` before other plugins
10
- that run on hook_rcpt
11
-
12
- WARNING: DO NOT USE THIS PLUGIN WITH queue/smtp_proxy.
13
-
14
- ## Configuration
15
-
16
- - aliases
17
-
18
- JSON formatted configuration file that must contain, at very least, a key
19
- to match against RCPT address, and a value that is an associative array
20
- with an "action" : "<action>" key, value pair. An example:
21
-
22
- { "test1" : { "action" : "drop" } }
23
-
24
- In the above example the "test1" alias will drop any message that matches
25
- test1, or test1-_ or test1+_ (wildcard '-' or '+', see below). Actions
26
- may in turn have 0 or more options listed with them like so:
27
-
28
- { "test3" : { "action" : "alias", "to" : "test3-works" } }
29
-
30
- In the above example the "test3" alias has an action of "alias", and
31
- a required "to" field. If this "to" field were missing the alias would
32
- fail to run, and an error would be printed in the logs.
33
-
34
- Now aliases of 'user', '@host' and 'user@host' possible:
35
-
36
- { "demo" : { "action" : "drop" } }
37
- or
38
- { "@example.com" : { "action" : "drop" } }
39
- or
40
- { "demo@example.com" : { "action" : "drop" } }
41
-
42
- Aliases may also be exploded to multiple recipients:
43
-
44
- { "sales@example.com": { "action: "alias", "to": ["alice@example.com", "bob@example.com"] } }
45
-
46
- - wildcard notation
47
-
48
- In an effort to match some of the functionality of other alias parsers
49
- we've allowed wildcard matching of the alias against the right most
50
- string of a RCPT address. The characters '-' and '+' are commonly used
51
- for subaddressing and this plugin has built-in support to alias the
52
- "user" part of the email address.
53
-
54
- That is, if our address were test2-testing@example.com (or
55
- test2+testing@example.com), the below alias would match:
56
-
57
- { "test2" : { "action" : "drop" } }
58
-
59
- The larger, and more specific alias, should always match first when
60
- using wildcard '-' notation. So if the above RCPT were put up against
61
- this alias config, it would not drop, but rather map to another
62
- address:
63
-
64
- {
65
- "test2" : { "action" : "drop" },
66
- "test2-testing" : { "action" : "alias", "to" : "test@foo.com" }
67
- }
68
-
69
- - chaining and circuits
70
-
71
- In short, we do not allow chaining of aliases at this time. As a
72
- side-effect, we enjoy protections against alias circuits.
73
-
74
- - optional one line formatting
75
-
76
- Any valid JSON will due, however, please consider keeping each alias
77
- on its own line so that others that wish to grep the aliases file
78
- have an easier time finding the full configuration for an alias.
79
-
80
- - nondeterministic duplicate matches
81
-
82
- This plugin was written with speed in mind. That means every lookup
83
- hashes into the alias file for its match. While the act of doing so
84
- is fast, it does mean that any duplicate alias entries will match
85
- nondeterministically. That is, we cannot predict what will happen
86
- here:
87
-
88
- {
89
- "coinflip" : { "action" : "alias", "to" : "heads@coin.com" },
90
- "coinflip" : { "action" : "alias", "to" : "tails@coin.com" }
91
- }
92
-
93
- Truth be told, one result will likely always be chosen over the other,
94
- so this is not exactly a coinflip. We simply cannot say what the
95
- language implementation will do here, it could change tomorrow.
96
-
97
- - action (required)
98
-
99
- The following is a list of supported actions, and the options they require.
100
- - drop
101
-
102
- This action simply drops a message, while pretending everything was
103
- okay to the sender. This acts much like an alias to /dev/null in
104
- other servers.
105
-
106
- - alias
107
-
108
- This action will map the alias key to the address specified in the
109
- "to" option. A note about matching in addition to the note
110
- about wildcard '-' above. When we match an alias, we store the
111
- hostname of the match for a shortcut substitution syntax later.
112
- - to (required)
113
-
114
- This option is the full address, or local part at matched hostname
115
- that the RCPT address will be re-written to. For an example of
116
- an alias to a full address consider the following:
117
-
118
- { "test5" : { "action" : "alias", "to" : "test5@foo.com" } }
119
-
120
- This will map RCPT matches for "test5" to "test5-works@foo.com".
121
- This would map "test5@somedomain.com" to "test5-works@foo.com"
122
- every time. Now compare this notation with its shortcut
123
- counterpart, best used when the "to" address is at the same
124
- domain as the match:
125
-
126
- { "test4" : { "action" : "alias", "to" : "test4" } }
127
-
128
- Clearly, this notation is more compact, but what does it do. Well,
129
- mail to "test4-foo@anydomain.com" will map to "test4@anydomain.com".
130
- One can see the clear benefit of using this notation with lots of
131
- aliases on a single domain that map to other local parts at the
132
- same domain.
133
-
134
- ### Example Configuration
135
-
136
- {
137
- "test1" : { "action" : "drop" },
138
- "test2" : { "action" : "drop" },
139
- "test3" : { "action" : "alias", "to" : "test3-works" },
140
- "test4" : { "action" : "alias", "to" : "test4" },
141
- "test5" : { "action" : "alias", "to" : "test5-works@success.com" },
142
- "test6" : { "action" : "alias", "to" : "test6-works@success.com" }
143
- }
3
+ Repackaged as [haraka-plugin-aliases](https://github.com/haraka/haraka-plugin-aliases).
@@ -1,41 +1,4 @@
1
1
  # auth/auth_ldap
2
2
 
3
- The `auth/auth_ldap` plugin uses an LDAP bind to authenticate a user. Currently
4
- only one server and multiple DNs can be configured. If any of the DN binds succeed,
5
- the user is authenticated.
6
-
7
- ## Configuration
8
-
9
- Configuration is stored in `config/auth_ldap.ini` and uses the INI
10
- style formatting.
11
-
12
- Only the `LOGIN` authentication method is supported assuming that passwords in the
13
- LDAP database are not stored in cleartext (which would allow for CRAM-MD5). Note
14
- that this means passwords will be sent in the clear to the LDAP server unless
15
- an `ldaps://` conection is used.
16
-
17
- Current configuration options in `[core]` are:
18
-
19
- server - the url of the LDAP server (ldap:// or ldaps://)
20
- timeout - time in miliseconds to wait for the server resonse before giving up
21
- rejectUnauthorized - boolean (true or false) as to whether to reject connections
22
- not verified against a CA. Meaning, a "false" allows non-verified.
23
-
24
- Example:
25
-
26
- [core]
27
- server=ldaps://ldap.opoet.com
28
- timeout=5000
29
- rejectUnauthorized=false
30
-
31
- The `[dns]` section (that is plural DN and not domain name system), is a list of DNs to use
32
- to bind. The `%u` in the strings is substituted with the user name used in the SMTP
33
- authentication. Note that the keys have no meaning and the DNs are tried in series until
34
- the first successful bind. The LDAP RFC does not allow for parallel binds on a connection,
35
- so it is suggested that the most commonly used DN be placed earlier in the list.
36
-
37
- Example:
38
-
39
- [dns]
40
- dn1=uid=%u,ou=Users,dc=opoet,dc=com
41
- dn2=uid=%u,ou=people,dc=opoet,dc=com
3
+ Repackaged as [haraka-plugin-auth-ldap](https://github.com/haraka/haraka-plugin-auth-ldap).
4
+ Loading `auth/auth_ldap` in `config/plugins` is auto-redirected to `auth-ldap`.
@@ -1,20 +1,6 @@
1
1
  # max_unrecognized_commands
2
2
 
3
- This plugin places a maximum limit on the number of unrecognized commands
4
- allowed before recognising that the connection is bad.
5
-
6
- If the limit is reached the connecting client is sent an error message and
7
- immediately (and rudely - technically an RFC violation) disconnected.
8
-
9
- **IMPORTANT**:
10
- This plugin should be listed near the bottom of `config/plugins` so that it
11
- runs after any plugins that use the unrecognized_command hook to implement
12
- other SMTP verbs and extensions (such as the auth/\* plugins), otherwise
13
- commands valid for these plugins will be counted as unknown by this plugin.
14
-
15
- ## Configuration
16
-
17
- - max_unrecognized_commands
18
-
19
- Specifies the number of unrecognized commands to allow before disconnecting.
20
- Default: 10.
3
+ The functionality of this plugin was folded into
4
+ [haraka-plugin-limit](https://github.com/haraka/haraka-plugin-limit).
5
+ Loading `max_unrecognized_commands` in `config/plugins` is auto-redirected
6
+ to `limit`.
@@ -37,6 +37,6 @@ across all workers, with the exception of outbound stats.
37
37
  All of the counts shown are since the process started, so if a
38
38
  worker has been re-started then the counts may not add up.
39
39
 
40
- Note: this plugin will only work on node >= 0.8 and should be
41
- added at the top of config/plugins to ensure that it functions
42
- correctly.
40
+ Note: this plugin should be added at the top of `config/plugins` so
41
+ that its `connect_init`, `rcpt`, `data`, and `disconnect` hooks run
42
+ before any plugin that might short-circuit those hooks.
@@ -38,9 +38,7 @@ Configuration is stored in smtp_forward.ini in the following keys:
38
38
 
39
39
  - enable_tls=[true]
40
40
 
41
- Enable TLS with the forward host (if supported). TLS uses options from the tls plugin. If key and cert are provided in the the outbound section of the tls plugin, that certificate will be used as a TLS Client Certificate.
42
-
43
- This option controls the use of TLS via `STARTTLS`. This plugin does not work with SMTP over TLS.
41
+ Enable opportunistic TLS with the forward host via `STARTTLS` (if the host advertises it). This plugin does not work with implicit SMTP over TLS.
44
42
 
45
43
  - auth_type=[plain\|login]
46
44
 
@@ -69,6 +67,24 @@ Configuration is stored in smtp_forward.ini in the following keys:
69
67
  [example.com]
70
68
  [example.net]
71
69
 
70
+ - [tls]
71
+
72
+ Client STARTTLS options are assembled by merging:
73
+
74
+ 1. `tls.ini` `[main]` — the global Haraka TLS config
75
+ 2. `smtp_forward.ini` `[tls]` — overrides. Anything set here wins.
76
+
77
+ Example `smtp_forward.ini` `[tls]` section:
78
+
79
+ [tls]
80
+ rejectUnauthorized=true
81
+ minVersion=TLSv1.2
82
+ no_tls_hosts[]=10.0.0.5
83
+
84
+ Per-domain `enable_tls=false` still disables STARTTLS for that backend. Per-domain TLS cipher/cert overrides are not currently supported.
85
+
86
+ Changes to `tls.ini` require a Haraka restart to apply to the forward path; changes to `smtp_forward.ini` are picked up by the existing reload hook.
87
+
72
88
  # Per-Domain Configuration
73
89
 
74
90
  More specific forward routes for domains can be defined. The domain is chosen based on the value of the `domain_selector` config variable.