haraka-plugin-karma 2.0.1 → 2.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.
- package/.gitmodules +3 -0
- package/Changes.md +30 -15
- package/index.js +33 -25
- package/package.json +3 -2
- package/test/karma.js +1 -1
package/.gitmodules
ADDED
package/Changes.md
CHANGED
|
@@ -1,84 +1,99 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
#### N.N.N - YYYY-MM-DD
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
#### 2.0.4 - 2022-05-28
|
|
6
|
+
|
|
7
|
+
- use .release as submodule
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#### 2.0.3 - 2022-05-28
|
|
11
|
+
|
|
12
|
+
- fix: depend directly on redis
|
|
13
|
+
- fix: update redis command names for v4 compatibility
|
|
14
|
+
- fix: update redis commands to be async
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
#### 2.0.1 - 2022-05-27
|
|
3
18
|
|
|
4
19
|
- chore(ci): depend on shared GHA workflows
|
|
5
20
|
|
|
6
21
|
|
|
7
|
-
|
|
22
|
+
#### 2.0.0 - 2022-03-29
|
|
8
23
|
|
|
9
24
|
- remove lots of plugin=this
|
|
10
25
|
- remove unnecessary braces and trailing ;
|
|
11
26
|
- some promises.
|
|
12
27
|
|
|
13
28
|
|
|
14
|
-
|
|
29
|
+
#### 1.0.14 - 2022-02-14
|
|
15
30
|
|
|
16
31
|
- try to unsubscribe in case connection is marked to skip during transaction
|
|
17
32
|
|
|
18
33
|
|
|
19
|
-
|
|
34
|
+
#### 1.0.13 - 2019-04-23
|
|
20
35
|
|
|
21
36
|
- add 'exists' pattern
|
|
22
37
|
|
|
23
38
|
|
|
24
|
-
|
|
39
|
+
#### 1.0.12 - 2019-03-08
|
|
25
40
|
|
|
26
41
|
- don't interfere with STARTLS and AUTH when karma is listed above those plugins in config/plugins
|
|
27
42
|
|
|
28
43
|
|
|
29
|
-
|
|
44
|
+
#### 1.0.11 - 2017-10-25
|
|
30
45
|
|
|
31
46
|
- private addresses and flagged connections exemption
|
|
32
47
|
|
|
33
48
|
|
|
34
|
-
|
|
49
|
+
#### 1.0.10 - 2017-08-30
|
|
35
50
|
|
|
36
51
|
- add TLS awards #19
|
|
37
52
|
|
|
38
53
|
|
|
39
|
-
|
|
54
|
+
#### 1.0.9 - 2017-07-29
|
|
40
55
|
|
|
41
56
|
- splash on some es6
|
|
42
57
|
- add AppVeyor CI testing
|
|
43
58
|
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
#### 1.0.8 - 2017-06-26
|
|
46
61
|
|
|
47
62
|
- revert #9, it breaks current Haraka deployments
|
|
48
63
|
|
|
49
64
|
|
|
50
|
-
|
|
65
|
+
#### 1.0.7 - 2017-06-16
|
|
51
66
|
|
|
52
67
|
- update for eslint 4 compat
|
|
53
68
|
- Add results_redis_publish=true for haraka-results changes #9
|
|
54
69
|
|
|
55
70
|
|
|
56
|
-
|
|
71
|
+
#### 1.0.6 - 2017-05-04
|
|
57
72
|
|
|
58
73
|
- emit error if redis plugin didn't create connection
|
|
59
74
|
|
|
60
75
|
|
|
61
|
-
|
|
76
|
+
#### 1.0.5 - 2017-02-06
|
|
62
77
|
|
|
63
78
|
- move merge_redis_ini into load_karma_ini, so it also gets applied
|
|
64
79
|
after a karma.ini change
|
|
65
80
|
- skip redis operations when no connection exists
|
|
66
81
|
|
|
67
82
|
|
|
68
|
-
|
|
83
|
+
#### 1.0.4 - 2017-01-29
|
|
69
84
|
|
|
70
85
|
- use the new haraka-plugin-redis
|
|
71
86
|
- remove exceptions for soft denials. This makes denial time simpler.
|
|
72
87
|
- rules updates
|
|
73
88
|
|
|
74
89
|
|
|
75
|
-
|
|
90
|
+
#### 1.0.3 - 2017-01-27
|
|
76
91
|
|
|
77
92
|
- add rule #280 for known-senders
|
|
78
93
|
- add support for 'length' type, with eq, gt, and lt operators
|
|
79
94
|
- use shared haraka-eslint
|
|
80
95
|
|
|
81
96
|
|
|
82
|
-
|
|
97
|
+
#### 1.0.2 - 2017-01-24
|
|
83
98
|
|
|
84
99
|
- use redis.merge_redis_ini()
|
package/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// karma - reward good and penalize bad mail senders
|
|
3
3
|
|
|
4
4
|
const constants = require('haraka-constants')
|
|
5
|
+
const redis = require('redis')
|
|
5
6
|
const utils = require('haraka-utils')
|
|
6
7
|
|
|
7
8
|
const phase_prefixes = utils.to_object([
|
|
@@ -104,8 +105,16 @@ exports.results_init = async function (next, connection) {
|
|
|
104
105
|
|
|
105
106
|
if (!this.result_awards) return next() // not configured
|
|
106
107
|
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
if (connection.notes.redis) {
|
|
109
|
+
connection.logdebug(this, `redis already subscribed`)
|
|
110
|
+
return // another plugin has already called this.
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
connection.notes.redis = redis.createClient(this.redisCfg.pubsub)
|
|
114
|
+
await connection.notes.redis.connect()
|
|
115
|
+
|
|
116
|
+
const pattern = this.get_redis_sub_channel(connection)
|
|
117
|
+
connection.notes.redis.pSubscribe(pattern, (message) => {
|
|
109
118
|
this.check_result(connection, message)
|
|
110
119
|
})
|
|
111
120
|
|
|
@@ -543,22 +552,18 @@ exports.ip_history_from_redis = function (next, connection) {
|
|
|
543
552
|
// redis plugin is emitting errors, no need to here
|
|
544
553
|
if (!plugin.db) return next()
|
|
545
554
|
|
|
546
|
-
plugin.db.
|
|
547
|
-
if (err) {
|
|
548
|
-
connection.results.add(plugin, { err })
|
|
549
|
-
return next()
|
|
550
|
-
}
|
|
551
|
-
|
|
555
|
+
plugin.db.hGetAll(dbkey).then(dbr => {
|
|
552
556
|
if (dbr === null) {
|
|
553
557
|
plugin.init_ip(dbkey, connection.remote.ip, expire)
|
|
554
558
|
return next()
|
|
555
559
|
}
|
|
556
560
|
|
|
557
561
|
plugin.db.multi()
|
|
558
|
-
.
|
|
562
|
+
.hIncrBy(dbkey, 'connections', 1) // increment total conn
|
|
559
563
|
.expire(dbkey, expire) // extend expiration
|
|
560
|
-
.exec(
|
|
561
|
-
|
|
564
|
+
.exec()
|
|
565
|
+
.catch(err => {
|
|
566
|
+
connection.results.add(plugin, { err })
|
|
562
567
|
})
|
|
563
568
|
|
|
564
569
|
const results = {
|
|
@@ -580,8 +585,13 @@ exports.ip_history_from_redis = function (next, connection) {
|
|
|
580
585
|
connection.results.add(plugin, results)
|
|
581
586
|
|
|
582
587
|
plugin.check_awards(connection)
|
|
583
|
-
|
|
588
|
+
next()
|
|
584
589
|
})
|
|
590
|
+
.catch(err => {
|
|
591
|
+
connection.results.add(plugin, { err })
|
|
592
|
+
next()
|
|
593
|
+
})
|
|
594
|
+
|
|
585
595
|
}
|
|
586
596
|
|
|
587
597
|
exports.hook_mail = function (next, connection, params) {
|
|
@@ -665,10 +675,10 @@ exports.increment = function (connection, key, val) {
|
|
|
665
675
|
const plugin = this
|
|
666
676
|
if (!plugin.db) return
|
|
667
677
|
|
|
668
|
-
plugin.db.
|
|
678
|
+
plugin.db.hIncrBy(`karma|${connection.remote.ip}`, key, 1)
|
|
669
679
|
|
|
670
680
|
const asnkey = plugin.get_asn_key(connection)
|
|
671
|
-
if (asnkey) plugin.db.
|
|
681
|
+
if (asnkey) plugin.db.hIncrBy(asnkey, key, 1)
|
|
672
682
|
}
|
|
673
683
|
|
|
674
684
|
exports.hook_disconnect = function (next, connection) {
|
|
@@ -930,19 +940,14 @@ exports.check_asn = function (connection, asnkey) {
|
|
|
930
940
|
|
|
931
941
|
if (this.cfg.asn.report_as) report_as.name = this.cfg.asn.report_as
|
|
932
942
|
|
|
933
|
-
this.db.
|
|
934
|
-
if (err) {
|
|
935
|
-
connection.results.add(this, { err })
|
|
936
|
-
return
|
|
937
|
-
}
|
|
938
|
-
|
|
943
|
+
this.db.hGetAll(asnkey).then(res => {
|
|
939
944
|
if (res === null) {
|
|
940
945
|
const expire = (this.cfg.redis.expire_days || 60) * 86400 // days
|
|
941
946
|
this.init_asn(asnkey, expire)
|
|
942
947
|
return
|
|
943
948
|
}
|
|
944
949
|
|
|
945
|
-
this.db.
|
|
950
|
+
this.db.hIncrBy(asnkey, 'connections', 1)
|
|
946
951
|
const asn_score = parseInt(res.good || 0) - (res.bad || 0)
|
|
947
952
|
const asn_results = {
|
|
948
953
|
asn_score,
|
|
@@ -970,12 +975,15 @@ exports.check_asn = function (connection, asnkey) {
|
|
|
970
975
|
|
|
971
976
|
connection.results.add(report_as, asn_results)
|
|
972
977
|
})
|
|
978
|
+
.catch(err => {
|
|
979
|
+
connection.results.add(this, { err })
|
|
980
|
+
})
|
|
973
981
|
}
|
|
974
982
|
|
|
975
|
-
exports.init_ip = function (dbkey, rip, expire) {
|
|
983
|
+
exports.init_ip = async function (dbkey, rip, expire) {
|
|
976
984
|
if (!this.db) return
|
|
977
|
-
this.db.multi()
|
|
978
|
-
.
|
|
985
|
+
await this.db.multi()
|
|
986
|
+
.hmSet(dbkey, {'bad': 0, 'good': 0, 'connections': 1})
|
|
979
987
|
.expire(dbkey, expire)
|
|
980
988
|
.exec()
|
|
981
989
|
}
|
|
@@ -992,7 +1000,7 @@ exports.init_asn = function (asnkey, expire) {
|
|
|
992
1000
|
const plugin = this
|
|
993
1001
|
if (!plugin.db) return
|
|
994
1002
|
plugin.db.multi()
|
|
995
|
-
.
|
|
1003
|
+
.hmSet(asnkey, {'bad': 0, 'good': 0, 'connections': 1})
|
|
996
1004
|
.expire(asnkey, expire * 2) // keep ASN longer
|
|
997
1005
|
.exec()
|
|
998
1006
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "haraka-plugin-karma",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "A heuristics scoring and reputation engine for SMTP connections",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"address-rfc2821": "*",
|
|
27
27
|
"haraka-constants": ">=1.0.2",
|
|
28
28
|
"haraka-utils": "*",
|
|
29
|
-
"haraka-plugin-redis": "2"
|
|
29
|
+
"haraka-plugin-redis": "2",
|
|
30
|
+
"redis": "4"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"eslint": "8",
|