nexpose 0.0.9 → 0.0.91
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/lib/nexpose.rb +13 -3236
- data/lib/nexpose/api_request.rb +144 -0
- data/lib/nexpose/connection.rb +106 -0
- data/lib/nexpose/creds.rb +189 -0
- data/lib/nexpose/error.rb +21 -0
- data/lib/nexpose/misc.rb +122 -0
- data/lib/nexpose/report.rb +570 -0
- data/lib/nexpose/scan.rb +280 -0
- data/lib/nexpose/scan_engine.rb +147 -0
- data/lib/nexpose/silo.rb +347 -0
- data/lib/nexpose/site.rb +877 -0
- data/lib/nexpose/ticket.rb +108 -0
- data/lib/nexpose/util.rb +35 -0
- data/lib/nexpose/vuln.rb +520 -0
- data/nexpose.gemspec +3 -3
- metadata +22 -11
data/lib/nexpose/misc.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
module Nexpose
|
2
|
+
module NexposeAPI
|
3
|
+
include XMLUtils
|
4
|
+
|
5
|
+
def device_delete(param)
|
6
|
+
r = execute(make_xml('DeviceDeleteRequest', {'device-id' => param}))
|
7
|
+
r.success
|
8
|
+
end
|
9
|
+
|
10
|
+
def asset_group_delete(connection, id, debug = false)
|
11
|
+
r = execute(make_xml('AssetGroupDeleteRequest', {'group-id' => param}))
|
12
|
+
r.success
|
13
|
+
end
|
14
|
+
|
15
|
+
#-------------------------------------------------------------------------
|
16
|
+
# Returns all asset group information
|
17
|
+
#-------------------------------------------------------------------------
|
18
|
+
def asset_groups_listing()
|
19
|
+
r = execute(make_xml('AssetGroupListingRequest'))
|
20
|
+
|
21
|
+
if r.success
|
22
|
+
res = []
|
23
|
+
r.res.elements.each('//AssetGroupSummary') do |group|
|
24
|
+
res << {
|
25
|
+
:asset_group_id => group.attributes['id'].to_i,
|
26
|
+
:name => group.attributes['name'].to_s,
|
27
|
+
:description => group.attributes['description'].to_s,
|
28
|
+
:risk_score => group.attributes['riskscore'].to_f,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
res
|
32
|
+
else
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
#-------------------------------------------------------------------------
|
38
|
+
# Returns an asset group configuration information for a specific group ID
|
39
|
+
#-------------------------------------------------------------------------
|
40
|
+
def asset_group_config(group_id)
|
41
|
+
r = execute(make_xml('AssetGroupConfigRequest', {'group-id' => group_id}))
|
42
|
+
|
43
|
+
if r.success
|
44
|
+
res = []
|
45
|
+
r.res.elements.each('//Devices/device') do |device_info|
|
46
|
+
res << {
|
47
|
+
:device_id => device_info.attributes['id'].to_i,
|
48
|
+
:site_id => device_info.attributes['site-id'].to_i,
|
49
|
+
:address => device_info.attributes['address'].to_s,
|
50
|
+
:riskfactor => device_info.attributes['riskfactor'].to_f,
|
51
|
+
}
|
52
|
+
end
|
53
|
+
res
|
54
|
+
else
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Lists all the users for the NSC along with the user details.
|
61
|
+
#
|
62
|
+
def list_users
|
63
|
+
r = execute(make_xml('UserListingRequest'))
|
64
|
+
if r.success
|
65
|
+
res = []
|
66
|
+
r.res.elements.each('//UserSummary') do |user_summary|
|
67
|
+
res << {
|
68
|
+
:auth_source => user_summary.attributes['authSource'],
|
69
|
+
:auth_module => user_summary.attributes['authModule'],
|
70
|
+
:user_name => user_summary.attributes['userName'],
|
71
|
+
:full_name => user_summary.attributes['fullName'],
|
72
|
+
:email => user_summary.attributes['email'],
|
73
|
+
:is_admin => user_summary.attributes['isAdmin'].to_s.chomp.eql?('1'),
|
74
|
+
:is_disabled => user_summary.attributes['disabled'].to_s.chomp.eql?('1'),
|
75
|
+
:site_count => user_summary.attributes['siteCount'],
|
76
|
+
:group_count => user_summary.attributes['groupCount']
|
77
|
+
}
|
78
|
+
end
|
79
|
+
res
|
80
|
+
else
|
81
|
+
false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def console_command(cmd_string)
|
87
|
+
xml = make_xml('ConsoleCommandRequest', {})
|
88
|
+
cmd = REXML::Element.new('Command')
|
89
|
+
cmd.text = cmd_string
|
90
|
+
xml << cmd
|
91
|
+
|
92
|
+
r = execute(xml)
|
93
|
+
|
94
|
+
if (r.success)
|
95
|
+
res = ""
|
96
|
+
r.res.elements.each("//Output") do |out|
|
97
|
+
res << out.text.to_s
|
98
|
+
end
|
99
|
+
|
100
|
+
res
|
101
|
+
else
|
102
|
+
false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def system_information
|
107
|
+
r = execute(make_xml('SystemInformationRequest', {}))
|
108
|
+
|
109
|
+
if (r.success)
|
110
|
+
res = {}
|
111
|
+
r.res.elements.each("//Statistic") do |stat|
|
112
|
+
res[stat.attributes['name'].to_s] = stat.text.to_s
|
113
|
+
end
|
114
|
+
|
115
|
+
res
|
116
|
+
else
|
117
|
+
false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,570 @@
|
|
1
|
+
module Nexpose
|
2
|
+
module NexposeAPI
|
3
|
+
include XMLUtils
|
4
|
+
|
5
|
+
#
|
6
|
+
#
|
7
|
+
#
|
8
|
+
def report_generate(param)
|
9
|
+
r = execute(make_xml('ReportGenerateRequest', {'report-id' => param}))
|
10
|
+
r.success
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
#
|
15
|
+
#
|
16
|
+
def report_last(param)
|
17
|
+
r = execute(make_xml('ReportHistoryRequest', {'reportcfg-id' => param}))
|
18
|
+
res = nil
|
19
|
+
if (r.success)
|
20
|
+
stk = []
|
21
|
+
r.res.elements.each("//ReportSummary") do |rep|
|
22
|
+
stk << [rep.attributes['id'].to_i, rep.attributes['report-URI']]
|
23
|
+
end
|
24
|
+
if (stk.length > 0)
|
25
|
+
stk.sort! { |a, b| b[0] <=> a[0] }
|
26
|
+
res = stk[0][1]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
res
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
#
|
34
|
+
#
|
35
|
+
def report_history(param)
|
36
|
+
execute(make_xml('ReportHistoryRequest', {'reportcfg-id' => param}))
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
#
|
41
|
+
#
|
42
|
+
def report_config_delete(param)
|
43
|
+
r = execute(make_xml('ReportDeleteRequest', {'reportcfg-id' => param}))
|
44
|
+
r.success
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
#
|
49
|
+
#
|
50
|
+
def report_delete(param)
|
51
|
+
r = execute(make_xml('ReportDeleteRequest', {'report-id' => param}))
|
52
|
+
r.success
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
#
|
57
|
+
#
|
58
|
+
def report_template_listing
|
59
|
+
r = execute(make_xml('ReportTemplateListingRequest', {}))
|
60
|
+
|
61
|
+
if (r.success)
|
62
|
+
res = []
|
63
|
+
r.res.elements.each("//ReportTemplateSummary") do |template|
|
64
|
+
desc = ''
|
65
|
+
template.elements.each("//description") do |ent|
|
66
|
+
desc = ent.text
|
67
|
+
end
|
68
|
+
|
69
|
+
res << {
|
70
|
+
:template_id => template.attributes['id'].to_s,
|
71
|
+
:name => template.attributes['name'].to_s,
|
72
|
+
:description => desc.to_s
|
73
|
+
}
|
74
|
+
end
|
75
|
+
res
|
76
|
+
else
|
77
|
+
false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# === Description
|
83
|
+
# Object that represents the summary of a Report Configuration.
|
84
|
+
#
|
85
|
+
class ReportConfigSummary
|
86
|
+
# The Report Configuration ID
|
87
|
+
attr_reader :id
|
88
|
+
# A unique name for the Report
|
89
|
+
attr_reader :name
|
90
|
+
# The report format
|
91
|
+
attr_reader :format
|
92
|
+
# The date of the last report generation
|
93
|
+
attr_reader :last_generated_on
|
94
|
+
# Relative URI of the last generated report
|
95
|
+
attr_reader :last_generated_uri
|
96
|
+
|
97
|
+
# Constructor
|
98
|
+
# ReportConfigSummary(id, name, format, last_generated_on, last_generated_uri)
|
99
|
+
def initialize(id, name, format, last_generated_on, last_generated_uri)
|
100
|
+
|
101
|
+
@id = id
|
102
|
+
@name = name
|
103
|
+
@format = format
|
104
|
+
@last_generated_on = last_generated_on
|
105
|
+
@last_generated_uri = last_generated_uri
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# === Description
|
111
|
+
# Object that represents the schedule on which to automatically generate new reports.
|
112
|
+
class ReportHistory
|
113
|
+
|
114
|
+
# true if an error condition exists; false otherwise
|
115
|
+
attr_reader :error
|
116
|
+
# Error message string
|
117
|
+
attr_reader :error_msg
|
118
|
+
# The last XML request sent by this object
|
119
|
+
attr_reader :request_xml
|
120
|
+
# The last XML response received by this object
|
121
|
+
attr_reader :response_xml
|
122
|
+
# The NSC Connection associated with this object
|
123
|
+
attr_reader :connection
|
124
|
+
# The report definition (report config) ID
|
125
|
+
# Report definition ID
|
126
|
+
attr_reader :config_id
|
127
|
+
# Array (ReportSummary*)
|
128
|
+
attr_reader :report_summaries
|
129
|
+
|
130
|
+
|
131
|
+
def initialize(connection, config_id)
|
132
|
+
|
133
|
+
@error = false
|
134
|
+
@connection = connection
|
135
|
+
@config_id = config_id
|
136
|
+
@report_summaries = []
|
137
|
+
|
138
|
+
reportHistory_request = APIRequest.new('<ReportHistoryRequest session-id="' + "#{connection.session_id}" + '" reportcfg-id="' + "#{@config_id}" + '"/>', @connection.url)
|
139
|
+
reportHistory_request.execute()
|
140
|
+
@response_xml = reportHistory_request.response_xml
|
141
|
+
@request_xml = reportHistory_request.request_xml
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
def xml_parse(response)
|
146
|
+
response = REXML::Document.new(response.to_s)
|
147
|
+
status = response.root.attributes['success']
|
148
|
+
if (status == '1')
|
149
|
+
response.elements.each('ReportHistoryResponse/ReportSummary') do |r|
|
150
|
+
@report_summaries.push(ReportSummary.new(r.attributes["id"], r.attributes["cfg-id"], r.attributes["status"], r.attributes["generated-on"], r.attributes['report-uri']))
|
151
|
+
end
|
152
|
+
else
|
153
|
+
@error = true
|
154
|
+
@error_msg = 'Error ReportHistoryReponse'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
# === Description
|
161
|
+
# Object that represents the summary of a single report.
|
162
|
+
class ReportSummary
|
163
|
+
|
164
|
+
# The Report ID
|
165
|
+
attr_reader :id
|
166
|
+
# The Report Configuration ID
|
167
|
+
attr_reader :cfg_id
|
168
|
+
# The status of this report
|
169
|
+
# available | generating | failed
|
170
|
+
attr_reader :status
|
171
|
+
# The date on which this report was generated
|
172
|
+
attr_reader :generated_on
|
173
|
+
# The relative URI of the report
|
174
|
+
attr_reader :report_uri
|
175
|
+
|
176
|
+
def initialize(id, cfg_id, status, generated_on, report_uri)
|
177
|
+
|
178
|
+
@id = id
|
179
|
+
@cfg_id = cfg_id
|
180
|
+
@status = status
|
181
|
+
@generated_on = generated_on
|
182
|
+
@report_uri = report_uri
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
# === Description
|
189
|
+
#
|
190
|
+
class ReportAdHoc
|
191
|
+
include XMLUtils
|
192
|
+
|
193
|
+
attr_reader :error
|
194
|
+
attr_reader :error_msg
|
195
|
+
attr_reader :connection
|
196
|
+
# Report Template ID strong e.g. full-audit
|
197
|
+
attr_reader :template_id
|
198
|
+
# pdf|html|xml|text|csv|raw-xml
|
199
|
+
attr_reader :format
|
200
|
+
# Array of (ReportFilter)*
|
201
|
+
attr_reader :filters
|
202
|
+
attr_reader :request_xml
|
203
|
+
attr_reader :response_xml
|
204
|
+
attr_reader :report_decoded
|
205
|
+
|
206
|
+
|
207
|
+
def initialize(connection, template_id = 'full-audit', format = 'raw-xml')
|
208
|
+
|
209
|
+
@error = false
|
210
|
+
@connection = connection
|
211
|
+
@filters = Array.new()
|
212
|
+
@template_id = template_id
|
213
|
+
@format = format
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
def addFilter(filter_type, id)
|
218
|
+
|
219
|
+
# filter_type can be site|group|device|scan
|
220
|
+
# id is the ID number. For scan, you can use 'last' for the most recently run scan
|
221
|
+
filter = ReportFilter.new(filter_type, id)
|
222
|
+
filters.push(filter)
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
def generate()
|
227
|
+
request_xml = '<ReportAdhocGenerateRequest session-id="' + @connection.session_id + '">'
|
228
|
+
request_xml += '<AdhocReportConfig template-id="' + @template_id + '" format="' + @format + '">'
|
229
|
+
request_xml += '<Filters>'
|
230
|
+
@filters.each do |f|
|
231
|
+
request_xml += '<filter type="' + f.type + '" id="'+ f.id.to_s + '"/>'
|
232
|
+
end
|
233
|
+
request_xml += '</Filters>'
|
234
|
+
request_xml += '</AdhocReportConfig>'
|
235
|
+
request_xml += '</ReportAdhocGenerateRequest>'
|
236
|
+
|
237
|
+
ad_hoc_request = APIRequest.new(request_xml, @connection.url)
|
238
|
+
ad_hoc_request.execute()
|
239
|
+
|
240
|
+
content_type_response = ad_hoc_request.raw_response.header['Content-Type']
|
241
|
+
if content_type_response =~ /multipart\/mixed;\s*boundary=([^\s]+)/
|
242
|
+
# NeXpose sends an incorrect boundary format which breaks parsing
|
243
|
+
# Eg: boundary=XXX; charset=XXX
|
244
|
+
# Fix by removing everything from the last semi-colon onward
|
245
|
+
last_semi_colon_index = content_type_response.index(/;/, content_type_response.index(/boundary/))
|
246
|
+
content_type_response = content_type_response[0, last_semi_colon_index]
|
247
|
+
|
248
|
+
data = "Content-Type: " + content_type_response + "\r\n\r\n" + ad_hoc_request.raw_response_data
|
249
|
+
doc = Rex::MIME::Message.new data
|
250
|
+
doc.parts.each do |part|
|
251
|
+
if /.*base64.*/ =~ part.header.to_s
|
252
|
+
return parse_xml(part.content.unpack("m*")[0])
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
# === Description
|
261
|
+
# Object that represents the configuration of a report definition.
|
262
|
+
#
|
263
|
+
class ReportConfig
|
264
|
+
|
265
|
+
# true if an error condition exists; false otherwise
|
266
|
+
attr_reader :error
|
267
|
+
# Error message string
|
268
|
+
attr_reader :error_msg
|
269
|
+
# The last XML request sent by this object
|
270
|
+
attr_reader :request_xml
|
271
|
+
# The last XML response received by this object
|
272
|
+
attr_reader :response_xml
|
273
|
+
# The NSC Connection associated with this object
|
274
|
+
attr_reader :connection
|
275
|
+
# The ID for this report definition
|
276
|
+
attr_reader :config_id
|
277
|
+
# A unique name for this report definition
|
278
|
+
attr_reader :name
|
279
|
+
# The template ID used for this report definition
|
280
|
+
attr_reader :template_id
|
281
|
+
# html, db, txt, xml, raw-xml, csv, pdf
|
282
|
+
attr_reader :format
|
283
|
+
# XXX new
|
284
|
+
attr_reader :timezone
|
285
|
+
# XXX new
|
286
|
+
attr_reader :owner
|
287
|
+
# Array of (ReportFilter)* - The Sites, Asset Groups, or Devices to run the report against
|
288
|
+
attr_reader :filters
|
289
|
+
# Automatically generate a new report at the conclusion of a scan
|
290
|
+
# 1 or 0
|
291
|
+
attr_reader :generate_after_scan
|
292
|
+
# Schedule to generate reports
|
293
|
+
# ReportSchedule Object
|
294
|
+
attr_reader :schedule
|
295
|
+
# Store the reports on the server
|
296
|
+
# 1 or 0
|
297
|
+
attr_reader :storeOnServer
|
298
|
+
# Location to store the report on the server
|
299
|
+
attr_reader :store_location
|
300
|
+
# Form to send the report via email
|
301
|
+
# "file", "zip", "url", or NULL (don’t send email)
|
302
|
+
attr_reader :email_As
|
303
|
+
# Send the Email to all Authorized Users
|
304
|
+
# boolean - Send the Email to all Authorized Users
|
305
|
+
attr_reader :email_to_all
|
306
|
+
# Array containing the email addresses of the recipients
|
307
|
+
attr_reader :email_recipients
|
308
|
+
# IP Address or Hostname of SMTP Relay Server
|
309
|
+
attr_reader :smtp_relay_server
|
310
|
+
# Sets the FROM field of the Email
|
311
|
+
attr_reader :sender
|
312
|
+
# TODO
|
313
|
+
attr_reader :db_export
|
314
|
+
# TODO
|
315
|
+
attr_reader :csv_export
|
316
|
+
# TODO
|
317
|
+
attr_reader :xml_export
|
318
|
+
|
319
|
+
|
320
|
+
def initialize(connection, config_id = -1)
|
321
|
+
|
322
|
+
@error = false
|
323
|
+
@connection = connection
|
324
|
+
@config_id = config_id
|
325
|
+
@xml_tag_stack = Array.new()
|
326
|
+
@filters = Array.new()
|
327
|
+
@email_recipients = Array.new()
|
328
|
+
@name = "New Report " + rand(999999999).to_s
|
329
|
+
|
330
|
+
r = @connection.execute('<ReportConfigRequest session-id="' + @connection.session_id.to_s + '" reportcfg-id="' + @config_id.to_s + '"/>')
|
331
|
+
if (r.success)
|
332
|
+
r.res.elements.each('ReportConfigResponse/ReportConfig') do |r|
|
333
|
+
@name = r.attributes['name']
|
334
|
+
@format = r.attributes['format']
|
335
|
+
@timezone = r.attributes['timezone']
|
336
|
+
@id = r.attributes['id']
|
337
|
+
@template_id = r.attributes['template-id']
|
338
|
+
@owner = r.attributes['owner']
|
339
|
+
end
|
340
|
+
else
|
341
|
+
@error = true
|
342
|
+
@error_msg = 'Error ReportHistoryReponse'
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
# === Description
|
347
|
+
# Generate a new report on this report definition. Returns the new report ID.
|
348
|
+
def generateReport(debug = false)
|
349
|
+
return generateReport(@connection, @config_id, debug)
|
350
|
+
end
|
351
|
+
|
352
|
+
# === Description
|
353
|
+
# Save the report definition to the NSC.
|
354
|
+
# Returns the config-id.
|
355
|
+
def saveReport()
|
356
|
+
r = @connection.execute('<ReportSaveRequest session-id="' + @connection.session_id.to_s + '">' + getXML().to_s + ' </ReportSaveRequest>')
|
357
|
+
if (r.success)
|
358
|
+
@config_id = r.attributes['reportcfg-id']
|
359
|
+
return true
|
360
|
+
end
|
361
|
+
return false
|
362
|
+
end
|
363
|
+
|
364
|
+
# === Description
|
365
|
+
# Adds a new filter to the report config
|
366
|
+
def addFilter(filter_type, id)
|
367
|
+
filter = ReportFilter.new(filter_type, id)
|
368
|
+
@filters.push(filter)
|
369
|
+
end
|
370
|
+
|
371
|
+
# === Description
|
372
|
+
# Adds a new email recipient
|
373
|
+
def addEmailRecipient(recipient)
|
374
|
+
@email_recipients.push(recipient)
|
375
|
+
end
|
376
|
+
|
377
|
+
# === Description
|
378
|
+
# Sets the schedule for this report config
|
379
|
+
def setSchedule(schedule)
|
380
|
+
@schedule = schedule
|
381
|
+
end
|
382
|
+
|
383
|
+
def getXML()
|
384
|
+
|
385
|
+
xml = '<ReportConfig id="' + @config_id.to_s + '" name="' + @name.to_s + '" template-id="' + @template_id.to_s + '" format="' + @format.to_s + '">'
|
386
|
+
|
387
|
+
xml += ' <Filters>'
|
388
|
+
|
389
|
+
@filters.each do |f|
|
390
|
+
xml += ' <' + f.type.to_s + ' id="' + f.id.to_s + '"/>'
|
391
|
+
end
|
392
|
+
|
393
|
+
xml += ' </Filters>'
|
394
|
+
|
395
|
+
xml += ' <Generate after-scan="' + @generate_after_scan.to_s + '">'
|
396
|
+
|
397
|
+
if (@schedule)
|
398
|
+
xml += ' <Schedule type="' + @schedule.type.to_s + '" interval="' + @schedule.interval.to_s + '" start="' + @schedule.start.to_s + '"/>'
|
399
|
+
end
|
400
|
+
|
401
|
+
xml += ' </Generate>'
|
402
|
+
|
403
|
+
xml += ' <Delivery>'
|
404
|
+
|
405
|
+
xml += ' <Storage storeOnServer="' + @storeOnServer.to_s + '">'
|
406
|
+
|
407
|
+
if (@store_location and @store_location.length > 0)
|
408
|
+
xml += ' <location>' + @store_location.to_s + '</location>'
|
409
|
+
end
|
410
|
+
|
411
|
+
xml += ' </Storage>'
|
412
|
+
|
413
|
+
|
414
|
+
xml += ' </Delivery>'
|
415
|
+
|
416
|
+
xml += ' </ReportConfig>'
|
417
|
+
|
418
|
+
return xml
|
419
|
+
end
|
420
|
+
|
421
|
+
def set_name(name)
|
422
|
+
@name = name
|
423
|
+
end
|
424
|
+
|
425
|
+
def set_template_id(template_id)
|
426
|
+
@template_id = template_id
|
427
|
+
end
|
428
|
+
|
429
|
+
def set_format(format)
|
430
|
+
@format = format
|
431
|
+
end
|
432
|
+
|
433
|
+
def set_email_As(email_As)
|
434
|
+
@email_As = email_As
|
435
|
+
end
|
436
|
+
|
437
|
+
def set_storeOnServer(storeOnServer)
|
438
|
+
@storeOnServer = storeOnServer
|
439
|
+
end
|
440
|
+
|
441
|
+
def set_smtp_relay_server(smtp_relay_server)
|
442
|
+
@smtp_relay_server = smtp_relay_server
|
443
|
+
end
|
444
|
+
|
445
|
+
def set_sender(sender)
|
446
|
+
@sender = sender
|
447
|
+
end
|
448
|
+
|
449
|
+
def set_generate_after_scan(generate_after_scan)
|
450
|
+
@generate_after_scan = generate_after_scan
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
# === Description
|
455
|
+
# Object that represents a report filter which determines which sites, asset
|
456
|
+
# groups, and/or devices that a report is run against. gtypes are
|
457
|
+
# "SiteFilter", "AssetGroupFilter", "DeviceFilter", or "ScanFilter". gid is
|
458
|
+
# the site-id, assetgroup-id, or devce-id. ScanFilter, if used, specifies
|
459
|
+
# a specifies a specific scan to use as the data source for the report. The gid
|
460
|
+
# can be a specific scan-id or "first" for the first run scan, or “last” for
|
461
|
+
# the last run scan.
|
462
|
+
#
|
463
|
+
class ReportFilter
|
464
|
+
|
465
|
+
attr_reader :type
|
466
|
+
attr_reader :id
|
467
|
+
|
468
|
+
def initialize(type, id)
|
469
|
+
|
470
|
+
@type = type
|
471
|
+
@id = id
|
472
|
+
|
473
|
+
end
|
474
|
+
|
475
|
+
end
|
476
|
+
|
477
|
+
|
478
|
+
# === Description
|
479
|
+
# Object that represents the schedule on which to automatically generate new reports.
|
480
|
+
#
|
481
|
+
class ReportSchedule
|
482
|
+
|
483
|
+
# The type of schedule
|
484
|
+
# (daily, hourly, monthly, weekly)
|
485
|
+
attr_reader :type
|
486
|
+
# The frequency with which to run the scan
|
487
|
+
attr_reader :interval
|
488
|
+
# The earliest date to generate the report
|
489
|
+
attr_reader :start
|
490
|
+
|
491
|
+
def initialize(type, interval, start)
|
492
|
+
|
493
|
+
@type = type
|
494
|
+
@interval = interval
|
495
|
+
@start = start
|
496
|
+
|
497
|
+
end
|
498
|
+
|
499
|
+
|
500
|
+
end
|
501
|
+
|
502
|
+
class ReportTemplateListing
|
503
|
+
|
504
|
+
attr_reader :error_msg
|
505
|
+
attr_reader :error
|
506
|
+
attr_reader :request_xml
|
507
|
+
attr_reader :response_xml
|
508
|
+
attr_reader :connection
|
509
|
+
attr_reader :xml_tag_stack
|
510
|
+
attr_reader :report_template_summaries #; //Array (ReportTemplateSummary*)
|
511
|
+
|
512
|
+
|
513
|
+
def initialize(connection)
|
514
|
+
|
515
|
+
@error = nil
|
516
|
+
@connection = connection
|
517
|
+
@report_template_summaries = Array.new()
|
518
|
+
|
519
|
+
r = @connection.execute('<ReportTemplateListingRequest session-id="' + connection.session_id.to_s + '"/>')
|
520
|
+
if (r.success)
|
521
|
+
r.res.elements.each('ReportTemplateListingResponse/ReportTemplateSummary') do |r|
|
522
|
+
@report_template_summaries.push(ReportTemplateSumary.new(r.attributes['id'], r.attributes['name']))
|
523
|
+
end
|
524
|
+
else
|
525
|
+
@error = true
|
526
|
+
@error_msg = 'ReportTemplateListingRequest Parse Error'
|
527
|
+
end
|
528
|
+
|
529
|
+
end
|
530
|
+
|
531
|
+
end
|
532
|
+
|
533
|
+
|
534
|
+
class ReportTemplateSummary
|
535
|
+
|
536
|
+
attr_reader :id
|
537
|
+
attr_reader :name
|
538
|
+
attr_reader :description
|
539
|
+
|
540
|
+
def initialize(id, name, description)
|
541
|
+
|
542
|
+
@id = id
|
543
|
+
@name = name
|
544
|
+
@description = description
|
545
|
+
|
546
|
+
end
|
547
|
+
|
548
|
+
end
|
549
|
+
|
550
|
+
|
551
|
+
class ReportSection
|
552
|
+
|
553
|
+
attr_reader :name
|
554
|
+
attr_reader :properties
|
555
|
+
|
556
|
+
def initialize(name)
|
557
|
+
|
558
|
+
@properties = Array.new()
|
559
|
+
@name = name
|
560
|
+
end
|
561
|
+
|
562
|
+
|
563
|
+
def addProperty(name, value)
|
564
|
+
|
565
|
+
@properties[name.to_s] = value
|
566
|
+
end
|
567
|
+
|
568
|
+
end
|
569
|
+
|
570
|
+
end
|