nexpose_sourcefire 0.2.0 → 0.2.1

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: 9c9fb896af914fcbcdbda0d0bde478430f11c359
4
- data.tar.gz: 2d3b0d70909afe2a7ebe7d42b6f16c6e0d9b22e4
3
+ metadata.gz: 66a0bd838b05bf5c28eb153bc0189f16709555c3
4
+ data.tar.gz: f546f226efeb05c8c57b726b64354b6df78019f4
5
5
  SHA512:
6
- metadata.gz: 364fca4f693195b3b82ddd25753e49b66af98a95f39134ddff023497f48f35f4efeff3e98a83e2b223cdcdcecb760e9d7551c29fe39e3bce483edb9ba2a5e463
7
- data.tar.gz: b9615320e59700e035ae1390777cfd95be116f42f08f06b33c24792fed36491f52220fcb57541a32106701047d8569288a62be58c456b43b3479e88760c585b3
6
+ metadata.gz: ac24ce75871839767af860c5168ac9b87d54c2253e7ab302cb4e23bda9adab55cc6235d04811c76c06758227d2f9b27b925cc2f8e7590864ab41b063008f139c
7
+ data.tar.gz: eb4de1ee51d40cdb57e843ada389d28b98700511065984472bbd54bbbf4c1450315084fa1f1791a8a08a586dc587198eb04d4eb707ac8f5d1efed07be9ba4205
@@ -25,8 +25,7 @@ raise 'Must configure SourceFire settings before starting' if ENV['SOURCEFIRE_AD
25
25
 
26
26
  log = Sourcefire::NxLogger.instance
27
27
  log.setup_statistics_collection(Sourcefire::PRODUCT, Sourcefire::VENDOR, Sourcefire::VERSION)
28
- logging_enabled = configuration_settings[:options][:logging_enabled] || false
29
- log.setup_logging(logging_enabled,
28
+ log.setup_logging(configuration_settings[:options][:logging_enabled],
30
29
  configuration_settings[:options][:log_level])
31
30
 
32
31
  configuration_settings[:nexpose_address] = ENV['NEXPOSE_URL']
@@ -6,27 +6,23 @@ require 'singleton'
6
6
  module Sourcefire
7
7
  class NxLogger
8
8
  include Singleton
9
- attr_accessor :options, :statistic_key, :product, :logger_file
10
9
  LOG_PATH = "./logs/rapid7_%s.log"
11
10
  KEY_FORMAT = "external.integration.%s"
12
11
  PRODUCT_FORMAT = "%s_%s"
13
12
 
14
13
  DEFAULT_LOG = 'integration'
15
- PRODUCT_RANGE = 3..30
14
+ PRODUCT_RANGE = 4..30
16
15
  KEY_RANGE = 3..15
17
16
 
18
17
  ENDPOINT = '/data/external/statistic/'
19
18
 
20
19
  def initialize()
21
- @logger_file = get_log_path product
20
+ create_calls
21
+ @logger_file = get_log_path @product
22
22
  setup_logging(true, 'info')
23
23
  end
24
24
 
25
25
  def setup_statistics_collection(vendor, product_name, gem_version)
26
- #Remove illegal characters
27
- vendor.to_s.gsub!('-', '_')
28
- product_name.to_s.gsub!('-', '_')
29
-
30
26
  begin
31
27
  @statistic_key = get_statistic_key vendor
32
28
  @product = get_product product_name, gem_version
@@ -35,13 +31,14 @@ module Sourcefire
35
31
  end
36
32
  end
37
33
 
38
- def setup_logging(enabled, log_level = 'info')
39
- unless enabled || @log.nil?
40
- log_message('Logging disabled.')
41
- return
42
- end
34
+ def setup_logging(enabled, log_level = 'info', stdout=false)
35
+ @stdout = stdout
43
36
 
44
- @logger_file = get_log_path product
37
+ log_message('Logging disabled.') unless enabled || @log.nil?
38
+ @enabled = enabled
39
+ return unless @enabled
40
+
41
+ @logger_file = get_log_path @product
45
42
 
46
43
  require 'logger'
47
44
  directory = File.dirname(@logger_file)
@@ -58,24 +55,19 @@ module Sourcefire
58
55
  log_message("Logging enabled at level <#{log_level}>")
59
56
  end
60
57
 
61
- # Logs an info message
62
- def log_message(message)
63
- @log.info(message) unless @log.nil?
64
- end
65
-
66
- # Logs a debug message
67
- def log_debug_message(message)
68
- @log.debug(message) unless @log.nil?
69
- end
70
-
71
- # Logs an error message
72
- def log_error_message(message)
73
- @log.error(message) unless @log.nil?
58
+ def create_calls
59
+ levels = [:info, :debug, :error, :warn]
60
+ levels.each do |level|
61
+ method_name =
62
+ define_singleton_method("log_#{level.to_s}_message") do |message|
63
+ puts message if @stdout
64
+ @log.send(level, message) unless !@enabled || @log.nil?
65
+ end
66
+ end
74
67
  end
75
68
 
76
- # Logs a warn message
77
- def log_warn_message(message)
78
- @log.warn(message) unless @log.nil?
69
+ def log_message(message)
70
+ log_info_message message
79
71
  end
80
72
 
81
73
  def log_stat_message(message)
@@ -92,13 +84,28 @@ module Sourcefire
92
84
  return nil
93
85
  end
94
86
 
87
+ vendor.gsub!('-', '_')
88
+ vendor.slice! vendor.rindex('_') until vendor.count('_') <= 1
89
+
90
+ vendor.delete! "^A-Za-z0-9\_"
91
+
95
92
  KEY_FORMAT % vendor[0...KEY_RANGE.max].downcase
96
93
  end
97
94
 
98
95
  def get_product(product, version)
99
- return nil if (product.nil? || version.nil?)
96
+ return nil if ((product.nil? || product.empty?) ||
97
+ (version.nil? || version.empty?))
98
+
99
+ product.gsub!('-', '_')
100
+ product.slice! product.rindex('_') until product.count('_') <= 1
101
+
102
+ product.delete! "^A-Za-z0-9\_"
103
+ version.delete! "^A-Za-z0-9\.\-"
104
+
100
105
  product = (PRODUCT_FORMAT % [product, version])[0...PRODUCT_RANGE.max]
101
106
 
107
+ product.slice! product.rindex(/[A-Z0-9]/i)+1..-1
108
+
102
109
  if product.length < PRODUCT_RANGE.min
103
110
  log_stat_message("Product length below minimum <#{PRODUCT_RANGE.min}>.")
104
111
  return nil
@@ -107,9 +114,12 @@ module Sourcefire
107
114
  end
108
115
 
109
116
  def generate_payload(statistic_value='')
110
- payload = {'statistic-key' => @statistic_key,
111
- 'statistic-value' => statistic_value,
112
- 'product' => @product}
117
+ product_name, separator, version = @product.to_s.rpartition('_')
118
+ payload_value = {'version' => version}.to_json
119
+
120
+ payload = {'statistic-key' => @statistic_key.to_s,
121
+ 'statistic-value' => payload_value,
122
+ 'product' => product_name}
113
123
  JSON.generate(payload)
114
124
  end
115
125
 
@@ -126,6 +136,7 @@ module Sourcefire
126
136
  log_stat_message "Received code #{response.code} from Nexpose console."
127
137
  log_stat_message "Received message #{response.msg} from Nexpose console."
128
138
  log_stat_message 'Finished sending statistics data to Nexpose.'
139
+
129
140
  response.code
130
141
  end
131
142
 
@@ -1,5 +1,5 @@
1
1
  module Sourcefire
2
2
  PRODUCT = 'Sourcefire'
3
3
  VENDOR = 'Sourcefire'
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
@@ -84,13 +84,17 @@ module Sourcefire
84
84
  redo
85
85
  end
86
86
 
87
- assets << current_asset + "ScanFlush\n" unless current_asset.nil?
87
+ assets << current_asset unless current_asset.nil?
88
88
  @log.log_message("Total of #{assets.count} assets")
89
89
  assets
90
90
  end
91
91
 
92
92
  def process_nexpose_data(report_file)
93
- max_data_size = 524288
93
+ #Originally using the value returned from SourceFire as the max data size.
94
+ #However, this caused issues with some ticket creation / batching, and the
95
+ #reduced value was hard-coded below.
96
+ #max_data_size = 524288
97
+ max_data_size = 450000
94
98
 
95
99
  @log.log_message('Creating data sets')
96
100
  header = "SetSource,NeXpose Scan Report\n"
@@ -107,7 +111,7 @@ module Sourcefire
107
111
  @log.log_message("Got a message of type <#{msg_details[0]}> and size <#{msg_details[1]}>")
108
112
  max_size = read_from_socket(ssl_socket, msg_details[1], msg_details[0])
109
113
  @log.log_message("Max message length is <#{max_size}>")
110
- max_data_size = max_size.first
114
+ #max_data_size = max_size.first
111
115
  end
112
116
  ssl_socket.close
113
117
 
@@ -116,11 +120,19 @@ module Sourcefire
116
120
 
117
121
  assets.each do |asset|
118
122
  if data_sets[-1].nil?
119
- data_sets << header.dup + asset
123
+ if (asset + footer).bytesize < max_data_size
124
+ data_sets << header.dup + asset
125
+ else
126
+ batch_single_ip(data_sets, asset, header, footer, max_data_size)
127
+ end
120
128
  elsif (data_sets[-1].to_s + asset + footer).bytesize < max_data_size
121
129
  data_sets[-1] += asset
122
- else
130
+ elsif (header.dup + asset + footer).bytesize < max_data_size
131
+ data_sets[-1] += footer
123
132
  data_sets << header.dup + asset
133
+ else
134
+ data_sets[-1] += footer
135
+ batch_single_ip(data_sets, asset, header, footer, max_data_size)
124
136
  end
125
137
  end
126
138
 
@@ -137,6 +149,27 @@ module Sourcefire
137
149
  data_sets
138
150
  end
139
151
 
152
+ def batch_single_ip(data_sets, asset, header, footer, max_data_size)
153
+ split_asset = nil
154
+ initial = true
155
+ update_footer = "ScanUpdate"
156
+
157
+ asset.each_line do |line|
158
+ if split_asset.nil?
159
+ split_asset = header.dup + line
160
+ elsif (split_asset + line + footer).bytesize < max_data_size
161
+ split_asset += line
162
+ else
163
+ data_sets << split_asset + (initial ? footer : update_footer)
164
+ initial = false
165
+ split_asset = header.dup
166
+ redo
167
+ end
168
+ end
169
+ data_sets << split_asset + update_footer
170
+ data_sets << header.dup
171
+ end
172
+
140
173
  def process_nexpose_data_alt(report_file)
141
174
  max_data_size = 524288
142
175
 
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexpose_sourcefire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - JJ Cassidy
8
8
  - David Valente
9
+ - Adam Robinson
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2016-02-10 00:00:00.000000000 Z
13
+ date: 2016-07-15 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: bundler
@@ -56,7 +57,7 @@ dependencies:
56
57
  description: This GEM allows enables the importing of Nexpose host and vulnerability
57
58
  data into SourceFire
58
59
  email:
59
- - integrations_support@rapid7.com
60
+ - support@rapid7.com
60
61
  executables:
61
62
  - nexpose_sourcefire
62
63
  extensions: []
@@ -75,8 +76,6 @@ files:
75
76
  - lib/sourcefire/queries.rb
76
77
  - lib/sourcefire/version.rb
77
78
  - lib/sourcefire_connector.rb
78
- - sourcefire.gemspec
79
- - sourcefire.iml
80
79
  homepage: http://www.rapid7.com
81
80
  licenses:
82
81
  - MIT
@@ -97,8 +96,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
96
  version: '0'
98
97
  requirements: []
99
98
  rubyforge_project:
100
- rubygems_version: 2.4.8
99
+ rubygems_version: 2.4.3
101
100
  signing_key:
102
101
  specification_version: 4
103
102
  summary: Nexpose SourceFire Integration GEM
104
103
  test_files: []
104
+ has_rdoc:
data/sourcefire.gemspec DELETED
@@ -1,25 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'sourcefire/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = 'nexpose_sourcefire'
8
- spec.version = Sourcefire::VERSION
9
- spec.authors = ['JJ Cassidy', 'David Valente']
10
- spec.email = ['integrations_support@rapid7.com']
11
-
12
- spec.summary = 'Nexpose SourceFire Integration GEM'
13
- spec.description = 'This GEM allows enables the importing of Nexpose host and vulnerability data into SourceFire'
14
- spec.homepage = 'http://www.rapid7.com'
15
- spec.license = 'MIT'
16
-
17
- spec.files = Dir['[A-Z]*'] + Dir['lib/**/*'] + Dir['bin/**']
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_development_dependency "bundler", "~> 1.10"
22
- spec.add_development_dependency "rake", "~> 10.0"
23
- spec.add_runtime_dependency 'nexpose', "~> 0.9"
24
- spec.required_ruby_version = '>= 1.9'
25
- end
data/sourcefire.iml DELETED
@@ -1,22 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="RUBY_MODULE" version="4">
3
- <component name="FacetManager">
4
- <facet type="gem" name="Ruby Gem">
5
- <configuration>
6
- <option name="GEM_APP_ROOT_PATH" value="$MODULE_DIR$" />
7
- <option name="GEM_APP_TEST_PATH" value="" />
8
- <option name="GEM_APP_LIB_PATH" value="" />
9
- </configuration>
10
- </facet>
11
- </component>
12
- <component name="NewModuleRootManager" inherit-compiler-output="true">
13
- <exclude-output />
14
- <content url="file://$MODULE_DIR$" />
15
- <orderEntry type="jdk" jdkName="RVM: ruby-1.9.3-p547 [global]" jdkType="RUBY_SDK" />
16
- <orderEntry type="sourceFolder" forTests="false" />
17
- <orderEntry type="library" scope="PROVIDED" name="bundler (v1.10.4, RVM: ruby-1.9.3-p547 [global]) [gem]" level="application" />
18
- <orderEntry type="library" scope="PROVIDED" name="nexpose (v0.9.8, RVM: ruby-1.9.3-p547 [global]) [gem]" level="application" />
19
- <orderEntry type="library" scope="PROVIDED" name="rake (v10.4.2, RVM: ruby-1.9.3-p547 [global]) [gem]" level="application" />
20
- <orderEntry type="library" scope="PROVIDED" name="rex (v2.0.7, RVM: ruby-1.9.3-p547 [global]) [gem]" level="application" />
21
- </component>
22
- </module>