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,180 +0,0 @@
1
- spamassassin
2
- ============
3
-
4
- This plugin implements the spamd protocol and will send messages to
5
- spamd for scoring.
6
-
7
- Configuration
8
- -------------
9
-
10
- spamassassin.ini
11
-
12
- - spamd\_socket = \[host:port | /path/to/socket\] *optional*
13
-
14
- Default: localhost:783
15
-
16
- Host or path to socket where spamd is running.
17
-
18
- - spamd\_user = \[user\] *optional*
19
-
20
- Default: default
21
-
22
- Username to pass to spamd. This is useful when you are running
23
- spamd with virtual users.
24
-
25
- You can also pass this value in dynamically by setting:
26
-
27
- 1. `connection.transaction.notes.spamd_user` in another plugin.
28
-
29
- 2. The special username: _first-recipient_. The first envelope recipient
30
- will be used as the username.
31
-
32
- 3. the special username _all-recipients_ may eventually be supported. See
33
- the get_spamd_username function in the plugin.
34
-
35
- - max\_size = N *optional*
36
-
37
- Default: 500000
38
-
39
- Maximum size of messages (in bytes) to send to spamd.
40
- Messages over this size will be skipped.
41
-
42
- - reject\_threshold = N *optional*
43
-
44
- Default: none (do not reject any mail)
45
-
46
- SpamAssassin score at which the mail should be rejected.
47
-
48
- - relay\_reject\_threshold = N *optional*
49
-
50
- Default: none
51
-
52
- As above, except this threshold only applies to connections
53
- that are relays (e.g. AUTH) where connection.relaying = true.
54
- This is used to set a *lower* thresold at which to reject mail
55
- from these hosts to prevent sending outbound spam.
56
-
57
- If this is not set, then the `reject_thresold` value is used.
58
-
59
- - munge\_subject\_threshold = N *optional*
60
-
61
- Default: none (do not munge the subject)
62
-
63
- Score at which the subject should be munged (prefixed).
64
-
65
- - subject\_prefix = \[prefix\] *optional*
66
-
67
- Default: *** SPAM ***
68
-
69
- Prefix to use when munging the subject.
70
-
71
- - old\_headers\_action = \[rename | drop | keep\] *optional*
72
-
73
- Default: rename
74
-
75
- If old X-Spam-\* headers are in the email, what do we do with them?
76
-
77
- `rename` them to X-Old-Spam-\*.
78
-
79
- `drop` will delete them.
80
-
81
- `keep` will keep them (new X-Spam-\* headers appear lower down in
82
- the headers then).
83
-
84
- - connect\_timeout = N *optional*
85
-
86
- Default: 30
87
-
88
- Time in seconds to wait for a connection to spamd
89
-
90
- - results\_timeout = N *optional*
91
-
92
- Default: 300
93
-
94
- Time in seconds to wait for results from spamd
95
-
96
-
97
- [check]
98
- =======
99
-
100
- The optional check section can allow skipping SpamAssassin check for remote connection
101
- meeting following criteria.
102
-
103
- - authenticated
104
-
105
- Default: true
106
-
107
- If true, messages from authenticated users will be scored.
108
-
109
- - private\_ip
110
-
111
- Default: true
112
-
113
- If true, messages from private IPs will be scored.
114
-
115
- - local\_ip
116
-
117
- Default: true
118
-
119
- If true, messages from localhost will be scored.
120
-
121
- - relay
122
-
123
- Default: true
124
-
125
- If true, messages that are to be relayed will be scored.
126
-
127
- [defer]
128
- =======
129
-
130
- The optional defer section can allow returning a DENYSOFT status back to the
131
- client. Setting these to true will force the client to retry later in cases where
132
- spamassassin is not responding properly. If set to false, then the errors
133
- will be ignored and message processing will continue.
134
-
135
- - error
136
-
137
- Default: false
138
-
139
- If true, return DENYSOFT on socket errors
140
-
141
- - connect\_timeout
142
-
143
- Default: false
144
-
145
- If true, return DENYSOFT on socket connection timeouts
146
-
147
- - scan\_timeout
148
-
149
- Default: false
150
-
151
- If true, return DENYSOFT on scan timeouts
152
-
153
- Extras
154
- ======
155
-
156
- A SpamAssassin plugin can be found in the `contrib` directory.
157
- The `Haraka.\[pm|cf\]` files should be placed in the SpamAssassin local
158
- site rules directory (/etc/mail/spamassassin on Linux), spamd should be
159
- restarted and the plugin will make spamd output the Haraka UUID as part
160
- of its log output to aid debugging when searching the mail logs.
161
-
162
-
163
- Changes
164
- --------------
165
-
166
- This plugin now passes the X-Spam-\* headers generated by SA through
167
- unaltered. You can control the presence and appearance of X-Spam-\*
168
- headers by editing your SpamAssassin config.
169
-
170
- The default headers added by SpamAssassin are:
171
-
172
- add_header all Checker-Version SpamAssassin _VERSION_ (_SUBVERSION_) on _HOSTNAME_
173
- add_header spam Flag _YESNOCAPS_
174
- add_header all Level _STARS(\*)_
175
- add_header all Status "_YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_"
176
-
177
- Other headers options you might find interesting or useful are:
178
-
179
- add_header all DCC _DCCB_: _DCCR_
180
- add_header all Tests _TESTS_
@@ -1,70 +0,0 @@
1
- "use strict";
2
-
3
- const dns = require('dns');
4
- const net_utils = require('haraka-net-utils')
5
-
6
- const obc = require('./config');
7
-
8
- exports.lookup_mx = function lookup_mx (domain, cb) {
9
- const mxs = [];
10
-
11
- // Possible DNS errors
12
- // NODATA
13
- // FORMERR
14
- // BADRESP
15
- // NOTFOUND
16
- // BADNAME
17
- // TIMEOUT
18
- // CONNREFUSED
19
- // NOMEM
20
- // DESTRUCTION
21
- // NOTIMP
22
- // EREFUSED
23
- // SERVFAIL
24
-
25
- // default wrap_mx just returns our object with "priority" and "exchange" keys
26
- let wrap_mx = a => a;
27
- async function process_dns (err, addresses) {
28
- if (err) {
29
- if (err.code === 'ENODATA' || err.code === 'ENOTFOUND') {
30
- // Most likely this is a hostname with no MX record
31
- // Drop through and we'll get the A record instead.
32
- return 0;
33
- }
34
- cb(err);
35
- }
36
- else if (addresses?.length) {
37
- for (let i=0,l=addresses.length; i < l; i++) {
38
- if (
39
- obc.cfg.local_mx_ok ||
40
- await net_utils.is_local_host(addresses[i].exchange).catch(() => null) === false
41
- ) {
42
- const mx = wrap_mx(addresses[i]);
43
- mxs.push(mx);
44
- }
45
- }
46
- cb(null, mxs);
47
- }
48
- else {
49
- // return zero if we need to keep trying next option
50
- return 0;
51
- }
52
- return 1;
53
- }
54
-
55
- net_utils.get_mx(domain, async (err, addresses) => {
56
- if (await process_dns(err, addresses)) return;
57
-
58
- // if MX lookup failed, we lookup an A record. To do that we change
59
- // wrap_mx() to return same thing as resolveMx() does.
60
- wrap_mx = a => ({priority:0,exchange:a});
61
- // IS: IPv6 compatible
62
- dns.resolve(domain, async (err2, addresses2) => {
63
- if (await process_dns(err2, addresses2)) return;
64
-
65
- err2 = new Error("Found nowhere to deliver to");
66
- err2.code = 'NOMX';
67
- cb(err2);
68
- });
69
- });
70
- }
@@ -1,3 +0,0 @@
1
- exports.register = function () {
2
- this.logerror('This plugin has moved. See https://github.com/haraka/haraka-plugin-auth-ldap');
3
- }
package/plugins/avg.js DELETED
@@ -1,162 +0,0 @@
1
- // avg - AVG virus scanner
2
- 'use strict';
3
-
4
- // TODO: use pooled connections
5
-
6
- const fs = require('fs');
7
- const path = require('path');
8
-
9
- const sock = require('./line_socket');
10
-
11
- const smtp_regexp = /^(\d{3})([ -])(.*)/;
12
-
13
- exports.register = function () {
14
-
15
- this.load_avg_ini();
16
- }
17
-
18
- exports.load_avg_ini = function () {
19
-
20
- this.cfg = this.config.get('avg.ini', {
21
- booleans: [
22
- '+defer.timeout',
23
- '+defer.error',
24
- ],
25
- }, () => {
26
- this.load_avg_ini();
27
- });
28
- }
29
-
30
- exports.get_tmp_file = function (transaction) {
31
- const tmpdir = this.cfg.main.tmpdir || '/tmp';
32
- return path.join(tmpdir, `${transaction.uuid}.tmp`);
33
- }
34
-
35
- exports.hook_data_post = function (next, connection) {
36
- if (!connection?.transaction) return next()
37
-
38
- const plugin = this;
39
- const tmpfile = plugin.get_tmp_file(connection.transaction);
40
- const ws = fs.createWriteStream(tmpfile);
41
-
42
- ws.once('error', err => {
43
- connection.results.add(plugin, {
44
- err: `Error writing temporary file: ${err.message}`
45
- });
46
- if (!plugin.cfg.defer.error) return next();
47
- return next(DENYSOFT, 'Virus scanner error (AVG)');
48
- });
49
-
50
- ws.once('close', () => {
51
- const start_time = Date.now();
52
- const socket = new sock.Socket();
53
- socket.setTimeout((plugin.cfg.main.connect_timeout || 10) * 1000);
54
- let connected = false;
55
- let command = 'connect';
56
- let response = [];
57
-
58
- function do_next (code, msg) {
59
- fs.unlink(tmpfile, () => {});
60
- return next(code, msg);
61
- }
62
-
63
- socket.send_command = function (cmd, data) {
64
- const line = cmd + (data ? (` ${data}`) : '');
65
- connection.logprotocol(plugin, `> ${line}`);
66
- this.write(`${line}\r\n`);
67
- command = cmd.toLowerCase();
68
- response = [];
69
- };
70
-
71
- socket.on('timeout', () => {
72
- const msg = `${connected ? 'connection' : 'session' } timed out`;
73
- connection.results.add(plugin, { err: msg });
74
- if (!plugin.cfg.defer.timeout) return do_next();
75
- return do_next(DENYSOFT, 'Virus scanner timeout (AVG)');
76
- });
77
-
78
- socket.on('error', err => {
79
- connection.results.add(plugin, { err: err.message });
80
- if (!plugin.cfg.defer.error) return do_next();
81
- return do_next(DENYSOFT, 'Virus scanner error (AVG)');
82
- });
83
-
84
- socket.on('connect', function () {
85
- connected = true;
86
- this.setTimeout((plugin.cfg.main.session_timeout || 30) * 1000);
87
- });
88
-
89
- socket.on('line', line => {
90
- const matches = smtp_regexp.exec(line);
91
- connection.logprotocol(plugin, `< ${line}`);
92
- if (!matches) {
93
- connection.results.add(plugin,
94
- { err: `Unrecognized response: ${line}` });
95
- socket.end();
96
- if (!plugin.cfg.defer.error) return do_next();
97
- return do_next(DENYSOFT, 'Virus scanner error (AVG)');
98
- }
99
-
100
- const code = matches[1];
101
- const cont = matches[2];
102
- const rest = matches[3];
103
- response.push(rest);
104
- if (cont !== ' ') return;
105
-
106
- switch (command) {
107
- case 'connect':
108
- if (code !== '220') {
109
- // Error
110
- connection.results.add(plugin, {
111
- err: `Unrecognized response: ${line}`,
112
- });
113
- if (!plugin.cfg.defer.timeout) return do_next();
114
- return do_next(DENYSOFT, 'Virus scanner error (AVG)');
115
- }
116
- else {
117
- socket.send_command('SCAN', tmpfile);
118
- }
119
- break;
120
- case 'scan': {
121
- const elapsed = Date.now() - start_time;
122
- connection.loginfo(plugin, {
123
- time: `${elapsed}ms`,
124
- code,
125
- response: `"${response.join(' ')}"`
126
- })
127
- // Check code
128
- switch (code) {
129
- case '200': // 200 ok
130
- // Message did not contain a virus
131
- connection.results.add(plugin, { pass: 'clean' });
132
- socket.send_command('QUIT');
133
- return do_next();
134
- case '403':
135
- // File 'eicar.com', 'Virus identified EICAR_Test'
136
- connection.results.add(plugin, {
137
- fail: response.join(' ')
138
- });
139
- socket.send_command('QUIT');
140
- return do_next(DENY, response.join(' '));
141
- default:
142
- // Any other result is an error
143
- connection.results.add(plugin, {
144
- err: `Bad response: ${response.join(' ')}`
145
- });
146
- }
147
- socket.send_command('QUIT');
148
- if (!plugin.cfg.defer.error) return do_next();
149
- return do_next(DENYSOFT, 'Virus scanner error (AVG)');
150
- }
151
- case 'quit':
152
- socket.end();
153
- break;
154
- default:
155
- throw new Error(`Unknown command: ${command}`);
156
- }
157
- });
158
- socket.connect((plugin.cfg.main.port || 54322), plugin.cfg.main.host);
159
- });
160
-
161
- connection.transaction.message_stream.pipe(ws, { line_endings: '\r\n' });
162
- }
@@ -1,25 +0,0 @@
1
- // backscatterer plugin
2
-
3
- exports.register = function () {
4
- this.inherits('dns_list_base');
5
- }
6
-
7
- exports.hook_mail = function (next, connection, params) {
8
- const user = ((params[0]?.user) ?
9
- params[0].user.toLowerCase() : null);
10
- if (!(!user || user === 'postmaster')) return next();
11
- // Check remote IP on ips.backscatterer.org
12
- const plugin = this;
13
-
14
- function resultCb (err, zone, a) {
15
- if (err) {
16
- connection.logerror(plugin, err);
17
- return next();
18
- }
19
- if (!a) return next();
20
- const msg = `Host ${connection.remote.host} [${connection.remote.ip}] is blacklisted by ${zone}`;
21
- return next(DENY, msg);
22
- }
23
-
24
- this.first(connection.remote.ip, [ 'ips.backscatterer.org' ], resultCb);
25
- }