nexpose 2.3.0 → 3.0.0

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: 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