threshold 0.2.2 → 0.2.3
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.
- 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
|
+
[](https://gitter.im/shadowbq/snort-thresholds?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
2
4
|
[](http://badge.fury.io/rb/threshold)
|
3
5
|
[](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
|