Haraka 3.0.3 → 3.0.5

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 (239) hide show
  1. package/.eslintrc.yaml +4 -9
  2. package/CONTRIBUTORS.md +11 -0
  3. package/Changes.md +1397 -1213
  4. package/Plugins.md +117 -105
  5. package/README.md +4 -13
  6. package/bin/haraka +198 -298
  7. package/config/auth_flat_file.ini +1 -0
  8. package/config/dhparams.pem +8 -0
  9. package/config/mail_from.is_resolvable.ini +4 -2
  10. package/config/me +1 -0
  11. package/config/outbound.ini +0 -2
  12. package/config/plugins +35 -36
  13. package/config/smtp.ini +1 -1
  14. package/config/smtp.json +17 -0
  15. package/config/tls.ini +2 -0
  16. package/config/tls_cert.pem +23 -0
  17. package/config/tls_key.pem +28 -0
  18. package/connection.js +46 -73
  19. package/contrib/bsd-rc.d/haraka +3 -1
  20. package/contrib/plugin2npm.sh +6 -36
  21. package/docs/CoreConfig.md +2 -2
  22. package/docs/Logging.md +7 -21
  23. package/docs/Outbound.md +104 -201
  24. package/docs/Plugins.md +2 -2
  25. package/docs/Transaction.md +59 -82
  26. package/docs/plugins/queue/smtp_proxy.md +5 -10
  27. package/docs/plugins/tls.md +37 -9
  28. package/endpoint.js +16 -13
  29. package/haraka.js +10 -14
  30. package/host_pool.js +5 -5
  31. package/http/html/index.html +6 -5
  32. package/line_socket.js +3 -4
  33. package/logger.js +44 -28
  34. package/outbound/client_pool.js +27 -23
  35. package/outbound/config.js +4 -6
  36. package/outbound/fsync_writestream.js +1 -1
  37. package/outbound/hmail.js +178 -218
  38. package/outbound/index.js +86 -99
  39. package/outbound/qfile.js +1 -1
  40. package/outbound/queue.js +51 -44
  41. package/outbound/timer_queue.js +3 -2
  42. package/outbound/tls.js +19 -7
  43. package/package.json +60 -51
  44. package/plugins/.eslintrc.yaml +0 -6
  45. package/plugins/auth/auth_base.js +4 -2
  46. package/plugins/auth/auth_proxy.js +14 -12
  47. package/plugins/auth/auth_vpopmaild.js +1 -1
  48. package/plugins/block_me.js +1 -1
  49. package/plugins/data.signatures.js +2 -4
  50. package/plugins/early_talker.js +2 -1
  51. package/plugins/mail_from.is_resolvable.js +65 -135
  52. package/plugins/queue/deliver.js +4 -5
  53. package/plugins/queue/lmtp.js +11 -12
  54. package/plugins/queue/qmail-queue.js +2 -2
  55. package/plugins/queue/quarantine.js +2 -2
  56. package/plugins/queue/rabbitmq.js +16 -17
  57. package/plugins/queue/smtp_forward.js +3 -3
  58. package/plugins/queue/smtp_proxy.js +10 -1
  59. package/plugins/queue/test.js +2 -2
  60. package/plugins/rcpt_to.host_list_base.js +5 -5
  61. package/plugins/rcpt_to.in_host_list.js +2 -2
  62. package/plugins/relay.js +6 -7
  63. package/plugins/reseed_rng.js +1 -1
  64. package/plugins/status.js +37 -33
  65. package/plugins/tls.js +2 -2
  66. package/plugins/xclient.js +3 -2
  67. package/plugins.js +50 -54
  68. package/run_tests +3 -30
  69. package/server.js +190 -190
  70. package/smtp_client.js +30 -23
  71. package/{tests → test}/config/plugins +0 -2
  72. package/{tests → test}/config/smtp.ini +3 -1
  73. package/test/config/tls/example.com/_.example.com.key +28 -0
  74. package/test/config/tls/example.com/example.com.crt +25 -0
  75. package/{tests/loud → test}/config/tls.ini +4 -2
  76. package/test/connection.js +302 -0
  77. package/test/endpoint.js +94 -0
  78. package/{tests → test}/fixtures/line_socket.js +1 -1
  79. package/{tests → test}/fixtures/util_hmailitem.js +19 -25
  80. package/{tests → test}/host_pool.js +42 -57
  81. package/test/logger.js +258 -0
  82. package/test/outbound/hmail.js +141 -0
  83. package/test/outbound/index.js +220 -0
  84. package/test/outbound/qfile.js +126 -0
  85. package/test/outbound_bounce_net_errors.js +142 -0
  86. package/{tests → test}/outbound_bounce_rfc3464.js +110 -122
  87. package/test/plugins/auth/auth_base.js +484 -0
  88. package/test/plugins/auth/auth_vpopmaild.js +83 -0
  89. package/test/plugins/early_talker.js +104 -0
  90. package/test/plugins/mail_from.is_resolvable.js +35 -0
  91. package/test/plugins/queue/smtp_forward.js +206 -0
  92. package/test/plugins/rcpt_to.host_list_base.js +122 -0
  93. package/test/plugins/rcpt_to.in_host_list.js +193 -0
  94. package/test/plugins/relay.js +303 -0
  95. package/test/plugins/status.js +130 -0
  96. package/test/plugins/tls.js +70 -0
  97. package/test/plugins.js +228 -0
  98. package/test/rfc1869.js +73 -0
  99. package/test/server.js +491 -0
  100. package/test/smtp_client.js +299 -0
  101. package/test/tls_socket.js +277 -0
  102. package/test/transaction.js +270 -0
  103. package/tls_socket.js +202 -252
  104. package/transaction.js +8 -23
  105. package/CONTRIBUTING.md +0 -1
  106. package/bin/dkimverify +0 -40
  107. package/config/access.domains +0 -13
  108. package/config/attachment.ctype.regex +0 -2
  109. package/config/attachment.filename.regex +0 -1
  110. package/config/avg.ini +0 -5
  111. package/config/bounce.ini +0 -15
  112. package/config/data.headers.ini +0 -61
  113. package/config/dkim/dkim_key_gen.sh +0 -78
  114. package/config/dkim_sign.ini +0 -4
  115. package/config/dkim_verify.ini +0 -7
  116. package/config/dnsbl.ini +0 -23
  117. package/config/greylist.ini +0 -43
  118. package/config/helo.checks.ini +0 -52
  119. package/config/messagesniffer.ini +0 -18
  120. package/config/spamassassin.ini +0 -56
  121. package/dkim.js +0 -614
  122. package/docs/plugins/avg.md +0 -35
  123. package/docs/plugins/bounce.md +0 -69
  124. package/docs/plugins/clamd.md +0 -147
  125. package/docs/plugins/esets.md +0 -8
  126. package/docs/plugins/greylist.md +0 -90
  127. package/docs/plugins/helo.checks.md +0 -135
  128. package/docs/plugins/messagesniffer.md +0 -163
  129. package/docs/plugins/spamassassin.md +0 -180
  130. package/outbound/mx_lookup.js +0 -70
  131. package/plugins/auth/auth_ldap.js +0 -3
  132. package/plugins/avg.js +0 -162
  133. package/plugins/backscatterer.js +0 -25
  134. package/plugins/bounce.js +0 -381
  135. package/plugins/clamd.js +0 -382
  136. package/plugins/data.uribl.js +0 -4
  137. package/plugins/dkim_sign.js +0 -395
  138. package/plugins/dkim_verify.js +0 -62
  139. package/plugins/dns_list_base.js +0 -221
  140. package/plugins/dnsbl.js +0 -146
  141. package/plugins/dnswl.js +0 -58
  142. package/plugins/esets.js +0 -71
  143. package/plugins/graph.js +0 -5
  144. package/plugins/greylist.js +0 -645
  145. package/plugins/helo.checks.js +0 -533
  146. package/plugins/messagesniffer.js +0 -381
  147. package/plugins/rcpt_to.ldap.js +0 -3
  148. package/plugins/rcpt_to.max_count.js +0 -24
  149. package/plugins/spamassassin.js +0 -384
  150. package/tests/config/dkim/example.com/dns +0 -29
  151. package/tests/config/dkim/example.com/private +0 -6
  152. package/tests/config/dkim/example.com/public +0 -4
  153. package/tests/config/dkim/example.com/selector +0 -1
  154. package/tests/config/dkim.private.key +0 -6
  155. package/tests/config/dkim_sign.ini +0 -4
  156. package/tests/config/helo.checks.ini +0 -52
  157. package/tests/connection.js +0 -327
  158. package/tests/endpoint.js +0 -128
  159. package/tests/fixtures/vm_harness.js +0 -59
  160. package/tests/logger.js +0 -327
  161. package/tests/outbound/hmail.js +0 -112
  162. package/tests/outbound/index.js +0 -324
  163. package/tests/outbound/qfile.js +0 -67
  164. package/tests/outbound_bounce_net_errors.js +0 -173
  165. package/tests/plugins/auth/auth_base.js +0 -463
  166. package/tests/plugins/auth/auth_vpopmaild.js +0 -91
  167. package/tests/plugins/bounce.js +0 -307
  168. package/tests/plugins/clamd.js +0 -224
  169. package/tests/plugins/deprecated/relay_acl.js +0 -140
  170. package/tests/plugins/deprecated/relay_all.js +0 -59
  171. package/tests/plugins/dkim_sign.js +0 -315
  172. package/tests/plugins/dkim_signer.js +0 -108
  173. package/tests/plugins/dns_list_base.js +0 -259
  174. package/tests/plugins/dnsbl.js +0 -101
  175. package/tests/plugins/early_talker.js +0 -115
  176. package/tests/plugins/greylist.js +0 -58
  177. package/tests/plugins/helo.checks.js +0 -525
  178. package/tests/plugins/mail_from.is_resolvable.js +0 -116
  179. package/tests/plugins/queue/smtp_forward.js +0 -221
  180. package/tests/plugins/rcpt_to.host_list_base.js +0 -132
  181. package/tests/plugins/rcpt_to.in_host_list.js +0 -218
  182. package/tests/plugins/relay.js +0 -339
  183. package/tests/plugins/spamassassin.js +0 -171
  184. package/tests/plugins/status.js +0 -138
  185. package/tests/plugins/tls.js +0 -84
  186. package/tests/plugins.js +0 -247
  187. package/tests/rfc1869.js +0 -61
  188. package/tests/server.js +0 -510
  189. package/tests/smtp_client/auth.js +0 -105
  190. package/tests/smtp_client/basic.js +0 -101
  191. package/tests/smtp_client.js +0 -80
  192. package/tests/tls_socket.js +0 -333
  193. package/tests/transaction.js +0 -284
  194. /package/docs/{plugins → deprecated}/dkim_sign.md +0 -0
  195. /package/docs/{plugins → deprecated}/dkim_verify.md +0 -0
  196. /package/docs/{plugins → deprecated}/dnsbl.md +0 -0
  197. /package/docs/{plugins → deprecated}/dnswl.md +0 -0
  198. /package/{tests → test}/.eslintrc.yaml +0 -0
  199. /package/{tests → test}/config/auth_flat_file.ini +0 -0
  200. /package/{tests → test}/config/dhparams.pem +0 -0
  201. /package/{tests → test}/config/host_list +0 -0
  202. /package/{tests → test}/config/outbound_tls_cert.pem +0 -0
  203. /package/{tests → test}/config/outbound_tls_key.pem +0 -0
  204. /package/{tests → test}/config/smtp_forward.ini +0 -0
  205. /package/{tests → test}/config/tls/ec.pem +0 -0
  206. /package/{tests → test}/config/tls/haraka.local.pem +0 -0
  207. /package/{tests → test}/config/tls/mismatched.pem +0 -0
  208. /package/{tests → test}/config/tls_cert.pem +0 -0
  209. /package/{tests → test}/config/tls_key.pem +0 -0
  210. /package/{tests → test}/fixtures/todo_qfile.txt +0 -0
  211. /package/{tests → test}/installation/config/test-plugin-flat +0 -0
  212. /package/{tests → test}/installation/config/test-plugin.ini +0 -0
  213. /package/{tests → test}/installation/config/tls.ini +0 -0
  214. /package/{tests → test}/installation/node_modules/load_first/index.js +0 -0
  215. /package/{tests → test}/installation/node_modules/load_first/package.json +0 -0
  216. /package/{tests → test}/installation/node_modules/test-plugin/config/test-plugin-flat +0 -0
  217. /package/{tests → test}/installation/node_modules/test-plugin/config/test-plugin.ini +0 -0
  218. /package/{tests → test}/installation/node_modules/test-plugin/package.json +0 -0
  219. /package/{tests → test}/installation/node_modules/test-plugin/test-plugin.js +0 -0
  220. /package/{tests → test}/installation/plugins/base_plugin.js +0 -0
  221. /package/{tests → test}/installation/plugins/folder_plugin/index.js +0 -0
  222. /package/{tests → test}/installation/plugins/folder_plugin/package.json +0 -0
  223. /package/{tests → test}/installation/plugins/inherits.js +0 -0
  224. /package/{tests → test}/installation/plugins/load_first.js +0 -0
  225. /package/{tests → test}/installation/plugins/plugin.js +0 -0
  226. /package/{tests → test}/installation/plugins/tls.js +0 -0
  227. /package/{tests → test}/loud/config/dhparams.pem +0 -0
  228. /package/{tests → test}/loud/config/tls/goobered.pem +0 -0
  229. /package/{tests → test/loud}/config/tls.ini +0 -0
  230. /package/{tests → test}/mail_specimen/base64-root-part.txt +0 -0
  231. /package/{tests → test}/mail_specimen/varied-fold-lengths-preserve-data.txt +0 -0
  232. /package/{tests → test}/queue/1507509981169_1507509981169_0_61403_e0Y0Ym_1_fixed +0 -0
  233. /package/{tests → test}/queue/1507509981169_1507509981169_0_61403_e0Y0Ym_1_haraka +0 -0
  234. /package/{tests → test}/queue/1508269674999_1508269674999_0_34002_socVUF_1_haraka +0 -0
  235. /package/{tests → test}/queue/1508455115683_1508455115683_0_90253_9Q4o4V_1_haraka +0 -0
  236. /package/{tests → test}/queue/multibyte +0 -0
  237. /package/{tests → test}/queue/plain +0 -0
  238. /package/{tests → test}/queue/zero-length +0 -0
  239. /package/{tests → test}/test-queue/delete-me +0 -0
