haraka-plugin-karma 2.1.6 → 2.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.
package/CHANGELOG.md CHANGED
@@ -4,9 +4,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
4
4
 
5
5
  ### Unreleased
6
6
 
7
+ ### [2.1.7] - 2025-01-31
8
+
9
+ - replace utils.in_array with [].includes
10
+ - dep(eslint): upgrade to v9
11
+ - doc(CONTRIBUTORS): updated
12
+
7
13
  ### [2.1.6] - 2024-11-08
8
14
 
9
- - fix missing error handler on redis client [#45](https://github.com/haraka/haraka-plugin-redis/issues/45)
15
+ - fix missing error handler on redis client #61
10
16
 
11
17
  ### [2.1.5] - 2024-04-23
12
18
 
@@ -134,3 +140,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
134
140
  [2.1.3]: https://github.com/haraka/haraka-plugin-karma/releases/tag/v2.1.3
135
141
  [2.1.4]: https://github.com/haraka/haraka-plugin-karma/releases/tag/v2.1.4
136
142
  [2.1.5]: https://github.com/haraka/haraka-plugin-karma/releases/tag/v2.1.5
143
+ [2.1.6]: https://github.com/haraka/haraka-plugin-karma/releases/tag/v2.1.6
package/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  [![Build Status][ci-img]][ci-url]
2
2
  [![Code Climate][clim-img]][clim-url]
3
- [![NPM][npm-img]][npm-url]
4
3
 
5
4
  # Karma - A heuristics based reputation engine for the Haraka MTA
6
5
 
@@ -200,5 +199,3 @@ Expect to use karma _with_ content filters.
200
199
  [cov-url]: https://codecov.io/github/haraka/haraka-plugin-karma
201
200
  [clim-img]: https://codeclimate.com/github/haraka/haraka-plugin-karma/badges/gpa.svg
202
201
  [clim-url]: https://codeclimate.com/github/haraka/haraka-plugin-karma
203
- [npm-img]: https://nodei.co/npm/haraka-plugin-karma.png
204
- [npm-url]: https://www.npmjs.com/package/haraka-plugin-karma
package/index.js CHANGED
@@ -364,8 +364,8 @@ exports.tarpit_delay = function (score, connection, hook, k) {
364
364
 
365
365
  // detect roaming users based on MSA ports that require auth
366
366
  if (
367
- utils.in_array(connection.local.port, [587, 465]) &&
368
- utils.in_array(hook, ['ehlo', 'connect'])
367
+ [587, 465].includes(connection.local.port) &&
368
+ ['ehlo', 'connect'].includes(hook)
369
369
  ) {
370
370
  return this.tarpit_delay_msa(connection, delay, k)
371
371
  }
@@ -673,6 +673,19 @@ exports.hook_data_post = function (next, connection) {
673
673
 
674
674
  if (this.should_we_skip(connection)) return next()
675
675
 
676
+ /*
677
+ This should not be a default due to highly probability of false positives,
678
+ but I've found it extremely effective against a recent (most of 2024) spam
679
+ campaign that Gmail apparently has no interest in stopping.
680
+ if (connection.transaction.header.get_decoded('subject').match(/\p{Emoji}/gu)) {
681
+ connection.results.add(this, { msg: 'subject_contains_emoji' })
682
+ if (connection.transaction.mail_from.host === 'gmail.com') {
683
+ connection.results.incr(this, { score: -10 })
684
+ connection.results.add(this, { msg: 'emoji_from_gmail' })
685
+ }
686
+ }
687
+ */
688
+
676
689
  this.check_awards(connection) // update awards
677
690
 
678
691
  const results = connection.results.collate(this)
package/package.json CHANGED
@@ -1,20 +1,19 @@
1
1
  {
2
2
  "name": "haraka-plugin-karma",
3
- "version": "2.1.6",
3
+ "version": "2.1.7",
4
4
  "description": "A heuristics scoring and reputation engine for SMTP connections",
5
5
  "main": "index.js",
6
6
  "files": [
7
7
  "CHANGELOG.md",
8
- "config",
9
- "test"
8
+ "config"
10
9
  ],
11
10
  "scripts": {
12
11
  "format": "npm run prettier:fix && npm run lint:fix",
13
- "lint": "npx eslint@^8 *.js test",
14
- "lint:fix": "npx eslint@^8 *.js test --fix",
12
+ "lint": "npx eslint@^9 *.js test",
13
+ "lint:fix": "npx eslint@^9 *.js test --fix",
15
14
  "prettier": "npx prettier . --check",
16
15
  "prettier:fix": "npx prettier . --write --log-level=warn",
17
- "test": "npx mocha@^10",
16
+ "test": "npx mocha@^11",
18
17
  "versions": "npx dependency-version-checker check",
19
18
  "versions:fix": "npx dependency-version-checker update"
20
19
  },
@@ -39,7 +38,11 @@
39
38
  "redis": "^4.6.13"
40
39
  },
41
40
  "devDependencies": {
42
- "@haraka/eslint-config": "^1.1.2",
41
+ "@haraka/eslint-config": "^2.0.2",
43
42
  "haraka-test-fixtures": "^1.3.4"
43
+ },
44
+ "prettier": {
45
+ "singleQuote": true,
46
+ "semi": false
44
47
  }
45
48
  }
package/test/karma.js DELETED
@@ -1,913 +0,0 @@
1
- 'use strict'
2
-
3
- const assert = require('assert')
4
-
5
- const Address = require('address-rfc2821').Address
6
- const fixtures = require('haraka-test-fixtures')
7
- const constants = require('haraka-constants')
8
-
9
- const stub = fixtures.stub.stub
10
-
11
- function _set_up(done) {
12
- this.plugin = new fixtures.plugin('karma')
13
-
14
- this.plugin.cfg = { main: {} }
15
- this.plugin.deny_hooks = { connect: true }
16
- this.plugin.tarpit_hooks = ['connect']
17
-
18
- this.connection = fixtures.connection.createConnection({}, { notes: {} })
19
- this.connection.init_transaction()
20
-
21
- done()
22
- }
23
-
24
- describe('karma_init', function () {
25
- beforeEach(function (done) {
26
- this.plugin = new fixtures.plugin('karma')
27
- done()
28
- })
29
-
30
- it('load_karma_ini', function (done) {
31
- this.plugin.inherits('haraka-plugin-redis')
32
- this.plugin.load_karma_ini()
33
- assert.ok(this.plugin.cfg.asn)
34
- assert.ok(this.plugin.deny_hooks)
35
- done()
36
- })
37
- })
38
-
39
- describe('results_init', function () {
40
- beforeEach(_set_up)
41
-
42
- it('init, pre', function (done) {
43
- const r = this.connection.results.get('karma')
44
- assert.equal(undefined, r)
45
- done()
46
- })
47
-
48
- it('init, empty cfg', function (done) {
49
- this.plugin.results_init(stub, this.connection)
50
- const r = this.connection.results.get('karma')
51
- assert.ok(r)
52
- done()
53
- })
54
-
55
- it('init, cfg', function (done) {
56
- this.plugin.cfg.awards = { test: 1 }
57
- this.plugin.results_init(stub, this.connection)
58
- const r = this.connection.results.get('karma')
59
- assert.ok(r)
60
- assert.ok(r.todo)
61
- done()
62
- })
63
-
64
- it('init, skip', function (done) {
65
- this.connection.remote.is_private = true
66
- this.plugin.results_init(stub, this.connection)
67
- const r = this.connection.results.get('karma')
68
- assert.equal(undefined, r)
69
- done()
70
- })
71
-
72
- it('init, private skip', function (done) {
73
- this.connection.notes.disable_karma = true
74
- this.plugin.results_init(stub, this.connection)
75
- const r = this.connection.results.get('karma')
76
- assert.equal(undefined, r)
77
- done()
78
- })
79
- })
80
-
81
- describe('assemble_note_obj', function () {
82
- beforeEach(_set_up)
83
-
84
- it('no auth fails', function (done) {
85
- const obj = this.plugin.assemble_note_obj(
86
- this.connection,
87
- 'notes.auth_fails',
88
- )
89
- assert.equal(undefined, obj)
90
- done()
91
- })
92
-
93
- it('has auth fails', function (done) {
94
- this.connection.notes.auth_fails = [1, 2]
95
- const obj = this.plugin.assemble_note_obj(
96
- this.connection,
97
- 'notes.auth_fails',
98
- )
99
- assert.deepEqual([1, 2], obj)
100
- done()
101
- })
102
- })
103
-
104
- describe('hook_deny', function () {
105
- beforeEach(_set_up)
106
-
107
- it('no params', function (done) {
108
- const next = function (rc) {
109
- assert.equal(constants.OK, rc, rc)
110
- done()
111
- }
112
- this.plugin.hook_deny(next, this.connection, ['', '', '', ''])
113
- })
114
-
115
- it('pi_name=karma', function (done) {
116
- const next = function (rc) {
117
- assert.equal(undefined, rc)
118
- done()
119
- }
120
- this.plugin.hook_deny(next, this.connection, ['', '', 'karma', ''])
121
- })
122
-
123
- it('pi_name=access', function (done) {
124
- const next = function (rc) {
125
- assert.equal(undefined, rc)
126
- done()
127
- }
128
- this.plugin.deny_exclude_plugins = { access: true }
129
- this.plugin.hook_deny(next, this.connection, ['', '', 'access', ''])
130
- })
131
-
132
- it('pi_hook=rcpt_to', function (done) {
133
- const next = function (rc) {
134
- assert.equal(undefined, rc)
135
- done()
136
- }
137
- this.plugin.deny_exclude_hooks = { rcpt_to: true }
138
- this.plugin.hook_deny(next, this.connection, [
139
- '',
140
- '',
141
- '',
142
- '',
143
- '',
144
- 'rcpt_to',
145
- ])
146
- })
147
-
148
- it('pi_hook=queue', function (done) {
149
- const next = function (rc) {
150
- assert.equal(undefined, rc)
151
- done()
152
- }
153
- this.plugin.deny_exclude_hooks = { queue: true }
154
- this.plugin.hook_deny(next, this.connection, ['', '', '', '', '', 'queue'])
155
- })
156
-
157
- it('denysoft', function (done) {
158
- const next = function (rc) {
159
- assert.equal(constants.OK, rc)
160
- done()
161
- }
162
- this.plugin.hook_deny(next, this.connection, [
163
- constants.DENYSOFT,
164
- '',
165
- '',
166
- '',
167
- '',
168
- '',
169
- ])
170
- })
171
- })
172
-
173
- describe('get_award_location', function () {
174
- beforeEach(_set_up)
175
-
176
- it('relaying=false', function (done) {
177
- this.connection.relaying = false
178
- const r = this.plugin.get_award_location(this.connection, 'relaying')
179
- assert.equal(false, r)
180
- done()
181
- })
182
-
183
- it('relaying=true', function (done) {
184
- this.connection.relaying = true
185
- const r = this.plugin.get_award_location(this.connection, 'relaying')
186
- assert.equal(true, r)
187
- done()
188
- })
189
-
190
- it('notes.undef=2', function (done) {
191
- const r = this.plugin.get_award_location(this.connection, 'notes.undef')
192
- assert.equal(undefined, r)
193
- done()
194
- })
195
-
196
- it('notes.tarpit=2', function (done) {
197
- this.connection.notes = { tarpit: 2 }
198
- const r = this.plugin.get_award_location(this.connection, 'notes.tarpit')
199
- assert.equal(2, r)
200
- done()
201
- })
202
-
203
- it('results.geoip', function (done) {
204
- this.connection.results.add('geoip', { country: 'US' })
205
- const r = this.plugin.get_award_location(this.connection, 'results.geoip')
206
- // console.log(r);
207
- assert.equal('US', r.country)
208
- done()
209
- })
210
-
211
- it('results.karma', function (done) {
212
- this.connection.results.add('karma', { score: -1 })
213
- const r = this.plugin.get_award_location(this.connection, 'results.karma')
214
- // console.log(r);
215
- assert.equal(-1, r.score)
216
- done()
217
- })
218
-
219
- it('results.karma, txn', function (done) {
220
- // results should be found in conn or txn
221
- this.connection.transaction.results.add('karma', { score: -1 })
222
- const r = this.plugin.get_award_location(this.connection, 'results.karma')
223
- // console.log(r);
224
- assert.equal(-1, r.score)
225
- done()
226
- })
227
-
228
- it('txn.results.karma', function (done) {
229
- // these results shouldn't be found, b/c txn specified
230
- this.connection.results.add('karma', { score: -1 })
231
- const r = this.plugin.get_award_location(
232
- this.connection,
233
- 'transaction.results.karma',
234
- )
235
- // console.log(r);
236
- assert.equal(undefined, r)
237
- done()
238
- })
239
-
240
- it('results.auth/auth_base', function (done) {
241
- this.connection.results.add('auth/auth_base', { fail: 'PLAIN' })
242
- const r = this.plugin.get_award_location(
243
- this.connection,
244
- 'results.auth/auth_base',
245
- )
246
- assert.equal('PLAIN', r.fail[0])
247
- done()
248
- })
249
- })
250
-
251
- describe('get_award_condition', function () {
252
- beforeEach(_set_up)
253
- it('geoip.distance', function (done) {
254
- assert.equal(
255
- 4000,
256
- this.plugin.get_award_condition(
257
- 'results.geoip.distance@4000',
258
- '-1 if gt',
259
- ),
260
- )
261
- assert.equal(
262
- 4000,
263
- this.plugin.get_award_condition(
264
- 'results.geoip.distance@uniq',
265
- '-1 if gt 4000',
266
- ),
267
- )
268
- done()
269
- })
270
-
271
- it('auth/auth_base', function (done) {
272
- assert.equal(
273
- 'plain',
274
- this.plugin.get_award_condition(
275
- 'results.auth/auth_base.fail@plain',
276
- '-1 if in',
277
- ),
278
- )
279
- done()
280
- })
281
- })
282
-
283
- describe('check_awards', function () {
284
- beforeEach(_set_up)
285
-
286
- it('no results', function (done) {
287
- const r = this.plugin.check_awards(this.connection)
288
- assert.equal(undefined, r)
289
- done()
290
- })
291
-
292
- it('no todo', function (done) {
293
- this.connection.results.add('karma', { todo: {} })
294
- const r = this.plugin.check_awards(this.connection)
295
- assert.equal(undefined, r)
296
- done()
297
- })
298
-
299
- it('geoip gt', function (done) {
300
- // populate the karma result with a todo item
301
- this.connection.results.add('karma', {
302
- todo: { 'results.geoip.distance@4000': '-1 if gt 4000' },
303
- })
304
- // test a non-matching criteria
305
- this.connection.results.add('geoip', { distance: 4000 })
306
- // check awards
307
- this.plugin.check_awards(this.connection)
308
- assert.equal(undefined, this.connection.results.get('karma').fail[0])
309
-
310
- // test a matching criteria
311
- this.connection.results.add('geoip', { distance: 4001 })
312
- // check awards
313
- this.plugin.check_awards(this.connection)
314
- // test that the award was applied
315
- assert.equal('geoip.distance', this.connection.results.get('karma').fail[0])
316
-
317
- done()
318
- })
319
-
320
- it('auth failure', function (done) {
321
- this.connection.results.add('karma', {
322
- todo: { 'results.auth/auth_base.fail@PLAIN': '-1 if in' },
323
- })
324
- this.connection.results.add('auth/auth_base', { fail: 'PLAIN' })
325
- const r = this.plugin.check_awards(this.connection)
326
- assert.equal(undefined, r)
327
- assert.equal(
328
- 'auth/auth_base.fail',
329
- this.connection.results.get('karma').fail[0],
330
- )
331
- done()
332
- })
333
-
334
- it('valid recipient', function (done) {
335
- this.connection.results.add('karma', {
336
- todo: { 'results.rcpt_to.qmd.pass@exist': '1 if in' },
337
- })
338
- this.connection.results.add('rcpt_to.qmd', { pass: 'exist' })
339
- const r = this.plugin.check_awards(this.connection)
340
- assert.equal(undefined, r)
341
- assert.equal('qmd.pass', this.connection.results.get('karma').pass[0])
342
- done()
343
- })
344
- })
345
-
346
- describe('apply_tarpit', function () {
347
- beforeEach(_set_up)
348
-
349
- it('tarpit=false', function (done) {
350
- const next = function (rc, msg) {
351
- assert.equal(undefined, rc)
352
- assert.equal(undefined, msg)
353
- done()
354
- }
355
- this.plugin.apply_tarpit(this.connection, 'connect', 0, next)
356
- })
357
-
358
- it('tarpit=true, score=0', function (done) {
359
- const next = function (rc, msg) {
360
- assert.equal(undefined, rc)
361
- assert.equal(undefined, msg)
362
- done()
363
- }
364
- this.plugin.cfg.tarpit = { max: 1, delay: 0 }
365
- this.plugin.apply_tarpit(this.connection, 'connect', 0, next)
366
- })
367
-
368
- it('tarpit=true, score=1', function (done) {
369
- const next = function (rc, msg) {
370
- assert.equal(undefined, rc)
371
- assert.equal(undefined, msg)
372
- done()
373
- }
374
- this.plugin.cfg.tarpit = { max: 1, delay: 0 }
375
- this.plugin.apply_tarpit(this.connection, 'connect', 1, next)
376
- })
377
-
378
- it('tarpit=true, score=-1', function (done) {
379
- const before = Date.now()
380
- const next = function (rc, msg) {
381
- assert.ok(Date.now() >= before + 1)
382
- assert.equal(undefined, rc)
383
- assert.equal(undefined, msg)
384
- done()
385
- }
386
- this.plugin.cfg.tarpit = { max: 1, delay: 0 }
387
- this.plugin.apply_tarpit(this.connection, 'connect', -1, next)
388
- })
389
-
390
- it('tarpit=true, score=-2, max=1', function (done) {
391
- const before = Date.now()
392
- const next = function (rc, msg) {
393
- assert.ok(Date.now() >= before + 1)
394
- assert.equal(undefined, rc)
395
- assert.equal(undefined, msg)
396
- done()
397
- }
398
- this.plugin.cfg.tarpit = { max: 1, delay: 0 }
399
- this.plugin.apply_tarpit(this.connection, 'connect', -2, next)
400
- })
401
-
402
- it('tarpit=true, score=connect, max=1', function (done) {
403
- const before = Date.now()
404
- const next = function (rc, msg) {
405
- assert.ok(Date.now() >= before + 1)
406
- assert.equal(undefined, rc)
407
- assert.equal(undefined, msg)
408
- done()
409
- }
410
- this.plugin.cfg.tarpit = { max: 1, delay: 0 }
411
- this.connection.results.add(this.plugin, { score: -2 })
412
- this.plugin.apply_tarpit(this.connection, 'connect', -2, next)
413
- })
414
- })
415
-
416
- describe('should_we_deny', function () {
417
- beforeEach(_set_up)
418
-
419
- it('no results', function (done) {
420
- const next = function (rc, msg) {
421
- assert.equal(undefined, rc)
422
- assert.equal(undefined, msg)
423
- done()
424
- }
425
- this.plugin.should_we_deny(next, this.connection, 'connect')
426
- })
427
-
428
- it('no score', function (done) {
429
- const next = function (rc, msg) {
430
- assert.equal(undefined, rc)
431
- assert.equal(undefined, msg)
432
- done()
433
- }
434
- this.connection.results.add(this.plugin, { test: 'blah' })
435
- this.plugin.should_we_deny(next, this.connection, 'connect')
436
- })
437
-
438
- it('invalid score', function (done) {
439
- const next = function (rc, msg) {
440
- assert.equal(undefined, rc)
441
- assert.equal(undefined, msg)
442
- done()
443
- }
444
- this.connection.results.add(this.plugin, { score: 'blah' })
445
- this.plugin.should_we_deny(next, this.connection, 'connect')
446
- })
447
-
448
- it('valid score, okay', function (done) {
449
- const next = function (rc, msg) {
450
- assert.equal(undefined, rc)
451
- assert.equal(undefined, msg)
452
- done()
453
- }.bind(this)
454
- this.plugin.cfg.tarpit = { max: 1, delay: 0 }
455
- this.connection.results.add(this.plugin, { score: -1 })
456
- this.plugin.should_we_deny(next, this.connection, 'connect')
457
- })
458
-
459
- it('valid score, -6, deny_hook', function (done) {
460
- const next = function (rc, msg) {
461
- assert.equal(constants.DENY, rc)
462
- assert.ok(msg)
463
- done()
464
- }.bind(this)
465
- this.plugin.cfg.tarpit = { max: 1, delay: 0 }
466
- this.plugin.deny_hooks = { connect: true }
467
- this.connection.results.add(this.plugin, { score: -6 })
468
- this.plugin.should_we_deny(next, this.connection, 'connect')
469
- })
470
-
471
- it('valid score, -6, pass_hook', function (done) {
472
- const next = function (rc, msg) {
473
- assert.equal(undefined, rc)
474
- assert.equal(undefined, msg)
475
- done()
476
- }.bind(this)
477
- this.plugin.cfg.tarpit = { max: 1, delay: 0 }
478
- this.plugin.deny_hooks = { helo: true }
479
- this.connection.results.add(this.plugin, { score: -6 })
480
- this.plugin.should_we_deny(next, this.connection, 'connect')
481
- })
482
- })
483
-
484
- describe('check_result_equal', function () {
485
- beforeEach(_set_up)
486
-
487
- it('equal match is scored', function (done) {
488
- const award = {
489
- id: 1,
490
- award: 2,
491
- operator: 'equals',
492
- value: 'clean',
493
- reason: 'testing',
494
- resolution: 'never',
495
- }
496
- this.plugin.check_result_equal(['clean'], award, this.connection)
497
- assert.equal(this.connection.results.store.karma.score, 2)
498
- assert.equal(this.connection.results.store.karma.awards[0], 1)
499
- done()
500
- })
501
-
502
- it('not equal match is not scored', function (done) {
503
- const award = {
504
- id: 1,
505
- award: 2,
506
- operator: 'equals',
507
- value: 'dirty',
508
- reason: 'testing',
509
- resolution: 'never',
510
- }
511
- this.plugin.check_result_equal(['clean'], award, this.connection)
512
- assert.equal(this.connection.results.store.karma, undefined)
513
- done()
514
- })
515
- })
516
-
517
- describe('check_result_gt', function () {
518
- beforeEach(_set_up)
519
-
520
- it('gt match is scored', function (done) {
521
- const award = {
522
- id: 5,
523
- award: 3,
524
- operator: 'gt',
525
- value: 3,
526
- reason: 'testing',
527
- resolution: 'never',
528
- }
529
- this.plugin.check_result_gt([4], award, this.connection)
530
- // console.log(this.connection.results.store);
531
- assert.equal(this.connection.results.store.karma.score, 3)
532
- assert.equal(this.connection.results.store.karma.awards[0], 5)
533
- done()
534
- })
535
- })
536
-
537
- describe('check_result_lt', function () {
538
- beforeEach(_set_up)
539
-
540
- it('lt match is scored', function (done) {
541
- const award = {
542
- id: 2,
543
- award: 3,
544
- operator: 'lt',
545
- value: 5,
546
- reason: 'testing',
547
- resolution: 'never',
548
- }
549
- this.plugin.check_result_lt([4], award, this.connection)
550
- // console.log(this.connection.results.store);
551
- assert.equal(this.connection.results.store.karma.score, 3)
552
- assert.equal(this.connection.results.store.karma.awards[0], 2)
553
- done()
554
- })
555
-
556
- it('lt match not scored', function (done) {
557
- const award = {
558
- id: 3,
559
- award: 3,
560
- operator: 'lt',
561
- value: 3,
562
- reason: 'testing',
563
- resolution: 'never',
564
- }
565
- this.plugin.check_result_lt([4], award, this.connection)
566
- // console.log(this.connection.results.store);
567
- assert.equal(this.connection.results.store.karma, undefined)
568
- done()
569
- })
570
- })
571
-
572
- describe('check_result_match', function () {
573
- beforeEach(_set_up)
574
-
575
- it('match pattern is scored', function (done) {
576
- const award = {
577
- id: 1,
578
- award: 2,
579
- operator: 'match',
580
- value: 'phish',
581
- reason: 'testing',
582
- resolution: 'never',
583
- }
584
- this.plugin.check_result_match(['isphishing'], award, this.connection)
585
- // console.log(this.connection.results.store);
586
- assert.equal(this.connection.results.store.karma.score, 2)
587
- assert.equal(this.connection.results.store.karma.awards[0], 1)
588
- done()
589
- })
590
-
591
- it('mismatch is not scored', function (done) {
592
- const award = {
593
- id: 1,
594
- award: 2,
595
- operator: 'match',
596
- value: 'dirty',
597
- reason: 'testing',
598
- resolution: 'never',
599
- }
600
- this.plugin.check_result_match(['clean'], award, this.connection)
601
- // console.log(this.connection.results.store);
602
- assert.equal(this.connection.results.store.karma, undefined)
603
- done()
604
- })
605
-
606
- it('FCrDNS match is scored', function (done) {
607
- const award = {
608
- id: 89,
609
- award: 2,
610
- operator: 'match',
611
- value: 'google.com',
612
- reason: 'testing',
613
- resolution: 'never',
614
- }
615
- this.plugin.check_result_match(
616
- ['mail-yk0-f182.google.com'],
617
- award,
618
- this.connection,
619
- )
620
- // console.log(this.connection.results.store);
621
- assert.equal(this.connection.results.store.karma.score, 2)
622
- assert.equal(this.connection.results.store.karma.awards[0], 89)
623
- done()
624
- })
625
- })
626
-
627
- describe('check_result_length', function () {
628
- beforeEach(_set_up)
629
- it('eq pattern is scored', function (done) {
630
- const award = {
631
- id: 1,
632
- award: 2,
633
- operator: 'length',
634
- value: 'eq 3',
635
- reason: 'testing',
636
- resolution: 'hah',
637
- }
638
- this.plugin.check_result_length(['3'], award, this.connection)
639
- // console.log(this.connection.results.store);
640
- assert.equal(this.connection.results.store.karma.score, 2)
641
- assert.equal(this.connection.results.store.karma.awards[0], 1)
642
- done()
643
- })
644
-
645
- it('eq pattern is not scored', function (done) {
646
- const award = {
647
- id: 1,
648
- award: 2,
649
- operator: 'length',
650
- value: 'eq 3',
651
- reason: 'testing',
652
- resolution: 'hah',
653
- }
654
- this.plugin.check_result_length(['4'], award, this.connection)
655
- // console.log(this.connection.results.store.karma);
656
- assert.deepEqual(this.connection.results.store.karma, undefined)
657
- done()
658
- })
659
-
660
- it('gt pattern is scored', function (done) {
661
- const award = {
662
- id: 1,
663
- award: 2,
664
- operator: 'length',
665
- value: 'gt 3',
666
- reason: 'testing',
667
- resolution: 'hah',
668
- }
669
- this.plugin.check_result_length(['5'], award, this.connection)
670
- // console.log(this.connection.results.store);
671
- assert.equal(this.connection.results.store.karma.score, 2)
672
- assert.equal(this.connection.results.store.karma.awards[0], 1)
673
- done()
674
- })
675
-
676
- it('gt pattern is not scored', function (done) {
677
- const award = {
678
- id: 1,
679
- award: 2,
680
- operator: 'length',
681
- value: 'gt 3',
682
- reason: 'testing',
683
- resolution: 'hah',
684
- }
685
- this.plugin.check_result_length(['3'], award, this.connection)
686
- // console.log(this.connection.results.store.karma);
687
- assert.deepEqual(this.connection.results.store.karma, undefined)
688
- done()
689
- })
690
-
691
- it('lt pattern is scored', function (done) {
692
- const award = {
693
- id: 1,
694
- award: 2,
695
- operator: 'length',
696
- value: 'lt 3',
697
- reason: 'testing',
698
- resolution: 'hah',
699
- }
700
- this.plugin.check_result_length(['2'], award, this.connection)
701
- // console.log(this.connection.results.store);
702
- assert.equal(this.connection.results.store.karma.score, 2)
703
- assert.equal(this.connection.results.store.karma.awards[0], 1)
704
- done()
705
- })
706
-
707
- it('lt pattern is not scored', function (done) {
708
- const award = {
709
- id: 1,
710
- award: 2,
711
- operator: 'length',
712
- value: 'lt 3',
713
- reason: 'testing',
714
- resolution: 'hah',
715
- }
716
- this.plugin.check_result_length(['3'], award, this.connection)
717
- // console.log(this.connection.results.store.karma);
718
- assert.deepEqual(this.connection.results.store.karma, undefined)
719
- done()
720
- })
721
- })
722
-
723
- describe('check_result_exists', function () {
724
- beforeEach(_set_up)
725
-
726
- it('exists pattern is scored', function (done) {
727
- const award = {
728
- id: 1,
729
- award: 2,
730
- operator: 'exists',
731
- value: 'any',
732
- reason: 'testing',
733
- resolution: 'high five',
734
- }
735
- this.plugin.check_result_exists(['3'], award, this.connection)
736
- // console.log(this.connection.results.store);
737
- assert.equal(this.connection.results.store.karma.score, 2)
738
- assert.equal(this.connection.results.store.karma.awards[0], 1)
739
- done()
740
- })
741
-
742
- it('not exists pattern is not scored', function (done) {
743
- const award = {
744
- id: 1,
745
- award: 3,
746
- operator: 'exists',
747
- value: '',
748
- reason: 'testing',
749
- resolution: 'misses',
750
- }
751
- this.plugin.check_result_exists([], award, this.connection)
752
- // console.log(this.connection.results.store);
753
- assert.equal(this.connection.results.store.karma, undefined)
754
- assert.equal(this.connection.results.store.karma, undefined)
755
- done()
756
- })
757
- })
758
-
759
- describe('check_result', function () {
760
- beforeEach(_set_up)
761
-
762
- it('geoip country is scored', function (done) {
763
- this.plugin.cfg.result_awards = {
764
- 1: 'geoip | country | equals | CN | 2',
765
- }
766
- this.plugin.preparse_result_awards()
767
- this.connection.results.add({ name: 'geoip' }, { country: 'CN' })
768
- this.plugin.check_result(
769
- this.connection,
770
- '{"plugin":"geoip","result":{"country":"CN"}}',
771
- )
772
- // console.log(this.connection.results.store);
773
- assert.equal(this.connection.results.store.karma.score, 2)
774
- assert.equal(this.connection.results.store.karma.awards[0], 1)
775
- done()
776
- })
777
-
778
- it('dnsbl listing is scored', function (done) {
779
- this.plugin.cfg.result_awards = {
780
- 2: 'dnsbl | fail | equals | dnsbl.sorbs.net | -5',
781
- }
782
- this.plugin.preparse_result_awards()
783
- this.connection.results.add({ name: 'dnsbl' }, { fail: 'dnsbl.sorbs.net' })
784
- this.plugin.check_result(
785
- this.connection,
786
- '{"plugin":"dnsbl","result":{"fail":"dnsbl.sorbs.net"}}',
787
- )
788
- // console.log(this.connection.results.store);
789
- assert.equal(this.connection.results.store.karma.score, -5)
790
- assert.equal(this.connection.results.store.karma.awards[0], 2)
791
- done()
792
- })
793
- })
794
-
795
- describe('check_spammy_tld', function () {
796
- beforeEach(_set_up)
797
-
798
- it('spammy TLD is scored: top', function (done) {
799
- this.plugin.cfg.spammy_tlds = { top: -3 }
800
- const mfrom = new Address('spamy@er7diogt.rrnsale.top')
801
- this.plugin.check_spammy_tld(mfrom, this.connection)
802
- // console.log(this.connection.results.store);
803
- assert.equal(this.connection.results.store.karma.score, -3)
804
- assert.equal(this.connection.results.store.karma.fail[0], 'spammy.TLD')
805
- done()
806
- })
807
-
808
- it('spammy TLD is scored: rocks', function (done) {
809
- this.plugin.cfg.spammy_tlds = { rocks: '-2' }
810
- const mfrom = new Address('spamy@foo.rocks')
811
- this.plugin.check_spammy_tld(mfrom, this.connection)
812
- // console.log(this.connection.results.store);
813
- assert.equal(this.connection.results.store.karma.score, -2)
814
- assert.equal(this.connection.results.store.karma.fail[0], 'spammy.TLD')
815
- done()
816
- })
817
- })
818
-
819
- describe('tls', function () {
820
- beforeEach(_set_up)
821
-
822
- it('unconfigured TLS does nothing', function (done) {
823
- this.connection.tls.enabled = true
824
- const mfrom = new Address('spamy@er7diogt.rrnsale.top')
825
- this.connection.current_line = 'MAIL FROM:<foo@test.com>'
826
- this.plugin.hook_mail(
827
- () => {
828
- assert.equal(this.connection.results.store.karma, undefined)
829
- done()
830
- },
831
- this.connection,
832
- [mfrom],
833
- )
834
- })
835
-
836
- it('TLS is scored', function (done) {
837
- this.plugin.cfg.tls = { set: 2, unset: -4 }
838
- this.connection.tls.enabled = true
839
- const mfrom = new Address('spamy@er7diogt.rrnsale.top')
840
- this.connection.current_line = 'MAIL FROM:<foo@test.com>'
841
- this.plugin.hook_mail(
842
- () => {
843
- // console.log(this.connection.results.store);
844
- assert.equal(this.connection.results.store.karma.score, 2)
845
- done()
846
- },
847
- this.connection,
848
- [mfrom],
849
- )
850
- })
851
-
852
- it('no TLS is scored', function (done) {
853
- this.plugin.cfg.tls = { set: 2, unset: -4 }
854
- this.connection.tls.enabled = false
855
- const mfrom = new Address('spamy@er7diogt.rrnsale.top')
856
- this.connection.current_line = 'MAIL FROM:<foo@test.com>'
857
- this.plugin.hook_mail(
858
- () => {
859
- // console.log(this.connection.results.store);
860
- assert.equal(this.connection.results.store.karma.score, -4)
861
- done()
862
- },
863
- this.connection,
864
- [mfrom],
865
- )
866
- })
867
- })
868
-
869
- describe('skipping hooks', function () {
870
- beforeEach(_set_up)
871
-
872
- it('notes.disable_karma', function (done) {
873
- function next(rc) {
874
- assert.equal(undefined, rc)
875
- }
876
- function last(rc) {
877
- assert.equal(undefined, rc)
878
- done()
879
- }
880
- this.connection.notes.disable_karma = true
881
-
882
- this.plugin.hook_deny(next, this.connection)
883
- this.plugin.hook_connect(next, this.connection)
884
- this.plugin.hook_ehlo(next, this.connection)
885
- this.plugin.hook_vrfy(next, this.connection)
886
- this.plugin.hook_noop(next, this.connection)
887
- this.plugin.hook_data(next, this.connection)
888
- this.plugin.hook_queue(next, this.connection)
889
- this.plugin.hook_reset_transaction(next, this.connection)
890
- this.plugin.hook_unrecognized_command(last, this.connection)
891
- })
892
-
893
- it('private skip', function (done) {
894
- function next(rc) {
895
- assert.equal(undefined, rc)
896
- }
897
- function last(rc) {
898
- assert.equal(undefined, rc)
899
- done()
900
- }
901
- this.connection.remote.is_private = true
902
-
903
- this.plugin.hook_deny(next, this.connection)
904
- this.plugin.hook_connect(next, this.connection)
905
- this.plugin.hook_ehlo(next, this.connection)
906
- this.plugin.hook_vrfy(next, this.connection)
907
- this.plugin.hook_noop(next, this.connection)
908
- this.plugin.hook_data(next, this.connection)
909
- this.plugin.hook_queue(next, this.connection)
910
- this.plugin.hook_reset_transaction(next, this.connection)
911
- this.plugin.hook_unrecognized_command(last, this.connection)
912
- })
913
- })