nexpose 2.3.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b700cb98e385100a28c8b58f7952a9d26644c24a
4
- data.tar.gz: 8595c6416a6b61a6855e2fcc19f3427e9ccd1301
3
+ metadata.gz: 655abc9506b7d35e2b0d09097a40fe2cd1be8957
4
+ data.tar.gz: 47dd93d3c38ab7d6834ec2f905ce41bf8644ddb4
5
5
  SHA512:
6
- metadata.gz: cd9cadc253fd186e47dd8bcde7a653c3926759e401e8a5a79babf869da3c2f434ab7ffecb51354f668c17626e82f0e21233068dd082d15305632ad69c4fed4f8
7
- data.tar.gz: 57e46c5e4cc26e7ed85057e3081556776f3320dfe1dd18f1ab7544966112b878df6190736077ab0b4ce3143c0fa2f90183b570f19c61a435b61c8a566ad170f9
6
+ metadata.gz: da349fdd82a17c6df04d4321b3ace9d10dab2fc49d3d2dfe614de2dbf4caa22f40e50f8a7102a199d81acff5a4e6409fae7fea59d1fdf0883567c75127e5e9d9
7
+ data.tar.gz: b879628ea4cc24feb49f35d5ed99d42c4f3e515dbd2eae6cedb21024bd2723de4236288db913c8daeb486f0d21c74a7b77527237e96c93ae13a595979426e528
data/lib/nexpose/ajax.rb CHANGED
@@ -187,8 +187,10 @@ module Nexpose
187
187
  # is 2.1 or greater otherwise use the request body
188
188
  def get_error_message(request, response)
189
189
  version = get_request_api_version(request)
190
-
191
- (version >= 2.1 && response.body) ? "response body: #{response.body}" : "request body: #{request.body}"
190
+ data_request = request.path.include? '/data/'
191
+ data_request ? response_is_text = (response.content_type.include? 'text/plain') : nil
192
+ return_response = (version >= 2.1 || (data_request && response_is_text))
193
+ (return_response && response.body) ? "response body: #{response.body}" : "request body: #{request.body}"
192
194
  end
193
195
 
194
196
  # Execute a block of code while presenving the preferences for any
@@ -130,6 +130,21 @@ module Nexpose
130
130
  end
131
131
 
132
132
  alias_method :delete_asset, :delete_device
133
+
134
+ # Retrieve the scan history for an asset.
135
+ # Note: This is not optimized for querying many assets.
136
+ #
137
+ # @param [Fixnum] asset_id Unique identifer of an asset.
138
+ # @return [Array[AssetScan]] A list of scans for the asset.
139
+ #
140
+ def asset_scan_history(asset_id)
141
+ uri = "/data/assets/#{asset_id}/scans"
142
+ AJAX.preserving_preference(self, 'asset-scan-history') do
143
+ data = DataTable._get_json_table(self, uri, {}, 500, nil, true)
144
+ data.each { |a| a['assetID'] = asset_id.to_s }
145
+ data.map(&AssetScan.method(:parse_json))
146
+ end
147
+ end
133
148
  end
134
149
 
135
150
  # Object that represents a single device in a Nexpose security console.
@@ -208,4 +223,50 @@ module Nexpose
208
223
  #
209
224
  class IncompleteAsset < CompletedAsset
210
225
  end
