nexpose 0.1.7 → 0.1.8

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 CHANGED
@@ -71,6 +71,7 @@ require 'nexpose/creds'
71
71
  require 'nexpose/connection'
72
72
  require 'nexpose/role'
73
73
  require 'nexpose/common'
74
+ require 'nexpose/group'
74
75
 
75
76
  module Nexpose
76
77
 
@@ -0,0 +1,118 @@
1
+ module Nexpose
2
+ module NexposeAPI
3
+ include XMLUtils
4
+
5
+ # Delete an asset group and all associated data.
6
+ #
7
+ # @param [Fixnum] id Asset group ID to delete.
8
+ #
9
+ # @return [Boolean] Whether group deletion succeeded.
10
+ #
11
+ def asset_group_delete(id)
12
+ r = execute(make_xml('AssetGroupDeleteRequest', {'group-id' => id}))
13
+ r.success
14
+ end
15
+
16
+ alias_method :delete_asset_group, :asset_group_delete
17
+
18
+ # Retrieve a list of all asset groups the user is authorized to view or
19
+ # manage.
20
+ #
21
+ # @return [Array[AssetGroupSummary]] Array of AssetGroupSummary objects.
22
+ #
23
+ def asset_groups
24
+ r = execute(make_xml('AssetGroupListingRequest'))
25
+
26
+ res = []
27
+ if r.success
28
+ r.res.elements.each('//AssetGroupSummary') do |group|
29
+ res << AssetGroupSummary.new(group.attributes['id'].to_i,
30
+ group.attributes['name'].to_s,
31
+ group.attributes['description'].to_s,
32
+ group.attributes['riskscore'].to_f)
33
+ end
34
+ end
35
+ res
36
+ end
37
+
38
+ alias_method :asset_groups_listing, :asset_groups
39
+ end
40
+
41
+ # Summary value object for asset group information.
42
+ #
43
+ class AssetGroupSummary
44
+ attr_reader :id, :name, :description, :risk_score
45
+
46
+ def initialize(id, name, desc, risk)
47
+ @id, @name, @description, @risk_score = id, name, desc, risk
48
+ end
49
+
50
+ # Delete this asset group and all associated data.
51
+ #
52
+ # @param [Connection] connection Connection to security console.
53
+ #
54
+ def delete(connection)
55
+ connection.asset_group_delete(@id)
56
+ end
57
+ end
58
+
59
+ # Asset group configuration object containing Device details.
60
+ #
61
+ class AssetGroup < AssetGroupSummary
62
+
63
+ # Array[Device] of devices associated with this asset group.
64
+ attr_accessor :devices
65
+
66
+ def initialize(id, name, desc, risk)
67
+ @id, @name, @description, @risk_score = id, name, desc, risk
68
+ @devices = []
69
+ end
70
+
71
+ # Launch adhoc scans against each group of assets per site.
72
+ #
73
+ # @param [Connection] connection Connection to console where asset group is configured.
74
+ # @return [Array[Hash[Fixnum, Fixnum]]] Array of scan ID and engine ID
75
+ # pairs for each scan launched.
76
+ #
77
+ def rescan_assets(connection)
78
+ sites_ids = @devices.collect { |d| d.site_id }.uniq
79
+ scans = []
80
+ sites_ids.each do |id|
81
+ dev_ids = @devices.select { |d| d.site_id == id }.map { |d| d.id }
82
+ scans << connection.site_device_scan_start(id, dev_ids)
83
+ end
84
+ scans
85
+ end
86
+
87
+ # Load an existing configuration from a Nexpose instance.
88
+ #
89
+ # @param [Connection] connection Connection to console where asset group is configured.
90
+ # @param [Fixnum] id Asset group ID of an existing group.
91
+ # @return [AssetGroup] Asset group configuration loaded from a Nexpose console.
92
+ #
93
+ def self.load(connection, id)
94
+ r = APIRequest.execute(connection.url,
95
+ %Q(<AssetGroupConfigRequest session-id="#{connection.session_id}" group-id="#{id}"/>))
96
+ parse(r.res)
97
+ end
98
+
99
+ def self.parse(rexml)
100
+ return nil unless rexml
101
+
102
+ rexml.elements.each('//AssetGroup') do |group|
103
+ asset_group = new(group.attributes['id'].to_i,
104
+ group.attributes['name'].to_s,
105
+ group.attributes['description'].to_s,
106
+ group.attributes['riskscore'].to_f)
107
+ rexml.elements.each('//Devices/device') do |dev|
108
+ asset_group.devices << Device.new(dev.attributes['id'].to_i,
109
+ dev.attributes['address'].to_s,
110
+ dev.attributes['site-id'].to_i,
111
+ dev.attributes['riskfactor'].to_f,
112
+ dev.attributes['riskscore'].to_f)
113
+ end
114
+ return asset_group
115
+ end
116
+ end
117
+ end
118
+ end
data/lib/nexpose/misc.rb CHANGED
@@ -7,56 +7,6 @@ module Nexpose
7
7
  r.success
