cef 0.7.1 → 0.8.0
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.
- data/VERSION +1 -1
- data/cef.gemspec +3 -2
- data/lib/cef/constants.rb +59 -16
- data/lib/cef/event.rb +20 -3
- data/lib/cef/parser.rb +56 -0
- data/spec/cef_spec.rb +31 -8
- data/spec/spec_helper.rb +22 -1
- metadata +6 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
data/cef.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{cef}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.8.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ryan Breed"]
|
12
|
-
s.date = %q{2011-03-
|
12
|
+
s.date = %q{2011-03-30}
|
13
13
|
s.default_executable = %q{cef_sender}
|
14
14
|
s.description = %q{ format/send CEF logs via API+syslog or client program }
|
15
15
|
s.email = %q{opensource@breed.org}
|
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
|
|
32
32
|
"lib/cef/constants.rb",
|
33
33
|
"lib/cef/event.rb",
|
34
34
|
"lib/cef/file_logger.rb",
|
35
|
+
"lib/cef/parser.rb",
|
35
36
|
"lib/cef/sender.rb",
|
36
37
|
"spec/cef_spec.rb",
|
37
38
|
"spec/spec_helper.rb"
|
data/lib/cef/constants.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module CEF
|
2
|
-
|
2
|
+
PREFIX_FORMAT="<%d>%s %s CEF:0|%s|%s"
|
3
3
|
VERSION=File.read(File.join(File.expand_path(File.dirname(__FILE__)),'..','..','VERSION'))
|
4
|
-
|
4
|
+
LOG_TIME_FORMAT="%b %d %Y %H:%M:%S"
|
5
5
|
|
6
6
|
# CEF Dictionary
|
7
7
|
# CEF Prefix attributes
|
@@ -21,15 +21,48 @@ module CEF
|
|
21
21
|
# differently than core attributes.
|
22
22
|
EXTENSION_ATTRIBUTES = {
|
23
23
|
:applicationProtocol => "app",
|
24
|
+
|
25
|
+
:agentZoneURI => "agentZoneURI",
|
26
|
+
:agentAddress => "agt",
|
27
|
+
:agentHostName => "ahost",
|
28
|
+
:agentId => "aid",
|
29
|
+
:agentName => "agentName",
|
30
|
+
:agentType => "at",
|
31
|
+
:agentTimeZone => "atz",
|
32
|
+
:agentVersion => "av",
|
33
|
+
|
24
34
|
:baseEventCount => "cnt",
|
35
|
+
:baseEventIds => "baseEventIds",
|
25
36
|
:bytesIn => "in",
|
26
37
|
:bytesOut => "out",
|
38
|
+
|
39
|
+
:categoryBehavior => "categoryBehavior",
|
40
|
+
:categoryDeviceGroup => "categoryDeviceGroup",
|
41
|
+
:categoryObject => "categoryObject",
|
42
|
+
:categoryOutcome => "categoryOutcome",
|
43
|
+
:categorySignificance => "categorySignificance",
|
44
|
+
|
45
|
+
|
46
|
+
|
27
47
|
:deviceAction => "act",
|
28
|
-
:
|
29
|
-
:deviceNtDomain => "deviceNtDomain",
|
48
|
+
:deviceDirection => "deviceDirection",
|
30
49
|
:deviceDnsDomain => "deviceDnsDomain",
|
31
|
-
:
|
50
|
+
:deviceEventCategory => "cat",
|
51
|
+
:deviceExternalId => "deviceExternalId",
|
52
|
+
:deviceFacility => "deviceFacility",
|
53
|
+
:deviceAddress => "dvc",
|
54
|
+
:deviceHostName => "dvchost",
|
55
|
+
:deviceInboundInterface => "deviceInboundInterface",
|
32
56
|
:deviceMacAddress => "deviceMacAddress",
|
57
|
+
:deviceNtDomain => "deviceNtDomain",
|
58
|
+
:deviceOutboundInterface => "deviceOutboundInterface",
|
59
|
+
:devicePayloadId => "devicePayloadId",
|
60
|
+
:deviceProcessName => "deviceProcessName",
|
61
|
+
:deviceTimeZone => "dtz",
|
62
|
+
:deviceTranslatedAddress => "deviceTranslatedAddress",
|
63
|
+
:deviceTranslatedZoneURI => "deviceTranslatedZoneURI",
|
64
|
+
:deviceZoneURI => "deviceZoneURI",
|
65
|
+
|
33
66
|
:deviceCustomNumber1 => "cn1",
|
34
67
|
:deviceCustomNumber2 => "cn2",
|
35
68
|
:deviceCustomNumber3 => "cn3",
|
@@ -52,7 +85,7 @@ module CEF
|
|
52
85
|
:deviceCustomDate2 => "deviceCustomDate2",
|
53
86
|
:deviceCustomDate1Label => "deviceCustomDate1Label",
|
54
87
|
:deviceCustomDate2Label => "deviceCustomDate2Label",
|
55
|
-
|
88
|
+
|
56
89
|
:destinationAddress => "dst",
|
57
90
|
:destinationDnsDomain => "destinationDnsDomain",
|
58
91
|
:destinationNtDomain => "dntdom",
|
@@ -61,26 +94,29 @@ module CEF
|
|
61
94
|
:destinationPort => "dpt",
|
62
95
|
:destinationProcessName => "dproc",
|
63
96
|
:destinationServiceName => "destinationServiceName",
|
97
|
+
:destinationTranslatedAddress => "destinationTranslatedAddress",
|
98
|
+
:destinationTranslatedPort => "destinationTranslatedPort",
|
64
99
|
:destinationUserId => "duid",
|
65
100
|
:destinationUserPrivileges => "dpriv",
|
66
101
|
:destinationUserName => "duser",
|
67
|
-
:
|
68
|
-
|
69
|
-
:
|
70
|
-
:deviceExternalId => "deviceExternalId",
|
71
|
-
:deviceFacility => "deviceFacility",
|
72
|
-
:deviceInboundInterface => "deviceInboundInterface",
|
73
|
-
:deviceOutboundInterface => "deviceOutboundInterface",
|
74
|
-
:deviceProcessName => "deviceProcessName",
|
102
|
+
:destinationZoneURI => "destinationZoneURI",
|
103
|
+
|
104
|
+
:eventId => "eventId",
|
75
105
|
:externalId => "externalId",
|
106
|
+
:eventType => "type",
|
107
|
+
|
76
108
|
:fileHash => "fileHash",
|
77
109
|
:fileId => "fileId",
|
78
110
|
:fileName => "fname",
|
79
111
|
:filePath => "filePath",
|
80
112
|
:filePermission => "filePermission",
|
81
|
-
:
|
113
|
+
:fileSize => "fsize",
|
82
114
|
:fileType => "fileType",
|
115
|
+
|
116
|
+
:generatorID => "generatorID",
|
117
|
+
|
83
118
|
:message => "msg",
|
119
|
+
|
84
120
|
:oldfileHash => "oldfileHash",
|
85
121
|
:oldfileId => "oldfileId",
|
86
122
|
:oldFilename => "oldFilename",
|
@@ -88,10 +124,12 @@ module CEF
|
|
88
124
|
:oldfilePermission => "oldfilePermission",
|
89
125
|
:oldfsize => "oldfsize",
|
90
126
|
:oldfileType => "oldfileType",
|
127
|
+
|
91
128
|
:requestURL => "request",
|
92
129
|
:requestClientApplication => "requestClientApplication",
|
93
130
|
:requestCookies => "requestCookies",
|
94
131
|
:requestMethod => "requestMethod",
|
132
|
+
|
95
133
|
:sourceAddress => "src",
|
96
134
|
:sourceDnsDomain => "sourceDnsDomain",
|
97
135
|
:sourceHostName => "shost",
|
@@ -104,6 +142,8 @@ module CEF
|
|
104
142
|
:sourceUserPrivileges => "spriv",
|
105
143
|
:sourceUserId => "suid",
|
106
144
|
:sourceUserName => "suser",
|
145
|
+
:sourceZoneURI => "sourceZoneURI",
|
146
|
+
|
107
147
|
:transportProtocol => "proto"
|
108
148
|
}
|
109
149
|
|
@@ -115,7 +155,10 @@ module CEF
|
|
115
155
|
:oldfileModificationTime => "oldfileModificationTime",
|
116
156
|
:receiptTime => "rt",
|
117
157
|
:startTime => "start",
|
118
|
-
:endTime => "end"
|
158
|
+
:endTime => "end",
|
159
|
+
:managerReceiptTime => "mrt",
|
160
|
+
:agentReceiptTime => "art",
|
161
|
+
|
119
162
|
}
|
120
163
|
|
121
164
|
ATTRIBUTES=PREFIX_ATTRIBUTES.merge EXTENSION_ATTRIBUTES.merge TIME_ATTRIBUTES
|
data/lib/cef/event.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module CEF
|
2
2
|
class Event
|
3
|
-
attr_accessor :my_hostname, :syslog_pri
|
3
|
+
attr_accessor :my_hostname, :syslog_pri, :event_time
|
4
4
|
# set up accessors for all of the CEF event attributes. ruby meta magic.
|
5
5
|
CEF::ATTRIBUTES.each do |k,v|
|
6
6
|
self.instance_eval do
|
@@ -20,20 +20,37 @@ module CEF
|
|
20
20
|
# used to avoid requiring syslog.h on windoze
|
21
21
|
#syslog_pri= Syslog::LOG_LOCAL0 | Syslog::LOG_NOTICE
|
22
22
|
@syslog_pri ||= 131
|
23
|
+
@other_attrs={}
|
24
|
+
@additional={}
|
23
25
|
end
|
24
26
|
|
25
27
|
# returns a cef formatted string
|
26
28
|
def format_cef
|
29
|
+
log_time=nil
|
30
|
+
if event_time.nil?
|
31
|
+
log_time=Time.new.strftime(CEF::LOG_TIME_FORMAT)
|
32
|
+
else
|
33
|
+
log_time=event_time.strftime(CEF::LOG_TIME_FORMAT)
|
34
|
+
end
|
35
|
+
|
27
36
|
cef_message=CEF::PREFIX_FORMAT % [
|
28
37
|
syslog_pri.to_s,
|
29
38
|
my_hostname,
|
30
|
-
|
39
|
+
log_time,
|
31
40
|
format_prefix,
|
32
41
|
format_extension
|
33
42
|
]
|
34
43
|
cef_message
|
35
44
|
end
|
36
45
|
|
46
|
+
# used for non-schema fields
|
47
|
+
def set_additional(k,v)
|
48
|
+
@additional[k]=v
|
49
|
+
end
|
50
|
+
def get_additional(k,v)
|
51
|
+
@additional[k]
|
52
|
+
end
|
53
|
+
|
37
54
|
private
|
38
55
|
# make a guess as to how the time was set. parse strings and convert
|
39
56
|
# them to epoch milliseconds, or leave it alone if it looks like a number
|
@@ -70,7 +87,7 @@ module CEF
|
|
70
87
|
# only equals signs need to be escaped in the extension. i think.
|
71
88
|
# TODO: something in the spec about \n and some others.
|
72
89
|
def extension_escape(val)
|
73
|
-
val.gsub(/=/,'\=').gsub(/\n/,' ')
|
90
|
+
val.gsub(/=/,'\=').gsub(/\n/,' ').gsub(/\\/,'\\')
|
74
91
|
end
|
75
92
|
|
76
93
|
# returns a pipe-delimeted list of prefix attributes
|
data/lib/cef/parser.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# COPYRIGHT: Ryan Breed
|
2
|
+
# DATE: 3/27/11
|
3
|
+
module CEF
|
4
|
+
class Parser
|
5
|
+
# TODO: deal with escaping delimeters
|
6
|
+
|
7
|
+
attr_accessor :file_name
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
# Parser.new(:foo=>"bar)
|
11
|
+
Hash[*args].each { |argname, argval| self.send(("%s="%argname), argval) }
|
12
|
+
|
13
|
+
yield self if block_given?
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_file
|
17
|
+
events=[]
|
18
|
+
File.open(file_name) do |f|
|
19
|
+
f.each_line do |line|
|
20
|
+
line.chomp!
|
21
|
+
prefix=line.split(/\|/)
|
22
|
+
e=Event.new
|
23
|
+
extension_string=prefix[7..-1].join("|")
|
24
|
+
extension_av_pairs=extension_string.split(/ ([\w\.]+)=/)
|
25
|
+
extension_av_pairs.shift
|
26
|
+
|
27
|
+
begin
|
28
|
+
extension=Hash[ *extension_av_pairs.map {|i| i.strip} ]
|
29
|
+
extension.each do |k,v|
|
30
|
+
next if k.match(/^ad\./)
|
31
|
+
methname=CEF::ATTRIBUTES.invert[k].to_s
|
32
|
+
#puts "METHNAME: #{k} -> #{methname}"
|
33
|
+
e.send("%s=" % methname, v)
|
34
|
+
end
|
35
|
+
|
36
|
+
rescue Exception => except
|
37
|
+
puts except.message
|
38
|
+
pp extension_av_pairs
|
39
|
+
puts line
|
40
|
+
next
|
41
|
+
end
|
42
|
+
|
43
|
+
%w{ deviceVendor deviceProduct deviceVersion
|
44
|
+
deviceEventClassId name deviceSeverity }.each_with_index {|att,i| e.send("%s="%att,prefix[i+1]) }
|
45
|
+
|
46
|
+
if block_given?
|
47
|
+
yield e
|
48
|
+
else
|
49
|
+
events.push e
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
events
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/spec/cef_spec.rb
CHANGED
@@ -1,13 +1,36 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
describe "CEF Event
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
describe "CEF Event Formatter" do
|
4
|
+
describe "CEF Preamble" do
|
5
|
+
it "should output a preamble" do
|
6
|
+
prefix_vals=test_prefix_vals
|
7
|
+
t=Time.new
|
8
|
+
e=CEF::Event.new
|
9
|
+
e.event_time=t
|
10
|
+
prefix_vals.each {|k,v| e.send("%s="%k,v) }
|
11
|
+
preformatted=CEF::PREFIX_FORMAT % [ 131, Socket.gethostname, t.strftime(CEF::LOG_TIME_FORMAT), test_prefix_string, ""]
|
12
|
+
formatted=e.format_cef
|
13
|
+
preformatted.should == formatted
|
14
|
+
end
|
15
|
+
it "should escape pipes in the prefix" do
|
16
|
+
prefix_vals=test_prefix_escape_vals
|
17
|
+
t=Time.new
|
18
|
+
e=CEF::Event.new
|
19
|
+
e.event_time=t
|
20
|
+
prefix_vals.each {|k,v| e.send("%s="%k,v) }
|
21
|
+
preformatted=CEF::PREFIX_FORMAT % [ 131, Socket.gethostname, t.strftime(CEF::LOG_TIME_FORMAT), test_prefix_escape_string, ""]
|
22
|
+
formatted=e.format_cef
|
23
|
+
preformatted.should == formatted
|
24
|
+
end
|
11
25
|
end
|
26
|
+
describe "Cef Extension" do
|
27
|
+
it "should output an extension"
|
28
|
+
it "should escape newlines"
|
29
|
+
it "should escape equal signs"
|
30
|
+
it "should format time attributes"
|
31
|
+
end
|
32
|
+
end
|
12
33
|
|
34
|
+
describe "UDPSender" do
|
35
|
+
|
13
36
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -22,6 +22,27 @@ def test_prefix_vals
|
|
22
22
|
}
|
23
23
|
end
|
24
24
|
|
25
|
+
def test_prefix_escape_vals
|
26
|
+
test_prefix_escape_vals={
|
27
|
+
:deviceVendor => "bre|ed",
|
28
|
+
:deviceProduct => "CEF Sender",
|
29
|
+
:deviceVersion => "0.1",
|
30
|
+
:deviceEventClassId => "0:debug",
|
31
|
+
:name => "test",
|
32
|
+
:deviceSeverity => "1"
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_extension_vals
|
37
|
+
test_extension_vals={
|
38
|
+
:sourceAddress => "192.168.1.1",
|
39
|
+
:destinationAddress => "192.168.1.2"
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
25
43
|
def test_prefix_string
|
26
|
-
"
|
44
|
+
"breed|CEF Sender|0.1|0:debug|test|1"
|
45
|
+
end
|
46
|
+
def test_prefix_escape_string
|
47
|
+
"bre\\|ed|CEF Sender|0.1|0:debug|test|1"
|
27
48
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 63
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 0.8.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Breed
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-30 00:00:00 -05:00
|
19
19
|
default_executable: cef_sender
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- lib/cef/constants.rb
|
120
120
|
- lib/cef/event.rb
|
121
121
|
- lib/cef/file_logger.rb
|
122
|
+
- lib/cef/parser.rb
|
122
123
|
- lib/cef/sender.rb
|
123
124
|
- spec/cef_spec.rb
|
124
125
|
- spec/spec_helper.rb
|