226
+
227
+
228
+ # Summary object of a scan for a particular asset.
229
+ #
230
+ class AssetScan
231
+ # Unique identifier of an asset.
232
+ attr_reader :asset_id
233
+ # IP address of the asset.
234
+ attr_reader :ip
235
+ # Host name of the asset, if discovered.
236
+ attr_reader :host_name
237
+ # Site name where the scan originated.
238
+ attr_reader :site_name
239
+ # Unique identifier for the site where the scan originated.
240
+ attr_reader :site_id
241
+ # Unique identifier for the scan.
242
+ attr_reader :scan_id
243
+ # Time when the asset finished scanning.
244
+ attr_reader :end_time
245
+ # Number of vulnerabilities discovered on the asset.
246
+ attr_reader :vulns
247
+ # Operating system fingerprint of the asset.
248
+ attr_reader :os
249
+ # Name of the scan engine used for the scan.
250
+ attr_reader :engine_name
251
+
252
+ # Internal constructor to be called by #parse_json.
253
+ def initialize(&block)
254
+ instance_eval(&block) if block_given?
255
+ end
256
+
257
+ def self.parse_json(json)
258
+ new do
259
+ @asset_id = json['assetID'].to_i
260
+ @scan_id = json['scanID'].to_i
261
+ @site_id = json['siteID'].to_i
262
+ @ip = json['ipAddress']
263
+ @host_name = json['hostname']
264
+ @os = json['operatingSystem']
265
+ @vulns = json['vulnCount']
266
+ @end_time = Time.at(json['completed'].to_i / 1000)
267
+ @site_name = json['siteName']
268
+ @engine_name = json['scanEngineName']
269
+ end
270
+ end
271
+ end
211
272
  end
@@ -249,7 +249,7 @@ module Nexpose
249
249
  content_type_response = content_type_response[0, last_semi_colon_index]
250
250
 
251
251
  data = 'Content-Type: ' + content_type_response + "\r\n\r\n" + response.raw_response_data
252
- doc = Rex::MIME::Message.new(data)
252
+ doc = Rexlite::MIME::Message.new(data)
253
253
  doc.parts.each do |part|
254
254
  if /.*base64.*/ =~ part.header.to_s
255
255
  if @format =~ /(?:ht|x)ml/