8
8
  end
9
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
10
  # Lists all the users for the NSC along with the user details.
61
11
  #
62
12
  def list_users
data/lib/nexpose/site.rb CHANGED
@@ -98,9 +98,9 @@ module Nexpose
98
98
  # Starts device specific site scanning.
99
99
  #
100
100
  # devices - An Array of device IDs
101
- # hosts - An Array of Hashes [o]=>{:range=>"to,from"} [1]=>{:host=>host}
101
+ # hosts - An Array of Hashes [o]=>{:range=>"from,to"} [1]=>{:host=>host}
102
102
  #-----------------------------------------------------------------------
103
- def site_device_scan_start(site_id, devices, hosts)
103
+ def site_device_scan_start(site_id, devices, hosts = nil)
104
104
 
105
105
  if hosts == nil and devices == nil
106
106
  raise ArgumentError.new("Both the device and host list is nil")
@@ -120,9 +120,12 @@ module Nexpose
120
120
  inner_xml = REXML::Element.new 'Hosts'
121
121
  hosts.each_index do |x|
122
122
  if hosts[x].key? :range
123
- to = hosts[x][:range].split(',')[0]
124
- from = hosts[x][:range].split(',')[1]
125
- inner_xml.add_element 'range', {'to' => "#{to}", 'from' => "#{from}"}
123
+ from, to = hosts[x][:range].split(',')
124
+ if to
125
+ inner_xml.add_element 'range', {'to' => to, 'from' => from}
126
+ else
127
+ inner_xml.add_element 'range', {'from' => from}
128
+ end
126
129
  end
127
130
  if hosts[x].key? :host
128
131
  host_element = REXML::Element.new 'host'
@@ -223,9 +226,40 @@ module Nexpose
223
226
  is_dynamic
224
227
  end
225
228
 
229
+ # Adds an asset to this site by host name.
230
+ #
231
+ # @param [String] hostname FQDN or DNS-resolvable host name of an asset.
232
+ def add_host(hostname)
233
+ @assets << HostName.new(hostname)
234
+ end
235
+
236
+ # Adds an asset to this site by IP address.
237
+ #
238
+ # @param [String] ip IP address of an asset.
239
+ def add_ip(ip)
240
+ @assets << IPRange.new(ip)
241
+ end
242
+
243
+ # Adds an asset to this site, resolving whether an IP or hostname is
244
+ # provided.
245
+ #
246
+ # @param [String] asset Identifier of an asset, either IP or host name.
247
+ #
248
+ def add_asset(asset)
249
+ begin
250
+ add_ip(asset)
251
+ rescue ArgumentError => e
252
+ if e.message == 'invalid address'
253
+ add_host(asset)
254
+ else
255
+ raise "Unable to parse asset: '#{asset}'"
256
+ end
257
+ end
258
+ end
259
+
226
260
  # Load an existing configuration from a Nexpose instance.
227
261
  #
228
- # @param [Connection] connection Connection to console where scan will be launched.
262
+ # @param [Connection] connection Connection to console where site exists.
229
263
  # @param [Fixnum] id Site ID of an existing site.
230
264
  # @return [Site] Site configuration loaded from a Nexpose console.
231
265
  def self.load(connection, id)
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: 0.1.7
4
+ version: 0.1.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-22 00:00:00.000000000 Z
13
+ date: 2013-03-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: librex
@@ -58,6 +58,7 @@ files:
58
58
  - README.markdown
59
59
  - Rakefile
60
60
  - lib/nexpose.rb
61
+ - lib/nexpose/group.rb
61
62
  - lib/nexpose/ticket.rb
62
63
  - lib/nexpose/common.rb
63
64
  - lib/nexpose/scan_engine.rb