nexpose 7.0.0 → 7.0.1

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2 -3
  3. data/Gemfile.lock +1 -1
  4. data/lib/nexpose/ajax.rb +12 -16
  5. data/lib/nexpose/alert.rb +20 -21
  6. data/lib/nexpose/api.rb +3 -3
  7. data/lib/nexpose/asset.rb +23 -23
  8. data/lib/nexpose/blackout.rb +6 -14
  9. data/lib/nexpose/common.rb +87 -92
  10. data/lib/nexpose/connection.rb +8 -10
  11. data/lib/nexpose/console.rb +9 -9
  12. data/lib/nexpose/dag.rb +2 -2
  13. data/lib/nexpose/data_table.rb +8 -12
  14. data/lib/nexpose/device.rb +35 -34
  15. data/lib/nexpose/discovery.rb +69 -69
  16. data/lib/nexpose/discovery/filter.rb +7 -8
  17. data/lib/nexpose/engine.rb +22 -21
  18. data/lib/nexpose/error.rb +7 -5
  19. data/lib/nexpose/external.rb +21 -16
  20. data/lib/nexpose/filter.rb +51 -52
  21. data/lib/nexpose/global_blackout.rb +6 -7
  22. data/lib/nexpose/global_settings.rb +2 -3
  23. data/lib/nexpose/group.rb +25 -19
  24. data/lib/nexpose/json_serializer.rb +4 -14
  25. data/lib/nexpose/maint.rb +8 -9
  26. data/lib/nexpose/manage.rb +2 -2
  27. data/lib/nexpose/multi_tenant_user.rb +42 -42
  28. data/lib/nexpose/password_policy.rb +14 -14
  29. data/lib/nexpose/pool.rb +6 -5
  30. data/lib/nexpose/report.rb +30 -34
  31. data/lib/nexpose/report_template.rb +17 -18
  32. data/lib/nexpose/role.rb +64 -55
  33. data/lib/nexpose/scan.rb +77 -60
  34. data/lib/nexpose/scan_template.rb +17 -17
  35. data/lib/nexpose/scheduled_backup.rb +8 -8
  36. data/lib/nexpose/scheduled_maintenance.rb +9 -9
  37. data/lib/nexpose/shared_credential.rb +30 -33
  38. data/lib/nexpose/shared_secret.rb +5 -5
  39. data/lib/nexpose/silo.rb +68 -66
  40. data/lib/nexpose/silo_profile.rb +47 -50
  41. data/lib/nexpose/site.rb +101 -123
  42. data/lib/nexpose/site_credentials.rb +15 -17
  43. data/lib/nexpose/tag.rb +73 -80
  44. data/lib/nexpose/ticket.rb +45 -42
  45. data/lib/nexpose/user.rb +45 -45
  46. data/lib/nexpose/util.rb +1 -1
  47. data/lib/nexpose/version.rb +1 -1
  48. data/lib/nexpose/vuln.rb +45 -43
  49. data/lib/nexpose/vuln_def.rb +7 -7
  50. data/lib/nexpose/vuln_exception.rb +35 -36
  51. data/lib/nexpose/wait.rb +32 -28
  52. data/lib/nexpose/web_credentials.rb +34 -36
  53. metadata +2 -2
@@ -19,9 +19,8 @@ module Nexpose
19
19
  # Private constructor. See #load method for retrieving a settings object.
20
20
  #
21
21
  def initialize(xml)
22
- @xml = xml
23
-
24
- @asset_linking = parse_asset_linking_from_xml(xml)
22
+ @xml = xml
23
+ @asset_linking = parse_asset_linking_from_xml(xml)
25
24
  @asset_exclusions = HostOrIP.parse(xml)
26
25
  @control_scanning = parse_control_scanning_from_xml(xml)
27
26
  end
@@ -10,11 +10,11 @@ module Nexpose
10
10
  # @return [Boolean] Whether group deletion succeeded.