@@ -0,0 +1,5 @@
1
+ # Rexlite
2
+
3
+ This is an extraction of the [Rex library](https://github.com/rapid7/rex) to reduce dependencies for the nexpose-client gem.
4
+
5
+ Currently only the Rex::MIME module has been pulled over since that is the only dependency that nexpose-client has on Rex.
@@ -0,0 +1,17 @@
1
+ # -*- coding: binary -*-
2
+ module Rexlite
3
+ module MIME
4
+ # Set of helpers methods to deal with SMTP encoding related topics.
5
+ module Encoding
6
+
7
+ # Enforces CRLF on the input data
8
+ #
9
+ # @param data [String] The data to CRLF enforce.
10
+ # @return [String] CRLF enforced data.
11
+ def force_crlf(data)
12
+ data.gsub("\r", '').gsub("\n", "\r\n")
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,76 @@
1
+ # -*- coding: binary -*-
2
+ module Rexlite
3
+ module MIME
4
+ class Header
5
+
6
+ attr_accessor :headers
7
+
8
+ def initialize(data='')
9
+ self.headers = []
10
+ parse(data)
11
+ end
12
+
13
+ def parse(data)
14
+ prev = nil
15
+ data.gsub("\r", '').split("\n").each do |line|
16
+
17
+ # Handle header folding
18
+ if (line =~ /^\s+/)
19
+ # Ignore if there is no previous header
20
+ next if not prev
21
+ next if not self.headers[prev]
22
+ self.headers[prev][1] << line.strip
23
+ next
24
+ end
25
+
26
+ var, val = line.split(':', 2)
27
+ next if val.nil?
28
+
29
+ self.headers << [ var.to_s.strip, val.to_s.strip ]
30
+ prev = self.headers.length - 1
31
+ end
32
+ end
33
+
34
+ def to_s
35
+ self.headers.map{ |pair| "#{pair[0]}: #{pair[1]}\r\n" }.join
36
+ end
37
+
38
+ def find(idx)
39
+ if (idx.class == ::Fixnum)
40
+ return self.headers[idx]
41
+ else
42
+ self.headers.each do |pair|
43
+ if (pair[0] == idx.to_s)
44
+ return pair
45
+ end
46
+ end
47
+ end
48
+ nil
49
+ end
50
+
51
+ def set(var, val)
52
+ hdr = self.find(var) || self.add(var, '')
53
+ hdr[1] = val
54
+ end
55
+
56
+ def add(var, val)
57
+ self.headers << [var, val]
58
+ self.headers[-1]
59
+ end
60
+
61
+ def remove(idx)
62
+ if (idx.class == ::Fixnum)
63
+ self.headers.delete_at(idx)
64
+ else
65
+ self.headers.each_index do |i|
66
+ pair = self.headers[i]
67
+ if (pair[0] == idx.to_s)
68
+ self.headers.delete_at(i)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,161 @@
1
+ # -*- coding: binary -*-
2
+ module Rexlite
3
+ module MIME
4
+ class Message
5
+
6
+ require 'nexpose/rexlite/mime/header'
7
+ require 'nexpose/rexlite/mime/part'
8
+ require 'nexpose/rexlite/mime/encoding'
9
+
10
+ include Rexlite::MIME::Encoding
11
+
12
+ attr_accessor :header, :parts, :bound, :content
13
+
14
+
15
+ def initialize(data=nil)
16
+ self.header = Rexlite::MIME::Header.new
17
+ self.parts = []
18
+ self.bound = "_Part_#{rand(1024)}_#{rand(0xffffffff)}_#{rand(0xffffffff)}"
19
+ self.content = ''
20
+ if data
21
+ head,body = data.split(/\r?\n\r?\n/, 2)
22
+
23
+ self.header.parse(head)
24
+ ctype = self.header.find('Content-Type')
25
+
26
+ if ctype && ctype[1] && ctype[1] =~ /multipart\/mixed;\s*boundary="?([A-Za-z0-9'\(\)\+\_,\-\.\/:=\?^\s]+)"?/
27
+ self.bound = $1
28
+ chunks = body.to_s.split(/--#{self.bound}(--)?\r?\n/)
29
+ self.content = chunks.shift.to_s.gsub(/\s+$/, '')
30
+ self.content << "\r\n" unless self.content.empty?
31
+
32
+ chunks.each do |chunk|
33
+ break if chunk == "--"
34
+ head,body = chunk.split(/\r?\n\r?\n/, 2)
35
+ part = Rexlite::MIME::Part.new
36
+ part.header.parse(head)
37
+ part.content = body.gsub(/\s+$/, '')
38
+ self.parts << part
39
+ end
40
+ else
41
+ self.content = body.to_s.gsub(/\s+$/, '') + "\r\n"
42
+ end
43
+ end
44
+ end
45
+
46
+ def to
47
+ (self.header.find('To') || [nil, nil])[1]
48
+ end
49
+
50
+ def to=(val)
51
+ self.header.set("To", val)
52
+ end
53
+
54
+ def from=(val)
55
+ self.header.set("From", val)
56
+ end
57
+
58
+ def from
59
+ (self.header.find('From') || [nil, nil])[1]
60
+ end
61
+
62
+ def subject=(val)
63
+ self.header.set("Subject", val)
64
+ end
65
+
66
+ def subject
67
+ (self.header.find('Subject') || [nil, nil])[1]
68
+ end
69
+
70
+ def mime_defaults
71
+ self.header.set("MIME-Version", "1.0")
72
+ self.header.set("Content-Type", "multipart/mixed; boundary=\"#{self.bound}\"")
73
+ self.header.set("Subject", '') # placeholder
74
+ self.header.set("Date", Time.now.strftime("%a,%e %b %Y %H:%M:%S %z"))
75
+ self.header.set("Message-ID",
76
+ "<"+
77
+ rand_text_alphanumeric(rand(20)+40)+
78
+ "@"+
79
+ rand_text_alpha(rand(20)+3)+
80
+ ">"
81
+ )
82
+ self.header.set("From", '') # placeholder
83
+ self.header.set("To", '') # placeholder
84
+ end
85
+
86
+ def rand_text_alphanumeric(len, bad='')
87
+ foo = []
88
+ foo += ('A' .. 'Z').to_a
89
+ foo += ('a' .. 'z').to_a
90
+ foo += ('0' .. '9').to_a
91
+ rand_base(len, bad, *foo )
92
+ end
93
+
94
+ def rand_text_alpha(len, bad='')
95
+ foo = []
96
+ foo += ('A' .. 'Z').to_a
97
+ foo += ('a' .. 'z').to_a
98
+ rand_base(len, bad, *foo )
99
+ end
100
+
101
+ def add_part(data='', content_type='text/plain', transfer_encoding="8bit", content_disposition=nil)
102
+ part = Rexlite::MIME::Part.new
103
+
104
+ if content_disposition
105
+ part.header.set("Content-Disposition", content_disposition)
106
+ end
107
+
108
+ part.header.set("Content-Type", content_type) if content_type
109
+
110
+ if transfer_encoding
111
+ part.header.set("Content-Transfer-Encoding", transfer_encoding)
112
+ end
113
+
114
+ part.content = data
115
+ self.parts << part
116
+ part
117
+ end
118
+
119
+ def add_part_attachment(data, name)
120
+ self.add_part(
121
+ encode_base64(data, "\r\n"),
122
+ "application/octet-stream; name=\"#{name}\"",
123
+ "base64",
124
+ "attachment; filename=\"#{name}\""
125
+ )
126
+ end
127
+
128
+
129
+ def add_part_inline_attachment(data, name)
130
+ self.add_part(
131
+ encode_base64(data, "\r\n"),
132
+ "application/octet-stream; name=\"#{name}\"",
133
+ "base64",
134
+ "inline; filename=\"#{name}\""
135
+ )
136
+ end
137
+
138
+ def encode_base64(str, delim='')
139
+ [str.to_s].pack("m").gsub(/\s+/, delim)
140
+ end
141
+
142
+
143
+ def to_s
144
+ header_string = self.header.to_s
145
+
146
+ msg = header_string.empty? ? '' : force_crlf(self.header.to_s + "\r\n")
147
+ msg << force_crlf(self.content + "\r\n") unless self.content.empty?
148
+
149
+ self.parts.each do |part|
150
+ msg << force_crlf("--" + self.bound + "\r\n")
151
+ msg << part.to_s
152
+ end
153
+
154
+ msg << force_crlf("--" + self.bound + "--\r\n") if self.parts.length > 0
155
+
156
+ msg
157
+ end
158
+
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,50 @@
1
+ # -*- coding: binary -*-
2
+ module Rexlite
3
+ module MIME
4
+ class Part
5
+
6
+ require 'nexpose/rexlite/mime/header'
7
+ require 'nexpose/rexlite/mime/encoding'
8
+
9
+ include Rexlite::MIME::Encoding
10
+
11
+ attr_accessor :header, :content
12
+
13
+ def initialize
14
+ self.header = Rexlite::MIME::Header.new
15
+ self.content = ''
16
+ end
17
+
18
+ def to_s
19
+ self.header.to_s + "\r\n" + content_encoded + "\r\n"
20
+ end
21
+
22
+ # Returns the part content with any necessary encoding or transformation
23
+ # applied.
24
+ #
25
+ # @return [String] Content with encoding or transformations applied.
26
+ def content_encoded
27
+ binary_content? ? content : force_crlf(content)
28
+ end
29
+
30
+ # Answers if the part content is binary.
31
+ #
32
+ # @return [Boolean] true if the part content is binary, false otherwise.
33
+ def binary_content?
34
+ transfer_encoding && transfer_encoding == 'binary'
35
+ end
36
+
37
+ # Returns the Content-Transfer-Encoding of the part.
38
+ #
39
+ # @return [nil] if the part hasn't Content-Transfer-Encoding.
40
+ # @return [String] The Content-Transfer-Encoding or the part.
41
+ def transfer_encoding
42
+ h = header.find('Content-Transfer-Encoding')
43
+ return nil if h.nil?
44
+
45
+ h[1]
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,10 @@
1
+ # -*- coding: binary -*-
2
+ module Rexlite
3
+ module MIME
4
+
5
+ require 'nexpose/rexlite/mime/header'
6
+ require 'nexpose/rexlite/mime/part'
7
+ require 'nexpose/rexlite/mime/message'
8
+
9
+ end
10
+ end
data/lib/nexpose/scan.rb CHANGED
@@ -204,6 +204,26 @@ module Nexpose
204
204
  Scan.parse(response.res) if response.success
205
205
  end
206
206
 
207
+ # Initiate an ad-hoc scan on a subset of site assets with
208
+ # a specific scan template and scan engine, which may differ
209
+ # from the site's defined scan template and scan engine.
210
+ #
211
+ # @param [Fixnum] site_id Site ID to scan.
212
+ # @param [Array[String]] assets Hostnames and/or IP addresses to scan.
213
+ # @param [String] scan_template The scan template ID.
214
+ # @param [Fixnum] scan_engine The scan engine ID.
215
+ # @return [Fixnum] Scan ID.
216
+ #
217
+ def scan_assets_with_template_and_engine(site_id, assets, scan_template, scan_engine)
218
+ uri = "/data/site/#{site_id}/scan"
219
+ assets.size > 1 ? addresses = assets.join(',') : addresses = assets.first
220
+ params = { 'addressList' => addresses,
221
+ 'template' => scan_template,
222
+ 'scanEngine' => scan_engine }
223
+ scan_id = AJAX.form_post(self, uri, params)
224
+ scan_id.to_i
225
+ end
226
+
207
227
  # Utility method for appending a HostName or IPRange object into an
208
228
  # XML object, in preparation for ad hoc scanning.
209
229
  #
@@ -357,6 +377,29 @@ module Nexpose
357
377
  end
358
378
  end
359
379
 
380
+ # Get paused scans. Provide a site ID to get paused scans for a site.
381
+ # With no site ID, all paused scans are returned.
382
+ #
383
+ # @param [Fixnum] site_id Site ID to retrieve paused scans for.
384
+ # @param [Fixnum] limit The maximum number of records to return from this call.
385
+ # @return [Array[ActiveScan]] List of paused scans.
386
+ #
387
+ def paused_scans(site_id = nil, limit = nil)
388
+ if site_id
389
+ uri = "/data/scan/site/#{site_id}?status=active"
390
+ rows = AJAX.row_pref_of(limit)
391
+ params = { 'sort' => 'endTime', 'dir' => 'DESC', 'startIndex' => 0 }
392
+ AJAX.preserving_preference(self, 'site-active-scans') do
393
+ data = DataTable._get_json_table(self, uri, params, rows, limit).select { |scan| scan['paused'] }
394
+ data.map(&ActiveScan.method(:parse_json))
395
+ end
396
+ else
397
+ uri = '/data/site/scans/dyntable.xml?printDocType=0&tableID=siteScansTable&activeOnly=true'
398
+ data = DataTable._get_dyn_table(self, uri).select { |scan| (scan['Status'].include? 'Paused') }
399
+ data.map(&ActiveScan.method(:parse_dyntable))
400
+ end
401
+ end
402
+
360
403
  # Export the data associated with a single scan, and optionally store it in
361
404
  # a zip-compressed file under the provided name.
362
405
  #
@@ -385,11 +428,7 @@ module Nexpose
385
428
  end
386
429
  end
387
430
 
388
- # Import scan data into a site. WARNING: Experimental!
389
- #
390
- # This code currently depends on a gem not in the gemspec. In order to use
391
- # this method, you will need to add the following line to your script:
392
- # require 'rest-client'
431
+ # Import scan data into a site.
393
432
  #
394
433
  # This method is designed to work with export_scan to migrate scan data
395
434
  # from one console to another. This method will import the data as if run
@@ -404,7 +443,7 @@ module Nexpose
404
443
  # @return [String] An empty string on success.
405
444
  #
406
445
  def import_scan(site_id, zip_file)
407
- data = Rex::MIME::Message.new
446
+ data = Rexlite::MIME::Message.new
408
447
  data.add_part(site_id.to_s, nil, nil, 'form-data; name="siteid"')
409
448
  data.add_part(session_id, nil, nil, 'form-data; name="nexposeCCSessionID"')
410
449
  ::File.open(zip_file, 'rb') do |scan|
@@ -768,4 +807,36 @@ module Nexpose
768
807
  end
769
808
  end
770
809
  end
810
+
811
+ class ActiveScan < CompletedScan
812
+ def self.parse_dyntable(json)
813
+ new do
814
+ @id = json['Scan ID']
815
+ @site_id = json['Site ID']
816
+ @status = CompletedScan._parse_status(json['Status Code'])
817
+ @start_time = Time.at(json['Started'].to_i / 1000)
818
+ @end_time = Time.at(json['Progress'].to_i / 1000)
819
+ @duration = json['Elapsed'].to_i
820
+ @vulns = json['Vulnerabilities Discovered'].to_i
821
+ @assets = json['Devices Discovered'].to_i
822
+ @risk_score = json['riskScore']
823
+ @type = json['Scan Type'] == 'Manual' ? :manual : :scheduled
824
+ @engine_name = json['Scan Engine']
825
+ end
826
+ end
827
+
828
+ # Internal method to parsing status codes.
829
+ def self._parse_status(code)
830
+ case code
831
+ when 'U'
832
+ :running
833
+ when 'P'
834
+ :paused
835
+ when 'I'
836
+ :integrating
837
+ else
838
+ :unknown
839
+ end
840
+ end
841
+ end
771
842
  end
@@ -321,12 +321,6 @@ module Nexpose
321
321
  checks ? checks.elements.to_a('VulnCategory').map { |c| c.attributes['name'] } : []
322
322
  end
323
323
 
324
- # @deprecated Use {#enabled_checks_by_category} instead
325
- def checks_by_category
326
- warn "[DEPRECATED] Use #{self.class}#enabled_checks_by_category instead of #{self.class}##{__method__}"
327
- enabled_checks_by_category
328
- end
329
-
330
324
  # Get a list of the check categories enabled for this scan template.
331
325
  #
332
326
  # @return [Array[String]] List of enabled categories.
@@ -370,12 +364,6 @@ module Nexpose
370
364
  checks ? checks.elements.to_a('CheckType').map { |c| c.attributes['name'] } : []
371
365
  end
372
366
 
373
- # @deprecated Use {#enabled_checks_by_type} instead
374
- def checks_by_type
375
- warn "[DEPRECATED] Use #{self.class}#enabled_checks_by_type instead of #{self.class}##{__method__}"
376
- enabled_checks_by_type
377
- end
378
-
379
367
  # Get a list of the check types enabled for this scan template.
380
368
  #
381
369
  # @return [Array[String]] List of enabled check types.
@@ -430,12 +418,6 @@ module Nexpose
430
418
  checks.elements.delete("Enabled/#{elem}[@name='#{check}']")
431
419
  end
432
420
 
433
- # @deprecated Use {#enabled_vuln_checks} instead
434
- def vuln_checks
435
- warn "[DEPRECATED] Use #{self.class}#enabled_vuln_checks instead of #{self.class}##{__method__}"
436
- enabled_vuln_checks
437
- end
438
-
439
421
  # Get a list of the individual vuln checks enabled for this scan template.
440
422
  #
441
423
  # @return [Array[String]] List of enabled vulnerability checks.
data/lib/nexpose/site.rb CHANGED
@@ -250,12 +250,6 @@ module Nexpose
250
250
  end
251
251
  end
252
252
 
253
- # @deprecated Use {#include_ip_range} instead.
254
- def add_ip_range(from, to)
255
- warn "[DEPRECATED] Use #{self.class}#include_ip_range instead of #{self.class}#add_ip_range."
256
- include_ip_range(from, to)
257
- end
258
-
259
253
  # Remove assets to this site by IP address range.
260
254
  #
261
255
  # @param [String] from Beginning IP address of a range.
@@ -274,12 +268,6 @@ module Nexpose
274
268
  end
275
269
  end
276
270
 
277
- # @deprecated Use {#remove_included_ip_range} instead.
278
- def remove_ip_range(from, to)
279
- warn "[DEPRECATED] Use #{self.class}#remove_included_ip_range instead of #{self.class}#remove_ip_range."
280
- remove_included_ip_range(from, to)
281
- end
282
-
283
271
  # Adds an asset to this site included scan targets, resolving whether an IP or hostname is
284
272
  # provided.
285
273
  #
@@ -289,15 +277,6 @@ module Nexpose
289
277
  @included_scan_targets[:addresses] << HostOrIP.convert(asset)
290
278
  end
291
279
 
292
- # @deprecated Use {#include_asset} instead.
293
- def add_asset(asset)
294
- warn "[DEPRECATED] Use #{self.class}#include_asset instead of #{self.class}#add_asset."
295
- include_asset(asset)
296
- end
297
-
298
- alias_method :add_host, :add_asset
299
- alias_method :add_ip, :add_asset
300
-
301
280
  # Remove an asset to this site included scan targets, resolving whether an IP or hostname is
302
281
  # provided.
303
282
  #
@@ -307,15 +286,6 @@ module Nexpose
307
286
  @included_scan_targets[:addresses].reject! { |existing_asset| existing_asset == HostOrIP.convert(asset) }
308
287
  end
309
288
 
310
- # @deprecated Use {#remove_included_asset} instead.
311
- def remove_asset(asset)
312
- warn "[DEPRECATED] Use #{self.class}#remove_included_asset instead of #{self.class}#remove_asset."
313
- remove_included_asset(asset)
314
- end
315
-
316
- alias_method :remove_host, :remove_asset
317
- alias_method :remove_ip, :remove_asset
318
-
319
289
  # Adds assets to this site excluded scan targets by IP address range.
320
290
  #
321
291
  # @param [String] from Beginning IP address of a range.
@@ -1,4 +1,4 @@
1
1
  module Nexpose
2
2
  # The latest version of the Nexpose gem
3
- VERSION = '2.3.0'
3
+ VERSION = '3.0.0'
4
4
  end
data/lib/nexpose.rb CHANGED
@@ -53,10 +53,10 @@ require 'rexml/document'
53
53
  require 'net/https'
54
54
  require 'net/http'
55
55
  require 'uri'
56
- require 'rex/mime'
57
56
  require 'ipaddr'
58
57
  require 'json'
59
58
  require 'cgi'
59
+ require 'nexpose/rexlite/mime'
60
60
  require 'nexpose/api'
61
61
  require 'nexpose/json_serializer'
62
62
  require 'nexpose/error'
@@ -116,11 +116,3 @@ module Nexpose
116
116
  puts 'response: ' + object.response_xml.to_s
117
117
  end
118
118
  end
119
-
120
- # Monkey patch from ActiveSupport which rex 2.0.3 incorrectly replies upon.
121
- # This enables the multipart MIME handling in Connection#import_scan
122
- class String
123
- def blank?
124
- self !~ /\S/
125
- end
126
- end
data/nexpose.gemspec CHANGED
@@ -18,8 +18,6 @@ Gem::Specification.new do |s|
18
18
  s.required_ruby_version = '>= 2.1'
19
19
  s.platform = 'ruby'
20
20
 
21
- s.add_runtime_dependency('rex', '= 2.0.8')
22
-
23
21
  s.add_development_dependency('bundler', '~> 1.3')
24
22
  s.add_development_dependency('codeclimate-test-reporter', '~> 0.4.6')
25
23
  s.add_development_dependency('simplecov', '~> 0.9.1')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexpose
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - HD Moore
@@ -13,22 +13,8 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2015-12-10 00:00:00.000000000 Z
16
+ date: 2015-12-11 00:00:00.000000000 Z
17
17
  dependencies:
18
- - !ruby/object:Gem::Dependency
19
- name: rex
20
- requirement: !ruby/object:Gem::Requirement
21
- requirements:
22
- - - '='
23
- - !ruby/object:Gem::Version
24
- version: 2.0.8
25
- type: :runtime
26
- prerelease: false
27
- version_requirements: !ruby/object:Gem::Requirement
28
- requirements:
29
- - - '='
30
- - !ruby/object:Gem::Version
31
- version: 2.0.8
32
18
  - !ruby/object:Gem::Dependency
33
19
  name: bundler
34
20
  requirement: !ruby/object:Gem::Requirement
@@ -179,6 +165,12 @@ files:
179
165
  - lib/nexpose/pool.rb
180
166
  - lib/nexpose/report.rb
181
167
  - lib/nexpose/report_template.rb
168
+ - lib/nexpose/rexlite/README.md
169
+ - lib/nexpose/rexlite/mime.rb
170
+ - lib/nexpose/rexlite/mime/encoding.rb
171
+ - lib/nexpose/rexlite/mime/header.rb
172
+ - lib/nexpose/rexlite/mime/message.rb
173
+ - lib/nexpose/rexlite/mime/part.rb
182
174
  - lib/nexpose/role.rb
183
175
  - lib/nexpose/scan.rb
184
176
  - lib/nexpose/scan_template.rb