package/test/server.js ADDED
@@ -0,0 +1,491 @@
1
+ const assert = require('node:assert')
2
+ const path = require('node:path');
3
+
4
+ const endpoint = require('../endpoint');
5
+ const message = require('haraka-email-message')
6
+
7
+ const _set_up = (done) => {
8
+ this.config = require('haraka-config');
9
+ this.server = require('../server');
10
+ done();
11
+ }
12
+
13
+ const _setupServer = (ip_port, done) => {
14
+ process.env.YES_REALLY_DO_DISCARD=1; // for queue/discard plugin
15
+ process.env.HARAKA_TEST_DIR=path.resolve('test');
16
+
17
+ // test sets the default path for plugin instances to the test dir
18
+ const test_cfg_path=path.resolve('test');
19
+
20
+ this.server = require('../server');
21
+ this.config = require('haraka-config').module_config(test_cfg_path);
22
+ this.server.logger.loglevel = 6; // INFO
23
+
24
+ // set the default path for the plugin loader
25
+ this.server.config = this.config.module_config(test_cfg_path);
26
+ this.server.plugins.config = this.config.module_config(test_cfg_path);
27
+ // this.server.outbound.config = this.config.module_config(this_cfg_path);
28
+
29
+ this.server.load_smtp_ini();
30
+ this.server.cfg.main.listen = ip_port;
31
+ this.server.cfg.main.smtps_port = 2465;
32
+
33
+ this.server.load_default_tls_config(() => {
34
+ this.server.createServer({});
35
+ setTimeout(() => {
36
+ done();
37
+ }, 200);
38
+ })
39
+ }
40
+
41
+ const _tearDownServer = (done) => {
42
+ delete process.env.YES_REALLY_DO_DISCARD;
43
+ delete process.env.HARAKA_TEST_DIR;
44
+ this.server.stopListeners();
45
+ this.server.plugins.registered_hooks = {};
46
+ setTimeout(() => {
47
+ done();
48
+ }, 200);
49
+ }
50
+
51
+ describe('server', () => {
52
+
53
+ describe('get_listen_addrs', () => {
54
+ beforeEach(_set_up)
55
+
56
+ it('IPv4 fully qualified', () => {
57
+ const listeners = this.server.get_listen_addrs({listen: '127.0.0.1:25'});
58
+ assert.deepEqual(['127.0.0.1:25'], listeners);
59
+ })
60
+
61
+ it('IPv4, default port', () => {
62
+ const listeners = this.server.get_listen_addrs({listen: '127.0.0.1'});
63
+ assert.deepEqual(['127.0.0.1:25'], listeners);
64
+ })
65
+
66
+ it('IPv4, custom port', () => {
67
+ const listeners = this.server.get_listen_addrs({ listen: '127.0.0.1'}, 250);
68
+ assert.deepEqual(['127.0.0.1:250'], listeners);
69
+ })
70
+
71
+ it('IPv6 fully qualified', () => {
72
+ const listeners = this.server.get_listen_addrs({listen: '[::1]:25'});
73
+ assert.deepEqual(['[::1]:25'], listeners);
74
+ })
75
+
76
+ it('IPv6, default port', () => {
77
+ const listeners = this.server.get_listen_addrs({listen: '[::1]'});
78
+ assert.deepEqual(['[::1]:25'], listeners);
79
+ })
80
+
81
+ it('IPv6, custom port', () => {
82
+ const listeners = this.server.get_listen_addrs({listen: '[::1]'}, 250);
83
+ assert.deepEqual(['[::1]:250'], listeners);
84
+ })
85
+
86
+ it('IPv4 & IPv6 fully qualified', () => {
87
+ const listeners = this.server.get_listen_addrs({
88
+ listen: '127.0.0.1:25,[::1]:25'
89
+ });
90
+ assert.deepEqual(['127.0.0.1:25','[::1]:25'], listeners);
91
+ })
92
+
93
+ it('IPv4 & IPv6, default port', () => {
94
+ const listeners = this.server.get_listen_addrs({
95
+ listen: '127.0.0.1:25,[::1]'
96
+ });
97
+ assert.deepEqual(['127.0.0.1:25','[::1]:25'], listeners);
98
+ })
99
+
100
+ it('IPv4 & IPv6, custom port', () => {
101
+ const listeners = this.server.get_listen_addrs({
102
+ listen: '127.0.0.1,[::1]'
103
+ }, 250);
104
+ assert.deepEqual(['127.0.0.1:250','[::1]:250'], listeners);
105
+ })
106
+ })
107
+
108
+ describe('load_smtp_ini', () => {
109
+ beforeEach(_set_up)
110
+
111
+ it('saves settings to Server.cfg', () => {
112
+ this.server.load_smtp_ini();
113
+ // console.log(this.server.cfg);
114
+ const c = this.server.cfg.main;
115
+ assert.notEqual(c.daemonize, undefined);
116
+ assert.notEqual(c.daemon_log_file, undefined);
117
+ assert.notEqual(c.daemon_pid_file, undefined);
118
+ })
119
+ })
120
+
121
+ describe('get_smtp_server', () => {
122
+ beforeEach((done) => {
123
+ this.config = require('haraka-config');
124
+ this.config = this.config.module_config(path.resolve('test'));
125
+
126
+ this.server = require('../server');
127
+ this.server.config = this.config;
128
+ this.server.plugins.config = this.config;
129
+
130
+ this.server.load_default_tls_config(() => {
131
+ setTimeout(() => {
132
+ done();
133
+ }, 200);
134
+ });
135
+ })
136
+
137
+ it('gets a net server object', (done) => {
138
+ this.server.get_smtp_server(endpoint('0.0.0.0:2501'), 10).then(server => {
139
+ if (!server) {
140
+ console.error('unable to bind to 0.0.0.0:2501');
141
+ if (process.env.CI) return // can't bind to IP/port (fails on Travis)
142
+ }
143
+ assert.ok(server);
144
+ assert.equal(server.has_tls, false);
145
+ server.getConnections((err, count) => {
146
+ assert.equal(0, count);
147
+ done()
148
+ })
149
+ })
150
+ })
151
+
152
+ it('gets a TLS net server object', (done) => {
153
+ this.server.cfg.main.smtps_port = 2502;
154
+ this.server.get_smtp_server(endpoint('0.0.0.0:2502'), 10).then((server) => {
155
+ if (!server) {
156
+ console.error('unable to bind to 0.0.0.0:2502');
157
+ if (process.env.CI) return // can't bind to IP/port (fails on Travis)
158
+ }
159
+ assert.ok(server);
160
+ assert.equal(server.has_tls, true);
161
+ server.getConnections((err, count) => {
162
+ assert.equal(0, count);
163
+ done()
164
+ });
165
+ });
166
+ })
167
+ })
168
+
169
+ describe('get_http_docroot', () => {
170
+ beforeEach(_set_up)
171
+
172
+ it('gets a fs path', () => {
173
+ assert.ok(this.server.get_http_docroot());
174
+ })
175
+ })
176
+
177
+ describe('smtp_client', () => {
178
+ beforeEach((done) => {
179
+ _setupServer('localhost:2500', done)
180
+ })
181
+
182
+ afterEach(_tearDownServer)
183
+
184
+ it('accepts SMTP message', () => {
185
+
186
+ const server = { notes: { } };
187
+ const cfg = {
188
+ connect_timeout: 2,
189
+ }
190
+
191
+ const smtp_client = require('../smtp_client');
192
+
193
+ smtp_client.get_client(server, (client) => {
194
+
195
+ client
196
+ .on('greeting', command => {
197
+ client.send_command('HELO', 'haraka.local');
198
+ })
199
+ .on('helo', () => {
200
+ client.send_command('MAIL', 'FROM:<test@haraka.local>');
201
+ })
202
+ .on('mail', () => {
203
+ client.send_command('RCPT', 'TO:<nobody-will-see-this@haraka.local>');
204
+ })
205
+ .on('rcpt', () => {
206
+ client.send_command('DATA');
207
+ })
208
+ .on('data', () => {
209
+ const message_stream = new message.stream(
210
+ { main : { spool_after : 1024 } }, "theMessageId"
211
+ );
212
+
213
+ message_stream.on('end', () => {
214
+ client.socket.write('.\r\n');
215
+ })
216
+ message_stream.add_line('Header: test\r\n');
217
+ message_stream.add_line('\r\n');
218
+ message_stream.add_line('I am body text\r\n');
219
+ message_stream.add_line_end();
220
+
221
+ client.start_data(message_stream);
222
+ })
223
+ .on('dot', () => {
224
+ assert.ok(1);
225
+ client.release();
226
+ })
227
+ .on('bad_code', (code, msg) => {
228
+ client.release();
229
+ });
230
+
231
+ }, { port: 2500, host: 'localhost', cfg });
232
+ })
233
+ })
234
+
235
+ describe('nodemailer', () => {
236
+ beforeEach((done) => {
237
+ _setupServer('127.0.0.1:2503', done)
238
+ })
239
+
240
+ afterEach(_tearDownServer)
241
+
242
+ it('accepts SMTP message', (done) => {
243
+
244
+ const nodemailer = require('nodemailer');
245
+ const transporter = nodemailer.createTransport({
246
+ host: '127.0.0.1',
247
+ port: 2503,
248
+ tls: {
249
+ // do not fail on invalid certs
250
+ rejectUnauthorized: false
251
+ }
252
+ });
253
+ transporter.sendMail({
254
+ from: '"Testalicious Matt" <harakamail@gmail.com>',
255
+ to: 'nobody-will-see-this@haraka.local',
256
+ envelope: {
257
+ from: 'Haraka Test <test@haraka.local>',
258
+ to: 'Discard Queue <discard@haraka.local>',
259
+ },
260
+ subject: 'Hello ✔',
261
+ text: 'Hello world ?',
262
+ html: '<b>Hello world ?</b>',
263
+ },
264
+ (error, info) => {
265
+ if (error){
266
+ console.log(error);
267
+ return;
268
+ }
269
+ assert.deepEqual(info.accepted, [ 'discard@haraka.local' ]);
270
+ console.log(`Message sent: ${info.response}`);
271
+ done()
272
+ })
273
+ })
274
+
275
+ it('accepts authenticated SMTP', (done) => {
276
+
277
+ const nodemailer = require('nodemailer');
278
+ const transporter = nodemailer.createTransport({
279
+ host: '127.0.0.1',
280
+ port: 2503,
281
+ auth: {
282
+ user: 'matt',
283
+ pass: 'goodPass'
284
+ },
285
+ requireTLS: true,
286
+ tls: {
287
+ // do not fail on invalid certs
288
+ rejectUnauthorized: false
289
+ }
290
+ })
291
+
292
+ transporter.sendMail({
293
+ from: '"Testalicious Matt" <harakamail@gmail.com>',
294
+ to: 'nobody-will-see-this@haraka.local',
295
+ envelope: {
296
+ from: 'Haraka Test <test@haraka.local>',
297
+ to: 'Discard Queue <discard@haraka.local>',
298
+ },
299
+ subject: 'Hello ✔',
300
+ text: 'Hello world ?',
301
+ html: '<b>Hello world ?</b>',
302
+ },
303
+ (error, info) => {
304
+ if (error){
305
+ console.log(error);
306
+ return;
307
+ }
308
+ assert.deepEqual(info.accepted, [ 'discard@haraka.local' ]);
309
+ console.log(`Message sent: ${info.response}`);
310
+ done()
311
+ })
312
+ })
313
+
314
+ it('rejects invalid auth', (done) => {
315
+
316
+ const nodemailer = require('nodemailer');
317
+ const transporter = nodemailer.createTransport({
318
+ host: '127.0.0.1',
319
+ port: 2503,
320
+ auth: {
321
+ user: 'matt',
322
+ pass: 'badPass'
323
+ },
324
+ tls: {
325
+ // do not fail on invalid certs
326
+ rejectUnauthorized: false
327
+ }
328
+ })
329
+
330
+ transporter.sendMail({
331
+ from: '"Testalicious Matt" <harakamail@gmail.com>',
332
+ to: 'nobody-will-see-this@haraka.local',
333
+ envelope: {
334
+ from: 'Haraka Test <test@haraka.local>',
335
+ to: 'Discard Queue <discard@haraka.local>',
336
+ },
337
+ subject: 'Hello ✔',
338
+ text: 'Hello world ?',
339
+ html: '<b>Hello world ?</b>',
340
+ },
341
+ (error, info) => {
342
+ if (error){
343
+ assert.equal(error.code, 'EAUTH');
344
+ // console.log(error);
345
+ return done();
346
+ }
347
+ console.log(info.response);
348
+ done()
349
+ })
350
+ })
351
+
352
+ it('DKIM validates signed message', (done) => {
353
+
354
+ const nodemailer = require('nodemailer');
355
+ const transporter = nodemailer.createTransport({
356
+ host: '127.0.0.1',
357
+ port: 2503,
358
+ tls: {
359
+ // do not fail on invalid certs
360
+ rejectUnauthorized: false
361
+ }
362
+ })
363
+
364
+ transporter.sendMail({
365
+ from: '"Testalicious Matt" <harakamail@gmail.com>',
366
+ to: 'nobody-will-see-this@haraka.local',
367
+ envelope: {
368
+ from: 'Haraka Test <test@haraka.local>',
369
+ to: 'Discard Queue <discard@haraka.local>',
370
+ },
371
+ subject: 'Hello ✔',
372
+ text: 'Hello world ?',
373
+ html: '<b>Hello world ?</b>',
374
+ dkim: {
375
+ domainName: "test.simerson.com",
376
+ keySelector: "harakatest2017",
377
+ privateKey: '-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAxqoUAnQ9GB3iNnkS7coj0Iggd0nyryW062tpK95NC5UXmmAwIpUMfkYdiHY2o2duWYGF0Bp237M/QXKhJYTXfsgkwP/bq9OGWtRZxHPHhbhdjbiI\nqObi6zvYcxrI77gpWDDvruhMeS9Hwa1R99pLUWd4PsuYTzbV/jwu2pz+XZXXXNEU\nVxzDAAj0yF7mwxHMLzQfR+hdhWcrgN0stUP0o7hm7hoOP8IWgcSW3JiQYavIKoI4\nm4+I9I1LzDJN2rHVnQvmjUrqqpG7X6SyFVFtuTWGaMqf1Cj/t8eSvU9VdgLFllS8\ntThqUZHq5S5hm8M8VzLuQLG9U0dtFolcFmJkbQIDAQABAoIBAB4fUbNhjpXmihM6\nXm1htfZ7fXi45Kw76me7vJGjPklgTNjidsn3kZJf7UBwtC4ok6nMos6ABMA8fH3e\n9KIst0QI8tG0ucke5INHKWlJKNqUrtK7RTVe9M84HsStLgRzBwnRObZqkJXbXmT2\nc7RCDCOGrcvPsQNpzB6lX3FUVpk3x24RXpQV1qSgH8yuHSPc1C6rssXwPAgnESfS\nK3MHRx2CLZvTTkq/YCsT+wS/O9RWPCVOYuWaa5DDDAIp3Yw1wYq9Upoh0BdIFC3U\nWm+5Cr3o9wxcvS6+W2RA6I51eymzvCU5ZakWt/bnUDb6/ByxsWOn5rL4WfPpCwE4\nnuC72v0CgYEA9imEq6a0GoaEsMoR7cxT7uXKimQH+Jaq3CGkuh0iN32F4FXhuUKz\nLYKSLCZzpb1MiDJv6BBchV6uSQ6ATo1cZ8WzYQISikk175bf0SPom591OZElvKA2\nSOrTrXtbl33YbWZEgyEcpTgelVi5ys9rj4eKkMvM0lwRmW6gctEFXRcCgYEAzpqc\nR/wqPjgPhpF1CZtdEwOZg4kkOig8CBcuQ7o/hDG7N69A9ZbeJO8eD+gKDrHRfkYr\nTH/UdkZGjilBk/lxnpIZpyBLxQ6UdhNPuwtxXKAvuSN+aQ0pdJn8tg03OSj2OzTK\nJ4hMsO/wt1xM8EDRobLZEosMadaYZUHzx8VU5RsCgYEAvFZbuXEcT0cocpLIUOaK\nOTf7VRLfvmSYaUAcZoEv0sDpExDiWPodWO6To8/vn5lL2tCsKiOKhkhAlIjRxkgF\nsSfj7I7HXKJS7/LBX6RXrem8qMTS2JTDs9pnBk5hb3DLjDg4pxNIdWiQjbeKvw8f\nvnr3m30yQqhKlte7Tt15exUCgYBzq7RbyR6Nfy2SFdYE7usJPjawohOaS/RwQyov\n2RK+nGlJH+GqnjD5VLbsCOm4mG3F2NtdFSSKo4XVCdwhUMMAGKQsIbTKOwN7qAw3\nmIx7Y2PUr76SakAPfDc0ZenJItnZBBE6WOE3Ht8Siaa5zFCRy2QlMZxdlTv1VRt7\neUuyiQKBgQDdXJO5+3h1HPxbYZcmNm/2CJUNw2ehU8vCiBXCcWPn7JukayHx+TXy\nyj0j/b1SvmKgjB+4JWluiqIU+QBjRjvb397QY1YoCEaGZd0zdFjTZwQksQ5AFst9\nCiD9OFXe/kkmIUQQra6aw1CoppyAfvAblp8uevLWb57xU3VUB3xeGg==\n-----END RSA PRIVATE KEY-----\n',
378
+ }
379
+ },
380
+ (error, info) => {
381
+ // console.log(info);
382
+ if (error){
383
+ console.log(error);
384
+ return;
385
+ }
386
+ assert.deepEqual(info.accepted, [ 'discard@haraka.local' ]);
387
+ console.log(`Message sent: ${info.response}`);
388
+ done()
389
+ })
390
+ })
391
+ })
392
+
393
+ describe('requireAuthorized_SMTPS', () => {
394
+ beforeEach((done) => {
395
+ _setupServer('127.0.0.1:2465', done)
396
+ })
397
+
398
+ afterEach(_tearDownServer)
399
+
400
+ it('rejects non-validated SMTPS connection', (done) => {
401
+
402
+ const nodemailer = require('nodemailer');
403
+ const transporter = nodemailer.createTransport({
404
+ host: '127.0.0.1',
405
+ port: 2465,
406
+ secure: true,
407
+ tls: {
408
+ // do not fail on invalid certs
409
+ rejectUnauthorized: false
410
+ }
411
+ })
412
+
413
+ // give the SMTPS listener a second to start listening
414
+ setTimeout(() => {
415
+ transporter.sendMail({
416
+ from: '"Testalicious Matt" <harakamail@gmail.com>',
417
+ to: 'nobody-will-see-this@haraka.local',
418
+ envelope: {
419
+ from: 'Haraka Test <test@haraka.local>',
420
+ to: 'Discard Queue <discard@haraka.local>',
421
+ },
422
+ subject: 'Hello ✔',
423
+ text: 'Hello world ?',
424
+ html: '<b>Hello world ?</b>',
425
+ },
426
+ (error, info) => {
427
+ if (error) {
428
+ // console.log(error);
429
+ if (error.message === 'socket hang up') { // node 6 & 8
430
+ assert.equal(error.message, 'socket hang up');
431
+ }
432
+ else if (/alert certificate required/.test(error.message)) { // node 18
433
+ assert.ok(/alert certificate required/.test(error.message))
434
+ }
435
+ else { // node 10+
436
+ assert.equal(error.message, 'Client network socket disconnected before secure TLS connection was established');
437
+ }
438
+ }
439
+ done()
440
+ })
441
+ }, 500);
442
+ })
443
+ })
444
+
445
+ describe('requireAuthorized_STARTTLS', () => {
446
+ beforeEach((done) => {
447
+ _setupServer('127.0.0.1:2587', done)
448
+ })
449
+
450
+ it('rejects non-validated STARTTLS connection', (done) => {
451
+
452
+ const nodemailer = require('nodemailer');
453
+ const transporter = nodemailer.createTransport({
454
+ host: '127.0.0.1',
455
+ port: 2587,
456
+ secure: false,
457
+ tls: {
458
+ // do not fail on invalid certs
459
+ rejectUnauthorized: false
460
+ }
461
+ });
462
+
463
+ // give the SMTPS listener a half second to start listening
464
+ setTimeout(() => {
465
+ transporter.sendMail({
466
+ from: '"Testalicious Matt" <harakamail@gmail.com>',
467
+ to: 'nobody-will-see-this@haraka.local',
468
+ envelope: {
469
+ from: 'Haraka Test <test@haraka.local>',
470
+ to: 'Discard Queue <discard@haraka.local>',
471
+ },
472
+ subject: 'Hello ✔',
473
+ text: 'Hello world ?',
474
+ html: '<b>Hello world ?</b>',
475
+ },
476
+ (error, info) => {
477
+ if (error) {
478
+ // console.log(error);
479
+ if (/alert certificate required/.test(error.message)) { // node 18
480
+ assert.ok(/alert certificate required/.test(error.message))
481
+ }
482
+ else {
483
+ assert.equal(error.message, 'Client network socket disconnected before secure TLS connection was established');
484
+ }
485
+ }
486
+ done()
487
+ })
488
+ }, 500);
489
+ })
490
+ })
491
+ })