11
11
  #
12
12
  def delete_asset_group(id)
13
- r = execute(make_xml('AssetGroupDeleteRequest', {'group-id' => id}))
13
+ r = execute(make_xml('AssetGroupDeleteRequest', { 'group-id' => id }))
14
14
  r.success
15
15
  end
16
16
 
17
- alias_method :delete_group, :delete_asset_group
17
+ alias delete_group delete_asset_group
18
18
 
19
19
  # Retrieve an array of all asset groups the user is authorized to view or
20
20
  # manage.
@@ -23,7 +23,6 @@ module Nexpose
23
23
  #
24
24
  def list_asset_groups
25
25
  r = execute(make_xml('AssetGroupListingRequest'))
26
-
27
26
  groups = []
28
27
  if r.success
29
28
  r.res.elements.each('AssetGroupListingResponse/AssetGroupSummary') do |group|
@@ -37,8 +36,8 @@ module Nexpose
37
36
  groups
38
37
  end
39
38
 
40
- alias_method :groups, :list_asset_groups
41
- alias_method :asset_groups, :list_asset_groups
39
+ alias groups list_asset_groups
40
+ alias asset_groups list_asset_groups
42
41
  end
43
42
 
44
43
  # Summary value object for asset group information.
@@ -47,7 +46,11 @@ module Nexpose
47
46
  attr_reader :id, :name, :description, :risk_score, :dynamic
48
47
 
49
48
  def initialize(id, name, desc, risk, dynamic)
50
- @id, @name, @description, @risk_score, @dynamic = id, name, desc, risk, dynamic
49
+ @id = id
50
+ @name = name
51
+ @description = desc
52
+ @risk_score = risk
53
+ @dynamic = dynamic
51
54
  end
52
55
 
53
56
  def dynamic?
@@ -68,17 +71,20 @@ module Nexpose
68
71
  class AssetGroup < AssetGroupSummary
69
72
  include Sanitize
70
73
 
71
- attr_accessor :name, :description, :id , :tags
74
+ attr_accessor :name, :description, :id, :tags
72
75
 
73
76
  # Array[Device] of devices associated with this asset group.
74
77
  attr_accessor :assets
75
- alias :devices :assets
76
- alias :devices= :assets=
78
+ alias devices assets
79
+ alias devices= assets=
77
80
 
78
81
  def initialize(name, desc, id = -1, risk = 0.0)
79
- @name, @description, @id, @risk_score = name, desc, id, risk
80
- @assets = []
81
- @tags = []
82
+ @name = name
83
+ @description = desc
84
+ @id = id
85
+ @risk_score = risk
86
+ @assets = []
87
+ @tags = []
82
88
  end
83
89
 
84
90
  def save(connection)
@@ -86,7 +92,7 @@ module Nexpose
86
92
  xml << to_xml
87
93
  xml << '</AssetGroupSaveRequest>'
88
94
  res = connection.execute(xml)
89
- @id = res.attributes['group-id'].to_i if res.success and @id < 1
95
+ @id = res.attributes['group-id'].to_i if res.success && @id < 1
90
96
  end
91
97
 
92
98
  # Generate an XML representation of this group configuration
@@ -95,8 +101,8 @@ module Nexpose
95
101
  #
96
102
  def as_xml
97
103
  xml = REXML::Element.new('AssetGroup')
98
- xml.attributes['id'] = @id
99
- xml.attributes['name'] = @name
104
+ xml.attributes['id'] = @id
105
+ xml.attributes['name'] = @name
100
106
  xml.attributes['description'] = @description
101
107
 
102
108
  if @description && !@description.empty?
@@ -106,7 +112,7 @@ module Nexpose
106
112
  end
107
113
 
108
114
  elem = REXML::Element.new('Devices')
109
- @assets.each { |a| elem.add_element('device', {'id' => a.id}) }
115
+ @assets.each { |a| elem.add_element('device', { 'id' => a.id }) }
110
116
  xml.add_element(elem)
