logstash-codec-cef 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 287752d7fdba67aa7b4b3b3d5e484c510f41566a
4
- data.tar.gz: 02fa53c9ab7b704672f587b50bad646791c1f26b
3
+ metadata.gz: 01d1c0ba310055e838ee41c651075e1aa1ee7189
4
+ data.tar.gz: 6f05794989c0ed626c67aa95ef4d81fbbbb046d7
5
5
  SHA512:
6
- metadata.gz: 1649c71394718505fdde40f51e861c818951ca68a58f242ebaf697bc95b7ebe9a1b9ce198defe95e5ee65317741dc09a0838e91e34121763f5793ca10040f867
7
- data.tar.gz: fbe45a2913364ce7384aeda3ef0afb064a89c56555f0636ca377fe48a181cd68b3a6b7638045b64be5fb0d9742693a54b73e8cd4c626825b8e29ebdfcf950c18
6
+ metadata.gz: 90b949419c532e776a5f86ed660f99e67c343d25c2d4fd93927519a3ed200f9ed0d840593b87c252a35bbf9372f56ae66ad778838a5a99a0839d9787e1d9d15e
7
+ data.tar.gz: 200cb50dff68168aac3e81bc64247899c149ac76dc7281cd3454f4f1d7394a6e3b8d6257513f370bd3f444d138abe273dc2c56d547284c8fbbff412aa516defb
data/.gitignore CHANGED
@@ -2,3 +2,6 @@ build
2
2
  vendor
3
3
  tools
4
4
  .VERSION.mk
5
+ *.gem
6
+ *.lock
7
+ *.swp
data/CHANGELOG.md ADDED
File without changes
data/CONTRIBUTORS CHANGED
@@ -10,6 +10,7 @@ Contributors:
10
10
  * Nick Ethier (nickethier)
11
11
  * Pete Fritchman (fetep)
12
12
  * Pier-Hugues Pellerin (ph)
13
+ * Karl Stoney (Stono)
13
14
 
14
15
  Note: If you've sent us patches, bug reports, or otherwise contributed to
15
16
  Logstash, and you aren't on the list above and want to be, please let us know
