nexpose_ticketing 0.8.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/nexpose_jira +7 -0
- data/bin/nexpose_remedy +6 -0
- data/bin/nexpose_servicedesk +6 -0
- data/bin/nexpose_servicenow +6 -0
- data/lib/nexpose_ticketing/common_helper.rb +344 -0
- data/lib/nexpose_ticketing/config/servicedesk.config +3 -3
- data/lib/nexpose_ticketing/config/ticket_service.config +2 -0
- data/lib/nexpose_ticketing/helpers/jira_helper.rb +53 -107
- data/lib/nexpose_ticketing/helpers/remedy_helper.rb +208 -594
- data/lib/nexpose_ticketing/helpers/servicedesk_helper.rb +302 -289
- data/lib/nexpose_ticketing/helpers/servicenow_helper.rb +74 -165
- data/lib/nexpose_ticketing/nx_logger.rb +139 -30
- data/lib/nexpose_ticketing/queries.rb +148 -59
- data/lib/nexpose_ticketing/ticket_repository.rb +6 -0
- data/lib/nexpose_ticketing/ticket_service.rb +28 -16
- data/lib/nexpose_ticketing/version.rb +3 -0
- metadata +14 -6
- data/Gemfile.lock +0 -67
@@ -4,6 +4,8 @@ require 'net/https'
|
|
4
4
|
require 'uri'
|
5
5
|
require 'csv'
|
6
6
|
require 'nexpose_ticketing/nx_logger'
|
7
|
+
require 'nexpose_ticketing/version'
|
8
|
+
require 'nexpose_ticketing/common_helper'
|
7
9
|
|
8
10
|
# Serves as the ServiceNow interface for creating/updating issues from
|
9
11
|
# vulnelrabilities found in Nexpose.
|
@@ -12,7 +14,8 @@ class ServiceNowHelper
|
|
12
14
|
def initialize(servicenow_data, options)
|
13
15
|
@servicenow_data = servicenow_data
|
14
16
|
@options = options
|
15
|
-
@log = NexposeTicketing::
|
17
|
+
@log = NexposeTicketing::NxLogger.instance
|
18
|
+
@common_helper = NexposeTicketing::CommonHelper.new(@options)
|
16
19
|
end
|
17
20
|
|
18
21
|
# Sends a list of tickets (in JSON format) to ServiceNow individually (each ticket in the list
|
@@ -73,7 +76,7 @@ class ServiceNowHelper
|
|
73
76
|
#
|
74
77
|
def send_ticket(ticket, url, limit)
|
75
78
|
raise ArgumentError, 'HTTP Redirect too deep' if limit == 0
|
76
|
-
|
79
|
+
|
77
80
|
uri = URI.parse(url)
|
78
81
|
headers = { 'Content-Type' => 'application/json',
|
79
82
|
'Accept' => 'application/json' }
|
@@ -108,64 +111,23 @@ class ServiceNowHelper
|
|
108
111
|
# - List of JSON-formated tickets for creating within ServiceNow.
|
109
112
|
#
|
110
113
|
def prepare_create_tickets(vulnerability_list, nexpose_identifier_id)
|
111
|
-
@ticket
|
114
|
+
@log.log_message('Preparing ticket requests...')
|
112
115
|
case @options[:ticket_mode]
|
113
|
-
# 'D' Default
|
114
|
-
when 'D'
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
116
|
+
# 'D' Default IP *-* Vulnerability
|
117
|
+
when 'D' then matching_fields = ['ip_address', 'vulnerability_id']
|
118
|
+
# 'I' IP address -* Vulnerability
|
119
|
+
when 'I' then matching_fields = ['ip_address']
|
120
|
+
# 'V' Vulnerability -* Assets
|
121
|
+
when 'V' then matching_fields = ['vulnerability_id']
|
119
122
|
else
|
120
|
-
|
123
|
+
fail 'Unsupported ticketing mode selected.'
|
121
124
|
end
|
122
|
-
end
|
123
|
-
|
124
|
-
|
125
|
-
# Prepares a list of vulnerabilities into a list of JSON-formatted tickets (incidents) for
|
126
|
-
# ServiceNow. The preparation by default means that each vulnerability within Nexpose is a
|
127
|
-
# separate incident within ServiceNow. This makes for smaller, more actionalble incidents but
|
128
|
-
# could lead to a very large total number of incidents.
|
129
|
-
#
|
130
|
-
# * *Args* :
|
131
|
-
# - +vulnerability_list+ - CSV of vulnerabilities within Nexpose.
|
132
|
-
#
|
133
|
-
# * *Returns* :
|
134
|
-
# - List of JSON-formated tickets for creating within ServiceNow.
|
135
|
-
#
|
136
|
-
def prepare_create_tickets_default(vulnerability_list, nexpose_identifier_id)
|
137
|
-
@log.log_message('Preparing tickets by default method.')
|
138
|
-
tickets = []
|
139
|
-
CSV.parse(vulnerability_list.chomp, headers: :first_row) do |row|
|
140
|
-
# ServiceNow doesn't allow new line characters in the incident short description.
|
141
|
-
summary = row['summary'].gsub(/\n/, ' ')
|
142
|
-
|
143
|
-
@log.log_message("Creating ticket with IP address: #{row['ip_address']}, Nexpose identifier id: #{nexpose_identifier_id} and summary: #{summary}")
|
144
|
-
# NXID in the u_work_notes is a unique identifier used to query incidents to update/resolve
|
145
|
-
# incidents as they are resolved in Nexpose.
|
146
125
|
|
147
|
-
|
148
|
-
'sysparm_action' => 'insert',
|
149
|
-
'u_caller_id' => "#{@servicenow_data[:username]}",
|
150
|
-
'u_category' => 'Software',
|
151
|
-
'u_impact' => '1',
|
152
|
-
'u_urgency' => '1',
|
153
|
-
'u_short_description' => "#{row['ip_address']} => #{summary}",
|
154
|
-
'u_work_notes' => "Summary: #{summary}
|
155
|
-
Fix: #{row['fix']}
|
156
|
-
----------------------------------------------------------------------------
|
157
|
-
URL: #{row['url']}
|
158
|
-
NXID: #{nexpose_identifier_id}#{row['asset_id']}#{row['vulnerability_id']}#{row['solution_id']}"
|
159
|
-
}.to_json
|
160
|
-
tickets.push(ticket)
|
161
|
-
end
|
162
|
-
tickets
|
126
|
+
prepare_tickets(vulnerability_list, nexpose_identifier_id, matching_fields)
|
163
127
|
end
|
164
128
|
|
165
129
|
# Prepares a list of vulnerabilities into a list of JSON-formatted tickets (incidents) for
|
166
|
-
# ServiceNow.
|
167
|
-
# address are consolidated into a single ServiceNow incident. This reduces the number of incidents
|
168
|
-
# within ServiceNow but greatly increases the size of the work notes.
|
130
|
+
# ServiceNow.
|
169
131
|
#
|
170
132
|
# * *Args* :
|
171
133
|
# - +vulnerability_list+ - CSV of vulnerabilities within Nexpose.
|
@@ -173,57 +135,65 @@ class ServiceNowHelper
|
|
173
135
|
# * *Returns* :
|
174
136
|
# - List of JSON-formated tickets for creating within ServiceNow.
|
175
137
|
#
|
176
|
-
def
|
177
|
-
@
|
138
|
+
def prepare_tickets(vulnerability_list, nexpose_identifier_id, matching_fields)
|
139
|
+
@ticket = Hash.new(-1)
|
140
|
+
|
141
|
+
@log.log_message("Preparing tickets in #{options[:ticket_mode]} address.")
|
178
142
|
tickets = []
|
179
|
-
|
143
|
+
previous_row = nil
|
144
|
+
description = nil
|
145
|
+
action = 'insert'
|
180
146
|
CSV.parse(vulnerability_list.chomp, headers: :first_row) do |row|
|
181
|
-
if
|
182
|
-
|
183
|
-
@
|
147
|
+
if previous_row.nil?
|
148
|
+
previous_row = row.dup
|
149
|
+
nxid = @common_helper.generate_nxid(nexpose_identifier_id, row)
|
150
|
+
action = unless row['comparison'].nil? || row['comparison'] == 'New'
|
151
|
+
'update'
|
152
|
+
else
|
153
|
+
'insert'
|
154
|
+
end
|
184
155
|
@ticket = {
|
185
|
-
'sysparm_action' =>
|
156
|
+
'sysparm_action' => action,
|
186
157
|
'u_caller_id' => "#{@servicenow_data[:username]}",
|
187
158
|
'u_category' => 'Software',
|
188
159
|
'u_impact' => '1',
|
189
160
|
'u_urgency' => '1',
|
190
|
-
'u_short_description' =>
|
191
|
-
'
|
192
|
-
|
193
|
-
+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"
|
161
|
+
'u_short_description' => @common_helper.get_title(row),
|
162
|
+
'sysparm_query' => "active=true^u_work_notesCONTAINSNXID: #{nxid}",
|
163
|
+
'u_work_notes' => ""
|
194
164
|
}
|
195
|
-
|
196
|
-
|
197
|
-
@
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
Fix: #{row['fix']}"
|
202
|
-
unless row['url'].nil?
|
203
|
-
@ticket['u_work_notes'] +=
|
204
|
-
"\n----------------------------------------------------------------------------
|
205
|
-
URL: #{row['url']}"
|
206
|
-
end
|
207
|
-
end
|
208
|
-
unless current_ip == row['ip_address']
|
209
|
-
# NXID in the u_work_notes is the unique identifier used to query incidents to update them.
|
210
|
-
@log.log_message("Found new IP address. Finishing ticket with with IP address: #{current_ip} and moving onto IP #{row['ip_address']}")
|
211
|
-
@ticket['u_work_notes'] += "\nNXID: #{nexpose_identifier_id}#{current_ip}"
|
212
|
-
@ticket = @ticket.to_json
|
165
|
+
description = @common_helper.get_description(nexpose_identifier_id, row)
|
166
|
+
elsif matching_fields.any? { |x| previous_row[x].nil? || previous_row[x] != row[x] }
|
167
|
+
info = @common_helper.get_field_info(matching_fields, previous_row)
|
168
|
+
@log.log_message("Generated ticket with #{info}")
|
169
|
+
|
170
|
+
@ticket['u_work_notes'] = @common_helper.print_description(description)
|
213
171
|
tickets.push(@ticket)
|
214
|
-
|
172
|
+
previous_row = nil
|
173
|
+
description = nil
|
215
174
|
redo
|
175
|
+
else
|
176
|
+
if !row['comparison'].nil? && row['comparison'] != 'New'
|
177
|
+
action = 'update'
|
178
|
+
end
|
179
|
+
description = @common_helper.update_description(description, row)
|
216
180
|
end
|
217
181
|
end
|
218
|
-
|
219
|
-
@ticket
|
220
|
-
|
221
|
-
|
182
|
+
|
183
|
+
unless @ticket.nil? || @ticket.empty?
|
184
|
+
@ticket['u_work_notes'] = @common_helper.print_description(description) unless (@ticket.size == 0)
|
185
|
+
tickets.push(@ticket)
|
186
|
+
end
|
187
|
+
@log.log_message("Generated <#{tickets.count.to_s}> tickets.")
|
188
|
+
|
189
|
+
tickets.map do |t|
|
190
|
+
t.delete('sysparm_query') if t['sysparm_action'] == 'insert'
|
191
|
+
t.to_json
|
192
|
+
end
|
222
193
|
end
|
223
|
-
|
224
|
-
# Prepare ticket updates from the CSV of vulnerabilities exported from Nexpose.
|
225
|
-
#
|
226
|
-
# are ordered by IP address and then by ticket_status, allowing the method to loop through and
|
194
|
+
|
195
|
+
# Prepare ticket updates from the CSV of vulnerabilities exported from Nexpose. The list of vulnerabilities
|
196
|
+
# are ordered depending on the ticketing mode and then by ticket_status, allowing the method to loop through and
|
227
197
|
# display new, old, and same vulnerabilities in that order.
|
228
198
|
#
|
229
199
|
# - +vulnerability_list+ - CSV of vulnerabilities within Nexpose.
|
@@ -232,67 +202,18 @@ class ServiceNowHelper
|
|
232
202
|
# - List of JSON-formated tickets for updating within ServiceNow.
|
233
203
|
#
|
234
204
|
def prepare_update_tickets(vulnerability_list, nexpose_identifier_id)
|
235
|
-
fail 'Ticket updates are only supported in IP-address mode.' if @options[:ticket_mode] == 'D'
|
236
|
-
@ticket = Hash.new(-1)
|
237
205
|
|
238
|
-
@
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
@log.log_message("Creating ticket update with IP address: #{row['ip_address']} and Nexpose identifier ID: #{nexpose_identifier_id}")
|
247
|
-
@log.log_message("Ticket status #{ticket_status}")
|
248
|
-
action = 'update'
|
249
|
-
if ticket_status == 'New'
|
250
|
-
action = 'insert'
|
251
|
-
end
|
252
|
-
@ticket = {
|
253
|
-
'sysparm_action' => action,
|
254
|
-
'sysparm_query' => "u_work_notesCONTAINSNXID: #{nexpose_identifier_id}#{row['ip_address']}",
|
255
|
-
'u_work_notes' =>
|
256
|
-
"\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
257
|
-
++ #{row['comparison']} Vulnerabilities +++++++++++++++++++++++++++++++++++++
|
258
|
-
+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"
|
259
|
-
}
|
260
|
-
end
|
261
|
-
if current_ip == row['ip_address']
|
262
|
-
# If the ticket_status is different, add a a new 'header' to signify a new block of tickets.
|
263
|
-
unless ticket_status == row['comparison']
|
264
|
-
@ticket['u_work_notes'] +=
|
265
|
-
"\n\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
266
|
-
++ #{row['comparison']} Vulnerabilities +++++++++++++++++++++++++++++++++++++
|
267
|
-
+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"
|
268
|
-
ticket_status = row['comparison']
|
269
|
-
end
|
270
|
-
|
271
|
-
@ticket['u_work_notes'] +=
|
272
|
-
"\n\n==========================================
|
273
|
-
Summary: #{row['summary']}
|
274
|
-
----------------------------------------------------------------------------
|
275
|
-
Fix: #{row['fix']}"
|
276
|
-
# Only add the URL block if data exists in the row.
|
277
|
-
unless row['url'].nil?
|
278
|
-
@ticket['u_work_notes'] +=
|
279
|
-
"----------------------------------------------------------------------------
|
280
|
-
URL: #{row['url']}"
|
281
|
-
end
|
282
|
-
end
|
283
|
-
unless current_ip == row['ip_address']
|
284
|
-
# NXID in the u_work_notes is the unique identifier used to query incidents to update them.
|
285
|
-
@ticket['u_work_notes'] += "\nNXID: #{nexpose_identifier_id}#{current_ip}"
|
286
|
-
@ticket = @ticket.to_json
|
287
|
-
tickets.push(@ticket)
|
288
|
-
current_ip = -1
|
289
|
-
redo
|
290
|
-
end
|
206
|
+
case @options[:ticket_mode]
|
207
|
+
when 'D' then fail 'Ticket updates are not supported in Default mode.'
|
208
|
+
# 'I' IP address -* Vulnerability
|
209
|
+
when 'I' then matching_fields = ['ip_address']
|
210
|
+
# 'V' Vulnerability -* Assets
|
211
|
+
when 'V' then matching_fields = ['vulnerability_id']
|
212
|
+
else
|
213
|
+
fail 'Unsupported ticketing mode selected.'
|
291
214
|
end
|
292
|
-
|
293
|
-
|
294
|
-
tickets.push(@ticket.to_json) unless @ticket.nil?
|
295
|
-
tickets
|
215
|
+
|
216
|
+
prepare_tickets(vulnerability_list, nexpose_identifier_id, matching_fields)
|
296
217
|
end
|
297
218
|
|
298
219
|
|
@@ -310,28 +231,16 @@ class ServiceNowHelper
|
|
310
231
|
tickets = []
|
311
232
|
@nxid = nil
|
312
233
|
CSV.parse(vulnerability_list.chomp, headers: :first_row) do |row|
|
313
|
-
|
314
|
-
# 'D' Default mode: IP *-* Vulnerability
|
315
|
-
when 'D'
|
316
|
-
@nxid = "#{nexpose_identifier_id}#{row['asset_id']}#{row['vulnerability_id']}#{row['solution_id']}"
|
317
|
-
# 'I' IP address mode: IP address -* Vulnerability
|
318
|
-
when 'I'
|
319
|
-
@nxid = "#{nexpose_identifier_id}#{row['ip_address']}"
|
320
|
-
# 'V' Vulnerability mode: Vulnerability -* IP address
|
321
|
-
## when 'V'
|
322
|
-
## @nxid = "#{nexpose_identifier_id}#{row['asset_id']}#{row['vulnerability_id']}"
|
323
|
-
else
|
324
|
-
fail 'Could not close tickets - do not understand the ticketing mode!'
|
325
|
-
end
|
234
|
+
@nxid = @common_helper.generate_nxid(nexpose_identifier_id, row)
|
326
235
|
# 'state' 7 is the "Closed" state within ServiceNow.
|
327
236
|
@log.log_message("Closing ticket with NXID: #{@nxid}.")
|
328
237
|
ticket = {
|
329
238
|
'sysparm_action' => 'update',
|
330
|
-
'sysparm_query' => "u_work_notesCONTAINSNXID: #{@nxid}",
|
239
|
+
'sysparm_query' => "active=true^u_work_notesCONTAINSNXID: #{@nxid}",
|
331
240
|
'state' => '7'
|
332
241
|
}.to_json
|
333
242
|
tickets.push(ticket)
|
334
243
|
end
|
335
244
|
tickets
|
336
245
|
end
|
337
|
-
end
|
246
|
+
end
|
@@ -1,41 +1,150 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
require 'singleton'
|
5
|
+
|
1
6
|
module NexposeTicketing
|
2
|
-
class
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
class NxLogger
|
8
|
+
include Singleton
|
9
|
+
attr_accessor :options, :statistic_key, :product, :logger_file
|
10
|
+
LOG_PATH = "./logs/rapid7_%s.log"
|
11
|
+
KEY_FORMAT = "external.integration.%s"
|
12
|
+
PRODUCT_FORMAT = "%s_%s"
|
13
|
+
|
14
|
+
DEFAULT_LOG = 'integration'
|
15
|
+
PRODUCT_RANGE = 3..30
|
16
|
+
KEY_RANGE = 3..15
|
17
|
+
|
18
|
+
ENDPOINT = '/data/external/statistic/'
|
19
|
+
|
20
|
+
def initialize()
|
21
|
+
@logger_file = get_log_path product
|
22
|
+
setup_logging(true, 'info')
|
23
|
+
end
|
24
|
+
|
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
|
+
begin
|
31
|
+
@statistic_key = get_statistic_key vendor
|
32
|
+
@product = get_product product_name, gem_version
|
33
|
+
rescue => e
|
34
|
+
#Continue
|
13
35
|
end
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
if enabled
|
21
|
-
require 'logger'
|
22
|
-
directory = File.dirname(LOGGER_FILE)
|
23
|
-
FileUtils.mkdir_p(directory) unless File.directory?(directory)
|
24
|
-
@log = Logger.new(LOGGER_FILE, 'monthly')
|
25
|
-
@log.level = Logger::INFO
|
26
|
-
log_message('Logging enabled for helper.')
|
36
|
+
end
|
37
|
+
|
38
|
+
def setup_logging(enabled, log_level = nil)
|
39
|
+
unless enabled || @log.nil?
|
40
|
+
log_message('Logging disabled.')
|
41
|
+
return
|
27
42
|
end
|
43
|
+
|
44
|
+
@logger_file = get_log_path product
|
45
|
+
|
46
|
+
require 'logger'
|
47
|
+
directory = File.dirname(@logger_file)
|
48
|
+
FileUtils.mkdir_p(directory) unless File.directory?(directory)
|
49
|
+
io = IO.for_fd(IO.sysopen(@logger_file, 'a'))
|
50
|
+
io.autoclose = false
|
51
|
+
io.sync = true
|
52
|
+
@log = Logger.new(io, 'weekly')
|
53
|
+
@log.level = if log_level.casecmp('info') == 0
|
54
|
+
Logger::INFO
|
55
|
+
else
|
56
|
+
Logger::DEBUG
|
57
|
+
end
|
58
|
+
log_message("Logging enabled at level <#{log_level}>")
|
28
59
|
end
|
29
60
|
|
30
|
-
# Logs
|
61
|
+
# Logs an info message
|
31
62
|
def log_message(message)
|
32
|
-
@log.info(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?
|
74
|
+
end
|
75
|
+
|
76
|
+
# Logs a warn message
|
77
|
+
def log_warn_message(message)
|
78
|
+
@log.warn(message) unless @log.nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
def log_stat_message(message)
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_log_path(product)
|
85
|
+
product.downcase! unless product.nil?
|
86
|
+
File.join(File.dirname(__FILE__), LOG_PATH % (product || DEFAULT_LOG))
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_statistic_key(vendor)
|
90
|
+
if vendor.nil? || vendor.length < KEY_RANGE.min
|
91
|
+
log_stat_message("Vendor length is below minimum of <#{KEY_RANGE}>")
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
|
95
|
+
KEY_FORMAT % vendor[0...KEY_RANGE.max].downcase
|
33
96
|
end
|
34
97
|
|
35
|
-
|
36
|
-
|
37
|
-
|
98
|
+
def get_product(product, version)
|
99
|
+
return nil if (product.nil? || version.nil?)
|
100
|
+
product = (PRODUCT_FORMAT % [product, version])[0...PRODUCT_RANGE.max]
|
101
|
+
|
102
|
+
if product.length < PRODUCT_RANGE.min
|
103
|
+
log_stat_message("Product length below minimum <#{PRODUCT_RANGE.min}>.")
|
104
|
+
return nil
|
105
|
+
end
|
106
|
+
product.downcase
|
107
|
+
end
|
108
|
+
|
109
|
+
def generate_payload(statistic_value='')
|
110
|
+
payload = {'statistic-key' => @statistic_key,
|
111
|
+
'statistic-value' => statistic_value,
|
112
|
+
'product' => @product}
|
113
|
+
JSON.generate(payload)
|
114
|
+
end
|
115
|
+
|
116
|
+
def send(nexpose_address, nexpose_port, session_id, payload)
|
117
|
+
header = {'Content-Type' => 'application/json',
|
118
|
+
'nexposeCCSessionID' => session_id,
|
119
|
+
'Cookie' => "nexposeCCSessionID=#{session_id}"}
|
120
|
+
req = Net::HTTP::Put.new(ENDPOINT, header)
|
121
|
+
req.body = payload
|
122
|
+
http_instance = Net::HTTP.new(nexpose_address, nexpose_port)
|
123
|
+
http_instance.use_ssl = true
|
124
|
+
http_instance.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
125
|
+
response = http_instance.start { |http| http.request(req) }
|
126
|
+
log_stat_message "Received code #{response.code} from Nexpose console."
|
127
|
+
log_stat_message "Received message #{response.msg} from Nexpose console."
|
128
|
+
log_stat_message 'Finished sending statistics data to Nexpose.'
|
129
|
+
response.code
|
130
|
+
end
|
131
|
+
|
132
|
+
def on_connect(nexpose_address, nexpose_port, session_id, value)
|
133
|
+
log_stat_message 'Sending statistics data to Nexpose'
|
134
|
+
|
135
|
+
if @product.nil? || @statistic_key.nil?
|
136
|
+
log_stat_message('Invalid product name and/or statistics key.')
|
137
|
+
log_stat_message('Statistics collection not enabled.')
|
138
|
+
return
|
139
|
+
end
|
140
|
+
|
141
|
+
begin
|
142
|
+
payload = generate_payload value
|
143
|
+
send(nexpose_address, nexpose_port, session_id, payload)
|
144
|
+
rescue => e
|
145
|
+
#Let the program continue
|
146
|
+
end
|
38
147
|
end
|
39
148
|
|
40
149
|
end
|
41
|
-
end
|
150
|
+
end
|