111
117
 
112
118
  unless tags.empty?
@@ -134,8 +140,8 @@ module Nexpose
134
140
  # @return [Hash] Hash of site ID to Scan launch information for each scan.
135
141
  #
136
142
  def rescan_assets(connection)
137
- sites_ids = @assets.map { |d| d.site_id }.uniq
138
- scans = {}
143
+ scans = {}
144
+ sites_ids = @assets.map(&:site_id).uniq
139
145
  sites_ids.each do |site_id|
140
146
  to_scan = @assets.select { |d| d.site_id == site_id }
141
147
  scans[site_id] = connection.scan_devices(to_scan)
@@ -153,7 +159,7 @@ module Nexpose
153
159
  #
154
160
  def self.load(connection, id)
155
161
  xml = %(<AssetGroupConfigRequest session-id="#{connection.session_id}" group-id="#{id}"/>)
156
- r = APIRequest.execute(connection.url, xml)
162
+ r = APIRequest.execute(connection.url, xml)
157
163
  parse(r.res)
158
164
  end
159
165
 
@@ -6,13 +6,11 @@ module Nexpose
6
6
  data.each do |key, value|
7
7
  if respond_to?(key)
8
8
  property = value
9
-
10
9
  if value.respond_to? :each
11
10
  obj = resolve_type(key)
12
-
13
11
  unless obj.nil?
14
12
  if value.is_a?(Array)
15
- property = value.map { |dv| ((dv.respond_to? :each) ? create_object(obj, dv).deserialize(dv): dv) }
13
+ property = value.map { |dv| ((dv.respond_to? :each) ? create_object(obj, dv).deserialize(dv) : dv) }
16
14
  else
17
15
  property = create_object(obj, value).deserialize(value)
18
16
  end
@@ -20,20 +18,15 @@ module Nexpose
20
18
  elsif value.is_a?(String) && value.match(/^\d{8}T\d{6}\.\d{3}/)
21
19
  property = ISO8601.to_time(value)
22
20
  end
23
-
24
21
  instance_variable_set("@#{key}", property)
25
22
  end
26
23
  end
27
-
28
24
  self
29
25
  end
30
26
 
31
- def serialize()
27
+ def serialize
32
28
  hash = to_hash(Hash.new)
33
-
34
- unless hash.nil?
35
- JSON.generate(hash)
36
- end
29
+ JSON.generate(hash) unless hash.nil?
37
30
  end
38
31
 
39
32
  def to_hash(hash)
@@ -41,7 +34,6 @@ module Nexpose
41
34
  value = self.instance_variable_get(m)
42
35
  hash[m.to_s.delete('@')] = do_hash(value)
43
36
  end
44
-
45
37
  hash
46
38
  end
47
39
 
@@ -51,12 +43,10 @@ module Nexpose
51
43
  if obj.is_a?(Array)
52
44
  obj = obj.map do |el|
53
45
  do_hash(el)
54
-
55
46
  end
56
47
  elsif obj.class.included_modules.include? JsonSerializer
57
48
  obj = obj.to_hash(Hash.new)
58
49
  end
59
-
60
50
  obj
61
51
  end
62
52
 
@@ -89,4 +79,4 @@ module Nexpose
89
79
  class_name
90
80
  end
91
81
  end
92
- end
82
+ end
@@ -46,11 +46,10 @@ module Nexpose
46
46
  #
47
47
  def db_maintenance(clean_up = false, compress = false, reindex = false)
48
48
  return unless compress || clean_up || reindex
49
- parameters = { 'cmd' => 'startMaintenance',
50
- 'targetTask' => 'dbMaintenance' }
51
- parameters['cleanup'] = 1 if clean_up
49
+ parameters = { 'cmd' => 'startMaintenance', 'targetTask' => 'dbMaintenance' }
50
+ parameters['cleanup'] = 1 if clean_up
52
51
  parameters['compress'] = 1 if compress
