threshold 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/threshold/builder.rb +10 -12
- data/lib/threshold/event_filter.rb +22 -22
- data/lib/threshold/parser.rb +14 -18
- data/lib/threshold/rate_filter.rb +40 -40
- data/lib/threshold/standalone.rb +8 -8
- data/lib/threshold/suppression.rb +30 -30
- data/lib/threshold/thresholds.rb +26 -31
- data/lib/threshold/version.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36f6c07c57491e1ea5e2df998588ceb2ad8227aa
|
4
|
+
data.tar.gz: 7bfb96142322407d7a13160e5a547bbee1c16b83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77ffe5e644c70d8eaef165e2ed17e65f240a64140b541dc74bbef0395c62a4bff29136ed704732e1c626b843fa37aac5bdd98df9033e4f8d44ed0799b3f70b60
|
7
|
+
data.tar.gz: 36762c4b6b745632bcccb94bc2fcb97763a53dc43feff54fe54ae42178c8887d0cf36a49da405a4620db6c93dc3e96d2f7cc0d073696febadb2bb5c7162ad285
|
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# snort-thresholds
|
2
|
+
|
3
|
+
[![Join the chat at https://gitter.im/shadowbq/snort-thresholds](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shadowbq/snort-thresholds?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
2
4
|
[![Gem Version](https://badge.fury.io/rb/threshold.png)](http://badge.fury.io/rb/threshold)
|
3
5
|
[![Gem](https://img.shields.io/gem/dt/threshold.svg)](http://badge.fury.io/rb/threshold)
|
4
6
|
|
data/lib/threshold/builder.rb
CHANGED
@@ -1,22 +1,20 @@
|
|
1
1
|
module Threshold
|
2
|
-
|
3
2
|
#Returns an Array of Grok Captures from the input file matching Threshold Conf standards
|
4
3
|
class Builder
|
5
|
-
|
4
|
+
def initialize(parsed_data)
|
6
5
|
@parsed_data = parsed_data
|
7
6
|
@parsed_data.reject! {|k,v| v.compact.first == nil }
|
8
7
|
end
|
9
8
|
|
10
9
|
def build
|
11
10
|
#Strip out NIL Stuctures
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
if @parsed_data.key?("SUPPRESSION")
|
12
|
+
return Threshold::Suppression.new(@parsed_data)
|
13
|
+
elsif @parsed_data.key?("RATEFILTER")
|
14
|
+
return Threshold::RateFilter.new(@parsed_data)
|
15
|
+
else @parsed_data.key?("EVENTFILTER")
|
16
|
+
return Threshold::EventFilter.new(@parsed_data)
|
17
|
+
end
|
18
|
+
end
|
20
19
|
end
|
21
|
-
|
22
|
-
end
|
20
|
+
end
|
@@ -48,25 +48,25 @@ module Threshold
|
|
48
48
|
|
49
49
|
# Create an Event Filter validator
|
50
50
|
class EventFilterValidator
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
51
|
+
include Veto.validator
|
52
|
+
|
53
|
+
validates :gid, :presence => true, :integer => true
|
54
|
+
validates :sid, :presence => true, :integer => true
|
55
|
+
validates :type, :presence => true, :inclusion => ['limit', 'threshold', 'both']
|
56
|
+
validates :track_by, :presence => true, :inclusion => ['src', 'dst']
|
57
|
+
validates :count, :presence => true, :integer => true
|
58
|
+
validates :seconds, :presence => true, :integer => true
|
59
|
+
validates :comment, :if => :comment_set?, :format => /^\s*?#.*/
|
60
|
+
|
61
|
+
def comment_set?(entity)
|
62
|
+
entity.comment
|
63
|
+
end
|
64
64
|
|
65
65
|
end
|
66
66
|
|
67
|
-
class EventFilter
|
67
|
+
class EventFilter
|
68
68
|
|
69
|
-
|
69
|
+
attr_accessor :gid, :sid, :type, :track_by, :count, :seconds, :comment
|
70
70
|
|
71
71
|
include Veto.model(EventFilterValidator.new)
|
72
72
|
include Comparable
|
@@ -76,17 +76,17 @@ module Threshold
|
|
76
76
|
transform(line) unless line.empty?
|
77
77
|
end
|
78
78
|
|
79
|
-
|
80
|
-
if self.valid?
|
79
|
+
def to_s(skip = false)
|
80
|
+
if self.valid?
|
81
81
|
if comment?(skip)
|
82
|
-
|
82
|
+
"event_filter gen_id #{@gid}, sig_id #{@sid}, type #{@type}, track by_#{@track_by}, count #{@count}, seconds #{@seconds} #{@comment}"
|
83
83
|
else
|
84
|
-
"event_filter gen_id #{@gid}, sig_id #{@sid}, type #{@type}, track by_#{@track_by}, count #{@count}, seconds #{@seconds}"
|
84
|
+
"event_filter gen_id #{@gid}, sig_id #{@sid}, type #{@type}, track by_#{@track_by}, count #{@count}, seconds #{@seconds}"
|
85
85
|
end
|
86
86
|
else
|
87
87
|
raise InvalidEventFilterObject, 'Event Filter did not validate'
|
88
88
|
end
|
89
|
-
|
89
|
+
end
|
90
90
|
|
91
91
|
def state
|
92
92
|
[@gid, @sid, @type, @track_by, @count, @seconds]
|
@@ -103,7 +103,7 @@ module Threshold
|
|
103
103
|
self.count = result["COUNT"].compact.first.to_i
|
104
104
|
self.seconds = result["SECONDS"].compact.first.to_i
|
105
105
|
if result.key?("COMMENT")
|
106
|
-
self.comment = result["COMMENT"].compact.first.
|
106
|
+
self.comment = result["COMMENT"].compact.first.strip
|
107
107
|
end
|
108
108
|
raise InvalidEventFilterObject unless self.valid?
|
109
109
|
rescue
|
@@ -113,4 +113,4 @@ module Threshold
|
|
113
113
|
|
114
114
|
end
|
115
115
|
|
116
|
-
end
|
116
|
+
end
|
data/lib/threshold/parser.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Threshold
|
2
|
-
|
3
|
-
#Returns an Array of Grok Captures from the input file matching Threshold Conf standards
|
2
|
+
#Returns an Array of Grok Captures from the input file matching Threshold Conf standards
|
4
3
|
class Parser
|
5
4
|
|
6
5
|
attr_reader :caps, :filehash
|
@@ -17,8 +16,7 @@ module Threshold
|
|
17
16
|
|
18
17
|
patterns["SUPPRESSIONOPTIONS"] = ", track %{TRACK}, ip %{IP}"
|
19
18
|
patterns["RATEFILTEROPTIONS"] = ", apply_to %{IPCIDR}"
|
20
|
-
|
21
|
-
patterns["ID"] = '\\d+'
|
19
|
+
patterns["ID"] = '\\d+'
|
22
20
|
patterns["ETYPE"] = "limit|threshold|both"
|
23
21
|
patterns["COUNT"] = "\\d+"
|
24
22
|
patterns["SECONDS"] = "\\d+"
|
@@ -34,25 +32,23 @@ module Threshold
|
|
34
32
|
|
35
33
|
# Remember to call result["GID"].compact because of the PIPE or below in grok compile
|
36
34
|
@grok.compile("^%{SUPPRESSION}|%{EVENTFILTER}|%{RATEFILTER}")
|
37
|
-
|
38
|
-
loadfile(@file)
|
35
|
+
loadfile(@file)
|
39
36
|
end
|
40
37
|
|
41
|
-
private
|
38
|
+
private
|
42
39
|
|
43
40
|
def loadfile(file)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
41
|
+
# FLOCK this and hash it..
|
42
|
+
handler = File.open(file)
|
43
|
+
handler.flock(File::LOCK_EX)
|
44
|
+
handler.each do |line|
|
45
|
+
match = @grok.match(line)
|
46
|
+
@caps << match.captures if match
|
47
|
+
end
|
48
|
+
hash = Digest::MD5.file file
|
49
|
+
handler.close
|
50
|
+
@filehash = hash
|
54
51
|
end
|
55
52
|
|
56
53
|
end
|
57
54
|
end
|
58
|
-
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# configure a new action to take for a specified time when a given rate is
|
3
3
|
# exceeded. Multiple rate filters can be defined on the same rule, in which case
|
4
4
|
# they are evaluated in the order they appear in the configuration file, and the
|
5
|
-
# first applicable action is taken.
|
5
|
+
# first applicable action is taken.
|
6
6
|
|
7
7
|
# Rate filters are used as standalone commands (outside any rule) and have the
|
8
8
|
# following format:
|
@@ -47,7 +47,7 @@
|
|
47
47
|
# destination IP address (indicated by track parameter) determined by
|
48
48
|
# <ip-list>. track by_rule and apply_to may not be used together. Note that
|
49
49
|
# events are generated during the timeout period, even if the rate falls below
|
50
|
-
# the configured limit.
|
50
|
+
# the configured limit.
|
51
51
|
|
52
52
|
|
53
53
|
# Example - allow a maximum of 100 connection attempts per second from any one
|
@@ -69,35 +69,35 @@ module Threshold
|
|
69
69
|
|
70
70
|
# Create a Rate Filter validator
|
71
71
|
class RateFilterValidator
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
72
|
+
include Veto.validator
|
73
|
+
|
74
|
+
validates :gid, :presence => true, :integer => true
|
75
|
+
validates :sid, :presence => true, :integer => true
|
76
|
+
validates :track_by, :presence =>true, :inclusion => ['src', 'dst', 'rule']
|
77
|
+
validates :count, :presence => true, :integer => true
|
78
|
+
validates :seconds, :presence => true, :integer => true
|
79
|
+
validates :new_action, :presence => true, :inclusion => ['alert', 'drop', 'pass', 'log', 'sdrop', 'reject']
|
80
|
+
validates :timeout, :presence => true, :integer => true
|
81
|
+
validates :apply_to, :if => :not_track_by_rule?, :format => /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([1-9]|[1-2][0-9]|3[0-2]))?$/
|
82
|
+
validates :comment, :if => :comment_set?, :format => /^\s*#.*/
|
83
|
+
|
84
|
+
def comment_set?(entity)
|
85
|
+
entity.comment
|
86
|
+
end
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
88
|
+
def not_track_by_rule?(entity)
|
89
|
+
if entity.apply_to == nil
|
90
|
+
entity.track_by == false
|
91
|
+
else
|
92
|
+
entity.track_by != 'rule'
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
96
|
end
|
97
97
|
|
98
|
-
class RateFilter
|
98
|
+
class RateFilter
|
99
99
|
|
100
|
-
|
100
|
+
attr_accessor :gid, :sid, :track_by, :count, :seconds, :new_action, :timeout, :apply_to, :comment
|
101
101
|
|
102
102
|
include Veto.model(RateFilterValidator.new)
|
103
103
|
include Comparable
|
@@ -107,27 +107,27 @@ module Threshold
|
|
107
107
|
transform(line) unless line.empty?
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
def to_s(skip = false)
|
111
111
|
|
112
|
-
if self.valid?
|
113
|
-
|
114
|
-
|
112
|
+
if self.valid?
|
113
|
+
if apply_to == nil then
|
114
|
+
if comment?(skip)
|
115
115
|
"rate_filter gen_id #{@gid}, sig_id #{@sid}, track by_#{@track_by}, count #{@count}, seconds #{@seconds}, new_action #{@new_action}, timeout #{@timeout} #{@comment}"
|
116
|
-
|
116
|
+
else
|
117
117
|
"rate_filter gen_id #{@gid}, sig_id #{@sid}, track by_#{@track_by}, count #{@count}, seconds #{@seconds}, new_action #{@new_action}, timeout #{@timeout}"
|
118
|
-
|
119
|
-
|
120
|
-
|
118
|
+
end
|
119
|
+
else
|
120
|
+
if comment?(skip)
|
121
121
|
"rate_filter gen_id #{@gid}, sig_id #{@sid}, count #{@count}, seconds #{@seconds}, new_action #{@new_action}, timeout #{@timeout} apply_to #{@apply_to} #{@comment}"
|
122
|
-
|
122
|
+
else
|
123
123
|
"rate_filter gen_id #{@gid}, sig_id #{@sid}, count #{@count}, seconds #{@seconds}, new_action #{@new_action}, timeout #{@timeout} apply_to #{@apply_to}"
|
124
|
-
|
125
|
-
|
124
|
+
end
|
125
|
+
end
|
126
126
|
else
|
127
127
|
raise InvalidRateFilterObject, 'Rate Filter did not validate'
|
128
128
|
end
|
129
|
-
|
130
|
-
|
129
|
+
end
|
130
|
+
|
131
131
|
#State does not track comments
|
132
132
|
def state
|
133
133
|
[@gid, @sid, @track_by, @count, @seconds, @new_action, @timeout, @apply_to]
|
@@ -136,7 +136,7 @@ module Threshold
|
|
136
136
|
private
|
137
137
|
|
138
138
|
def transform(result)
|
139
|
-
begin
|
139
|
+
begin
|
140
140
|
self.gid = result["GID"].compact.first.to_i
|
141
141
|
self.sid = result["SID"].compact.first.to_i
|
142
142
|
self.track_by = result["TRACK"].compact.first.split('_')[1]
|
@@ -150,7 +150,7 @@ module Threshold
|
|
150
150
|
self.apply_to = result["IPCIDR"].compact.first
|
151
151
|
end
|
152
152
|
if result.key?("COMMENT")
|
153
|
-
self.comment = result["COMMENT"].compact.first.
|
153
|
+
self.comment = result["COMMENT"].compact.first.strip
|
154
154
|
end
|
155
155
|
raise InvalidRateFilterObject unless self.valid?
|
156
156
|
rescue
|
@@ -160,4 +160,4 @@ module Threshold
|
|
160
160
|
|
161
161
|
end
|
162
162
|
|
163
|
-
end
|
163
|
+
end
|
data/lib/threshold/standalone.rb
CHANGED
@@ -10,7 +10,7 @@ module Threshold
|
|
10
10
|
return true
|
11
11
|
else
|
12
12
|
return false
|
13
|
-
end
|
13
|
+
end
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -28,30 +28,30 @@ module Threshold
|
|
28
28
|
def include?(an0ther)
|
29
29
|
return false unless an0ther.class == self.class
|
30
30
|
|
31
|
-
state.zip(an0ther.state).each{ |item|
|
31
|
+
state.zip(an0ther.state).each{ |item|
|
32
32
|
if !(item[1].nil?)
|
33
|
-
return false unless item[0] == item[1]
|
34
|
-
end
|
33
|
+
return false unless item[0] == item[1]
|
34
|
+
end
|
35
35
|
}
|
36
36
|
|
37
37
|
return true
|
38
|
-
end
|
38
|
+
end
|
39
39
|
|
40
40
|
#Comparable
|
41
41
|
def <=>(anOther)
|
42
42
|
#gid <=> anOther.gid
|
43
43
|
c = self.class.to_s <=> anOther.class.to_s
|
44
|
-
if c == 0 then
|
44
|
+
if c == 0 then
|
45
45
|
d = self.gid <=> anOther.gid
|
46
46
|
if d == 0 then
|
47
47
|
self.sid <=> anOther.sid
|
48
48
|
else
|
49
49
|
return d
|
50
|
-
end
|
50
|
+
end
|
51
51
|
else
|
52
52
|
return c
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
end
|
57
|
-
end
|
57
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
# suppress \
|
3
3
|
# gen_id <gid>, sig_id <sid>
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# suppress \
|
6
6
|
# gen_id <gid>, sig_id <sid>, \
|
7
7
|
# track by_src|by_dst, \
|
@@ -16,32 +16,32 @@ module Threshold
|
|
16
16
|
|
17
17
|
# Create a Suppression validator
|
18
18
|
class SuppressionValidator
|
19
|
-
|
19
|
+
include Veto.validator
|
20
20
|
|
21
|
-
|
21
|
+
validates :comment, :if => :comment_set?, :format => /^\s*?#.*/
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
validates :gid, :presence => true, :integer => true
|
24
|
+
validates :sid, :presence => true, :integer => true
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
validates :track_by, :presence => true, :if => :ip_set?, :inclusion => ['src', 'dst']
|
27
|
+
validates :ip, :presence => true, :if => :track_by_set?, :format => /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([1-9]|[1-2][0-9]|3[0-2]))?$/
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def comment_set?(entity)
|
30
|
+
entity.comment
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
def track_by_set?(entity)
|
34
|
+
entity.track_by
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
def ip_set?(entity)
|
38
|
+
entity.ip
|
39
|
+
end
|
40
40
|
end
|
41
41
|
|
42
|
-
class Suppression
|
42
|
+
class Suppression
|
43
43
|
|
44
|
-
|
44
|
+
attr_accessor :gid, :sid, :track_by, :ip, :comment
|
45
45
|
|
46
46
|
include Veto.model(SuppressionValidator.new)
|
47
47
|
include Comparable
|
@@ -51,25 +51,25 @@ module Threshold
|
|
51
51
|
transform(line) unless line.empty?
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
def to_s(skip = false)
|
55
55
|
if self.valid?
|
56
|
-
|
56
|
+
if track_by == nil then
|
57
57
|
if comment?(skip)
|
58
|
-
|
58
|
+
"suppress gen_id #{@gid}, sig_id #{@sid}#{@comment}"
|
59
59
|
else
|
60
60
|
"suppress gen_id #{@gid}, sig_id #{@sid}"
|
61
|
-
end
|
62
|
-
|
63
|
-
|
61
|
+
end
|
62
|
+
else
|
63
|
+
if comment?(skip)
|
64
64
|
"suppress gen_id #{@gid}, sig_id #{@sid}, track by_#{@track_by}, ip #{@ip} #{@comment}"
|
65
65
|
else
|
66
66
|
"suppress gen_id #{@gid}, sig_id #{@sid}, track by_#{@track_by}, ip #{@ip}"
|
67
|
-
end
|
68
|
-
|
67
|
+
end
|
68
|
+
end
|
69
69
|
else
|
70
70
|
raise InvalidSuppressionObject, 'Suppression did not validate'
|
71
71
|
end
|
72
|
-
|
72
|
+
end
|
73
73
|
|
74
74
|
#State does not track comments
|
75
75
|
def state
|
@@ -79,7 +79,7 @@ module Threshold
|
|
79
79
|
private
|
80
80
|
|
81
81
|
def transform(result)
|
82
|
-
begin
|
82
|
+
begin
|
83
83
|
self.gid = result["GID"].compact.first.to_i
|
84
84
|
self.sid = result["SID"].compact.first.to_i
|
85
85
|
if result.key?("TRACK")
|
@@ -89,7 +89,7 @@ module Threshold
|
|
89
89
|
self.ip = result["IP"].compact.first
|
90
90
|
end
|
91
91
|
if result.key?("COMMENT")
|
92
|
-
self.comment = result["COMMENT"].compact.first.
|
92
|
+
self.comment = result["COMMENT"].compact.first.strip
|
93
93
|
end
|
94
94
|
raise InvalidSuppressionObject unless self.valid?
|
95
95
|
rescue
|
@@ -101,4 +101,4 @@ module Threshold
|
|
101
101
|
|
102
102
|
end
|
103
103
|
|
104
|
-
end
|
104
|
+
end
|
data/lib/threshold/thresholds.rb
CHANGED
@@ -20,8 +20,7 @@ module Threshold
|
|
20
20
|
|
21
21
|
# Write changes to the file
|
22
22
|
def flush
|
23
|
-
|
24
|
-
begin
|
23
|
+
begin
|
25
24
|
valid_existing_file?(@file)
|
26
25
|
raise ReadOnlyThresholdsFile if @readonly
|
27
26
|
hash = current_hash
|
@@ -38,10 +37,10 @@ module Threshold
|
|
38
37
|
end
|
39
38
|
|
40
39
|
stored_hash=current_hash
|
41
|
-
return true
|
40
|
+
return true
|
42
41
|
end
|
43
42
|
|
44
|
-
# Clears current collection and Read in the thresholds.conf file
|
43
|
+
# Clears current collection and Read in the thresholds.conf file
|
45
44
|
def loadfile!
|
46
45
|
@thresholds.clear
|
47
46
|
loadfile
|
@@ -55,16 +54,16 @@ module Threshold
|
|
55
54
|
@stored_hash= results.filehash
|
56
55
|
#puts stored_hash
|
57
56
|
results.caps.each do |result|
|
58
|
-
|
59
|
-
|
57
|
+
builder = Threshold::Builder.new(result)
|
58
|
+
self << builder.build
|
60
59
|
end
|
61
60
|
|
62
61
|
end
|
63
62
|
|
64
63
|
# Check if all objects in the Threshold Instance report .valid?
|
65
64
|
def valid?
|
66
|
-
begin
|
67
|
-
self.each do |threshold|
|
65
|
+
begin
|
66
|
+
self.each do |threshold|
|
68
67
|
if threshold.respond_to?(:valid?)
|
69
68
|
return false unless threshold.valid?
|
70
69
|
else
|
@@ -76,8 +75,7 @@ module Threshold
|
|
76
75
|
return false
|
77
76
|
end
|
78
77
|
end
|
79
|
-
|
80
|
-
# Printer
|
78
|
+
# Printer
|
81
79
|
# Pass (true) to_s to skip the printing of InternalObjects.comment
|
82
80
|
def to_s(skip = false)
|
83
81
|
output = ""
|
@@ -94,8 +92,7 @@ module Threshold
|
|
94
92
|
def stored_hash
|
95
93
|
@stored_hash
|
96
94
|
end
|
97
|
-
|
98
|
-
def to_a
|
95
|
+
def to_a
|
99
96
|
@thresholds
|
100
97
|
end
|
101
98
|
|
@@ -103,8 +100,7 @@ module Threshold
|
|
103
100
|
## Corrected for forwardable due to Core Array returning new Arrays on the methods.
|
104
101
|
|
105
102
|
# Array(@thresholds) Creates a new Array on @threshold.sort so.. direct forwardable delegation fails.
|
106
|
-
|
107
|
-
# Returns a new Threshold Object
|
103
|
+
# Returns a new Threshold Object
|
108
104
|
def sort
|
109
105
|
Thresholds.new(@thresholds.sort)
|
110
106
|
end
|
@@ -121,34 +117,34 @@ module Threshold
|
|
121
117
|
|
122
118
|
# Returns a new Threshold Object
|
123
119
|
def reject(&blk)
|
124
|
-
if block_given?
|
120
|
+
if block_given?
|
125
121
|
Thresholds.new(@thresholds.reject(&blk))
|
126
122
|
else
|
127
123
|
Thresholds.new(@thresholds.reject)
|
128
|
-
end
|
124
|
+
end
|
129
125
|
end
|
130
126
|
|
131
127
|
# Returns a new Threshold Object
|
132
128
|
def select(&blk)
|
133
|
-
if block_given?
|
129
|
+
if block_given?
|
134
130
|
Thresholds.new(@thresholds.select(&blk))
|
135
131
|
else
|
136
132
|
Thresholds.new(@thresholds.select)
|
137
|
-
end
|
133
|
+
end
|
138
134
|
end
|
139
135
|
|
140
136
|
#Uniques by default to printable output
|
141
137
|
# Returns a new Threshold Object
|
142
138
|
def uniq(&blk)
|
143
|
-
if block_given?
|
139
|
+
if block_given?
|
144
140
|
Thresholds.new(@thresholds.uniq(&blk))
|
145
141
|
else
|
146
142
|
Thresholds.new(@thresholds.uniq{ |lineitem| lineitem.to_s(true) })
|
147
|
-
end
|
148
|
-
end
|
143
|
+
end
|
144
|
+
end
|
149
145
|
|
150
146
|
## Complex SET Methods
|
151
|
-
## &(union), | (intersect), + (concat), - (Difference)
|
147
|
+
## &(union), | (intersect), + (concat), - (Difference)
|
152
148
|
|
153
149
|
# + (concat)
|
154
150
|
# Returns a new Threshold Object
|
@@ -161,14 +157,13 @@ module Threshold
|
|
161
157
|
def |(an0ther)
|
162
158
|
Thresholds.new(@thresholds | an0ther.to_a)
|
163
159
|
end
|
164
|
-
|
165
|
-
# & (union)
|
160
|
+
# & (union)
|
166
161
|
# Returns a new Threshold Object
|
167
162
|
def &(an0ther)
|
168
163
|
Thresholds.new(@thresholds & an0ther.to_a)
|
169
164
|
end
|
170
165
|
|
171
|
-
# - (Difference)
|
166
|
+
# - (Difference)
|
172
167
|
# Returns a new Threshold Object
|
173
168
|
def -(an0ther)
|
174
169
|
Thresholds.new(@thresholds - an0ther.to_a)
|
@@ -176,16 +171,16 @@ module Threshold
|
|
176
171
|
|
177
172
|
# Returns a new Threshold Object with just suppressions
|
178
173
|
def suppressions(&blk)
|
179
|
-
if block_given?
|
174
|
+
if block_given?
|
180
175
|
self.suppressions.select(&blk)
|
181
176
|
else
|
182
|
-
|
177
|
+
Thresholds.new(@thresholds.select{|t| t.class.to_s == "Threshold::Suppression"})
|
183
178
|
end
|
184
179
|
end
|
185
180
|
|
186
181
|
# Returns a new Threshold Object with just event_filters
|
187
182
|
def event_filters(&blk)
|
188
|
-
if block_given?
|
183
|
+
if block_given?
|
189
184
|
self.event_filters.select(&blk)
|
190
185
|
else
|
191
186
|
Thresholds.new(@thresholds.select{|t| t.class.to_s == "Threshold::EventFilter"})
|
@@ -194,7 +189,7 @@ module Threshold
|
|
194
189
|
|
195
190
|
# Returns a new Threshold Object with just rate_filters
|
196
191
|
def rate_filters(&blk)
|
197
|
-
if block_given?
|
192
|
+
if block_given?
|
198
193
|
self.rate_filters.select(&blk)
|
199
194
|
else
|
200
195
|
Thresholds.new(@thresholds.select{|t| t.class.to_s == "Threshold::RateFilter"})
|
@@ -209,7 +204,7 @@ module Threshold
|
|
209
204
|
end
|
210
205
|
|
211
206
|
def current_hash
|
212
|
-
file = File.open(@file, 'rb+')
|
207
|
+
file = File.open(@file, 'rb+')
|
213
208
|
file.flock(File::LOCK_EX)
|
214
209
|
hash = Digest::MD5.file @file
|
215
210
|
file.close
|
@@ -227,4 +222,4 @@ module Threshold
|
|
227
222
|
|
228
223
|
|
229
224
|
end
|
230
|
-
end
|
225
|
+
end
|
data/lib/threshold/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Threshold
|
2
|
+
VERSION = '0.2.3'
|
3
|
+
SNORT_VERSION='~>2.9.3'
|
4
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: threshold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shadowbq
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-01
|
12
|
+
date: 2015-05-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: veto
|