cef 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/bin/cef_sender +77 -0
- data/cef.gemspec +69 -0
- data/lib/cef.rb +274 -0
- data/spec/cef_spec.rb +19 -0
- data/spec/spec_helper.rb +12 -0
- metadata +157 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.3.0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Ryan Breed
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= cef
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to cef
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 Ryan Breed. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "cef"
|
16
|
+
gem.homepage = "http://github.com/ryanbreed/cef"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{CEF Generation }
|
19
|
+
gem.description = %Q{Library and client }
|
20
|
+
gem.email = "opensource@breed.org"
|
21
|
+
gem.authors = ["Ryan Breed"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
#gem.add_runtime_dependency 'escape', '~> 0.0.4'
|
25
|
+
gem.add_development_dependency 'rspec', '~> 2.3.0'
|
26
|
+
gem.files.include('VERSION')
|
27
|
+
end
|
28
|
+
Jeweler::RubygemsDotOrgTasks.new
|
29
|
+
|
30
|
+
require 'rspec/core'
|
31
|
+
require 'rspec/core/rake_task'
|
32
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
33
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
34
|
+
end
|
35
|
+
|
36
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
37
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
38
|
+
spec.rcov = true
|
39
|
+
end
|
40
|
+
|
41
|
+
task :default => :spec
|
42
|
+
|
43
|
+
require 'rake/rdoctask'
|
44
|
+
Rake::RDocTask.new do |rdoc|
|
45
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
46
|
+
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "cef #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
|
+
end
|
52
|
+
|
53
|
+
task 'clean' do |t|
|
54
|
+
FileUtils.rm_f(Dir.glob(('{coverage,pkg}/*')))
|
55
|
+
FileUtils.rm_f(Dir.glob(('Gemfile.lock')))
|
56
|
+
%w{ coverage pkg }.each {|d| Dir.rmdir(d) if File.exists?(d)}
|
57
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.6.0
|
data/bin/cef_sender
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'cef'
|
4
|
+
require 'getoptlong'
|
5
|
+
|
6
|
+
sender=CEF::Sender.new
|
7
|
+
|
8
|
+
e=CEF::Event.new
|
9
|
+
@verbose=0
|
10
|
+
@file=nil
|
11
|
+
opts=GetoptLong.new(
|
12
|
+
["--verbose", GetoptLong::OPTIONAL_ARGUMENT],
|
13
|
+
["--help", GetoptLong::OPTIONAL_ARGUMENT],
|
14
|
+
["--schema", GetoptLong::OPTIONAL_ARGUMENT],
|
15
|
+
["--receiver", GetoptLong::OPTIONAL_ARGUMENT],
|
16
|
+
["--receiverPort", GetoptLong::OPTIONAL_ARGUMENT],
|
17
|
+
["--append-file", GetoptLong::OPTIONAL_ARGUMENT],
|
18
|
+
*e.attrs.keys.collect {|o| ["--#{o}", GetoptLong::OPTIONAL_ARGUMENT]}
|
19
|
+
)
|
20
|
+
|
21
|
+
def print_usage
|
22
|
+
puts <<END_USAGE
|
23
|
+
Usage: cef_sender --sourceAddress="192.168.1.1" [--eventAttribute="something"]
|
24
|
+
|
25
|
+
non-schema arguments:
|
26
|
+
--help gets you here
|
27
|
+
--schema will dump all of the callable event attribute names
|
28
|
+
--receiver= syslog receiver hostname/ip
|
29
|
+
--receiverPort= syslog port
|
30
|
+
|
31
|
+
cef_sender will send CEF-formatted syslog messages to a receiver of your choice.
|
32
|
+
only the cef fields defined in the cef reader flex connector are supported.
|
33
|
+
datatyping is not enforced here.
|
34
|
+
|
35
|
+
END_USAGE
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def print_schema(e)
|
40
|
+
e.attrs.keys.collect {|k| k.to_s}.sort.each {|a| puts a}
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.each do |opt,arg|
|
44
|
+
# TODO: set up cases for startTime, receiptTime, endTime to parse
|
45
|
+
# text and convert to unix time * 1000
|
46
|
+
case opt
|
47
|
+
when "--verbose"
|
48
|
+
@verbose+=1
|
49
|
+
when "--schema"
|
50
|
+
print_schema(e)
|
51
|
+
exit(0)
|
52
|
+
when "--receiverPort"
|
53
|
+
sender.receiverPort=arg
|
54
|
+
when "--receiver"
|
55
|
+
sender.receiver=arg
|
56
|
+
when "--help"
|
57
|
+
print_usage
|
58
|
+
exit(0)
|
59
|
+
when "--append-file"
|
60
|
+
@file=File.open(arg,"w+")
|
61
|
+
else
|
62
|
+
fieldname = opt.gsub(/-/,'')
|
63
|
+
value=arg
|
64
|
+
e.send("#{fieldname}=",value)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
msg=sender.format_event(e)
|
68
|
+
|
69
|
+
|
70
|
+
if @verbose>0
|
71
|
+
puts msg
|
72
|
+
end
|
73
|
+
if !(@file.nil?) && File.exists?(@file)
|
74
|
+
@file.write "%s\n" % msg.gsub(/^<\d+>/,'')
|
75
|
+
else
|
76
|
+
sender.emit(e)
|
77
|
+
end
|
data/cef.gemspec
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{cef}
|
8
|
+
s.version = "0.6.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ryan Breed"]
|
12
|
+
s.date = %q{2011-02-20}
|
13
|
+
s.default_executable = %q{cef_sender}
|
14
|
+
s.description = %q{Library and client }
|
15
|
+
s.email = %q{opensource@breed.org}
|
16
|
+
s.executables = ["cef_sender"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".rspec",
|
24
|
+
"Gemfile",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.rdoc",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"bin/cef_sender",
|
30
|
+
"cef.gemspec",
|
31
|
+
"lib/cef.rb",
|
32
|
+
"spec/cef_spec.rb",
|
33
|
+
"spec/spec_helper.rb"
|
34
|
+
]
|
35
|
+
s.homepage = %q{http://github.com/ryanbreed/cef}
|
36
|
+
s.licenses = ["MIT"]
|
37
|
+
s.require_paths = ["lib"]
|
38
|
+
s.rubygems_version = %q{1.5.2}
|
39
|
+
s.summary = %q{CEF Generation}
|
40
|
+
s.test_files = [
|
41
|
+
"spec/cef_spec.rb",
|
42
|
+
"spec/spec_helper.rb"
|
43
|
+
]
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
50
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
51
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
52
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
53
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
54
|
+
else
|
55
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
56
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
58
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
59
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
63
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
64
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
65
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
66
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
data/lib/cef.rb
ADDED
@@ -0,0 +1,274 @@
|
|
1
|
+
module CEF
|
2
|
+
require 'socket'
|
3
|
+
require 'parsedate'
|
4
|
+
PREFIX_FORMAT="<%d>%s %s CEF:0|%s|%s"
|
5
|
+
VERSION=File.read(File.join(File.expand_path(File.dirname(__FILE__)),'..','VERSION'))
|
6
|
+
|
7
|
+
|
8
|
+
# CEF Dictionary
|
9
|
+
# CEF Prefix attributes
|
10
|
+
PREFIX_ATTRIBUTES = {
|
11
|
+
:deviceVendor => "deviceVendor",
|
12
|
+
:deviceVersion => "deviceVersion",
|
13
|
+
:deviceProduct => "deviceProduct",
|
14
|
+
:name => "name",
|
15
|
+
:deviceSeverity => "deviceSeverity",
|
16
|
+
:deviceEventClassId => "deviceEventClassId"
|
17
|
+
}
|
18
|
+
|
19
|
+
# these are the basic extension attributes. implementing others is as
|
20
|
+
# simple as adding :symbolRepresentingMethodName => "cefkeyname", but
|
21
|
+
# i am supremely lazy to type in the whole dictionary right now. perhaps
|
22
|
+
# this should be a .yaml config file. Extension attributes are formatted
|
23
|
+
# differently than core attributes.
|
24
|
+
EXTENSION_ATTRIBUTES = {
|
25
|
+
:applicationProtocol => "app",
|
26
|
+
:baseEventCount => "cnt",
|
27
|
+
:bytesIn => "in",
|
28
|
+
:bytesOut => "out",
|
29
|
+
:deviceAction => "act",
|
30
|
+
:deviceHostNam => "dvc",
|
31
|
+
:deviceNtDomain => "deviceNtDomain",
|
32
|
+
:deviceDnsDomain => "deviceDnsDomain",
|
33
|
+
:deviceTranslatedAddress => "deviceTranslatedAddress",
|
34
|
+
:deviceMacAddress => "deviceMacAddress",
|
35
|
+
:deviceCustomNumber1 => "cn1",
|
36
|
+
:deviceCustomNumber2 => "cn2",
|
37
|
+
:deviceCustomNumber3 => "cn3",
|
38
|
+
:deviceCustomNumber1Label => "cn1Label",
|
39
|
+
:deviceCustomNumber2Label => "cn2Label",
|
40
|
+
:deviceCustomNumber3Label => "cn3Label",
|
41
|
+
:deviceCustomString1 => "cs1",
|
42
|
+
:deviceCustomString2 => "cs2",
|
43
|
+
:deviceCustomString3 => "cs3",
|
44
|
+
:deviceCustomString4 => "cs4",
|
45
|
+
:deviceCustomString5 => "cs5",
|
46
|
+
:deviceCustomString6 => "cs6",
|
47
|
+
:deviceCustomString1Label => "cs1Label",
|
48
|
+
:deviceCustomString2Label => "cs2Label",
|
49
|
+
:deviceCustomString3Label => "cs3Label",
|
50
|
+
:deviceCustomString4Label => "cs4Label",
|
51
|
+
:deviceCustomString5Label => "cs5Label",
|
52
|
+
:deviceCustomString6Label => "cs6Label",
|
53
|
+
:deviceCustomDate1 => "deviceCustomDate1",
|
54
|
+
:deviceCustomDate2 => "deviceCustomDate2",
|
55
|
+
:deviceCustomDate1Label => "deviceCustomDate1Label",
|
56
|
+
:deviceCustomDate2Label => "deviceCustomDate2Label",
|
57
|
+
:deviceEventCategory => "cat",
|
58
|
+
:destinationAddress => "dst",
|
59
|
+
:destinationDnsDomain => "destinationDnsDomain",
|
60
|
+
:destinationNtDomain => "dntdom",
|
61
|
+
:destinationHostName => "dhost",
|
62
|
+
:destinationMacAddress => "dmac",
|
63
|
+
:destinationPort => "dpt",
|
64
|
+
:destinationProcessName => "dproc",
|
65
|
+
:destinationServiceName => "destinationServiceName",
|
66
|
+
:destinationUserId => "duid",
|
67
|
+
:destinationUserPrivileges => "dpriv",
|
68
|
+
:destinationUserName => "duser",
|
69
|
+
:destinationTranslatedAddress => "destinationTranslatedAddress",
|
70
|
+
:destinationTranslatedPort => "destinationTranslatedPort",
|
71
|
+
:deviceDirection => "deviceDirection",
|
72
|
+
:deviceExternalId => "deviceExternalId",
|
73
|
+
:deviceFacility => "deviceFacility",
|
74
|
+
:deviceInboundInterface => "deviceInboundInterface",
|
75
|
+
:deviceOutboundInterface => "deviceOutboundInterface",
|
76
|
+
:deviceProcessName => "deviceProcessName",
|
77
|
+
:externalId => "externalId",
|
78
|
+
:fileHash => "fileHash",
|
79
|
+
:fileId => "fileId",
|
80
|
+
:fileName => "fname",
|
81
|
+
:filePath => "filePath",
|
82
|
+
:filePermission => "filePermission",
|
83
|
+
:fsize => "fsize",
|
84
|
+
:fileType => "fileType",
|
85
|
+
:message => "msg",
|
86
|
+
:oldfileHash => "oldfileHash",
|
87
|
+
:oldfileId => "oldfileId",
|
88
|
+
:oldFilename => "oldFilename",
|
89
|
+
:oldfilePath => "oldfilePath",
|
90
|
+
:oldfilePermission => "oldfilePermission",
|
91
|
+
:oldfsize => "oldfsize",
|
92
|
+
:oldfileType => "oldfileType",
|
93
|
+
:requestURL => "request",
|
94
|
+
:requestClientApplication => "requestClientApplication",
|
95
|
+
:requestCookies => "requestCookies",
|
96
|
+
:requestMethod => "requestMethod",
|
97
|
+
:sourceAddress => "src",
|
98
|
+
:sourceDnsDomain => "sourceDnsDomain",
|
99
|
+
:sourceHostName => "shost",
|
100
|
+
:sourceMacAddress => "smac",
|
101
|
+
:sourceNtDomain => "sntdom",
|
102
|
+
:sourcePort => "spt",
|
103
|
+
:sourceServiceName => "sourceServiceName",
|
104
|
+
:sourceTranslatedAddress => "sourceTranslatedAddress",
|
105
|
+
:sourceTranslatedPort => "sourceTranslatedPort",
|
106
|
+
:sourceUserPrivileges => "spriv",
|
107
|
+
:sourceUserId => "suid",
|
108
|
+
:sourceUserName => "suser",
|
109
|
+
:transportProtocol => "proto"
|
110
|
+
}
|
111
|
+
|
112
|
+
# these are tracked separately so they can be normalized during formatting
|
113
|
+
TIME_ATTRIBUTES={
|
114
|
+
:fileCreateTime => "fileCreateTime",
|
115
|
+
:fileModificationTime => "fileModificationTime",
|
116
|
+
:oldfileCreateTime => "oldfileCreateTime",
|
117
|
+
:oldfileModificationTime => "oldfileModificationTime",
|
118
|
+
:receiptTime => "rt",
|
119
|
+
:startTime => "start",
|
120
|
+
:endTime => "end"
|
121
|
+
}
|
122
|
+
|
123
|
+
ATTRIBUTES=PREFIX_ATTRIBUTES.merge EXTENSION_ATTRIBUTES.merge TIME_ATTRIBUTES
|
124
|
+
|
125
|
+
# this class will formats and sends the cef event objects. you can use senders to set
|
126
|
+
# default values for any event attribute, and you can send cef event objects to multiple
|
127
|
+
# senders if you wish.
|
128
|
+
class Sender
|
129
|
+
attr_accessor :receiver, :receiverPort, :eventDefaults
|
130
|
+
attr_reader :sock
|
131
|
+
|
132
|
+
# you can pass in a hash of options to be run to set parameters
|
133
|
+
def initialize(*params)
|
134
|
+
Hash[*params].each {|k,v| self.send("%s="%k,v) }
|
135
|
+
@sock=nil
|
136
|
+
end
|
137
|
+
|
138
|
+
def socksetup
|
139
|
+
@sock=UDPSocket.new
|
140
|
+
receiver= self.receiver || "127.0.0.1"
|
141
|
+
port= self.receiverPort || 514
|
142
|
+
@sock.connect(receiver,port)
|
143
|
+
end
|
144
|
+
|
145
|
+
# formats a CEFEvent
|
146
|
+
def format_event( event )
|
147
|
+
#HELL yeah it's hard-coded. What are you going to do about it?
|
148
|
+
#syslog_pri= Syslog::LOG_LOCAL0 | Syslog::LOG_NOTICE
|
149
|
+
syslog_pri=131
|
150
|
+
|
151
|
+
# process eventDefaults - we are expecting a hash here. These will
|
152
|
+
# override any values in the events passed to us. i know. brutal.
|
153
|
+
unless self.eventDefaults.nil?
|
154
|
+
self.eventDefaults.each do |k,v|
|
155
|
+
event.send("#{k}=",v)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
cef_message=PREFIX_FORMAT % [
|
160
|
+
syslog_pri.to_s,
|
161
|
+
Socket::gethostname,
|
162
|
+
Time.new.strftime("%b %d %Y %H:%M:%S"),
|
163
|
+
event.prefix,
|
164
|
+
event.extension
|
165
|
+
]
|
166
|
+
cef_message
|
167
|
+
end
|
168
|
+
|
169
|
+
#fire the message off
|
170
|
+
def emit(event)
|
171
|
+
self.socksetup if self.sock.nil?
|
172
|
+
self.sock.send self.format_event(event), 0
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
class Event
|
177
|
+
#%#
|
178
|
+
# set up accessors for all of the event attributes. ruby meta magic.
|
179
|
+
ATTRIBUTES.each do |k,v|
|
180
|
+
self.instance_eval do
|
181
|
+
attr_accessor k
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def attrs
|
186
|
+
ATTRIBUTES
|
187
|
+
end
|
188
|
+
|
189
|
+
# so we can CEFEvent.new(:foo=>"bar")
|
190
|
+
def initialize( *params )
|
191
|
+
Hash[*params].each { |k,v| self.send("%s="%k,v) }
|
192
|
+
end
|
193
|
+
|
194
|
+
# escape only pipes and backslashes in the prefix. you bet your sweet
|
195
|
+
# ass there's a lot of backslashes in the substitution. you can thank
|
196
|
+
# the three levels of lexical analysis/substitution in the ruby interpreter
|
197
|
+
# for that.
|
198
|
+
def prefix_escape(val)
|
199
|
+
val.gsub(/(\||\\)/,'\\\\\&')
|
200
|
+
end
|
201
|
+
|
202
|
+
# only equals signs need to be escaped in the extension. i think.
|
203
|
+
# TODO: something in the spec about \n and some others.
|
204
|
+
def extension_escape(val)
|
205
|
+
val.gsub(/=/,'\=')
|
206
|
+
end
|
207
|
+
|
208
|
+
# make a guess as to how the time was set. parse strings and convert
|
209
|
+
# them to epoch milliseconds, or leave it alone if it looks like a number
|
210
|
+
# bigger than epoch milliseconds when i wrote this.
|
211
|
+
def time_convert(val)
|
212
|
+
converted=nil
|
213
|
+
#puts "converting time for #{val.class.to_s}/#{val}"
|
214
|
+
case val.class.to_s
|
215
|
+
when "String"
|
216
|
+
begin
|
217
|
+
converted=val.to_i
|
218
|
+
rescue
|
219
|
+
res=ParseDate.parsedate(val)
|
220
|
+
converted=Time.local(*res).to_i * 1000
|
221
|
+
end
|
222
|
+
when "Integer","Bignum"
|
223
|
+
if val < 1232589621000 #Wed Jan 21 20:00:21 -0600 2009
|
224
|
+
converted=val * 1000
|
225
|
+
else
|
226
|
+
converted=val
|
227
|
+
end
|
228
|
+
end
|
229
|
+
converted
|
230
|
+
end
|
231
|
+
|
232
|
+
# returns a pipe-delimeted list of prefix attributes
|
233
|
+
def prefix
|
234
|
+
vendor= self.deviceVendor || "Breed"
|
235
|
+
product= self.deviceProduct || "CEF Sender"
|
236
|
+
version= self.deviceVersion || CEF::VERSION
|
237
|
+
declid= self.deviceEventClassId || "generic:0"
|
238
|
+
name= self.name || "Generic Event"
|
239
|
+
sev= self.deviceSeverity || "1"
|
240
|
+
cef_prefix="%s|%s|%s|%s|%s|%s" % [
|
241
|
+
prefix_escape(vendor),
|
242
|
+
prefix_escape(product),
|
243
|
+
prefix_escape(version),
|
244
|
+
prefix_escape(declid),
|
245
|
+
prefix_escape(name),
|
246
|
+
prefix_escape(sev),
|
247
|
+
]
|
248
|
+
end
|
249
|
+
|
250
|
+
# returns a space-delimeted list of attribute=value pairs for all optionals
|
251
|
+
def extension
|
252
|
+
avpairs=[]
|
253
|
+
EXTENSION_ATTRIBUTES.each do |attribute,shortname|
|
254
|
+
unless self.send(attribute).nil?
|
255
|
+
avpairs.push(
|
256
|
+
"%s=%s" % [ shortname, extension_escape(self.send(attribute)) ]
|
257
|
+
)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# make sure time comes out as milliseconds since epoch
|
262
|
+
TIME_ATTRIBUTES.each do |attribute,shortname|
|
263
|
+
unless self.send(attribute).nil?
|
264
|
+
avpairs.push(
|
265
|
+
"%s=%s" % [ shortname, time_convert(self.send(attribute)) ]
|
266
|
+
)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
avpairs.join(" ")
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
|
data/spec/cef_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "CEF Event Format" do
|
4
|
+
it "should output a preamble" do
|
5
|
+
test_prefix_vals={
|
6
|
+
:deviceVendor => "breed",
|
7
|
+
:deviceProduct => "CEF Sender",
|
8
|
+
:deviceVersion => "0.1",
|
9
|
+
:deviceEventClassId => "0:debug",
|
10
|
+
:name => "test",
|
11
|
+
:deviceSeverity => "1"
|
12
|
+
}
|
13
|
+
e=CEF::Event.new
|
14
|
+
test_prefix_vals.each {|k,v| e.send("%s="%k,v) }
|
15
|
+
s=CEF::Sender.new
|
16
|
+
formatted=CEF::PREFIX_FORMAT % [ 131, *test_prefix_vals.values ]
|
17
|
+
s.format_event(e) ==formatted
|
18
|
+
end
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'cef'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cef
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 7
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
- 0
|
10
|
+
version: 0.6.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ryan Breed
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-20 00:00:00 -06:00
|
19
|
+
default_executable: cef_sender
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 2
|
31
|
+
- 3
|
32
|
+
- 0
|
33
|
+
version: 2.3.0
|
34
|
+
prerelease: false
|
35
|
+
type: :development
|
36
|
+
requirement: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: bundler
|
39
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 23
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 0
|
48
|
+
- 0
|
49
|
+
version: 1.0.0
|
50
|
+
prerelease: false
|
51
|
+
type: :development
|
52
|
+
requirement: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: jeweler
|
55
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 7
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 5
|
64
|
+
- 2
|
65
|
+
version: 1.5.2
|
66
|
+
prerelease: false
|
67
|
+
type: :development
|
68
|
+
requirement: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rcov
|
71
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
prerelease: false
|
81
|
+
type: :development
|
82
|
+
requirement: *id004
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 2
|
93
|
+
- 3
|
94
|
+
- 0
|
95
|
+
version: 2.3.0
|
96
|
+
prerelease: false
|
97
|
+
type: :development
|
98
|
+
requirement: *id005
|
99
|
+
description: "Library and client "
|
100
|
+
email: opensource@breed.org
|
101
|
+
executables:
|
102
|
+
- cef_sender
|
103
|
+
extensions: []
|
104
|
+
|
105
|
+
extra_rdoc_files:
|
106
|
+
- LICENSE.txt
|
107
|
+
- README.rdoc
|
108
|
+
files:
|
109
|
+
- .document
|
110
|
+
- .rspec
|
111
|
+
- Gemfile
|
112
|
+
- LICENSE.txt
|
113
|
+
- README.rdoc
|
114
|
+
- Rakefile
|
115
|
+
- VERSION
|
116
|
+
- bin/cef_sender
|
117
|
+
- cef.gemspec
|
118
|
+
- lib/cef.rb
|
119
|
+
- spec/cef_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
121
|
+
has_rdoc: true
|
122
|
+
homepage: http://github.com/ryanbreed/cef
|
123
|
+
licenses:
|
124
|
+
- MIT
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
|
128
|
+
require_paths:
|
129
|
+
- lib
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
hash: 3
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
hash: 3
|
145
|
+
segments:
|
146
|
+
- 0
|
147
|
+
version: "0"
|
148
|
+
requirements: []
|
149
|
+
|
150
|
+
rubyforge_project:
|
151
|
+
rubygems_version: 1.5.2
|
152
|
+
signing_key:
|
153
|
+
specification_version: 3
|
154
|
+
summary: CEF Generation
|
155
|
+
test_files:
|
156
|
+
- spec/cef_spec.rb
|
157
|
+
- spec/spec_helper.rb
|