53
- parameters['reindex'] = 1 if reindex
52
+ parameters['reindex'] = 1 if reindex
54
53
  xml = AJAX.form_post(self, '/admin/global/maintenance/maintCmd.txml', parameters)
55
54
  if !!(xml =~ /succeded="true"/)
56
55
  _maintenance_restart
@@ -85,12 +84,12 @@ module Nexpose
85
84
  attr_reader :size
86
85
 
87
86
  def initialize(name, date, description, version, independent, size)
88
- @name = name
89
- @date = date
90
- @description = description
91
- @version = version
87
+ @name = name
88
+ @date = date
89
+ @description = description
90
+ @version = version
92
91
  @platform_independent = independent
93
- @size = size
92
+ @size = size
94
93
  end
95
94
 
96
95
  # Restore this backup to the Nexpose console.
@@ -47,9 +47,9 @@ module Nexpose
47
47
  # Includes Product, Content, and Java versions.
48
48
  #
49
49
  def engine_versions
50
- info = console_command('version engines')
50
+ info = console_command('version engines')
51
51
  versions = []
52
- engines = info.sub('VERSION INFORMATION\n', '').split(/\n\n/)
52
+ engines = info.sub('VERSION INFORMATION\n', '').split(/\n\n/)
53
53
  engines.each do |eng|
54
54
  engdata = {}
55
55
  eng.split(/\n/).each do |kv|
@@ -17,14 +17,14 @@ module Nexpose
17
17
  end
18
18
  arr
19
19
  end
20
- alias_method :silo_users, :list_silo_users
20
+ alias silo_users list_silo_users
21
21
 
22
22
  # Delete the specified silo user
23
23
  #
24
24
  # @return Whether or not the delete request succeeded.
25
25
  #
26
26
  def delete_silo_user(user_id)
27
- r = execute(make_xml('MultiTenantUserDeleteRequest', {'user-id' => user_id}), '1.2')
27
+ r = execute(make_xml('MultiTenantUserDeleteRequest', { 'user-id' => user_id }), '1.2')
28
28
  r.success
29
29
  end
30
30
  end
@@ -42,21 +42,21 @@ module Nexpose
42
42
  attr_reader :locked
43
43
 
44
44
  def initialize(&block)
45
- instance_eval &block if block_given?
45
+ instance_eval(&block) if block_given?
46
46
  end
47
47
 
48
48
  def self.parse(xml)
49
49
  new do
50
- @id = xml.attributes['id'].to_i
51
- @full_name = xml.attributes['full-name']
52
- @user_name = xml.attributes['user-name']
53
- @email = xml.attributes['email']
54
- @superuser = xml.attributes['superuser'].to_s.chomp.eql?('true')
55
- @enabled = xml.attributes['enabled'].to_s.chomp.eql?('true')
50
+ @id = xml.attributes['id'].to_i
51
+ @full_name = xml.attributes['full-name']
52
+ @user_name = xml.attributes['user-name']
53
+ @email = xml.attributes['email']
54
+ @superuser = xml.attributes['superuser'].to_s.chomp.eql?('true')
55
+ @enabled = xml.attributes['enabled'].to_s.chomp.eql?('true')
56
56
  @auth_module = xml.attributes['auth-module']
57
57
  @auth_source = xml.attributes['auth-source']
58
- @silo_count = xml.attributes['silo-count'].to_i
59
- @locked = xml.attributes['locked'].to_s.chomp.eql?('true')
58
+ @silo_count = xml.attributes['silo-count'].to_i
59
+ @locked = xml.attributes['locked'].to_s.chomp.eql?('true')
60
60
  end
61
61
  end
62
62
  end
@@ -73,13 +73,13 @@ module Nexpose
73
73
  attr_accessor :silo_access
74
74
 
75
75
  def initialize(&block)