data/NOTICE.TXT ADDED
@@ -0,0 +1,5 @@
1
+ Elasticsearch
2
+ Copyright 2012-2015 Elasticsearch
3
+
4
+ This product includes software developed by The Apache Software
5
+ Foundation (http://www.apache.org/).
data/README.md CHANGED
@@ -13,9 +13,18 @@ Logstash provides infrastructure to automatically generate documentation for thi
13
13
 
14
14
  ## Need Help?
15
15
 
16
- Need help? Try #logstash on freenode IRC or the logstash-users@googlegroups.com mailing list.
16
+ Need help? Try #logstash on freenode IRC or the https://discuss.elastic.co/c/logstash discussion forum.
17
17
 
18
- ## Developing
18
+ ## Developing with Docker
19
+ You can use a docker container with all of the requirements pre installed to save you installing the development environment on your host.
20
+
21
+ ### 1. Starting the container
22
+ Simply type `docker-compose run devenv` and you'll be entered into the container. Then you'll need to do `jruby -S bundle install` to get all the dependencies down.
23
+
24
+ ### 2. Running tests
25
+ Once you've done #1 above, you can run your tests with `jruby -S bundle exec rspec`
26
+
27
+ ## Developing without Docker
19
28
 
20
29
  ### 1. Plugin Developement and Testing
21
30
 
@@ -83,4 +92,4 @@ Programming is not a required skill. Whatever you've seen about open source and
83
92
 
84
93
  It is more important to the community that you are able to contribute.
85
94
 
86
- For more information about contributing, see the [CONTRIBUTING](https://github.com/elasticsearch/logstash/blob/master/CONTRIBUTING.md) file.
95
+ For more information about contributing, see the [CONTRIBUTING](https://github.com/elasticsearch/logstash/blob/master/CONTRIBUTING.md) file.
@@ -0,0 +1,5 @@
1
+ devenv:
2
+ image: hpess/devenv-jruby:master
3
+ entrypoint: /bin/bash
4
+ volumes:
5
+ - ./:/storage
@@ -2,11 +2,6 @@ require "logstash/codecs/base"
2
2
 
3
3
  class LogStash::Codecs::CEF < LogStash::Codecs::Base
4
4
  config_name "cef"
5
-
6
-
7
- # Specify if the Syslog header will be expected
8
- config :syslog, :validate => :boolean, :default => false
9
-
10
5
  config :signature, :validate => :string, :default => "Logstash"
11
6
  config :name, :validate => :string, :default => "Logstash"
12
7
  config :sev, :validate => :number, :default => 6
@@ -20,31 +15,44 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
20
15
 
21
16
  public
22
17
  def decode(data)
23
- # Need to break out the headers, then return the headers as individual fields, and the extension to be processed by a filter (ie: KV)
24
- # %{SYSLOGDATE} %{HOST} CEF:Version|Device Vendor|Device Product|Device Version|SignatureID|Name|Severity|Extension
25
- event = LogStash::Event.new()
26
- if @syslog
27
- @logger.debug("Expecting SYSLOG headers")
28
- event['syslog'], data = data.split('CEF:', 2)
29
- # Since we have the syslog headers, lets pull them out first and put them into their own field to be handled
30
- else
31
- # We don't have syslog headers, so we just need to remove CEF:
32
- data.sub! /^CEF:/, ''
33
- end #if @syslog
34
- # Now, break out the rest of the headers
35
- event['cef_version'], event['cef_vendor'], event['cef_product'], event['cef_device_version'], event['cef_sigid'], event['cef_name'], event['cef_severity'], event['message'] = data.scan /(?:[^\|\\]|\\.)+/
36
- # Now, try to break out the Extension Dictionary
37
- message=event['message']
38
- if message.to_s.strip.length != 0
18
+ # Strip any quotations at the start and end, flex connectors seem to send this
19
+ if data[0] == "\""
20
+ data = data[1..-2]
21
+ end
22
+ event = LogStash::Event.new
23
+
24
+ # Split by the pipes
25
+ event['cef_version'], event['cef_vendor'], event['cef_product'], event['cef_device_version'], event['cef_sigid'], event['cef_name'], event['cef_severity'], message = data.split /(?<!\\)[\|]/
26
+
27
+ # Try and parse out the syslog header if there is one
28
+ if event['cef_version'].include? ' '
29
+ event['syslog'], unused, event['cef_version'] = event['cef_version'].rpartition(' ')
30
+ end
31
+
32
+ # Get rid of the CEF bit in the version
33
+ event['cef_version'].sub! /^CEF:/, ''
34
+
35
+ # Strip any whitespace from the message
36
+ if not message.nil? and message.include? '='
37
+ message = message.strip
38
+
39
+ # If the last KVP has no value, add an empty string, this prevents hash errors below
40
+ if message.end_with?("=")
41
+ message=message + ' '
42
+ end
43
+
44
+ # Now parse the key value pairs into it
45
+ extensions = {}
39
46
  message = message.split(/ ([\w\.]+)=/)
47
+ key, value = message.shift.split('=', 2)
48
+ extensions[key] = value
49
+
50
+ Hash[*message].each{ |k, v| extensions[k] = v }
51
+
52
+ # And save the new has as the extensions
53
+ event['cef_ext'] = extensions
54
+ end
40
55
 
41
- key, value = message.shift.split('=',2)
42
- @logger.debug(message)
43
- kv = Hash[*message]
44
- @logger.debug(kv)
45
- addKey(kv,key,value)
46
- event.to_hash.merge!(Hash[kv.map{ |k,v| ["cef_ext_"+k,v] }])
47
- end #
48
56
  yield event
49
57
  end
50
58
 
@@ -62,19 +70,6 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
62
70
  @on_event.call(header + " " + values + "\n")
63
71
  end
64
72
 
65
- private
66
- def addKey(kv_keys, key, value)
67
- if kv_keys.has_key?(key)
68
- if kv_keys[key].is_a? Array
69
- kv_keys[key].push(value)
70
- else
71
- kv_keys[key] = [kv_keys[key], value]
72
- end
73
- else
74
- kv_keys[key] = value
75
- end
76
- end # addKey
77
-
78
73
  private
79
74
  def get_value(name, event)
80
75
  val = event[name]
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-codec-cef'
4
- s.version = '0.1.4'
4
+ s.version = '0.1.5'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "CEF codec to parse 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"
@@ -16,29 +16,73 @@ describe LogStash::Codecs::CEF do
16
16
  context "#decode" do
17
17
  let (:message) { "CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 spt=1232" }
18
18
 
19
- it "should parse the cef header" do
19
+ def validate(e)
20
+ insist { e.is_a?(LogStash::Event) }
21
+ insist { e['cef_version'] } == "0"
22
+ insist { e['cef_device_version'] } == "1.0"
23
+ insist { e['cef_sigid'] } == "100"
24
+ insist { e['cef_name'] } == "trojan successfully stopped"
25
+ insist { e['cef_severity'] } == "10"
26
+ end
27
+
28
+ it "should parse the cef headers" do
20
29
  subject.decode(message) do |e|
21
- insist { e.is_a?(LogStash::Event) }
22
- insist { e["cef_version"] } == "0"
30
+ validate(e)
31
+ ext = e['cef_ext']
23
32
  insist { e["cef_vendor"] } == "security"
24
33
  insist { e["cef_product"] } == "threatmanager"
25
- insist { e["cef_device_version"] } == "1.0"
26
- insist { e["cef_sigid"] } == "100"
27
- insist { e["cef_name"] } == "trojan successfully stopped"
28
- insist { e["cef_severity"] } == "10"
29
- insist { e["message"] } == "src=10.0.0.192 dst=12.121.122.82 spt=1232"
30
34
  end
31
35
  end
32
36
 
33
37
  it "should parse the cef body" do
34
38
  subject.decode(message) do |e|
35
- insist { e["cef_ext_src"] } == "10.0.0.192"
36
- insist { e["cef_ext_dst"] } == "12.121.122.82"
37
- insist { e["cef_ext_spt"] } == "1232"
39
+ ext = e['cef_ext']
40
+ insist { ext['src'] } == "10.0.0.192"
41
+ insist { ext['dst'] } == "12.121.122.82"
42
+ insist { ext['spt'] } == "1232"
38
43
  end
39
44
  end
40
45
 
41
- it "should handle values in the body that contain spaces"
46
+ let (:no_ext) { "CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|" }
47
+ it "should be OK with no extension dictionary" do
48
+ subject.decode(no_ext) do |e|
49
+ validate(e)
50
+ insist { e["cef_ext"] } == nil
51
+ end
52
+ end
53
+
54
+ let (:missing_headers) { "CEF:0|||1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 spt=1232" }
55
+ it "should be OK with missing CEF headers (multiple pipes in sequence)" do
56
+ subject.decode(missing_headers) do |e|
57
+ validate(e)
58
+ insist { e["cef_vendor"] } == ""
59
+ insist { e["cef_product"] } == ""
60
+ end
61
+ end
62
+
63
+ let (:leading_whitespace) { "CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10| src=10.0.0.192 dst=12.121.122.82 spt=1232" }
64
+ it "should strip leading whitespace from the message" do
65
+ subject.decode(leading_whitespace) do |e|
66
+ validate(e)
67
+ end
68
+ end
69
+
70
+ let (:escaped_pipes) { 'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|moo=this\|has an escaped pipe' }
71
+ it "should be OK with escaped pipes in the message" do
72
+ subject.decode(escaped_pipes) do |e|
73
+ ext = e['cef_ext']
74
+ insist { ext['moo'] } == 'this\|has an escaped pipe'
75
+ end
76
+ end
77
+
78
+ let (:syslog) { "Syslogdate Sysloghost CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 spt=1232" }
79
+ it "Should detect headers before CEF starts" do
80
+ subject.decode(syslog) do |e|
81
+ validate(e)
82
+ insist { e['syslog'] } == 'Syslogdate Sysloghost'
83
+ end
84
+ end
85
+
42
86
  end
43
87
 
44
88
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-codec-cef
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-20 00:00:00.000000000 Z
11
+ date: 2015-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -51,11 +51,14 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
  files:
53
53
  - .gitignore
54
+ - CHANGELOG.md
54
55
  - CONTRIBUTORS
55
56
  - Gemfile
56
57
  - LICENSE
58
+ - NOTICE.TXT
57
59
  - README.md
58
60
  - Rakefile
61
+ - docker-compose.yml
59
62
  - lib/logstash/codecs/cef.rb
60
63
  - lib/logstash/version.rb
61
64
  - logstash-codec-cef.gemspec
@@ -82,9 +85,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
85
  version: '0'
83
86
  requirements: []
84
87
  rubyforge_project:
85
- rubygems_version: 2.1.9
88
+ rubygems_version: 2.4.7
86
89
  signing_key:
87
90
  specification_version: 4
88
91
  summary: CEF codec to parse CEF formated logs
89
92
  test_files:
90
93
  - spec/codecs/cef_spec.rb
94
+ has_rdoc: