Haraka 3.0.2 → 3.0.4

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 (267) hide show
  1. package/.eslintrc.yaml +5 -9
  2. package/.prettierrc.yml +1 -0
  3. package/CONTRIBUTORS.md +11 -0
  4. package/Changes.md +1393 -1211
  5. package/Dockerfile +3 -3
  6. package/Plugins.md +119 -106
  7. package/README.md +7 -16
  8. package/TODO +1 -24
  9. package/bin/haraka +197 -298
  10. package/config/auth_flat_file.ini +2 -0
  11. package/config/auth_vpopmaild.ini +4 -2
  12. package/config/dhparams.pem +8 -0
  13. package/config/mail_from.is_resolvable.ini +4 -2
  14. package/config/me +1 -0
  15. package/config/outbound.ini +0 -2
  16. package/config/plugins +36 -35
  17. package/config/rabbitmq_amqplib.ini +8 -1
  18. package/config/smtp.ini +0 -1
  19. package/config/smtp.json +17 -0
  20. package/config/tls_cert.pem +23 -0
  21. package/config/tls_key.pem +28 -0
  22. package/connection.js +46 -73
  23. package/contrib/bsd-rc.d/haraka +3 -1
  24. package/contrib/plugin2npm.sh +6 -36
  25. package/docs/Connection.md +1 -1
  26. package/docs/CoreConfig.md +2 -2
  27. package/docs/Logging.md +7 -21
  28. package/docs/Outbound.md +104 -210
  29. package/docs/Plugins.md +47 -40
  30. package/docs/Transaction.md +59 -82
  31. package/docs/{plugins → deprecated}/connect.rdns_access.md +1 -1
  32. package/docs/{plugins → deprecated}/mail_from.access.md +1 -1
  33. package/docs/{plugins → deprecated}/rcpt_to.access.md +1 -1
  34. package/docs/plugins/auth/auth_vpopmaild.md +15 -19
  35. package/docs/plugins/auth/flat_file.md +23 -30
  36. package/docs/plugins/queue/rabbitmq_amqplib.md +7 -0
  37. package/docs/plugins/queue/smtp_forward.md +1 -1
  38. package/docs/plugins/queue/smtp_proxy.md +5 -10
  39. package/docs/plugins/relay.md +2 -2
  40. package/docs/plugins/tls.md +29 -9
  41. package/endpoint.js +16 -13
  42. package/haraka.js +10 -14
  43. package/host_pool.js +5 -5
  44. package/line_socket.js +3 -4
  45. package/logger.js +44 -28
  46. package/outbound/client_pool.js +27 -23
  47. package/outbound/config.js +4 -6
  48. package/outbound/fsync_writestream.js +1 -1
  49. package/outbound/hmail.js +180 -220
  50. package/outbound/index.js +86 -99
  51. package/outbound/qfile.js +1 -1
  52. package/outbound/queue.js +55 -43
  53. package/outbound/timer_queue.js +3 -2
  54. package/outbound/tls.js +19 -7
  55. package/package.json +66 -55
  56. package/plugins/.eslintrc.yaml +0 -6
  57. package/plugins/auth/auth_base.js +30 -12
  58. package/plugins/auth/auth_proxy.js +14 -12
  59. package/plugins/auth/auth_vpopmaild.js +30 -20
  60. package/plugins/auth/flat_file.js +17 -12
  61. package/plugins/block_me.js +1 -1
  62. package/plugins/data.signatures.js +2 -4
  63. package/plugins/early_talker.js +2 -1
  64. package/plugins/mail_from.is_resolvable.js +65 -135
  65. package/plugins/queue/deliver.js +4 -5
  66. package/plugins/queue/lmtp.js +11 -14
  67. package/plugins/queue/qmail-queue.js +2 -2
  68. package/plugins/queue/quarantine.js +2 -2
  69. package/plugins/queue/rabbitmq.js +16 -17
  70. package/plugins/queue/rabbitmq_amqplib.js +1 -1
  71. package/plugins/queue/smtp_forward.js +6 -6
  72. package/plugins/queue/smtp_proxy.js +10 -1
  73. package/plugins/queue/test.js +2 -2
  74. package/plugins/rcpt_to.host_list_base.js +5 -5
  75. package/plugins/rcpt_to.in_host_list.js +2 -2
  76. package/plugins/relay.js +6 -7
  77. package/plugins/reseed_rng.js +1 -1
  78. package/plugins/status.js +37 -33
  79. package/plugins/tls.js +2 -2
  80. package/plugins/xclient.js +3 -2
  81. package/plugins.js +51 -54
  82. package/run_tests +3 -30
  83. package/server.js +190 -190
  84. package/smtp_client.js +30 -23
  85. package/{tests → test}/config/plugins +0 -2
  86. package/{tests → test}/config/smtp.ini +1 -1
  87. package/test/config/tls/example.com/_.example.com.key +28 -0
  88. package/test/config/tls/example.com/example.com.crt +25 -0
  89. package/test/connection.js +302 -0
  90. package/test/endpoint.js +94 -0
  91. package/{tests → test}/fixtures/line_socket.js +1 -1
  92. package/{tests → test}/fixtures/util_hmailitem.js +19 -25
  93. package/{tests → test}/host_pool.js +42 -57
  94. package/test/logger.js +258 -0
  95. package/test/outbound/hmail.js +141 -0
  96. package/test/outbound/index.js +220 -0
  97. package/test/outbound/qfile.js +126 -0
  98. package/test/outbound_bounce_net_errors.js +142 -0
  99. package/{tests → test}/outbound_bounce_rfc3464.js +110 -122
  100. package/test/plugins/auth/auth_base.js +484 -0
  101. package/test/plugins/auth/auth_vpopmaild.js +83 -0
  102. package/test/plugins/early_talker.js +104 -0
  103. package/test/plugins/mail_from.is_resolvable.js +35 -0
  104. package/test/plugins/queue/smtp_forward.js +206 -0
  105. package/test/plugins/rcpt_to.host_list_base.js +122 -0
  106. package/test/plugins/rcpt_to.in_host_list.js +193 -0
  107. package/test/plugins/relay.js +303 -0
  108. package/test/plugins/status.js +130 -0
  109. package/test/plugins/tls.js +70 -0
  110. package/test/plugins.js +228 -0
  111. package/{tests → test}/queue/multibyte +0 -0
  112. package/{tests → test}/queue/plain +0 -0
  113. package/test/rfc1869.js +73 -0
  114. package/test/server.js +491 -0
  115. package/test/smtp_client.js +299 -0
  116. package/test/tls_socket.js +273 -0
  117. package/test/transaction.js +270 -0
  118. package/tls_socket.js +202 -252
  119. package/transaction.js +9 -24
  120. package/CONTRIBUTING.md +0 -1
  121. package/bin/dkimverify +0 -40
  122. package/config/access.domains +0 -13
  123. package/config/attachment.ctype.regex +0 -2
  124. package/config/attachment.filename.regex +0 -1
  125. package/config/avg.ini +0 -5
  126. package/config/bounce.ini +0 -15
  127. package/config/data.headers.ini +0 -61
  128. package/config/dkim/dkim_key_gen.sh +0 -78
  129. package/config/dkim_sign.ini +0 -4
  130. package/config/dkim_verify.ini +0 -7
  131. package/config/dnsbl.ini +0 -23
  132. package/config/greylist.ini +0 -43
  133. package/config/helo.checks.ini +0 -52
  134. package/config/lookup_rdns.strict.ini +0 -12
  135. package/config/lookup_rdns.strict.timeout +0 -1
  136. package/config/lookup_rdns.strict.whitelist +0 -1
  137. package/config/lookup_rdns.strict.whitelist_regex +0 -5
  138. package/config/messagesniffer.ini +0 -18
  139. package/config/rcpt_to.blocklist +0 -1
  140. package/config/rdns.allow_regexps +0 -0
  141. package/config/rdns.deny_regexps +0 -0
  142. package/config/spamassassin.ini +0 -56
  143. package/config.js +0 -6
  144. package/dkim.js +0 -614
  145. package/docs/plugins/avg.md +0 -35
  146. package/docs/plugins/bounce.md +0 -69
  147. package/docs/plugins/clamd.md +0 -147
  148. package/docs/plugins/esets.md +0 -8
  149. package/docs/plugins/greylist.md +0 -90
  150. package/docs/plugins/helo.checks.md +0 -135
  151. package/docs/plugins/messagesniffer.md +0 -163
  152. package/docs/plugins/relay_acl.md +0 -29
  153. package/docs/plugins/relay_all.md +0 -15
  154. package/docs/plugins/relay_force_routing.md +0 -33
  155. package/docs/plugins/spamassassin.md +0 -180
  156. package/outbound/mx_lookup.js +0 -70
  157. package/plugins/auth/auth_ldap.js +0 -3
  158. package/plugins/avg.js +0 -162
  159. package/plugins/backscatterer.js +0 -25
  160. package/plugins/bounce.js +0 -381
  161. package/plugins/clamd.js +0 -381
  162. package/plugins/data.headers.js +0 -4
  163. package/plugins/data.uribl.js +0 -4
  164. package/plugins/dkim_sign.js +0 -395
  165. package/plugins/dkim_verify.js +0 -62
  166. package/plugins/dns_list_base.js +0 -221
  167. package/plugins/dnsbl.js +0 -146
  168. package/plugins/dnswl.js +0 -58
  169. package/plugins/esets.js +0 -71
  170. package/plugins/graph.js +0 -5
  171. package/plugins/greylist.js +0 -645
  172. package/plugins/helo.checks.js +0 -533
  173. package/plugins/messagesniffer.js +0 -381
  174. package/plugins/rcpt_to.ldap.js +0 -3
  175. package/plugins/rcpt_to.max_count.js +0 -24
  176. package/plugins/relay_all.js +0 -13
  177. package/plugins/spamassassin.js +0 -384
  178. package/tests/config/dkim/example.com/dns +0 -29
  179. package/tests/config/dkim/example.com/private +0 -6
  180. package/tests/config/dkim/example.com/public +0 -4
  181. package/tests/config/dkim/example.com/selector +0 -1
  182. package/tests/config/dkim.private.key +0 -6
  183. package/tests/config/dkim_sign.ini +0 -4
  184. package/tests/config/helo.checks.ini +0 -52
  185. package/tests/connection.js +0 -327
  186. package/tests/endpoint.js +0 -128
  187. package/tests/fixtures/vm_harness.js +0 -59
  188. package/tests/logger.js +0 -327
  189. package/tests/outbound/hmail.js +0 -112
  190. package/tests/outbound/index.js +0 -324
  191. package/tests/outbound/qfile.js +0 -67
  192. package/tests/outbound_bounce_net_errors.js +0 -173
  193. package/tests/plugins/auth/auth_base.js +0 -463
  194. package/tests/plugins/auth/auth_vpopmaild.js +0 -91
  195. package/tests/plugins/bounce.js +0 -307
  196. package/tests/plugins/clamd.js +0 -224
  197. package/tests/plugins/deprecated/relay_acl.js +0 -140
  198. package/tests/plugins/deprecated/relay_all.js +0 -59
  199. package/tests/plugins/dkim_sign.js +0 -315
  200. package/tests/plugins/dkim_signer.js +0 -108
  201. package/tests/plugins/dns_list_base.js +0 -259
  202. package/tests/plugins/dnsbl.js +0 -101
  203. package/tests/plugins/early_talker.js +0 -115
  204. package/tests/plugins/greylist.js +0 -58
  205. package/tests/plugins/helo.checks.js +0 -525
  206. package/tests/plugins/mail_from.is_resolvable.js +0 -116
  207. package/tests/plugins/queue/smtp_forward.js +0 -221
  208. package/tests/plugins/rcpt_to.host_list_base.js +0 -132
  209. package/tests/plugins/rcpt_to.in_host_list.js +0 -218
  210. package/tests/plugins/relay.js +0 -339
  211. package/tests/plugins/spamassassin.js +0 -171
  212. package/tests/plugins/status.js +0 -138
  213. package/tests/plugins/tls.js +0 -84
  214. package/tests/plugins.js +0 -247
  215. package/tests/rfc1869.js +0 -61
  216. package/tests/server.js +0 -510
  217. package/tests/smtp_client/auth.js +0 -105
  218. package/tests/smtp_client/basic.js +0 -101
  219. package/tests/smtp_client.js +0 -80
  220. package/tests/tls_socket.js +0 -333
  221. package/tests/transaction.js +0 -284
  222. /package/docs/{plugins → deprecated}/dkim_sign.md +0 -0
  223. /package/docs/{plugins → deprecated}/dkim_verify.md +0 -0
  224. /package/docs/{plugins → deprecated}/dnsbl.md +0 -0
  225. /package/docs/{plugins → deprecated}/dnswl.md +0 -0
  226. /package/docs/{plugins → deprecated}/rcpt_to.routes.md +0 -0
  227. /package/{tests → test}/.eslintrc.yaml +0 -0
  228. /package/{tests → test}/config/auth_flat_file.ini +0 -0
  229. /package/{tests → test}/config/dhparams.pem +0 -0
  230. /package/{tests → test}/config/host_list +0 -0
  231. /package/{tests → test}/config/outbound_tls_cert.pem +0 -0
  232. /package/{tests → test}/config/outbound_tls_key.pem +0 -0
  233. /package/{tests → test}/config/smtp_forward.ini +0 -0
  234. /package/{tests → test}/config/tls/ec.pem +0 -0
  235. /package/{tests → test}/config/tls/haraka.local.pem +0 -0
  236. /package/{tests → test}/config/tls/mismatched.pem +0 -0
  237. /package/{tests → test}/config/tls.ini +0 -0
  238. /package/{tests → test}/config/tls_cert.pem +0 -0
  239. /package/{tests → test}/config/tls_key.pem +0 -0
  240. /package/{tests → test}/fixtures/todo_qfile.txt +0 -0
  241. /package/{tests → test}/installation/config/test-plugin-flat +0 -0
  242. /package/{tests → test}/installation/config/test-plugin.ini +0 -0
  243. /package/{tests → test}/installation/config/tls.ini +0 -0
  244. /package/{tests → test}/installation/node_modules/load_first/index.js +0 -0
  245. /package/{tests → test}/installation/node_modules/load_first/package.json +0 -0
  246. /package/{tests → test}/installation/node_modules/test-plugin/config/test-plugin-flat +0 -0
  247. /package/{tests → test}/installation/node_modules/test-plugin/config/test-plugin.ini +0 -0
  248. /package/{tests → test}/installation/node_modules/test-plugin/package.json +0 -0
  249. /package/{tests → test}/installation/node_modules/test-plugin/test-plugin.js +0 -0
  250. /package/{tests → test}/installation/plugins/base_plugin.js +0 -0
  251. /package/{tests → test}/installation/plugins/folder_plugin/index.js +0 -0
  252. /package/{tests → test}/installation/plugins/folder_plugin/package.json +0 -0
  253. /package/{tests → test}/installation/plugins/inherits.js +0 -0
  254. /package/{tests → test}/installation/plugins/load_first.js +0 -0
  255. /package/{tests → test}/installation/plugins/plugin.js +0 -0
  256. /package/{tests → test}/installation/plugins/tls.js +0 -0
  257. /package/{tests → test}/loud/config/dhparams.pem +0 -0
  258. /package/{tests → test}/loud/config/tls/goobered.pem +0 -0
  259. /package/{tests → test}/loud/config/tls.ini +0 -0
  260. /package/{tests → test}/mail_specimen/base64-root-part.txt +0 -0
  261. /package/{tests → test}/mail_specimen/varied-fold-lengths-preserve-data.txt +0 -0
  262. /package/{tests → test}/queue/1507509981169_1507509981169_0_61403_e0Y0Ym_1_fixed +0 -0
  263. /package/{tests → test}/queue/1507509981169_1507509981169_0_61403_e0Y0Ym_1_haraka +0 -0
  264. /package/{tests → test}/queue/1508269674999_1508269674999_0_34002_socVUF_1_haraka +0 -0
  265. /package/{tests → test}/queue/1508455115683_1508455115683_0_90253_9Q4o4V_1_haraka +0 -0
  266. /package/{tests → test}/queue/zero-length +0 -0
  267. /package/{tests → test}/test-queue/delete-me +0 -0
@@ -1,324 +0,0 @@
1
-
2
- 'use strict';
3
- const fs = require('fs');
4
- const path = require('path');
5
- const os = require('os');
6
-
7
- const constants = require('haraka-constants');
8
- const logger = require('../../logger');
9
-
10
- const lines = [
11
- 'From: John Johnson <john@example.com>',
12
- 'To: Jane Johnson <jane@example.com>',
13
- "Subject: What's for dinner?",
14
- '',
15
- "I'm hungry.",
16
- '',
17
- ];
18
-
19
- exports.outbound = {
20
- 'converts \\n and \\r\\n line endings to \\r\\n' : test => {
21
- test.expect(2);
22
-
23
- ['\n', '\r\n'].forEach(ending => {
24
- let contents = lines.join(ending);
25
- let result = '';
26
-
27
- // Set data_lines to lines in contents
28
- let match;
29
- const re = /^([^\n]*\n?)/;
30
- while ((match = re.exec(contents))) {
31
- let line = match[1];
32
- line = line.replace(/\r?\n?$/, '\r\n'); // assure \r\n ending
33
- // transaction.add_data(new Buffer(line));
34
- result += line;
35
- contents = contents.substr(match[1].length);
36
- if (contents.length === 0) {
37
- break;
38
- }
39
- }
40
-
41
- test.deepEqual(lines.join('\r\n'), result);
42
- });
43
- test.done();
44
- },
45
- 'log_methods added': test => {
46
- test.expect(Object.keys(logger.levels).length);
47
-
48
- const HMailItem = require('../../outbound/hmail');
49
-
50
- Object.keys(logger.levels).forEach(level => {
51
- test.ok(HMailItem.prototype[`log${level.toLowerCase()}`], `Log method for level: ${level}`);
52
- });
53
- test.done();
54
- },
55
- 'set_temp_fail_intervals coverage': test => {
56
- test.expect(5);
57
-
58
- const config = require('../../outbound/config');
59
- // Test default configuration
60
- test.deepEqual(config.cfg.temp_fail_intervals, [64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072]);
61
- // Test a simple configuration
62
- config.cfg.temp_fail_intervals = '10s, 1m*2';
63
- config.set_temp_fail_intervals();
64
- test.deepEqual(config.cfg.temp_fail_intervals, [10, 60, 60]);
65
- // Test a complex configuration
66
- config.cfg.temp_fail_intervals = '30s, 1m, 5m, 9m, 15m*3, 30m*2, 1h*3, 2h*3, 1d';
67
- config.set_temp_fail_intervals();
68
- test.deepEqual(config.cfg.temp_fail_intervals, [30,60,300,540,900,900,900,1800,1800,3600,3600,3600,7200,7200,7200,86400]);
69
- // Test the "none" configuration
70
- config.cfg.temp_fail_intervals = 'none';
71
- config.set_temp_fail_intervals();
72
- test.deepEqual(config.cfg.temp_fail_intervals, []);
73
- // Test bad config (should revert to default)
74
- config.cfg.temp_fail_intervals = '60 min';
75
- config.set_temp_fail_intervals();
76
- test.deepEqual(config.cfg.temp_fail_intervals, [64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072]);
77
- test.done();
78
- }
79
- }
80
-
81
- exports.qfile = {
82
- setUp (done) {
83
- this.qfile = require('../../outbound').qfile;
84
- done();
85
- },
86
- 'name() basic functions' (test){
87
- test.expect(3);
88
- const name = this.qfile.name();
89
- const split = name.split('_');
90
- test.equal(split.length, 7);
91
- test.equal(split[2], 0);
92
- test.equal(split[3], process.pid);
93
- test.done();
94
- },
95
- 'name() with overrides' (test){
96
- test.expect(7);
97
- const overrides = {
98
- arrival : 12345,
99
- next_attempt : 12345,
100
- attempts : 15,
101
- pid : process.pid,
102
- uid : 'XXYYZZ',
103
- host : os.hostname(),
104
- };
105
- const name = this.qfile.name(overrides);
106
- const split = name.split('_');
107
- test.equal(split.length, 7);
108
- test.equal(split[0], overrides.arrival);
109
- test.equal(split[1], overrides.next_attempt);
110
- test.equal(split[2], overrides.attempts);
111
- test.equal(split[3], overrides.pid);
112
- test.equal(split[4], overrides.uid);
113
- test.equal(split[6], overrides.host);
114
- test.done();
115
- },
116
- 'rnd_unique() is unique-ish' (test){
117
- const repeats = 1000;
118
- test.expect(repeats);
119
- const u = this.qfile.rnd_unique();
120
- for (let i = 0; i < repeats; i++){
121
- test.notEqual(u, this.qfile.rnd_unique());
122
- }
123
- test.done();
124
- },
125
- 'parts() updates previous queue filenames' (test){
126
- test.expect(4);
127
- // $nextattempt_$attempts_$pid_$uniq.$host
128
- const name = "1111_0_2222_3333.foo.example.com"
129
- const parts = this.qfile.parts(name);
130
- test.equal(parts.next_attempt, 1111);
131
- test.equal(parts.attempts, 0);
132
- test.equal(parts.pid, 2222);
133
- test.equal(parts.host, 'foo.example.com');
134
- test.done();
135
- },
136
- 'parts() handles standard queue filenames' (test){
137
- test.expect(6);
138
- const overrides = {
139
- arrival : 12345,
140
- next_attempt : 12345,
141
- attempts : 15,
142
- pid : process.pid,
143
- uid : 'XXYYZZ',
144
- host : os.hostname(),
145
- };
146
- const name = this.qfile.name(overrides);
147
- const parts = this.qfile.parts(name);
148
- test.equal(parts.arrival, overrides.arrival);
149
- test.equal(parts.next_attempt, overrides.next_attempt);
150
- test.equal(parts.attempts, overrides.attempts);
151
- test.equal(parts.pid, overrides.pid);
152
- test.equal(parts.uid, overrides.uid);
153
- test.equal(parts.host, overrides.host);
154
- test.done();
155
- }
156
- }
157
-
158
- exports.get_tls_options = {
159
- setUp (done) {
160
- process.env.HARAKA_TEST_DIR=path.resolve('tests');
161
- this.outbound = require('../../outbound');
162
- this.obtls = require('../../outbound/tls');
163
- const tls_socket = require('../../tls_socket');
164
-
165
- // reset config to load from tests directory
166
- const testDir = path.resolve('tests');
167
- this.outbound.config = this.outbound.config.module_config(testDir);
168
- this.obtls.test_config(tls_socket.config.module_config(testDir), this.outbound.config);
169
- this.obtls.init(() => {
170
- done();
171
- })
172
-
173
- },
174
- tearDown: done => {
175
- delete process.env.HARAKA_TEST_DIR;
176
- done();
177
- },
178
- 'gets TLS properties from tls.ini.outbound' (test) {
179
- test.expect(1);
180
- const tls_config = this.obtls.get_tls_options(
181
- { exchange: 'mail.example.com'}
182
- );
183
-
184
- test.deepEqual(tls_config, {
185
- servername: 'mail.example.com',
186
- key: fs.readFileSync(path.resolve('tests','config','outbound_tls_key.pem')),
187
- cert: fs.readFileSync(path.resolve('tests','config','outbound_tls_cert.pem')),
188
- dhparam: fs.readFileSync(path.resolve('tests','config','dhparams.pem')),
189
- ciphers: 'ECDHE-RSA-AES256-GCM-SHA384',
190
- minVersion: 'TLSv1',
191
- rejectUnauthorized: false,
192
- requestCert: false,
193
- honorCipherOrder: false,
194
- redis: { disable_for_failed_hosts: false },
195
- no_tls_hosts: [],
196
- force_tls_hosts: ['first.example.com', 'second.example.net']
197
- });
198
- test.done();
199
- },
200
- }
201
-
202
- exports.build_todo = {
203
- setUp (done) {
204
- this.outbound = require('../../outbound');
205
- try {
206
- fs.unlinkSync('tests/queue/multibyte');
207
- fs.unlinkSync('tests/queue/plain');
208
- }
209
- catch (ignore) {}
210
- done();
211
- },
212
- tearDown: done => {
213
- // fs.unlink('tests/queue/multibyte', done);
214
- done();
215
- },
216
- 'saves a file' (test) {
217
- const todo = JSON.parse('{"queue_time":1507509981169,"domain":"redacteed.com","rcpt_to":[{"original":"<postmaster@redacteed.com>","original_host":"redacteed.com","host":"redacteed.com","user":"postmaster"}],"mail_from":{"original":"<matt@tnpi.net>","original_host":"tnpi.net","host":"tnpi.net","user":"matt"},"notes":{"authentication_results":["spf=pass smtp.mailfrom=tnpi.net"],"spf_mail_result":"Pass","spf_mail_record":"v=spf1 a mx include:mx.theartfarm.com ?include:forwards._spf.tnpi.net include:lists._spf.tnpi.net -all","attachment_count":0,"attachments":[{"ctype":"application/pdf","filename":"FileWithoutAccent Chars.pdf","extension":".pdf","md5":"6c1d5f5c047cff3f6320b1210970bdf6"}],"attachment_ctypes":["application/pdf","multipart/mixed","text/plain","application/pdf"],"attachment_files":["FileWithoutaccent Chars.pdf"],"attachment_archive_files":[]},"uuid":"1D5483B0-3E00-4280-A961-3AFD2017B4FC.1"}');
218
- const fd = fs.openSync('tests/queue/plain', 'w');
219
- const ws = new fs.createWriteStream('tests/queue/plain', { fd, flags: constants.WRITE_EXCL });
220
- ws.on('close', () => {
221
- // console.log(arguments);
222
- test.ok(1);
223
- test.done();
224
- })
225
- ws.on('error', (e) => {
226
- console.error(e);
227
- test.done();
228
- })
229
- this.outbound.build_todo(todo, ws, () => {
230
- ws.write(Buffer.from('This is the message body'));
231
- fs.fsync(fd, () => { ws.close(); })
232
- })
233
- },
234
- 'saves a file with multibyte chars' (test) {
235
- const todo = JSON.parse('{"queue_time":1507509981169,"domain":"redacteed.com","rcpt_to":[{"original":"<postmaster@redacteed.com>","original_host":"redacteed.com","host":"redacteed.com","user":"postmaster"}],"mail_from":{"original":"<matt@tnpi.net>","original_host":"tnpi.net","host":"tnpi.net","user":"matt"},"notes":{"authentication_results":["spf=pass smtp.mailfrom=tnpi.net"],"spf_mail_result":"Pass","spf_mail_record":"v=spf1 a mx include:mx.theartfarm.com ?include:forwards._spf.tnpi.net include:lists._spf.tnpi.net -all","attachment_count":0,"attachments":[{"ctype":"application/pdf","filename":"FileWîthÁccent Chars.pdf","extension":".pdf","md5":"6c1d5f5c047cff3f6320b1210970bdf6"}],"attachment_ctypes":["application/pdf","multipart/mixed","text/plain","application/pdf"],"attachment_files":["FileWîthÁccent Chars.pdf"],"attachment_archive_files":[]},"uuid":"1D5483B0-3E00-4280-A961-3AFD2017B4FC.1"}');
236
- const fd = fs.openSync('tests/queue/multibyte', 'w');
237
- const ws = new fs.WriteStream('tests/queue/multibyte', { fd, flags: constants.WRITE_EXCL });
238
- ws.on('close', () => {
239
- test.ok(1);
240
- test.done();
241
- })
242
- ws.on('error', (e) => {
243
- console.error(e);
244
- test.done();
245
- })
246
- this.outbound.build_todo(todo, ws, () => {
247
- ws.write(Buffer.from('This is the message body'));
248
- fs.fsync(fd, () => { ws.close(); })
249
- })
250
- },
251
- // '': function (test) {
252
-
253
- // test.done();
254
- // },
255
- }
256
-
257
- exports.timer_queue = {
258
- setUp (done) {
259
- process.env.HARAKA_TEST_DIR=path.resolve('tests');
260
- this.outbound = require('../../outbound');
261
- const TimerQueue = require('../../outbound/timer_queue');
262
- this.ob_timer_queue = new TimerQueue(500);
263
- done();
264
- },
265
- tearDown (done) {
266
- delete process.env.HARAKA_TEST_DIR;
267
- this.ob_timer_queue.shutdown();
268
- done();
269
- },
270
- 'has initial length of 0' (test) {
271
- test.expect(1);
272
-
273
- const tq_length = this.ob_timer_queue.length();
274
-
275
- test.equal(tq_length, 0);
276
- test.done();
277
- },
278
- 'can add items' (test) {
279
- test.expect(1);
280
-
281
- this.ob_timer_queue.add("1", 1000);
282
- this.ob_timer_queue.add("2", 2000);
283
-
284
- const tq_length = this.ob_timer_queue.length();
285
-
286
- test.equal(tq_length, 2);
287
- test.done();
288
- },
289
- 'can drain items' (test) {
290
- test.expect(2);
291
-
292
- this.ob_timer_queue.add("1", 1000);
293
- this.ob_timer_queue.add("2", 2000);
294
-
295
- let tq_length = this.ob_timer_queue.length();
296
-
297
- test.equal(tq_length, 2);
298
-
299
- this.ob_timer_queue.drain();
300
- tq_length = this.ob_timer_queue.length();
301
-
302
- test.equal(tq_length, 0);
303
-
304
- test.done();
305
- },
306
- 'can discard items by id' (test) {
307
- test.expect(3);
308
-
309
- this.ob_timer_queue.add("1", 1000);
310
- this.ob_timer_queue.add("2", 2000);
311
-
312
- let tq_length = this.ob_timer_queue.length();
313
-
314
- test.equal(tq_length, 2);
315
-
316
- this.ob_timer_queue.discard("2");
317
- tq_length = this.ob_timer_queue.length();
318
-
319
- test.equal(tq_length, 1);
320
- test.equal(this.ob_timer_queue.queue[0].id, "1");
321
-
322
- test.done();
323
- }
324
- }
@@ -1,67 +0,0 @@
1
-
2
- const qfile = require('../../outbound/qfile');
3
-
4
- exports.parts = {
5
- 'handles 4': (test) => {
6
- test.expect(1)
7
- const r = qfile.parts('1484878079415_0_12345_8888.mta1.example.com')
8
- // console.log(r);
9
- delete r.arrival
10
- delete r.uid
11
- delete r.counter
12
- test.deepEqual(r, {
13
- next_attempt: 1484878079415,
14
- attempts: 0,
15
- pid: 12345,
16
- host: 'mta1.example.com',
17
- age: 0
18
- })
19
- test.done()
20
- },
21
- 'handles 7': (test) => {
22
- test.expect(1)
23
- const r = qfile.parts('1516650518128_1516667073032_8_29538_TkPZWz_1_haraka')
24
- // console.log(r);
25
- delete r.age;
26
- test.deepEqual(r, {
27
- arrival: 1516650518128,
28
- next_attempt: 1516667073032,
29
- attempts: 8,
30
- pid: 29538,
31
- uid: 'TkPZWz',
32
- counter: 1,
33
- host: 'haraka',
34
- })
35
- test.done()
36
- },
37
- 'punts on 5': (test) => {
38
- test.expect(1)
39
- const r = qfile.parts('1516650518128_1516667073032_8_29538_TkPZWz')
40
- test.deepEqual(r, null)
41
- test.done()
42
- },
43
- }
44
-
45
- exports.hostname = {
46
- 'hostname, defaults to os.hostname()': test => {
47
- test.expect(1)
48
- const r = qfile.hostname();
49
- // console.log(r)
50
- test.deepEqual(r, require('os').hostname())
51
- test.done()
52
- },
53
- 'hostname, replaces \\ char': test => {
54
- test.expect(1)
55
- const r = qfile.hostname('mt\\a1.exam\\ple.com')
56
- // console.log(r)
57
- test.deepEqual(r, 'mt\\057a1.exam\\057ple.com')
58
- test.done()
59
- },
60
- 'hostname, replaces _ char': test => {
61
- test.expect(1)
62
- const r = qfile.hostname('mt_a1.exam_ple.com')
63
- // console.log(r)
64
- test.deepEqual(r, 'mt\\137a1.exam\\137ple.com')
65
- test.done()
66
- }
67
- }
@@ -1,173 +0,0 @@
1
- 'use strict';
2
-
3
- // Testing bounce email contents related to errors occuring during SMTP dialog
4
-
5
- // About running the tests:
6
- // - Making a folder for queuing files
7
- // - Creating a HMailItem instance using fixtures/util_hmailitem
8
- // - Talk some STMP in the playbook
9
- // - Test the outcome by replacing trigger functions with our testing code (outbound.send_email, HMailItem.temp_fail, ...)
10
-
11
- const dns = require('dns');
12
- const fs = require('fs');
13
- const path = require('path');
14
-
15
- const constants = require('haraka-constants');
16
- const util_hmailitem = require('./fixtures/util_hmailitem');
17
- const TODOItem = require('../outbound/todo');
18
- const HMailItem = require('../outbound/hmail');
19
- const outbound = require('../outbound');
20
-
21
- const outbound_context = {
22
- TODOItem,
23
- exports: outbound
24
- }
25
-
26
- const queue_dir = path.resolve(__dirname, 'test-queue');
27
-
28
- exports.bounce_3464 = {
29
- setUp : done => {
30
- fs.exists(queue_dir, exists => {
31
- if (exists) {
32
- done();
33
- }
34
- else {
35
- fs.mkdir(queue_dir, err => {
36
- if (err) {
37
- return done(err);
38
- }
39
- done();
40
- });
41
- }
42
- });
43
- },
44
- tearDown: done => {
45
- fs.exists(queue_dir, exists => {
46
- if (exists) {
47
- const files = fs.readdirSync(queue_dir);
48
- files.forEach((file,index) => {
49
- const curPath = path.resolve(queue_dir, file);
50
- if (fs.lstatSync(curPath).isDirectory()) { // recurse
51
- return done(new Error(`did not expect an sub folder here ("${curPath}")! cancel`));
52
- }
53
- });
54
- files.forEach((file,index) => {
55
- const curPath = path.resolve(queue_dir, file);
56
- fs.unlinkSync(curPath);
57
- });
58
- done();
59
- }
60
- else {
61
- done();
62
- }
63
- });
64
- },
65
- 'test get-mx-deny triggers bounce(...)': test => {
66
- test.expect(2);
67
-
68
- util_hmailitem.newMockHMailItem(outbound_context, test, {}, mock_hmail => {
69
- const orig_bounce = HMailItem.prototype.bounce;
70
- HMailItem.prototype.bounce = function (err, opts) {
71
- test.ok(true, 'get_mx=DENY: bounce function called');
72
- /* dsn_code: 550,
73
- dsn_status: '5.1.2',
74
- dsn_action: 'failed' */
75
- test.equal('5.1.2', this.todo.rcpt_to[0].dsn_status, 'get_mx=DENY dsn status = 5.1.2');
76
- };
77
- mock_hmail.domain = mock_hmail.todo.domain;
78
- HMailItem.prototype.get_mx_respond.apply(mock_hmail, [constants.deny, {}]);
79
- HMailItem.prototype.bounce = orig_bounce;
80
- test.done();
81
- });
82
- },
83
- 'test get-mx-denysoft triggers temp_fail(...)': test => {
84
- test.expect(2);
85
-
86
- util_hmailitem.newMockHMailItem(outbound_context, test, {}, mock_hmail => {
87
- const orig_temp_fail = HMailItem.prototype.temp_fail;
88
- HMailItem.prototype.temp_fail = function (err, opts) {
89
- test.ok(true, 'get_mx-DENYSOFT: temp_fail function called');
90
- /*dsn_code: 450,
91
- dsn_status: '4.1.2',
92
- dsn_action: 'delayed' */
93
- test.equal('4.1.2', this.todo.rcpt_to[0].dsn_status, 'get_mx=DENYSOFT dsn status = 4.1.2');
94
- };
95
- mock_hmail.domain = mock_hmail.todo.domain;
96
- HMailItem.prototype.get_mx_respond.apply(mock_hmail, [constants.denysoft, {}]);
97
- HMailItem.prototype.temp_fail = orig_temp_fail;
98
- test.done();
99
- });
100
- },
101
- 'test found_mx({code:dns.NXDOMAIN}) triggers bounce(...)': test => {
102
- test.expect(2);
103
-
104
- util_hmailitem.newMockHMailItem(outbound_context, test, {}, mock_hmail => {
105
- const orig_bounce = HMailItem.prototype.bounce;
106
- HMailItem.prototype.bounce = function (err, opts) {
107
- test.ok(true, 'found_mx({code: dns.NXDOMAIN}): bounce function called');
108
- test.equal('5.1.2', this.todo.rcpt_to[0].dsn_status, 'found_mx({code: dns.NXDOMAIN}: dsn status = 5.1.2');
109
- };
110
- HMailItem.prototype.found_mx.apply(mock_hmail, [{code: dns.NXDOMAIN}, {}]);
111
- HMailItem.prototype.bounce = orig_bounce;
112
- test.done();
113
- });
114
- },
115
- 'test found_mx({code:\'NOMX\'}) triggers bounce(...)': test => {
116
- test.expect(2);
117
-
118
- util_hmailitem.newMockHMailItem(outbound_context, test, {}, mock_hmail => {
119
- const orig_bounce = HMailItem.prototype.bounce;
120
- HMailItem.prototype.bounce = function (err, opts) {
121
- test.ok(true, 'found_mx({code: "NOMX"}): bounce function called');
122
- test.equal('5.1.2', this.todo.rcpt_to[0].dsn_status, 'found_mx({code: "NOMX"}: dsn status = 5.1.2');
123
- };
124
- HMailItem.prototype.found_mx.apply(mock_hmail, [{code: 'NOMX'}, {}]);
125
- HMailItem.prototype.bounce = orig_bounce;
126
- test.done();
127
- });
128
- },
129
- 'test found_mx({code:\'SOME-OTHER-ERR\'}) triggers temp_fail(...)': test => {
130
- test.expect(2);
131
-
132
- util_hmailitem.newMockHMailItem(outbound_context, test, {}, mock_hmail => {
133
- const orig_temp_fail = HMailItem.prototype.temp_fail;
134
- HMailItem.prototype.temp_fail = function (err, opts) {
135
- test.ok(true, 'found_mx({code: "SOME-OTHER-ERR"}): temp_fail function called');
136
- test.equal('4.1.0', this.todo.rcpt_to[0].dsn_status, 'found_mx({code: "SOME-OTHER-ERR"}: dsn status = 4.1.0');
137
- };
138
- HMailItem.prototype.found_mx.apply(mock_hmail, [{code: 'SOME-OTHER-ERR'}, {}]);
139
- HMailItem.prototype.temp_fail = orig_temp_fail;
140
- test.done();
141
- });
142
- },
143
- 'test found_mx(null, [{priority:0,exchange:\'\'}]) triggers bounce(...)': test => {
144
- test.expect(2);
145
-
146
-
147
- util_hmailitem.newMockHMailItem(outbound_context, test, {}, mock_hmail => {
148
- const orig_bounce = HMailItem.prototype.bounce;
149
- HMailItem.prototype.bounce = function (err, opts) {
150
- test.ok(true, 'found_mx(null, [{priority:0,exchange:""}]): bounce function called');
151
- test.equal('5.1.2', this.todo.rcpt_to[0].dsn_status, 'found_mx(null, [{priority:0,exchange:""}]): dsn status = 5.1.2');
152
- };
153
- HMailItem.prototype.found_mx.apply(mock_hmail, [null, [{priority:0,exchange:''}]]);
154
- HMailItem.prototype.bounce = orig_bounce;
155
- test.done();
156
- });
157
- },
158
- 'test try_deliver while hmail.mxlist=[] triggers bounce(...)': test => {
159
- test.expect(2);
160
-
161
- util_hmailitem.newMockHMailItem(outbound_context, test, {}, mock_hmail => {
162
- mock_hmail.mxlist = [];
163
- const orig_temp_fail = HMailItem.prototype.temp_fail;
164
- HMailItem.prototype.temp_fail = function (err, opts) {
165
- test.ok(true, 'try_deliver while hmail.mxlist=[]: temp_fail function called');
166
- test.equal('5.1.2', this.todo.rcpt_to[0].dsn_status, 'try_deliver while hmail.mxlist=[]: dsn status = 5.1.2');
167
- };
168
- HMailItem.prototype.try_deliver.apply(mock_hmail, []);
169
- HMailItem.prototype.temp_fail = orig_temp_fail;
170
- test.done();
171
- });
172
- },
173
- }