76
- instance_eval &block if block_given?
76
+ instance_eval(&block) if block_given?
77
77
 
78
78
  @silo_access = Array(@silo_access)
79
79
  end
80
80
 
81
81
  def save(connection)
82
- if (@id)
82
+ if @id
83
83
  update(connection)
84
84
  else
85
85
  create(connection)
@@ -112,14 +112,14 @@ module Nexpose
112
112
 
113
113
  def as_xml
114
114
  xml = REXML::Element.new('MultiTenantUserConfig')
115
- xml.add_attributes({'id' => @id,
116
- 'full-name' => @full_name,
117
- 'user-name' => @user_name,
118
- 'authsrcid' => @auth_source_id,
119
- 'email' => @email,
120
- 'password' => @password,
121
- 'superuser' => @superuser,
122
- 'enabled' => @enabled})
115
+ xml.add_attributes({ 'id' => @id,
116
+ 'full-name' => @full_name,
117
+ 'user-name' => @user_name,
118
+ 'authsrcid' => @auth_source_id,
119
+ 'email' => @email,
120
+ 'password' => @password,
121
+ 'superuser' => @superuser,
122
+ 'enabled' => @enabled })
123
123
  siloaccesses = xml.add_element('SiloAccesses')
124
124
  @silo_access.each { |silo_access| siloaccesses.add_element(silo_access.as_xml) }
125
125
  xml
@@ -135,20 +135,20 @@ module Nexpose
135
135
 
136
136
  def self.parse(xml)
137
137
  new do |user|
138
- user.id = xml.attributes['id'].to_i
139
- user.full_name = xml.attributes['full-name']
140
- user.user_name = xml.attributes['user-name']
141
- user.email = xml.attributes['email']
142
- user.superuser = xml.attributes['superuser'].to_s.chomp.eql?('true')
143
- user.enabled = xml.attributes['enabled'].to_s.chomp.eql?('true')
138
+ user.id = xml.attributes['id'].to_i
139
+ user.full_name = xml.attributes['full-name']
140
+ user.user_name = xml.attributes['user-name']
141
+ user.email = xml.attributes['email']
142
+ user.superuser = xml.attributes['superuser'].to_s.chomp.eql?('true')
143
+ user.enabled = xml.attributes['enabled'].to_s.chomp.eql?('true')
144
144
  user.auth_source_id = xml.attributes['authsrcid'].to_i
145
- user.silo_access = []
145
+ user.silo_access = []
146
146
  xml.elements.each('SiloAccesses/SiloAccess') { |access| user.silo_access << SiloAccess.parse(access) }
147
147
  end
148
148
  end
149
149
 
150
150
  def self.load(connection, user_id)
151
- r = connection.execute(connection.make_xml('MultiTenantUserConfigRequest', {'user-id' => user_id}), '1.2')
151
+ r = connection.execute(connection.make_xml('MultiTenantUserConfigRequest', { 'user-id' => user_id }), '1.2')
152
152
 
153
153
  if r.success
154
154
  r.res.elements.each('MultiTenantUserConfigResponse/MultiTenantUserConfig') do |config|
@@ -169,30 +169,30 @@ module Nexpose
169
169
  attr_accessor :groups
170
170
 
171
171
  def initialize(&block)
172
- instance_eval &block if block_given?
172
+ instance_eval(&block) if block_given?
173
173
  @sites = Array(@sites)
174
174
  @groups = Array(@groups)
175
175
  end
176
176
 
177
177
  def as_xml
178
178
  xml = REXML::Element.new('SiloAccess')
179
- xml.add_attributes({'all-groups' => @all_groups,
180
- 'all-sites' => @all_sites,
181
- 'role-name' => @role_name,
182
- 'silo-id' => @silo_id,
183
- 'default-silo' => @default})
179
+ xml.add_attributes({ 'all-groups' => @all_groups,
180
+ 'all-sites' => @all_sites,
181
+ 'role-name' => @role_name,
182
+ 'silo-id' => @silo_id,
183
+ 'default-silo' => @default })
184
184
 
