logstash-codec-cef 2.0.3 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b07e21611300d4682e481db32cb96f37e5f8b659
4
- data.tar.gz: 52ca214b4b2e0623bf45902113d02f1986cbb235
3
+ metadata.gz: 8d9084e0831538c85ddcabe642a00db46b22e08d
4
+ data.tar.gz: 9de28cadc061797c5b65b0107ef46ccf1b2868a0
5
5
  SHA512:
6
- metadata.gz: 77353440739c5fda71c5cc410457a37ab40f5d5a00ceb48d690f11ea605a44741b4b38b75bffa23badb42b05316cd2fb9d721da3c4d117e582d6f7c333629884
7
- data.tar.gz: 927f654424f3f19ca954fd465573b7c26170e2195f562c52338a3e737a788078c6ea7b71bd67644ea83001c00824ea63de9e1b9f1c8210d21ea07e8d7c4bfc3e
6
+ metadata.gz: b7a357ac86677710e8da105eabe837498595a58d4e75867447f85e0e0a8fe1144d60735a8edd1ca3c2484624c1d3aeb2fa9a5b82b686044a4b16b44ca6aeeb4f
7
+ data.tar.gz: bdb89985dd333aa2e1fa82eba3fdc22026a8d1e06404d2ba74b54f05b2ec1e142a7610971fe1473463735133e5dbdacd17e3b0762ae97a293087fd058b1bd329
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 2.1.0
2
+ - Implements `encode` with escaping according to the [CEF specification](https://protect724.hp.com/docs/DOC-1072).
3
+ - Config option `sev` is deprecated, use `severity` instead.
4
+
1
5
  ## 2.0.0
2
6
  - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
3
7
  instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
data/CONTRIBUTORS CHANGED
@@ -11,6 +11,7 @@ Contributors:
11
11
  * Pete Fritchman (fetep)
12
12
  * Pier-Hugues Pellerin (ph)
13
13
  * Karl Stoney (Stono)
14
+ * Lucas Bremgartner (breml)
14
15
 
15
16
  Note: If you've sent us patches, bug reports, or otherwise contributed to
16
17
  Logstash, and you aren't on the list above and want to be, please let us know
@@ -1,12 +1,53 @@
1
+ # encoding: utf-8
1
2
  require "logstash/codecs/base"
3
+ require "json"
2
4
 
3
5
  class LogStash::Codecs::CEF < LogStash::Codecs::Base
6
+ # Implementation of a Logstash codec for the ArcSight Common Event Format (CEF)
7
+ # Based on Revision 20 of Implementing ArcSight CEF, dated from June 05, 2013
8
+ # https://protect724.hp.com/servlet/JiveServlet/downloadBody/1072-102-6-4697/CommonEventFormat.pdf
4
9
  config_name "cef"
10
+
11
+ # Device vendor field in CEF header. The new value can include `%{foo}` strings
12
+ # to help you build a new value from other parts of the event.
13
+ config :vendor, :validate => :string, :default => "Elasticsearch"
14
+
15
+ # Device product field in CEF header. The new value can include `%{foo}` strings
16
+ # to help you build a new value from other parts of the event.
17
+ config :product, :validate => :string, :default => "Logstash"
18
+
19
+ # Device version field in CEF header. The new value can include `%{foo}` strings
20
+ # to help you build a new value from other parts of the event.
21
+ config :version, :validate => :string, :default => "1.0"
22
+
23
+ # Signature ID field in CEF header. The new value can include `%{foo}` strings
24
+ # to help you build a new value from other parts of the event.
5
25
  config :signature, :validate => :string, :default => "Logstash"
26
+
27
+ # Name field in CEF header. The new value can include `%{foo}` strings
28
+ # to help you build a new value from other parts of the event.
6
29
  config :name, :validate => :string, :default => "Logstash"
7
- config :sev, :validate => :number, :default => 6
8
30
 
9
- config :fields, :validate => :array
31
+ # Deprecated severity field for CEF header. The new value can include `%{foo}` strings
32
+ # to help you build a new value from other parts of the event.
33
+ #
34
+ # This field is used only if :severity is unchanged set to the default value.
35
+ #
36
+ # Defined as field of type string to allow sprintf. The value will be validated
37
+ # to be an integer in the range from 0 to 10 (including).
38
+ # All invalid values will be mapped to the default of 6.
39
+ config :sev, :validate => :string, :default => "6", :deprecated => "This setting is being deprecated, use :severity instead."
40
+
41
+ # Severity field in CEF header. The new value can include `%{foo}` strings
42
+ # to help you build a new value from other parts of the event.
43
+ #
44
+ # Defined as field of type string to allow sprintf. The value will be validated
45
+ # to be an integer in the range from 0 to 10 (including).
46
+ # All invalid values will be mapped to the default of 6.
47
+ config :severity, :validate => :string, :default => "6"
48
+
49
+ # Fields to be included in CEV extension part as key/value pairs
50
+ config :fields, :validate => :array, :default => []
10
51
 
11
52
  public
12
53
  def initialize(params={})
@@ -57,28 +98,118 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
57
98
  end
58
99
 
59
100
  public
60
- def encode(data)
101
+ def encode(event)
61
102
  # "CEF:0|Elasticsearch|Logstash|1.0|Signature|Name|Sev|"
62
103
 
63
- # TODO: Need to check that fields are set!
104
+ vendor = sanitize_header_field(event.sprintf(@vendor))
105
+ vendor = self.class.get_config["vendor"][:default] if vendor == ""
106
+
107
+ product = sanitize_header_field(event.sprintf(@product))
108
+ product = self.class.get_config["product"][:default] if product == ""
109
+
110
+ version = sanitize_header_field(event.sprintf(@version))
111
+ version = self.class.get_config["version"][:default] if version == ""
112
+
113
+ signature = sanitize_header_field(event.sprintf(@signature))
114
+ signature = self.class.get_config["signature"][:default] if signature == ""
115
+
116
+ name = sanitize_header_field(event.sprintf(@name))
117
+ name = self.class.get_config["name"][:default] if name == ""
118
+
119
+ # :sev is deprecated and therefore only considered if :severity equals the default setting or is invalid
120
+ severity = sanitize_severity(event, @severity)
121
+ if severity == self.class.get_config["severity"][:default]
122
+ # Use deprecated setting sev
123
+ severity = sanitize_severity(event, @sev)
124
+ end
64
125
 
65
- # Signature, Name, and Sev should be set in the config, with ref to fields
66
126
  # Should also probably set the fields sent
67
- header = ["CEF:0", "Elasticsearch", "Logstash", "1.0", @signature, @name, @sev].join("|")
68
- values = @fields.map {|name| get_value(name, data)}.join(" ")
69
- # values = values.map {|k,v| "#{k}=#{v}"}.join(" ")
70
- @on_event.call(header + " " + values + "\n")
127
+ header = ["CEF:0", vendor, product, version, signature, name, severity].join("|")
128
+ values = @fields.map {|fieldname| get_value(fieldname, event)}.compact.join(" ")
129
+
130
+ @on_event.call(event, "#{header}|#{values}\n")
71
131
  end
72
132
 
73
133
  private
74
- def get_value(name, event)
75
- val = event[name]
134
+
135
+ # Escape pipes and backslashes in the header. Equal signs are ok.
136
+ # Newlines are forbidden.
137
+ def sanitize_header_field(value)
138
+ output = ""
139
+
140
+ value = value.to_s.gsub(/\r\n/, "\n")
141
+
142
+ value.each_char{|c|
143
+ case c
144
+ when "\\", "|"
145
+ output += "\\" + c
146
+ when "\n", "\r"
147
+ output += " "
148
+ else
149
+ output += c
150
+ end
151
+ }
152
+
153
+ return output
154
+ end
155
+
156
+ # Keys must be made up of a single word, with no spaces
157
+ # must be alphanumeric
158
+ def sanitize_extension_key(value)
159
+ value = value.to_s.gsub(/[^a-zA-Z0-9]/, "")
160
+ return value
161
+ end
162
+
163
+ # Escape equal signs in the extensions. Canonicalize newlines.
164
+ # CEF spec leaves it up to us to choose \r or \n for newline.
165
+ # We choose \n as the default.
166
+ def sanitize_extension_val(value)
167
+ output = ""
168
+
169
+ value = value.to_s.gsub(/\r\n/, "\n")
170
+
171
+ value.each_char{|c|
172
+ case c
173
+ when "\\", "="
174
+ output += "\\" + c
175
+ when "\n", "\r"
176
+ output += "\\n"
177
+ else
178
+ output += c
179
+ end
180
+ }
181
+
182
+ return output
183
+ end
184
+
185
+ def get_value(fieldname, event)
186
+ val = event[fieldname]
187
+
188
+ return nil if val.nil?
189
+
76
190
  case val
77
- when Hash
78
- return name + "=" + val.to_json
191
+ when Array, Hash
192
+ return "#{sanitize_extension_key(fieldname)}=#{sanitize_extension_val(val.to_json)}"
193
+ when LogStash::Timestamp
194
+ return "#{sanitize_extension_key(fieldname)}=#{val.to_s}"
79
195
  else
80
- return name + "=" + val
196
+ return "#{sanitize_extension_key(fieldname)}=#{sanitize_extension_val(val)}"
81
197
  end
82
198
  end
83
199
 
200
+ def sanitize_severity(event, severity)
201
+ severity = sanitize_header_field(event.sprintf(severity)).strip
202
+ severity = self.class.get_config["severity"][:default] unless valid_severity?(severity)
203
+ severity = severity.to_i.to_s
204
+ end
205
+
206
+ def valid_severity?(sev)
207
+ f = Float(sev)
208
+ # check if it's an integer or a float with no remainder
209
+ # and if the value is between 0 and 10 (inclusive)
210
+ (f % 1 == 0) && f.between?(0,10)
211
+ rescue TypeError, ArgumentError
212
+ false
213
+ end
214
+
84
215
  end
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-codec-cef'
4
- s.version = '2.0.3'
4
+ s.version = '2.1.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
- s.summary = "CEF codec to parse CEF formated logs"
6
+ s.summary = "CEF codec to parse and encode CEF formated logs"
7
7
  s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
8
8
  s.authors = ["Elastic"]
9
9
  s.email = 'info@elastic.co'
@@ -10,7 +10,301 @@ describe LogStash::Codecs::CEF do
10
10
  end
11
11
 
12
12
  context "#encode" do
13
- it "should assert all header fields are present"
13
+ subject(:codec) { LogStash::Codecs::CEF.new }
14
+
15
+ let(:results) { [] }
16
+
17
+ it "should not fail if fields is nil" do
18
+ codec.on_event{|data, newdata| results << newdata}
19
+ event = LogStash::Event.new("foo" => "bar")
20
+ codec.encode(event)
21
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|$/m)
22
+ end
23
+
24
+ it "should assert all header fields are present" do
25
+ codec.on_event{|data, newdata| results << newdata}
26
+ codec.fields = []
27
+ event = LogStash::Event.new("foo" => "bar")
28
+ codec.encode(event)
29
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|$/m)
30
+ end
31
+
32
+ it "should use default values for empty header fields" do
33
+ codec.on_event{|data, newdata| results << newdata}
34
+ codec.vendor = ""
35
+ codec.product = ""
36
+ codec.version = ""
37
+ codec.signature = ""
38
+ codec.name = ""
39
+ codec.severity = ""
40
+ codec.fields = []
41
+ event = LogStash::Event.new("foo" => "bar")
42
+ codec.encode(event)
43
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|$/m)
44
+ end
45
+
46
+ it "should use configured values for header fields" do
47
+ codec.on_event{|data, newdata| results << newdata}
48
+ codec.vendor = "vendor"
49
+ codec.product = "product"
50
+ codec.version = "2.0"
51
+ codec.signature = "signature"
52
+ codec.name = "name"
53
+ codec.severity = "1"
54
+ codec.fields = []
55
+ event = LogStash::Event.new("foo" => "bar")
56
+ codec.encode(event)
57
+ expect(results.first).to match(/^CEF:0\|vendor\|product\|2.0\|signature\|name\|1\|$/m)
58
+ end
59
+
60
+ it "should use sprintf for header fields" do
61
+ codec.on_event{|data, newdata| results << newdata}
62
+ codec.vendor = "%{vendor}"
63
+ codec.product = "%{product}"
64
+ codec.version = "%{version}"
65
+ codec.signature = "%{signature}"
66
+ codec.name = "%{name}"
67
+ codec.severity = "%{severity}"
68
+ codec.fields = []
69
+ event = LogStash::Event.new("vendor" => "vendor", "product" => "product", "version" => "2.0", "signature" => "signature", "name" => "name", "severity" => "1")
70
+ codec.encode(event)
71
+ expect(results.first).to match(/^CEF:0\|vendor\|product\|2.0\|signature\|name\|1\|$/m)
72
+ end
73
+
74
+ it "should use default, if severity is not numeric" do
75
+ codec.on_event{|data, newdata| results << newdata}
76
+ codec.severity = "foo"
77
+ codec.fields = []
78
+ event = LogStash::Event.new("foo" => "bar")
79
+ codec.encode(event)
80
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|$/m)
81
+ end
82
+
83
+ it "should use default, if severity is > 10" do
84
+ codec.on_event{|data, newdata| results << newdata}
85
+ codec.severity = "11"
86
+ codec.fields = []
87
+ event = LogStash::Event.new("foo" => "bar")
88
+ codec.encode(event)
89
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|$/m)
90
+ end
91
+
92
+ it "should use default, if severity is < 0" do
93
+ codec.on_event{|data, newdata| results << newdata}
94
+ codec.severity = "-1"
95
+ codec.fields = []
96
+ event = LogStash::Event.new("foo" => "bar")
97
+ codec.encode(event)
98
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|$/m)
99
+ end
100
+
101
+ it "should use default, if severity is float with decimal part" do
102
+ codec.on_event{|data, newdata| results << newdata}
103
+ codec.severity = "5.4"
104
+ codec.fields = []
105
+ event = LogStash::Event.new("foo" => "bar")
106
+ codec.encode(event)
107
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|$/m)
108
+ end
109
+
110
+ it "should append fields as key/value pairs in cef extension part" do
111
+ codec.on_event{|data, newdata| results << newdata}
112
+ codec.fields = [ "foo", "bar" ]
113
+ event = LogStash::Event.new("foo" => "foo value", "bar" => "bar value")
114
+ codec.encode(event)
115
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|foo=foo value bar=bar value$/m)
116
+ end
117
+
118
+ it "should ignore fields in fields if not present in event" do
119
+ codec.on_event{|data, newdata| results << newdata}
120
+ codec.fields = [ "foo", "bar", "baz" ]
121
+ event = LogStash::Event.new("foo" => "foo value", "baz" => "baz value")
122
+ codec.encode(event)
123
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|foo=foo value baz=baz value$/m)
124
+ end
125
+
126
+ it "should sanitize header fields" do
127
+ codec.on_event{|data, newdata| results << newdata}
128
+ codec.vendor = "ven\ndor"
129
+ codec.product = "pro|duct"
130
+ codec.version = "ver\\sion"
131
+ codec.signature = "sig\r\nnature"
132
+ codec.name = "na\rme"
133
+ codec.severity = "4\n"
134
+ codec.fields = []
135
+ event = LogStash::Event.new("foo" => "bar")
136
+ codec.encode(event)
137
+ expect(results.first).to match(/^CEF:0\|ven dor\|pro\\\|duct\|ver\\\\sion\|sig nature\|na me\|4\|$/m)
138
+ end
139
+
140
+ it "should sanitize extension keys" do
141
+ codec.on_event{|data, newdata| results << newdata}
142
+ codec.fields = [ "f o\no", "@b-a_r" ]
143
+ event = LogStash::Event.new("f o\no" => "foo value", "@b-a_r" => "bar value")
144
+ codec.encode(event)
145
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|foo=foo value bar=bar value$/m)
146
+ end
147
+
148
+ it "should sanitize extension values" do
149
+ codec.on_event{|data, newdata| results << newdata}
150
+ codec.fields = [ "foo", "bar", "baz" ]
151
+ event = LogStash::Event.new("foo" => "foo\\value\n", "bar" => "bar=value\r")
152
+ codec.encode(event)
153
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|foo=foo\\\\value\\n bar=bar\\=value\\n$/m)
154
+ end
155
+
156
+ it "should encode a hash value" do
157
+ codec.on_event{|data, newdata| results << newdata}
158
+ codec.fields = [ "foo" ]
159
+ event = LogStash::Event.new("foo" => { "bar" => "bar value", "baz" => "baz value" })
160
+ codec.encode(event)
161
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|foo=\{\"bar\":\"bar value\",\"baz\":\"baz value\"\}$/m)
162
+ end
163
+
164
+ it "should encode an array value" do
165
+ codec.on_event{|data, newdata| results << newdata}
166
+ codec.fields = [ "foo" ]
167
+ event = LogStash::Event.new("foo" => [ "bar", "baz" ])
168
+ codec.encode(event)
169
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|foo=\[\"bar\",\"baz\"\]$/m)
170
+ end
171
+
172
+ it "should encode a hash in an array value" do
173
+ codec.on_event{|data, newdata| results << newdata}
174
+ codec.fields = [ "foo" ]
175
+ event = LogStash::Event.new("foo" => [ { "bar" => "bar value" }, "baz" ])
176
+ codec.encode(event)
177
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|foo=\[\{\"bar\":\"bar value\"\},\"baz\"\]$/m)
178
+ end
179
+
180
+ it "should encode a LogStash::Timestamp" do
181
+ codec.on_event{|data, newdata| results << newdata}
182
+ codec.fields = [ "foo" ]
183
+ event = LogStash::Event.new("foo" => LogStash::Timestamp.new)
184
+ codec.encode(event)
185
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|foo=[0-9TZ.:-]+$/m)
186
+ end
187
+
188
+ it "should use severity (instead of depricated sev), if severity is set)" do
189
+ codec.on_event{|data, newdata| results << newdata}
190
+ codec.sev = "4"
191
+ codec.severity = "5"
192
+ codec.fields = []
193
+ event = LogStash::Event.new("foo" => "bar")
194
+ codec.encode(event)
195
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|5\|$/m)
196
+ end
197
+
198
+ it "should use deprecated sev, if severity is not set (equals default value)" do
199
+ codec.on_event{|data, newdata| results << newdata}
200
+ codec.sev = "4"
201
+ codec.fields = []
202
+ event = LogStash::Event.new("foo" => "bar")
203
+ codec.encode(event)
204
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|4\|$/m)
205
+ end
206
+
207
+ it "should use deprecated sev, if severity is explicitly set to default value)" do
208
+ codec.on_event{|data, newdata| results << newdata}
209
+ codec.sev = "4"
210
+ codec.severity = "6"
211
+ codec.fields = []
212
+ event = LogStash::Event.new("foo" => "bar")
213
+ codec.encode(event)
214
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|4\|$/m)
215
+ end
216
+
217
+ it "should use deprecated sev, if severity is invalid" do
218
+ codec.on_event{|data, newdata| results << newdata}
219
+ codec.sev = "4"
220
+ codec.severity = ""
221
+ codec.fields = []
222
+ event = LogStash::Event.new("foo" => "bar")
223
+ codec.encode(event)
224
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|4\|$/m)
225
+ end
226
+
227
+ it "should use default value, if severity is not set and sev is invalid" do
228
+ codec.on_event{|data, newdata| results << newdata}
229
+ codec.sev = ""
230
+ codec.fields = []
231
+ event = LogStash::Event.new("foo" => "bar")
232
+ codec.encode(event)
233
+ expect(results.first).to match(/^CEF:0\|Elasticsearch\|Logstash\|1.0\|Logstash\|Logstash\|6\|$/m)
234
+ end
235
+ end
236
+
237
+ context "sanitize header field" do
238
+ subject(:codec) { LogStash::Codecs::CEF.new }
239
+
240
+ it "should sanitize" do
241
+ expect(codec.send(:sanitize_header_field, "foo")).to be == "foo"
242
+ expect(codec.send(:sanitize_header_field, "foo\nbar")).to be == "foo bar"
243
+ expect(codec.send(:sanitize_header_field, "foo\rbar")).to be == "foo bar"
244
+ expect(codec.send(:sanitize_header_field, "foo\r\nbar")).to be == "foo bar"
245
+ expect(codec.send(:sanitize_header_field, "foo\r\nbar\r\nbaz")).to be == "foo bar baz"
246
+ expect(codec.send(:sanitize_header_field, "foo\\bar")).to be == "foo\\\\bar"
247
+ expect(codec.send(:sanitize_header_field, "foo|bar")).to be == "foo\\|bar"
248
+ expect(codec.send(:sanitize_header_field, "foo=bar")).to be == "foo=bar"
249
+ expect(codec.send(:sanitize_header_field, 123)).to be == "123" # Input value is a Fixnum
250
+ expect(codec.send(:sanitize_header_field, 123.123)).to be == "123.123" # Input value is a Float
251
+ expect(codec.send(:sanitize_header_field, [])).to be == "[]" # Input value is an Array
252
+ expect(codec.send(:sanitize_header_field, {})).to be == "{}" # Input value is a Hash
253
+ end
254
+ end
255
+
256
+ context "sanitize extension key" do
257
+ subject(:codec) { LogStash::Codecs::CEF.new }
258
+
259
+ it "should sanitize" do
260
+ expect(codec.send(:sanitize_extension_key, " foo ")).to be == "foo"
261
+ expect(codec.send(:sanitize_extension_key, " FOO 123 ")).to be == "FOO123"
262
+ expect(codec.send(:sanitize_extension_key, "foo\nbar\rbaz")).to be == "foobarbaz"
263
+ expect(codec.send(:sanitize_extension_key, "Foo_Bar\r\nBaz")).to be == "FooBarBaz"
264
+ expect(codec.send(:sanitize_extension_key, "foo-@bar=baz")).to be == "foobarbaz"
265
+ expect(codec.send(:sanitize_extension_key, "[foo]|bar.baz")).to be == "foobarbaz"
266
+ expect(codec.send(:sanitize_extension_key, 123)).to be == "123" # Input value is a Fixnum
267
+ expect(codec.send(:sanitize_extension_key, 123.123)).to be == "123123" # Input value is a Float, "." is not allowed and therefore removed
268
+ expect(codec.send(:sanitize_extension_key, [])).to be == "" # Input value is an Array, "[" and "]" are not allowed and therefore removed
269
+ expect(codec.send(:sanitize_extension_key, {})).to be == "" # Input value is a Hash, "{" and "}" are not allowed and therefore removed
270
+ end
271
+ end
272
+
273
+ context "sanitize extension value" do
274
+ subject(:codec) { LogStash::Codecs::CEF.new }
275
+
276
+ it "should sanitize" do
277
+ expect(codec.send(:sanitize_extension_val, "foo")).to be == "foo"
278
+ expect(codec.send(:sanitize_extension_val, "foo\nbar")).to be == "foo\\nbar"
279
+ expect(codec.send(:sanitize_extension_val, "foo\rbar")).to be == "foo\\nbar"
280
+ expect(codec.send(:sanitize_extension_val, "foo\r\nbar")).to be == "foo\\nbar"
281
+ expect(codec.send(:sanitize_extension_val, "foo\r\nbar\r\nbaz")).to be == "foo\\nbar\\nbaz"
282
+ expect(codec.send(:sanitize_extension_val, "foo\\bar")).to be == "foo\\\\bar"
283
+ expect(codec.send(:sanitize_extension_val, "foo|bar")).to be == "foo|bar"
284
+ expect(codec.send(:sanitize_extension_val, "foo=bar")).to be == "foo\\=bar"
285
+ expect(codec.send(:sanitize_extension_val, 123)).to be == "123" # Input value is a Fixnum
286
+ expect(codec.send(:sanitize_extension_val, 123.123)).to be == "123.123" # Input value is a Float
287
+ expect(codec.send(:sanitize_extension_val, [])).to be == "[]" # Input value is an Array
288
+ expect(codec.send(:sanitize_extension_val, {})).to be == "{}" # Input value is a Hash
289
+ end
290
+ end
291
+
292
+ context "valid_severity?" do
293
+ subject(:codec) { LogStash::Codecs::CEF.new }
294
+
295
+ it "should validate severity" do
296
+ expect(codec.send(:valid_severity?, nil)).to be == false
297
+ expect(codec.send(:valid_severity?, "")).to be == false
298
+ expect(codec.send(:valid_severity?, "foo")).to be == false
299
+ expect(codec.send(:valid_severity?, "1.5")).to be == false
300
+ expect(codec.send(:valid_severity?, "-1")).to be == false
301
+ expect(codec.send(:valid_severity?, "11")).to be == false
302
+ expect(codec.send(:valid_severity?, "0")).to be == true
303
+ expect(codec.send(:valid_severity?, "10")).to be == true
304
+ expect(codec.send(:valid_severity?, "1.0")).to be == true
305
+ expect(codec.send(:valid_severity?, 1)).to be == true
306
+ expect(codec.send(:valid_severity?, 1.0)).to be == true
307
+ end
14
308
  end
15
309
 
16
310
  context "#decode" do
metadata CHANGED
@@ -1,18 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-codec-cef
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-19 00:00:00.000000000 Z
11
+ date: 2016-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: logstash-core
15
- version_requirements: !ruby/object:Gem::Requirement
14
+ requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - '>='
18
17
  - !ruby/object:Gem::Version
@@ -20,7 +19,10 @@ dependencies:
20
19
  - - <
21
20
  - !ruby/object:Gem::Version
22
21
  version: 3.0.0
23
- requirement: !ruby/object:Gem::Requirement
22
+ name: logstash-core
23
+ prerelease: false
24
+ type: :runtime
25
+ version_requirements: !ruby/object:Gem::Requirement
24
26
  requirements:
25
27
  - - '>='
26
28
  - !ruby/object:Gem::Version
@@ -28,22 +30,20 @@ dependencies:
28
30
  - - <
29
31
  - !ruby/object:Gem::Version
30
32
  version: 3.0.0
31
- prerelease: false
32
- type: :runtime
33
33
  - !ruby/object:Gem::Dependency
34
- name: logstash-devutils
35
- version_requirements: !ruby/object:Gem::Requirement
34
+ requirement: !ruby/object:Gem::Requirement
36
35
  requirements:
37
36
  - - '>='
38
37
  - !ruby/object:Gem::Version
39
38
  version: '0'
40
- requirement: !ruby/object:Gem::Requirement
39
+ name: logstash-devutils
40
+ prerelease: false
41
+ type: :development
42
+ version_requirements: !ruby/object:Gem::Requirement
41
43
  requirements:
42
44
  - - '>='
43
45
  - !ruby/object:Gem::Version
44
46
  version: '0'
45
- prerelease: false
46
- type: :development
47
47
  description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
48
48
  email: info@elastic.co
49
49
  executables: []
@@ -81,9 +81,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  version: '0'
82
82
  requirements: []
83
83
  rubyforge_project:
84
- rubygems_version: 2.4.8
84
+ rubygems_version: 2.4.5
85
85
  signing_key:
86
86
  specification_version: 4
87
- summary: CEF codec to parse CEF formated logs
87
+ summary: CEF codec to parse and encode CEF formated logs
88
88
  test_files:
89
89
  - spec/codecs/cef_spec.rb