185
185
  unless @groups.empty?
186
186
  groups = xml.add_element('AllowedGroups')
187
187
  @groups.each do |group|
188
- groups.add_element('AllowedGroup', {'id' => group})
188
+ groups.add_element('AllowedGroup', { 'id' => group })
189
189
  end
190
190
  end
191
191
 
192
192
  unless @sites.empty?
193
193
  sites = xml.add_element('AllowedSites')
194
194
  @sites.each do |site|
195
- sites.add_element('AllowedSite', {'id' => site})
195
+ sites.add_element('AllowedSite', { 'id' => site })
196
196
  end
197
197
  end
198
198
 
@@ -206,11 +206,11 @@ module Nexpose
206
206
  def self.parse(xml)
207
207
  new do |access|
208
208
  access.all_groups = xml.attributes['all-groups'].to_s.chomp.eql?('true')
209
- access.all_sites = xml.attributes['all-sites'].to_s.chomp.eql?('true')
210
- access.role_name = xml.attributes['role-name']
211
- access.silo_id = xml.attributes['silo-id']
212
- access.default = xml.attributes['default-silo'].to_s.chomp.eql?('true')
213
- access.sites = []
209
+ access.all_sites = xml.attributes['all-sites'].to_s.chomp.eql?('true')
210
+ access.role_name = xml.attributes['role-name']
211
+ access.silo_id = xml.attributes['silo-id']
212
+ access.default = xml.attributes['default-silo'].to_s.chomp.eql?('true')
213
+ access.sites = []
214
214
  xml.elements.each('AllowedSites/AllowedSite') { |site| access.sites << site.attributes['id'].to_i }
215
215
  access.groups = []
216
216
  xml.elements.each('AllowedGroups/AllowedGroup') { |group| access.groups << group.attributes['id'].to_i }
@@ -11,12 +11,12 @@ module Nexpose
11
11
  attr_accessor :expiration_days
12
12
 
13
13
  def initialize(policy_name:, min_length:, max_length:, special_chars:, capitals:, digits:, expiration_days: 0)
14
- @policy_name = policy_name.to_s
15
- @min_length = min_length.to_i
16
- @max_length = max_length.to_i
17
- @special_chars = special_chars.to_i
18
- @capitals = capitals.to_i
19
- @digits = digits.to_i
14
+ @policy_name = policy_name.to_s
15
+ @min_length = min_length.to_i
16
+ @max_length = max_length.to_i
17
+ @special_chars = special_chars.to_i
18
+ @capitals = capitals.to_i
19
+ @digits = digits.to_i
20
20
  @expiration_days = expiration_days.to_i
21
21
  end
22
22
 
@@ -32,13 +32,13 @@ module Nexpose
32
32
 
33
33
  def to_h
34
34
  {
35
- policyName: @policy_name,
36
- minLength: @min_length,
37
- maxLength: @max_length,
38
- specialChars: @special_chars,
39
- capitals: @capitals,
40
- digits: @digits,
41
- expirationDays: @expiration_days
35
+ policyName: @policy_name,
36
+ minLength: @min_length,
37
+ maxLength: @max_length,
38
+ specialChars: @special_chars,
39
+ capitals: @capitals,
40
+ digits: @digits,
41
+ expirationDays: @expiration_days
42
42
  }
43
43
  end
44
44
 
@@ -52,7 +52,7 @@ module Nexpose
52
52
  end
53
53
 
54
54
  def self.load(nsc)
55
- uri = '/api/2.1/password_policy/'
55
+ uri = '/api/2.1/password_policy/'
56
56
  resp = AJAX.get(nsc, uri, AJAX::CONTENT_TYPE::JSON)
57
57
  hash = JSON.parse(resp, symbolize_names: true)
58
58
  self.from_hash(hash)