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.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +2 -3
 - data/Gemfile.lock +1 -1
 - data/lib/nexpose/ajax.rb +12 -16
 - data/lib/nexpose/alert.rb +20 -21
 - data/lib/nexpose/api.rb +3 -3
 - data/lib/nexpose/asset.rb +23 -23
 - data/lib/nexpose/blackout.rb +6 -14
 - data/lib/nexpose/common.rb +87 -92
 - data/lib/nexpose/connection.rb +8 -10
 - data/lib/nexpose/console.rb +9 -9
 - data/lib/nexpose/dag.rb +2 -2
 - data/lib/nexpose/data_table.rb +8 -12
 - data/lib/nexpose/device.rb +35 -34
 - data/lib/nexpose/discovery.rb +69 -69
 - data/lib/nexpose/discovery/filter.rb +7 -8
 - data/lib/nexpose/engine.rb +22 -21
 - data/lib/nexpose/error.rb +7 -5
 - data/lib/nexpose/external.rb +21 -16
 - data/lib/nexpose/filter.rb +51 -52
 - data/lib/nexpose/global_blackout.rb +6 -7
 - data/lib/nexpose/global_settings.rb +2 -3
 - data/lib/nexpose/group.rb +25 -19
 - data/lib/nexpose/json_serializer.rb +4 -14
 - data/lib/nexpose/maint.rb +8 -9
 - data/lib/nexpose/manage.rb +2 -2
 - data/lib/nexpose/multi_tenant_user.rb +42 -42
 - data/lib/nexpose/password_policy.rb +14 -14
 - data/lib/nexpose/pool.rb +6 -5
 - data/lib/nexpose/report.rb +30 -34
 - data/lib/nexpose/report_template.rb +17 -18
 - data/lib/nexpose/role.rb +64 -55
 - data/lib/nexpose/scan.rb +77 -60
 - data/lib/nexpose/scan_template.rb +17 -17
 - data/lib/nexpose/scheduled_backup.rb +8 -8
 - data/lib/nexpose/scheduled_maintenance.rb +9 -9
 - data/lib/nexpose/shared_credential.rb +30 -33
 - data/lib/nexpose/shared_secret.rb +5 -5
 - data/lib/nexpose/silo.rb +68 -66
 - data/lib/nexpose/silo_profile.rb +47 -50
 - data/lib/nexpose/site.rb +101 -123
 - data/lib/nexpose/site_credentials.rb +15 -17
 - data/lib/nexpose/tag.rb +73 -80
 - data/lib/nexpose/ticket.rb +45 -42
 - data/lib/nexpose/user.rb +45 -45
 - data/lib/nexpose/util.rb +1 -1
 - data/lib/nexpose/version.rb +1 -1
 - data/lib/nexpose/vuln.rb +45 -43
 - data/lib/nexpose/vuln_def.rb +7 -7
 - data/lib/nexpose/vuln_exception.rb +35 -36
 - data/lib/nexpose/wait.rb +32 -28
 - data/lib/nexpose/web_credentials.rb +34 -36
 - metadata +2 -2
 
    
        data/lib/nexpose/site.rb
    CHANGED
    
    | 
         @@ -22,7 +22,7 @@ module Nexpose 
     | 
|
| 
       22 
22 
     | 
    
         
             
                  arr
         
     | 
| 
       23 
23 
     | 
    
         
             
                end
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                 
     | 
| 
      
 25 
     | 
    
         
            +
                alias sites list_sites
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                # Delete the specified site and all associated scan data.
         
     | 
| 
       28 
28 
     | 
    
         
             
                #
         
     | 
| 
         @@ -69,7 +69,7 @@ module Nexpose 
     | 
|
| 
       69 
69 
     | 
    
         
             
                #
         
     | 
| 
       70 
70 
     | 
    
         
             
                def completed_scans(site_id)
         
     | 
| 
       71 
71 
     | 
    
         
             
                  table = { 'table-id' => 'site-completed-scans' }
         
     | 
| 
       72 
     | 
    
         
            -
                  data 
     | 
| 
      
 72 
     | 
    
         
            +
                  data  = DataTable._get_json_table(self, "/data/scan/site/#{site_id}", table)
         
     | 
| 
       73 
73 
     | 
    
         
             
                  data.map(&CompletedScan.method(:parse_json))
         
     | 
| 
       74 
74 
     | 
    
         
             
                end
         
     | 
| 
       75 
75 
     | 
    
         
             
              end
         
     | 
| 
         @@ -158,21 +158,21 @@ module Nexpose 
     | 
|
| 
       158 
158 
     | 
    
         
             
                # @param [String] name Unique name of the site.
         
     | 
| 
       159 
159 
     | 
    
         
             
                # @param [String] scan_template_id ID of the scan template to use.
         
     | 
| 
       160 
160 
     | 
    
         
             
                def initialize(name = nil, scan_template_id = 'full-audit-without-web-spider')
         
     | 
| 
       161 
     | 
    
         
            -
                  @name 
     | 
| 
       162 
     | 
    
         
            -
                  @scan_template_id 
     | 
| 
       163 
     | 
    
         
            -
                  @id 
     | 
| 
       164 
     | 
    
         
            -
                  @risk_factor 
     | 
| 
       165 
     | 
    
         
            -
                  @config_version 
     | 
| 
       166 
     | 
    
         
            -
                  @schedules 
     | 
| 
       167 
     | 
    
         
            -
                  @blackouts 
     | 
| 
      
 161 
     | 
    
         
            +
                  @name                  = name
         
     | 
| 
      
 162 
     | 
    
         
            +
                  @scan_template_id      = scan_template_id
         
     | 
| 
      
 163 
     | 
    
         
            +
                  @id                    = -1
         
     | 
| 
      
 164 
     | 
    
         
            +
                  @risk_factor           = 1.0
         
     | 
| 
      
 165 
     | 
    
         
            +
                  @config_version        = 3
         
     | 
| 
      
 166 
     | 
    
         
            +
                  @schedules             = []
         
     | 
| 
      
 167 
     | 
    
         
            +
                  @blackouts             = []
         
     | 
| 
       168 
168 
     | 
    
         
             
                  @included_scan_targets = { addresses: [], asset_groups: [] }
         
     | 
| 
       169 
169 
     | 
    
         
             
                  @excluded_scan_targets = { addresses: [], asset_groups: [] }
         
     | 
| 
       170 
     | 
    
         
            -
                  @site_credentials 
     | 
| 
       171 
     | 
    
         
            -
                  @shared_credentials 
     | 
| 
       172 
     | 
    
         
            -
                  @web_credentials 
     | 
| 
       173 
     | 
    
         
            -
                  @alerts 
     | 
| 
       174 
     | 
    
         
            -
                  @users 
     | 
| 
       175 
     | 
    
         
            -
                  @tags 
     | 
| 
      
 170 
     | 
    
         
            +
                  @site_credentials      = []
         
     | 
| 
      
 171 
     | 
    
         
            +
                  @shared_credentials    = []
         
     | 
| 
      
 172 
     | 
    
         
            +
                  @web_credentials       = []
         
     | 
| 
      
 173 
     | 
    
         
            +
                  @alerts                = []
         
     | 
| 
      
 174 
     | 
    
         
            +
                  @users                 = []
         
     | 
| 
      
 175 
     | 
    
         
            +
                  @tags                  = []
         
     | 
| 
       176 
176 
     | 
    
         
             
                end
         
     | 
| 
       177 
177 
     | 
    
         | 
| 
       178 
178 
     | 
    
         
             
                # Returns the array of included scan target addresses.
         
     | 
| 
         @@ -231,23 +231,20 @@ module Nexpose 
     | 
|
| 
       231 
231 
     | 
    
         
             
                def is_dynamic?
         
     | 
| 
       232 
232 
     | 
    
         
             
                  !@discovery_config.nil?
         
     | 
| 
       233 
233 
     | 
    
         
             
                end
         
     | 
| 
      
 234 
     | 
    
         
            +
                alias dynamic? is_dynamic?
         
     | 
| 
       234 
235 
     | 
    
         | 
| 
       235 
236 
     | 
    
         
             
                # Adds assets to this site by IP address range.
         
     | 
| 
       236 
237 
     | 
    
         
             
                #
         
     | 
| 
       237 
238 
     | 
    
         
             
                # @param [String] from Beginning IP address of a range.
         
     | 
| 
       238 
239 
     | 
    
         
             
                # @param [String] to Ending IP address of a range.
         
     | 
| 
       239 
240 
     | 
    
         
             
                def include_ip_range(from, to)
         
     | 
| 
       240 
     | 
    
         
            -
                   
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
       243 
     | 
    
         
            -
             
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
       245 
     | 
    
         
            -
             
     | 
| 
       246 
     | 
    
         
            -
             
     | 
| 
       247 
     | 
    
         
            -
                    @included_scan_targets[:addresses] << IPRange.new(from, to)
         
     | 
| 
       248 
     | 
    
         
            -
                  rescue ArgumentError => e
         
     | 
| 
       249 
     | 
    
         
            -
                    raise "#{e.message} in given IP range"
         
     | 
| 
       250 
     | 
    
         
            -
                  end
         
     | 
| 
      
 241 
     | 
    
         
            +
                  from_ip = IPAddr.new(from)
         
     | 
| 
      
 242 
     | 
    
         
            +
                  to_ip   = IPAddr.new(to)
         
     | 
| 
      
 243 
     | 
    
         
            +
                  (from_ip..to_ip)
         
     | 
| 
      
 244 
     | 
    
         
            +
                  raise 'Invalid IP range specified' if (from_ip..to_ip).to_a.size.zero?
         
     | 
| 
      
 245 
     | 
    
         
            +
                  @included_scan_targets[:addresses] << IPRange.new(from, to)
         
     | 
| 
      
 246 
     | 
    
         
            +
                rescue ArgumentError => e
         
     | 
| 
      
 247 
     | 
    
         
            +
                  raise "#{e.message} in given IP range"
         
     | 
| 
       251 
248 
     | 
    
         
             
                end
         
     | 
| 
       252 
249 
     | 
    
         | 
| 
       253 
250 
     | 
    
         
             
                # Remove assets to this site by IP address range.
         
     | 
| 
         @@ -255,17 +252,13 @@ module Nexpose 
     | 
|
| 
       255 
252 
     | 
    
         
             
                # @param [String] from Beginning IP address of a range.
         
     | 
| 
       256 
253 
     | 
    
         
             
                # @param [String] to Ending IP address of a range.
         
     | 
| 
       257 
254 
     | 
    
         
             
                def remove_included_ip_range(from, to)
         
     | 
| 
       258 
     | 
    
         
            -
                   
     | 
| 
       259 
     | 
    
         
            -
             
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
       261 
     | 
    
         
            -
             
     | 
| 
       262 
     | 
    
         
            -
             
     | 
| 
       263 
     | 
    
         
            -
             
     | 
| 
       264 
     | 
    
         
            -
             
     | 
| 
       265 
     | 
    
         
            -
                    @included_scan_targets[:addresses].reject! { |t| t.eql? IPRange.new(from, to) }
         
     | 
| 
       266 
     | 
    
         
            -
                  rescue ArgumentError => e
         
     | 
| 
       267 
     | 
    
         
            -
                    raise "#{e.message} in given IP range"
         
     | 
| 
       268 
     | 
    
         
            -
                  end
         
     | 
| 
      
 255 
     | 
    
         
            +
                  from_ip = IPAddr.new(from)
         
     | 
| 
      
 256 
     | 
    
         
            +
                  to_ip   = IPAddr.new(to)
         
     | 
| 
      
 257 
     | 
    
         
            +
                  (from_ip..to_ip)
         
     | 
| 
      
 258 
     | 
    
         
            +
                  raise 'Invalid IP range specified' if (from_ip..to_ip).to_a.size.zero?
         
     | 
| 
      
 259 
     | 
    
         
            +
                  @included_scan_targets[:addresses].reject! { |t| t.eql? IPRange.new(from, to) }
         
     | 
| 
      
 260 
     | 
    
         
            +
                rescue ArgumentError => e
         
     | 
| 
      
 261 
     | 
    
         
            +
                  raise "#{e.message} in given IP range"
         
     | 
| 
       269 
262 
     | 
    
         
             
                end
         
     | 
| 
       270 
263 
     | 
    
         | 
| 
       271 
264 
     | 
    
         
             
                # Adds an asset to this site included scan targets, resolving whether an IP or hostname is
         
     | 
| 
         @@ -291,17 +284,13 @@ module Nexpose 
     | 
|
| 
       291 
284 
     | 
    
         
             
                # @param [String] from Beginning IP address of a range.
         
     | 
| 
       292 
285 
     | 
    
         
             
                # @param [String] to Ending IP address of a range.
         
     | 
| 
       293 
286 
     | 
    
         
             
                def exclude_ip_range(from, to)
         
     | 
| 
       294 
     | 
    
         
            -
                   
     | 
| 
       295 
     | 
    
         
            -
             
     | 
| 
       296 
     | 
    
         
            -
             
     | 
| 
       297 
     | 
    
         
            -
             
     | 
| 
       298 
     | 
    
         
            -
             
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
       300 
     | 
    
         
            -
             
     | 
| 
       301 
     | 
    
         
            -
                    @excluded_scan_targets[:addresses] << IPRange.new(from, to)
         
     | 
| 
       302 
     | 
    
         
            -
                  rescue ArgumentError => e
         
     | 
| 
       303 
     | 
    
         
            -
                    raise "#{e.message} in given IP range"
         
     | 
| 
       304 
     | 
    
         
            -
                  end
         
     | 
| 
      
 287 
     | 
    
         
            +
                  from_ip = IPAddr.new(from)
         
     | 
| 
      
 288 
     | 
    
         
            +
                  to_ip   = IPAddr.new(to)
         
     | 
| 
      
 289 
     | 
    
         
            +
                  (from_ip..to_ip)
         
     | 
| 
      
 290 
     | 
    
         
            +
                  raise 'Invalid IP range specified' if (from_ip..to_ip).to_a.size.zero?
         
     | 
| 
      
 291 
     | 
    
         
            +
                  @excluded_scan_targets[:addresses] << IPRange.new(from, to)
         
     | 
| 
      
 292 
     | 
    
         
            +
                rescue ArgumentError => e
         
     | 
| 
      
 293 
     | 
    
         
            +
                  raise "#{e.message} in given IP range"
         
     | 
| 
       305 
294 
     | 
    
         
             
                end
         
     | 
| 
       306 
295 
     | 
    
         | 
| 
       307 
296 
     | 
    
         
             
                # Remove assets from this site excluded scan targets by IP address range.
         
     | 
| 
         @@ -309,17 +298,13 @@ module Nexpose 
     | 
|
| 
       309 
298 
     | 
    
         
             
                # @param [String] from Beginning IP address of a range.
         
     | 
| 
       310 
299 
     | 
    
         
             
                # @param [String] to Ending IP address of a range.
         
     | 
| 
       311 
300 
     | 
    
         
             
                def remove_excluded_ip_range(from, to)
         
     | 
| 
       312 
     | 
    
         
            -
                   
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
       314 
     | 
    
         
            -
             
     | 
| 
       315 
     | 
    
         
            -
             
     | 
| 
       316 
     | 
    
         
            -
             
     | 
| 
       317 
     | 
    
         
            -
             
     | 
| 
       318 
     | 
    
         
            -
             
     | 
| 
       319 
     | 
    
         
            -
                    @excluded_scan_targets[:addresses].reject! { |t| t.eql? IPRange.new(from, to) }
         
     | 
| 
       320 
     | 
    
         
            -
                  rescue ArgumentError => e
         
     | 
| 
       321 
     | 
    
         
            -
                    raise "#{e.message} in given IP range"
         
     | 
| 
       322 
     | 
    
         
            -
                  end
         
     | 
| 
      
 301 
     | 
    
         
            +
                  from_ip = IPAddr.new(from)
         
     | 
| 
      
 302 
     | 
    
         
            +
                  to_ip   = IPAddr.new(to)
         
     | 
| 
      
 303 
     | 
    
         
            +
                  (from_ip..to_ip)
         
     | 
| 
      
 304 
     | 
    
         
            +
                  raise 'Invalid IP range specified' if (from_ip..to_ip).to_a.size.zero?
         
     | 
| 
      
 305 
     | 
    
         
            +
                  @excluded_scan_targets[:addresses].reject! { |t| t.eql? IPRange.new(from, to) }
         
     | 
| 
      
 306 
     | 
    
         
            +
                rescue ArgumentError => e
         
     | 
| 
      
 307 
     | 
    
         
            +
                  raise "#{e.message} in given IP range"
         
     | 
| 
       323 
308 
     | 
    
         
             
                end
         
     | 
| 
       324 
309 
     | 
    
         | 
| 
       325 
310 
     | 
    
         
             
                # Adds an asset to this site excluded scan targets, resolving whether an IP or hostname is
         
     | 
| 
         @@ -391,7 +376,7 @@ module Nexpose 
     | 
|
| 
       391 
376 
     | 
    
         
             
                    raise 'Invalid user id. A user id must be a positive number and refer to an existing system user.'
         
     | 
| 
       392 
377 
     | 
    
         
             
                  end
         
     | 
| 
       393 
378 
     | 
    
         | 
| 
       394 
     | 
    
         
            -
                  @users << { id: user_id}
         
     | 
| 
      
 379 
     | 
    
         
            +
                  @users << { id: user_id }
         
     | 
| 
       395 
380 
     | 
    
         
             
                end
         
     | 
| 
       396 
381 
     | 
    
         | 
| 
       397 
382 
     | 
    
         
             
                def remove_user(user_id)
         
     | 
| 
         @@ -427,36 +412,29 @@ module Nexpose 
     | 
|
| 
       427 
412 
     | 
    
         
             
                end
         
     | 
| 
       428 
413 
     | 
    
         | 
| 
       429 
414 
     | 
    
         
             
                def to_h
         
     | 
| 
       430 
     | 
    
         
            -
                  included_scan_targets = {
         
     | 
| 
       431 
     | 
    
         
            -
             
     | 
| 
       432 
     | 
    
         
            -
             
     | 
| 
       433 
     | 
    
         
            -
             
     | 
| 
       434 
     | 
    
         
            -
                   
     | 
| 
       435 
     | 
    
         
            -
             
     | 
| 
       436 
     | 
    
         
            -
             
     | 
| 
       437 
     | 
    
         
            -
             
     | 
| 
       438 
     | 
    
         
            -
             
     | 
| 
       439 
     | 
    
         
            -
             
     | 
| 
       440 
     | 
    
         
            -
             
     | 
| 
       441 
     | 
    
         
            -
             
     | 
| 
       442 
     | 
    
         
            -
             
     | 
| 
       443 
     | 
    
         
            -
             
     | 
| 
       444 
     | 
    
         
            -
             
     | 
| 
       445 
     | 
    
         
            -
             
     | 
| 
       446 
     | 
    
         
            -
             
     | 
| 
       447 
     | 
    
         
            -
             
     | 
| 
       448 
     | 
    
         
            -
             
     | 
| 
       449 
     | 
    
         
            -
             
     | 
| 
       450 
     | 
    
         
            -
             
     | 
| 
       451 
     | 
    
         
            -
             
     | 
| 
       452 
     | 
    
         
            -
             
     | 
| 
       453 
     | 
    
         
            -
                      discovery_config: @discovery_config.to_h,
         
     | 
| 
       454 
     | 
    
         
            -
                      search_criteria: @search_criteria.to_h,
         
     | 
| 
       455 
     | 
    
         
            -
                      tags: (@tags || []).map{|tag| tag.to_h},
         
     | 
| 
       456 
     | 
    
         
            -
                      alerts: (@alerts || []).map {|alert| alert.to_h },
         
     | 
| 
       457 
     | 
    
         
            -
                      organization: @organization.to_h,
         
     | 
| 
       458 
     | 
    
         
            -
                      users: users
         
     | 
| 
       459 
     | 
    
         
            -
                  }
         
     | 
| 
      
 415 
     | 
    
         
            +
                  included_scan_targets = { addresses: @included_scan_targets[:addresses].compact,
         
     | 
| 
      
 416 
     | 
    
         
            +
                                            asset_groups: @included_scan_targets[:asset_groups].compact }
         
     | 
| 
      
 417 
     | 
    
         
            +
                  excluded_scan_targets = { addresses: @excluded_scan_targets[:addresses].compact,
         
     | 
| 
      
 418 
     | 
    
         
            +
                                            asset_groups: @excluded_scan_targets[:asset_groups].compact }
         
     | 
| 
      
 419 
     | 
    
         
            +
                  hash = { id: @id,
         
     | 
| 
      
 420 
     | 
    
         
            +
                           name: @name,
         
     | 
| 
      
 421 
     | 
    
         
            +
                           description: @description,
         
     | 
| 
      
 422 
     | 
    
         
            +
                           auto_engine_selection_enabled: @auto_engine_selection_enabled,
         
     | 
| 
      
 423 
     | 
    
         
            +
                           included_scan_targets: included_scan_targets,
         
     | 
| 
      
 424 
     | 
    
         
            +
                           excluded_scan_targets: excluded_scan_targets,
         
     | 
| 
      
 425 
     | 
    
         
            +
                           engine_id: @engine_id,
         
     | 
| 
      
 426 
     | 
    
         
            +
                           scan_template_id: @scan_template_id,
         
     | 
| 
      
 427 
     | 
    
         
            +
                           risk_factor: @risk_factor,
         
     | 
| 
      
 428 
     | 
    
         
            +
                           schedules: (@schedules || []).map(&:to_h),
         
     | 
| 
      
 429 
     | 
    
         
            +
                           shared_credentials: (@shared_credentials || []).map(&:to_h),
         
     | 
| 
      
 430 
     | 
    
         
            +
                           site_credentials: (@site_credentials || []).map(&:to_h),
         
     | 
| 
      
 431 
     | 
    
         
            +
                           web_credentials: (@web_credentials || []).map(&:to_h),
         
     | 
| 
      
 432 
     | 
    
         
            +
                           discovery_config: @discovery_config.to_h,
         
     | 
| 
      
 433 
     | 
    
         
            +
                           search_criteria: @search_criteria.to_h,
         
     | 
| 
      
 434 
     | 
    
         
            +
                           tags: (@tags || []).map(&:to_h),
         
     | 
| 
      
 435 
     | 
    
         
            +
                           alerts: (@alerts || []).map(&:to_h),
         
     | 
| 
      
 436 
     | 
    
         
            +
                           organization: @organization.to_h,
         
     | 
| 
      
 437 
     | 
    
         
            +
                           users: users }
         
     | 
| 
       460 
438 
     | 
    
         
             
                  # @TODO: Revisit this for 2.0.0 update
         
     | 
| 
       461 
439 
     | 
    
         
             
                  # Only pass in blackouts if they were actually specified (for backwards compatibility)
         
     | 
| 
       462 
440 
     | 
    
         
             
                  hash[:blackouts] = @blackouts.map(&:to_h) if @blackouts && @blackouts.any?
         
     | 
| 
         @@ -472,7 +450,7 @@ module Nexpose 
     | 
|
| 
       472 
450 
     | 
    
         
             
                # @return [Site] The requested site, if found.
         
     | 
| 
       473 
451 
     | 
    
         
             
                #
         
     | 
| 
       474 
452 
     | 
    
         
             
                def self.load(nsc, id)
         
     | 
| 
       475 
     | 
    
         
            -
                  uri 
     | 
| 
      
 453 
     | 
    
         
            +
                  uri  = "/api/2.1/site_configurations/#{id}"
         
     | 
| 
       476 
454 
     | 
    
         
             
                  resp = AJAX.get(nsc, uri, AJAX::CONTENT_TYPE::JSON)
         
     | 
| 
       477 
455 
     | 
    
         
             
                  hash = JSON.parse(resp, symbolize_names: true)
         
     | 
| 
       478 
456 
     | 
    
         
             
                  site = self.json_initializer(hash).deserialize(hash)
         
     | 
| 
         @@ -486,19 +464,19 @@ module Nexpose 
     | 
|
| 
       486 
464 
     | 
    
         
             
                  site.excluded_scan_targets[:addresses] = []
         
     | 
| 
       487 
465 
     | 
    
         
             
                  excluded_addresses.each { |asset| site.exclude_asset(asset) }
         
     | 
| 
       488 
466 
     | 
    
         | 
| 
       489 
     | 
    
         
            -
                  site.organization 
     | 
| 
       490 
     | 
    
         
            -
                  site.schedules 
     | 
| 
       491 
     | 
    
         
            -
                  site.blackouts 
     | 
| 
       492 
     | 
    
         
            -
                  site.site_credentials 
     | 
| 
       493 
     | 
    
         
            -
                  site.shared_credentials = hash[:shared_credentials].map {|cred| Nexpose::SiteCredentials.new.object_from_hash(nsc,cred)}
         
     | 
| 
       494 
     | 
    
         
            -
                  site.discovery_config 
     | 
| 
       495 
     | 
    
         
            -
                  site.search_criteria 
     | 
| 
       496 
     | 
    
         
            -
                  site.alerts 
     | 
| 
       497 
     | 
    
         
            -
                  site.tags 
     | 
| 
       498 
     | 
    
         
            -
                  site.web_credentials = hash[:web_credentials].map {| 
     | 
| 
       499 
     | 
    
         
            -
                   
     | 
| 
       500 
     | 
    
         
            -
                      Nexpose::WebCredentials::Headers.new( 
     | 
| 
       501 
     | 
    
         
            -
                      Nexpose::WebCredentials::HTMLForms.new( 
     | 
| 
      
 467 
     | 
    
         
            +
                  site.organization       = Organization.create(site.organization)
         
     | 
| 
      
 468 
     | 
    
         
            +
                  site.schedules          = (hash[:schedules] || []).map { |schedule| Nexpose::Schedule.from_hash(schedule) }
         
     | 
| 
      
 469 
     | 
    
         
            +
                  site.blackouts          = (hash[:blackouts] || []).map { |blackout| Nexpose::Blackout.from_hash(blackout) }
         
     | 
| 
      
 470 
     | 
    
         
            +
                  site.site_credentials   = hash[:site_credentials].map { |cred| Nexpose::SiteCredentials.new.object_from_hash(nsc, cred) }
         
     | 
| 
      
 471 
     | 
    
         
            +
                  site.shared_credentials = hash[:shared_credentials].map { |cred| Nexpose::SiteCredentials.new.object_from_hash(nsc, cred) }
         
     | 
| 
      
 472 
     | 
    
         
            +
                  site.discovery_config   = Nexpose::DiscoveryConnection.new.object_from_hash(nsc, hash[:discovery_config]) unless hash[:discovery_config].nil?
         
     | 
| 
      
 473 
     | 
    
         
            +
                  site.search_criteria    = Nexpose::DiscoveryConnection::Criteria.parseHash(hash[:search_criteria]) unless hash[:search_criteria].nil?
         
     | 
| 
      
 474 
     | 
    
         
            +
                  site.alerts             = Alert.load_alerts(hash[:alerts])
         
     | 
| 
      
 475 
     | 
    
         
            +
                  site.tags               = Tag.load_tags(hash[:tags])
         
     | 
| 
      
 476 
     | 
    
         
            +
                  site.web_credentials = hash[:web_credentials].map { |web_cred| (
         
     | 
| 
      
 477 
     | 
    
         
            +
                  web_cred[:service] == Nexpose::WebCredentials::WebAppAuthType::HTTP_HEADER ?
         
     | 
| 
      
 478 
     | 
    
         
            +
                      Nexpose::WebCredentials::Headers.new(web_cred[:name], web_cred[:baseURL], web_cred[:soft403Pattern], web_cred[:id]).object_from_hash(nsc, web_cred) :
         
     | 
| 
      
 479 
     | 
    
         
            +
                      Nexpose::WebCredentials::HTMLForms.new(web_cred[:name], web_cred[:baseURL], web_cred[:loginURL], web_cred[:soft403Pattern], web_cred[:id]).object_from_hash(nsc, web_cred)) }
         
     | 
| 
       502 
480 
     | 
    
         | 
| 
       503 
481 
     | 
    
         
             
                  site
         
     | 
| 
       504 
482 
     | 
    
         
             
                end
         
     | 
| 
         @@ -516,8 +494,8 @@ module Nexpose 
     | 
|
| 
       516 
494 
     | 
    
         
             
                # @return [Site] Site configuration loaded from a Nexpose console.
         
     | 
| 
       517 
495 
     | 
    
         
             
                #
         
     | 
| 
       518 
496 
     | 
    
         
             
                def self.copy(connection, id)
         
     | 
| 
       519 
     | 
    
         
            -
                  site 
     | 
| 
       520 
     | 
    
         
            -
                  site.id 
     | 
| 
      
 497 
     | 
    
         
            +
                  site      = self.load(connection, id)
         
     | 
| 
      
 498 
     | 
    
         
            +
                  site.id   = -1
         
     | 
| 
       521 
499 
     | 
    
         
             
                  site.name = "#{site.name} Copy"
         
     | 
| 
       522 
500 
     | 
    
         
             
                  site
         
     | 
| 
       523 
501 
     | 
    
         
             
                end
         
     | 
| 
         @@ -536,14 +514,14 @@ module Nexpose 
     | 
|
| 
       536 
514 
     | 
    
         
             
                    resp = AJAX.post(connection, '/api/2.1/site_configurations/', to_json, AJAX::CONTENT_TYPE::JSON)
         
     | 
| 
       537 
515 
     | 
    
         
             
                    @id = resp.to_i
         
     | 
| 
       538 
516 
     | 
    
         
             
                  else
         
     | 
| 
       539 
     | 
    
         
            -
                     
     | 
| 
      
 517 
     | 
    
         
            +
                    AJAX.put(connection, "/api/2.1/site_configurations/#{@id}", to_json, AJAX::CONTENT_TYPE::JSON)
         
     | 
| 
       540 
518 
     | 
    
         
             
                  end
         
     | 
| 
       541 
519 
     | 
    
         | 
| 
       542 
520 
     | 
    
         
             
                  # Retrieve the scan engine and shared credentials and add them to the site configuration
         
     | 
| 
       543 
     | 
    
         
            -
                  site_config 
     | 
| 
       544 
     | 
    
         
            -
                  @engine_id 
     | 
| 
      
 521 
     | 
    
         
            +
                  site_config         = Site.load(connection, @id)
         
     | 
| 
      
 522 
     | 
    
         
            +
                  @engine_id          = site_config.engine_id
         
     | 
| 
       545 
523 
     | 
    
         
             
                  @shared_credentials = site_config.shared_credentials
         
     | 
| 
       546 
     | 
    
         
            -
                  @alerts 
     | 
| 
      
 524 
     | 
    
         
            +
                  @alerts             = site_config.alerts
         
     | 
| 
       547 
525 
     | 
    
         | 
| 
       548 
526 
     | 
    
         
             
                  @id
         
     | 
| 
       549 
527 
     | 
    
         
             
                end
         
     | 
| 
         @@ -592,11 +570,11 @@ module Nexpose 
     | 
|
| 
       592 
570 
     | 
    
         
             
                # Constructor
         
     | 
| 
       593 
571 
     | 
    
         
             
                # SiteSummary(id, name, description, riskfactor = 1)
         
     | 
| 
       594 
572 
     | 
    
         
             
                def initialize(id, name, description = nil, risk_factor = 1.0, risk_score = 0.0)
         
     | 
| 
       595 
     | 
    
         
            -
                  @id 
     | 
| 
       596 
     | 
    
         
            -
                  @name 
     | 
| 
      
 573 
     | 
    
         
            +
                  @id          = id
         
     | 
| 
      
 574 
     | 
    
         
            +
                  @name        = name
         
     | 
| 
       597 
575 
     | 
    
         
             
                  @description = description
         
     | 
| 
       598 
576 
     | 
    
         
             
                  @risk_factor = risk_factor
         
     | 
| 
       599 
     | 
    
         
            -
                  @risk_score 
     | 
| 
      
 577 
     | 
    
         
            +
                  @risk_score  = risk_score
         
     | 
| 
       600 
578 
     | 
    
         
             
                end
         
     | 
| 
       601 
579 
     | 
    
         
             
              end
         
     | 
| 
       602 
580 
     | 
    
         | 
| 
         @@ -629,7 +607,7 @@ module Nexpose 
     | 
|
| 
       629 
607 
     | 
    
         
             
                  xml.text = @host
         
     | 
| 
       630 
608 
     | 
    
         
             
                  xml
         
     | 
| 
       631 
609 
     | 
    
         
             
                end
         
     | 
| 
       632 
     | 
    
         
            -
                 
     | 
| 
      
 610 
     | 
    
         
            +
                alias to_xml_elem as_xml
         
     | 
| 
       633 
611 
     | 
    
         | 
| 
       634 
612 
     | 
    
         
             
                def to_xml
         
     | 
| 
       635 
613 
     | 
    
         
             
                  to_xml_elem.to_s
         
     | 
| 
         @@ -670,14 +648,14 @@ module Nexpose 
     | 
|
| 
       670 
648 
     | 
    
         
             
                # @return [IPRange] an IP address range of one or more addresses.
         
     | 
| 
       671 
649 
     | 
    
         
             
                def initialize(from, to = nil)
         
     | 
| 
       672 
650 
     | 
    
         
             
                  @from = from
         
     | 
| 
       673 
     | 
    
         
            -
                  @to 
     | 
| 
      
 651 
     | 
    
         
            +
                  @to   = to unless from == to
         
     | 
| 
       674 
652 
     | 
    
         | 
| 
       675 
653 
     | 
    
         
             
                  return unless @to.nil?
         
     | 
| 
       676 
654 
     | 
    
         | 
| 
       677 
655 
     | 
    
         
             
                  range = IPAddr.new(@from.to_s).to_range
         
     | 
| 
       678 
656 
     | 
    
         
             
                  unless range.one?
         
     | 
| 
       679 
657 
     | 
    
         
             
                    @from = range.first.to_s
         
     | 
| 
       680 
     | 
    
         
            -
                    @to 
     | 
| 
      
 658 
     | 
    
         
            +
                    @to   = range.last.to_s
         
     | 
| 
       681 
659 
     | 
    
         
             
                  end
         
     | 
| 
       682 
660 
     | 
    
         
             
                end
         
     | 
| 
       683 
661 
     | 
    
         | 
| 
         @@ -689,7 +667,7 @@ module Nexpose 
     | 
|
| 
       689 
667 
     | 
    
         
             
                def size
         
     | 
| 
       690 
668 
     | 
    
         
             
                  return 1 if @to.nil?
         
     | 
| 
       691 
669 
     | 
    
         
             
                  from = IPAddr.new(@from)
         
     | 
| 
       692 
     | 
    
         
            -
                  to 
     | 
| 
      
 670 
     | 
    
         
            +
                  to   = IPAddr.new(@to)
         
     | 
| 
       693 
671 
     | 
    
         
             
                  (from..to).to_a.size
         
     | 
| 
       694 
672 
     | 
    
         
             
                end
         
     | 
| 
       695 
673 
     | 
    
         | 
| 
         @@ -697,10 +675,10 @@ module Nexpose 
     | 
|
| 
       697 
675 
     | 
    
         | 
| 
       698 
676 
     | 
    
         
             
                def <=>(other)
         
     | 
| 
       699 
677 
     | 
    
         
             
                  return 1 unless other.respond_to? :from
         
     | 
| 
       700 
     | 
    
         
            -
                  from 
     | 
| 
       701 
     | 
    
         
            -
                  to 
     | 
| 
      
 678 
     | 
    
         
            +
                  from    = IPAddr.new(@from)
         
     | 
| 
      
 679 
     | 
    
         
            +
                  to      = @to.nil? ? from : IPAddr.new(@to)
         
     | 
| 
       702 
680 
     | 
    
         
             
                  cf_from = IPAddr.new(other.from)
         
     | 
| 
       703 
     | 
    
         
            -
                  cf_to 
     | 
| 
      
 681 
     | 
    
         
            +
                  cf_to   = IPAddr.new(other.to.nil? ? other.from : other.to)
         
     | 
| 
       704 
682 
     | 
    
         
             
                  if cf_to < from
         
     | 
| 
       705 
683 
     | 
    
         
             
                    1
         
     | 
| 
       706 
684 
     | 
    
         
             
                  elsif to < cf_from
         
     | 
| 
         @@ -721,8 +699,8 @@ module Nexpose 
     | 
|
| 
       721 
699 
     | 
    
         | 
| 
       722 
700 
     | 
    
         
             
                def include?(single_ip)
         
     | 
| 
       723 
701 
     | 
    
         
             
                  return false unless single_ip.respond_to? :from
         
     | 
| 
       724 
     | 
    
         
            -
                  from 
     | 
| 
       725 
     | 
    
         
            -
                  to 
     | 
| 
      
 702 
     | 
    
         
            +
                  from  = IPAddr.new(@from)
         
     | 
| 
      
 703 
     | 
    
         
            +
                  to    = @to.nil? ? from : IPAddr.new(@to)
         
     | 
| 
       726 
704 
     | 
    
         
             
                  other = IPAddr.new(single_ip)
         
     | 
| 
       727 
705 
     | 
    
         | 
| 
       728 
706 
     | 
    
         
             
                  if other < from
         
     | 
| 
         @@ -743,7 +721,7 @@ module Nexpose 
     | 
|
| 
       743 
721 
     | 
    
         
             
                  xml.add_attributes({ 'from' => @from, 'to' => @to })
         
     | 
| 
       744 
722 
     | 
    
         
             
                  xml
         
     | 
| 
       745 
723 
     | 
    
         
             
                end
         
     | 
| 
       746 
     | 
    
         
            -
                 
     | 
| 
      
 724 
     | 
    
         
            +
                alias to_xml_elem as_xml
         
     | 
| 
       747 
725 
     | 
    
         | 
| 
       748 
726 
     | 
    
         
             
                def to_xml
         
     | 
| 
       749 
727 
     | 
    
         
             
                  as_xml.to_s
         
     | 
| 
         @@ -49,7 +49,7 @@ module Nexpose 
     | 
|
| 
       49 
49 
     | 
    
         
             
                attr_accessor :use_windows_auth
         
     | 
| 
       50 
50 
     | 
    
         
             
                # sid for oracle
         
     | 
| 
       51 
51 
     | 
    
         
             
                attr_accessor :sid
         
     | 
| 
       52 
     | 
    
         
            -
                #for ssh public key require pem format private key
         
     | 
| 
      
 52 
     | 
    
         
            +
                # for ssh public key require pem format private key
         
     | 
| 
       53 
53 
     | 
    
         
             
                attr_accessor :pem_format_private_key
         
     | 
| 
       54 
54 
     | 
    
         
             
                # for snmp v1/v2
         
     | 
| 
       55 
55 
     | 
    
         
             
                attr_accessor :community_name
         
     | 
| 
         @@ -71,14 +71,13 @@ module Nexpose 
     | 
|
| 
       71 
71 
     | 
    
         
             
                  unless engine_id
         
     | 
| 
       72 
72 
     | 
    
         
             
                    engine_id = nsc.engines.detect { |e| e.name == 'Local scan engine' }.id
         
     | 
| 
       73 
73 
     | 
    
         
             
                  end
         
     | 
| 
       74 
     | 
    
         
            -
                  @port 
     | 
| 
      
 74 
     | 
    
         
            +
                  @port      = Credential::DEFAULT_PORTS[@service] if @port.nil?
         
     | 
| 
       75 
75 
     | 
    
         
             
                  parameters = _to_param(target, engine_id, @port, siteid)
         
     | 
| 
       76 
76 
     | 
    
         
             
                  parameters = JSON.generate(parameters)
         
     | 
| 
       77 
     | 
    
         
            -
                  resp 
     | 
| 
      
 77 
     | 
    
         
            +
                  resp       = JSON.parse(Nexpose::AJAX.post(nsc, '/data/credential/test', parameters, Nexpose::AJAX::CONTENT_TYPE::JSON))
         
     | 
| 
       78 
78 
     | 
    
         
             
                  resp['success'] == 'true'
         
     | 
| 
       79 
79 
     | 
    
         
             
                end
         
     | 
| 
       80 
80 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
81 
     | 
    
         
             
                def _to_param(target, engine_id, port, siteid)
         
     | 
| 
       83 
82 
     | 
    
         
             
                  {
         
     | 
| 
       84 
83 
     | 
    
         
             
                    dev: target,
         
     | 
| 
         @@ -100,17 +99,17 @@ module Nexpose 
     | 
|
| 
       100 
99 
     | 
    
         
             
                  }
         
     | 
| 
       101 
100 
     | 
    
         
             
                end
         
     | 
| 
       102 
101 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
                #Create a credential object using name, id, description, host and port
         
     | 
| 
      
 102 
     | 
    
         
            +
                # Create a credential object using name, id, description, host and port
         
     | 
| 
       104 
103 
     | 
    
         
             
                def self.for_service(name, id = -1, desc = nil, host = nil, port = nil, service = Credential::Service::CIFS)
         
     | 
| 
       105 
     | 
    
         
            -
                  cred 
     | 
| 
       106 
     | 
    
         
            -
                  cred.name 
     | 
| 
       107 
     | 
    
         
            -
                  cred.id 
     | 
| 
       108 
     | 
    
         
            -
                  cred.enabled 
     | 
| 
       109 
     | 
    
         
            -
                  cred.description 
     | 
| 
       110 
     | 
    
         
            -
                  cred.host_restriction 
     | 
| 
       111 
     | 
    
         
            -
                  cred.port_restriction 
     | 
| 
       112 
     | 
    
         
            -
                  cred.service 
     | 
| 
       113 
     | 
    
         
            -
                  cred.scope 
     | 
| 
      
 104 
     | 
    
         
            +
                  cred                           = new
         
     | 
| 
      
 105 
     | 
    
         
            +
                  cred.name                      = name
         
     | 
| 
      
 106 
     | 
    
         
            +
                  cred.id                        = id.to_i
         
     | 
| 
      
 107 
     | 
    
         
            +
                  cred.enabled                   = true
         
     | 
| 
      
 108 
     | 
    
         
            +
                  cred.description               = desc
         
     | 
| 
      
 109 
     | 
    
         
            +
                  cred.host_restriction          = host
         
     | 
| 
      
 110 
     | 
    
         
            +
                  cred.port_restriction          = port
         
     | 
| 
      
 111 
     | 
    
         
            +
                  cred.service                   = service
         
     | 
| 
      
 112 
     | 
    
         
            +
                  cred.scope                     = Credential::Scope::SITE_SPECIFIC
         
     | 
| 
       114 
113 
     | 
    
         
             
                  cred.permission_elevation_type = Credential::ElevationType::NONE
         
     | 
| 
       115 
114 
     | 
    
         
             
                  cred
         
     | 
| 
       116 
115 
     | 
    
         
             
                end
         
     | 
| 
         @@ -123,7 +122,7 @@ module Nexpose 
     | 
|
| 
       123 
122 
     | 
    
         
             
                # @return [SiteCredential] The requested credential of site, if found.
         
     | 
| 
       124 
123 
     | 
    
         
             
                #
         
     | 
| 
       125 
124 
     | 
    
         
             
                def self.load(nsc, site_id, credential_id)
         
     | 
| 
       126 
     | 
    
         
            -
                  uri 
     | 
| 
      
 125 
     | 
    
         
            +
                  uri  = "/api/2.1/sites/#{site_id}/credentials/#{credential_id}"
         
     | 
| 
       127 
126 
     | 
    
         
             
                  resp = AJAX.get(nsc, uri, AJAX::CONTENT_TYPE::JSON)
         
     | 
| 
       128 
127 
     | 
    
         
             
                  hash = JSON.parse(resp, symbolize_names: true)
         
     | 
| 
       129 
128 
     | 
    
         
             
                  new.object_from_hash(nsc, hash)
         
     | 
| 
         @@ -187,8 +186,7 @@ module Nexpose 
     | 
|
| 
       187 
186 
     | 
    
         
             
                    sid: sid,
         
     | 
| 
       188 
187 
     | 
    
         
             
                    pem_format_private_key: pem_format_private_key,
         
     | 
| 
       189 
188 
     | 
    
         
             
                    community_name: community_name,
         
     | 
| 
       190 
     | 
    
         
            -
                    scope: scope
         
     | 
| 
       191 
     | 
    
         
            -
                  }
         
     | 
| 
      
 189 
     | 
    
         
            +
                    scope: scope }
         
     | 
| 
       192 
190 
     | 
    
         
             
                end
         
     | 
| 
       193 
191 
     | 
    
         | 
| 
       194 
192 
     | 
    
         
             
                def ==(other)
         
     | 
    
        data/lib/nexpose/tag.rb
    CHANGED
    
    | 
         @@ -8,13 +8,13 @@ module Nexpose 
     | 
|
| 
       8 
8 
     | 
    
         
             
                #
         
     | 
| 
       9 
9 
     | 
    
         
             
                def tags
         
     | 
| 
       10 
10 
     | 
    
         
             
                  tag_summary = []
         
     | 
| 
       11 
     | 
    
         
            -
                  tags 
     | 
| 
      
 11 
     | 
    
         
            +
                  tags        = JSON.parse(AJAX.get(self, '/api/2.0/tags', AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 }))
         
     | 
| 
       12 
12 
     | 
    
         
             
                  tags['resources'].each do |json|
         
     | 
| 
       13 
13 
     | 
    
         
             
                    tag_summary << TagSummary.parse(json)
         
     | 
| 
       14 
14 
     | 
    
         
             
                  end
         
     | 
| 
       15 
15 
     | 
    
         
             
                  tag_summary
         
     | 
| 
       16 
16 
     | 
    
         
             
                end
         
     | 
| 
       17 
     | 
    
         
            -
                 
     | 
| 
      
 17 
     | 
    
         
            +
                alias list_tags tags
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
19 
     | 
    
         
             
                # Deletes a tag by ID
         
     | 
| 
       20 
20 
     | 
    
         
             
                #
         
     | 
| 
         @@ -31,13 +31,13 @@ module Nexpose 
     | 
|
| 
       31 
31 
     | 
    
         
             
                #
         
     | 
| 
       32 
32 
     | 
    
         
             
                def asset_tags(asset_id)
         
     | 
| 
       33 
33 
     | 
    
         
             
                  tag_summary = []
         
     | 
| 
       34 
     | 
    
         
            -
                  asset_tag 
     | 
| 
      
 34 
     | 
    
         
            +
                  asset_tag   = JSON.parse(AJAX.get(self, "/api/2.0/assets/#{asset_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 }))
         
     | 
| 
       35 
35 
     | 
    
         
             
                  asset_tag['resources'].select { |r| r['asset_ids'].find { |i| i == asset_id } }.each do |json|
         
     | 
| 
       36 
36 
     | 
    
         
             
                    tag_summary << TagSummary.parse(json)
         
     | 
| 
       37 
37 
     | 
    
         
             
                  end
         
     | 
| 
       38 
38 
     | 
    
         
             
                  tag_summary
         
     | 
| 
       39 
39 
     | 
    
         
             
                end
         
     | 
| 
       40 
     | 
    
         
            -
                 
     | 
| 
      
 40 
     | 
    
         
            +
                alias list_asset_tags asset_tags
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                # Removes a tag from an asset
         
     | 
| 
       43 
43 
     | 
    
         
             
                #
         
     | 
| 
         @@ -61,7 +61,7 @@ module Nexpose 
     | 
|
| 
       61 
61 
     | 
    
         
             
                  end
         
     | 
| 
       62 
62 
     | 
    
         
             
                  tag_summary
         
     | 
| 
       63 
63 
     | 
    
         
             
                end
         
     | 
| 
       64 
     | 
    
         
            -
                 
     | 
| 
      
 64 
     | 
    
         
            +
                alias list_site_tags site_tags
         
     | 
| 
       65 
65 
     | 
    
         | 
| 
       66 
66 
     | 
    
         
             
                # Removes a tag from a site
         
     | 
| 
       67 
67 
     | 
    
         
             
                #
         
     | 
| 
         @@ -85,8 +85,8 @@ module Nexpose 
     | 
|
| 
       85 
85 
     | 
    
         
             
                  end
         
     | 
| 
       86 
86 
     | 
    
         
             
                  tag_summary
         
     | 
| 
       87 
87 
     | 
    
         
             
                end
         
     | 
| 
       88 
     | 
    
         
            -
                 
     | 
| 
       89 
     | 
    
         
            -
                 
     | 
| 
      
 88 
     | 
    
         
            +
                alias group_tags asset_group_tags
         
     | 
| 
      
 89 
     | 
    
         
            +
                alias list_asset_group_tags asset_group_tags
         
     | 
| 
       90 
90 
     | 
    
         | 
| 
       91 
91 
     | 
    
         
             
                # Removes a tag from an asset_group
         
     | 
| 
       92 
92 
     | 
    
         
             
                #
         
     | 
| 
         @@ -96,7 +96,7 @@ module Nexpose 
     | 
|
| 
       96 
96 
     | 
    
         
             
                def remove_tag_from_asset_group(asset_group_id, tag_id)
         
     | 
| 
       97 
97 
     | 
    
         
             
                  AJAX.delete(self, "/api/2.0/asset_groups/#{asset_group_id}/tags/#{tag_id}")
         
     | 
| 
       98 
98 
     | 
    
         
             
                end
         
     | 
| 
       99 
     | 
    
         
            -
                 
     | 
| 
      
 99 
     | 
    
         
            +
                alias remove_tag_from_group remove_tag_from_asset_group
         
     | 
| 
       100 
100 
     | 
    
         | 
| 
       101 
101 
     | 
    
         
             
                # Returns the criticality value which takes precedent for an asset
         
     | 
| 
       102 
102 
     | 
    
         
             
                #
         
     | 
| 
         @@ -123,7 +123,9 @@ module Nexpose 
     | 
|
| 
       123 
123 
     | 
    
         
             
                attr_accessor :type
         
     | 
| 
       124 
124 
     | 
    
         | 
| 
       125 
125 
     | 
    
         
             
                def initialize(name, type, id)
         
     | 
| 
       126 
     | 
    
         
            -
                  @name 
     | 
| 
      
 126 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 127 
     | 
    
         
            +
                  @type = type
         
     | 
| 
      
 128 
     | 
    
         
            +
                  @id   = id
         
     | 
| 
       127 
129 
     | 
    
         
             
                end
         
     | 
| 
       128 
130 
     | 
    
         | 
| 
       129 
131 
     | 
    
         
             
                def self.parse(json)
         
     | 
| 
         @@ -154,27 +156,27 @@ module Nexpose 
     | 
|
| 
       154 
156 
     | 
    
         
             
                  # Criticality tag types
         
     | 
| 
       155 
157 
     | 
    
         
             
                  module Level
         
     | 
| 
       156 
158 
     | 
    
         
             
                    VERY_HIGH = 'Very High'
         
     | 
| 
       157 
     | 
    
         
            -
                    HIGH 
     | 
| 
       158 
     | 
    
         
            -
                    MEDIUM 
     | 
| 
       159 
     | 
    
         
            -
                    LOW 
     | 
| 
       160 
     | 
    
         
            -
                    VERY_LOW 
     | 
| 
      
 159 
     | 
    
         
            +
                    HIGH      = 'High'
         
     | 
| 
      
 160 
     | 
    
         
            +
                    MEDIUM    = 'Medium'
         
     | 
| 
      
 161 
     | 
    
         
            +
                    LOW       = 'Low'
         
     | 
| 
      
 162 
     | 
    
         
            +
                    VERY_LOW  = 'Very Low'
         
     | 
| 
       161 
163 
     | 
    
         
             
                  end
         
     | 
| 
       162 
164 
     | 
    
         | 
| 
       163 
165 
     | 
    
         
             
                  # Tag types
         
     | 
| 
       164 
166 
     | 
    
         
             
                  module Generic
         
     | 
| 
       165 
     | 
    
         
            -
                    CUSTOM 
     | 
| 
       166 
     | 
    
         
            -
                    OWNER 
     | 
| 
       167 
     | 
    
         
            -
                    LOCATION 
     | 
| 
      
 167 
     | 
    
         
            +
                    CUSTOM      = 'CUSTOM'
         
     | 
| 
      
 168 
     | 
    
         
            +
                    OWNER       = 'OWNER'
         
     | 
| 
      
 169 
     | 
    
         
            +
                    LOCATION    = 'LOCATION'
         
     | 
| 
       168 
170 
     | 
    
         
             
                    CRITICALITY = 'CRITICALITY'
         
     | 
| 
       169 
171 
     | 
    
         
             
                  end
         
     | 
| 
       170 
172 
     | 
    
         | 
| 
       171 
173 
     | 
    
         
             
                  module Color
         
     | 
| 
       172 
     | 
    
         
            -
                    BLUE 
     | 
| 
       173 
     | 
    
         
            -
                    DEFAULT =  
     | 
| 
       174 
     | 
    
         
            -
                    GREEN 
     | 
| 
       175 
     | 
    
         
            -
                    ORANGE 
     | 
| 
       176 
     | 
    
         
            -
                    PURPLE 
     | 
| 
       177 
     | 
    
         
            -
                    RED 
     | 
| 
      
 174 
     | 
    
         
            +
                    BLUE    = '#496a77'
         
     | 
| 
      
 175 
     | 
    
         
            +
                    DEFAULT = '#f6f6f6'
         
     | 
| 
      
 176 
     | 
    
         
            +
                    GREEN   = '#7d8a58'
         
     | 
| 
      
 177 
     | 
    
         
            +
                    ORANGE  = '#de7200'
         
     | 
| 
      
 178 
     | 
    
         
            +
                    PURPLE  = '#844f7d'
         
     | 
| 
      
 179 
     | 
    
         
            +
                    RED     = '#a0392e'
         
     | 
| 
       178 
180 
     | 
    
         
             
                  end
         
     | 
| 
       179 
181 
     | 
    
         
             
                end
         
     | 
| 
       180 
182 
     | 
    
         | 
| 
         @@ -198,26 +200,28 @@ module Nexpose 
     | 
|
| 
       198 
200 
     | 
    
         | 
| 
       199 
201 
     | 
    
         
             
                # Array containing Asset Group IDs to be associated with tag
         
     | 
| 
       200 
202 
     | 
    
         
             
                attr_accessor :asset_group_ids
         
     | 
| 
       201 
     | 
    
         
            -
                 
     | 
| 
       202 
     | 
    
         
            -
                 
     | 
| 
      
 203 
     | 
    
         
            +
                alias group_ids asset_group_ids
         
     | 
| 
      
 204 
     | 
    
         
            +
                alias group_ids= asset_group_ids=
         
     | 
| 
       203 
205 
     | 
    
         | 
| 
       204 
206 
     | 
    
         
             
                # A TagCriteria
         
     | 
| 
       205 
207 
     | 
    
         
             
                attr_accessor :search_criteria
         
     | 
| 
       206 
208 
     | 
    
         | 
| 
       207 
209 
     | 
    
         
             
                def initialize(name, type, id = -1)
         
     | 
| 
       208 
     | 
    
         
            -
                  @name 
     | 
| 
      
 210 
     | 
    
         
            +
                  @name   = name
         
     | 
| 
      
 211 
     | 
    
         
            +
                  @type   = type
         
     | 
| 
      
 212 
     | 
    
         
            +
                  @id     = id
         
     | 
| 
       209 
213 
     | 
    
         
             
                  @source = 'nexpose-client'
         
     | 
| 
       210 
     | 
    
         
            -
                  @color 
     | 
| 
      
 214 
     | 
    
         
            +
                  @color  = @type == Type::Generic::CUSTOM ? Type::Color::DEFAULT : nil
         
     | 
| 
       211 
215 
     | 
    
         
             
                end
         
     | 
| 
       212 
216 
     | 
    
         | 
| 
       213 
217 
     | 
    
         
             
                # Set the color but validate it
         
     | 
| 
       214 
218 
     | 
    
         
             
                def color=(hex)
         
     | 
| 
       215 
     | 
    
         
            -
                  valid_colors = Type::Color 
     | 
| 
      
 219 
     | 
    
         
            +
                  valid_colors = Type::Color.constants.map { |c| Type::Color.const_get(c) }
         
     | 
| 
       216 
220 
     | 
    
         
             
                  unless hex.nil? || valid_colors.include?(hex.to_s.downcase)
         
     | 
| 
       217 
221 
     | 
    
         
             
                    raise ArgumentError, "Unable to set color to an invalid color.\nUse one of #{valid_colors}"
         
     | 
| 
       218 
     | 
    
         
            -
                  end 
     | 
| 
      
 222 
     | 
    
         
            +
                  end
         
     | 
| 
       219 
223 
     | 
    
         | 
| 
       220 
     | 
    
         
            -
                  @color = hex 
     | 
| 
      
 224 
     | 
    
         
            +
                  @color = hex
         
     | 
| 
       221 
225 
     | 
    
         
             
                end
         
     | 
| 
       222 
226 
     | 
    
         | 
| 
       223 
227 
     | 
    
         
             
                # Create list of tag objects from hash
         
     | 
| 
         @@ -233,12 +237,12 @@ module Nexpose 
     | 
|
| 
       233 
237 
     | 
    
         
             
                # Create tag object from hash
         
     | 
| 
       234 
238 
     | 
    
         
             
                def self.create(hash)
         
     | 
| 
       235 
239 
     | 
    
         
             
                  attributes = hash[:attributes]
         
     | 
| 
       236 
     | 
    
         
            -
                  color 
     | 
| 
       237 
     | 
    
         
            -
                  color 
     | 
| 
       238 
     | 
    
         
            -
                  source 
     | 
| 
       239 
     | 
    
         
            -
                  source 
     | 
| 
       240 
     | 
    
         
            -
                  tag 
     | 
| 
       241 
     | 
    
         
            -
                  tag.color 
     | 
| 
      
 240 
     | 
    
         
            +
                  color      = attributes.find { |attr| attr[:tag_attribute_name] == 'COLOR' }
         
     | 
| 
      
 241 
     | 
    
         
            +
                  color      = color[:tag_attribute_value] if color
         
     | 
| 
      
 242 
     | 
    
         
            +
                  source     = attributes.find { |attr| attr[:tag_attribute_name] == 'SOURCE' }
         
     | 
| 
      
 243 
     | 
    
         
            +
                  source     = source[:tag_attribute_value] if source
         
     | 
| 
      
 244 
     | 
    
         
            +
                  tag        = Tag.new(hash[:tag_name], hash[:tag_type], hash[:tag_id])
         
     | 
| 
      
 245 
     | 
    
         
            +
                  tag.color  = color
         
     | 
| 
       242 
246 
     | 
    
         
             
                  tag.source = source
         
     | 
| 
       243 
247 
     | 
    
         
             
                  tag
         
     | 
| 
       244 
248 
     | 
    
         
             
                end
         
     | 
| 
         @@ -248,15 +252,9 @@ module Nexpose 
     | 
|
| 
       248 
252 
     | 
    
         
             
                    tag_id: id,
         
     | 
| 
       249 
253 
     | 
    
         
             
                    tag_name: name,
         
     | 
| 
       250 
254 
     | 
    
         
             
                    tag_type: type,
         
     | 
| 
       251 
     | 
    
         
            -
                    attributes:[
         
     | 
| 
       252 
     | 
    
         
            -
                      {
         
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
       254 
     | 
    
         
            -
                        tag_attribute_value: color
         
     | 
| 
       255 
     | 
    
         
            -
                      },
         
     | 
| 
       256 
     | 
    
         
            -
                      {
         
     | 
| 
       257 
     | 
    
         
            -
                        tag_attribute_name: "SOURCE",
         
     | 
| 
       258 
     | 
    
         
            -
                        tag_attribute_value: source
         
     | 
| 
       259 
     | 
    
         
            -
                      }
         
     | 
| 
      
 255 
     | 
    
         
            +
                    attributes: [
         
     | 
| 
      
 256 
     | 
    
         
            +
                      { tag_attribute_name: 'COLOR', tag_attribute_value: color },
         
     | 
| 
      
 257 
     | 
    
         
            +
                      { tag_attribute_name: 'SOURCE', tag_attribute_value: source }
         
     | 
| 
       260 
258 
     | 
    
         
             
                    ]
         
     | 
| 
       261 
259 
     | 
    
         
             
                  }
         
     | 
| 
       262 
260 
     | 
    
         
             
                end
         
     | 
| 
         @@ -289,18 +287,15 @@ module Nexpose 
     | 
|
| 
       289 
287 
     | 
    
         
             
                end
         
     | 
| 
       290 
288 
     | 
    
         | 
| 
       291 
289 
     | 
    
         
             
                def to_json
         
     | 
| 
       292 
     | 
    
         
            -
                  json = {
         
     | 
| 
       293 
     | 
    
         
            -
             
     | 
| 
       294 
     | 
    
         
            -
             
     | 
| 
       295 
     | 
    
         
            -
             
     | 
| 
       296 
     | 
    
         
            -
             
     | 
| 
       297 
     | 
    
         
            -
             
     | 
| 
       298 
     | 
    
         
            -
             
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
       300 
     | 
    
         
            -
             
     | 
| 
       301 
     | 
    
         
            -
                                        'search_criteria' => @search_criteria ? @search_criteria.to_h : nil
         
     | 
| 
       302 
     | 
    
         
            -
                      }
         
     | 
| 
       303 
     | 
    
         
            -
                  }
         
     | 
| 
      
 290 
     | 
    
         
            +
                  json = { 'tag_name' => @name,
         
     | 
| 
      
 291 
     | 
    
         
            +
                           'tag_type' => @type,
         
     | 
| 
      
 292 
     | 
    
         
            +
                           'tag_id' => @id,
         
     | 
| 
      
 293 
     | 
    
         
            +
                           'attributes' => [{ 'tag_attribute_name' => 'SOURCE',
         
     | 
| 
      
 294 
     | 
    
         
            +
                                              'tag_attribute_value' => @source }],
         
     | 
| 
      
 295 
     | 
    
         
            +
                           'tag_config' => { 'site_ids' => @site_ids,
         
     | 
| 
      
 296 
     | 
    
         
            +
                                             'tag_associated_asset_ids' => @associated_asset_ids,
         
     | 
| 
      
 297 
     | 
    
         
            +
                                             'asset_group_ids' => @asset_group_ids,
         
     | 
| 
      
 298 
     | 
    
         
            +
                                             'search_criteria' => @search_criteria ? @search_criteria.to_h : nil } }
         
     | 
| 
       304 
299 
     | 
    
         
             
                  if @type == Type::Generic::CUSTOM
         
     | 
| 
       305 
300 
     | 
    
         
             
                    json['attributes'] << { 'tag_attribute_name' => 'COLOR', 'tag_attribute_value' => @color }
         
     | 
| 
       306 
301 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -316,25 +311,23 @@ module Nexpose 
     | 
|
| 
       316 
311 
     | 
    
         
             
                end
         
     | 
| 
       317 
312 
     | 
    
         | 
| 
       318 
313 
     | 
    
         
             
                def self.parse(json)
         
     | 
| 
       319 
     | 
    
         
            -
                  color 
     | 
| 
       320 
     | 
    
         
            -
                  color 
     | 
| 
       321 
     | 
    
         
            -
                  source 
     | 
| 
       322 
     | 
    
         
            -
                  source 
     | 
| 
       323 
     | 
    
         
            -
                  tag 
     | 
| 
       324 
     | 
    
         
            -
                  tag.color 
     | 
| 
       325 
     | 
    
         
            -
                  tag.source 
     | 
| 
      
 314 
     | 
    
         
            +
                  color         = json['attributes'].find { |attr| attr['tag_attribute_name'] == 'COLOR' }
         
     | 
| 
      
 315 
     | 
    
         
            +
                  color         = color['tag_attribute_value'] if color
         
     | 
| 
      
 316 
     | 
    
         
            +
                  source        = json['attributes'].find { |attr| attr['tag_attribute_name'] == 'SOURCE' }
         
     | 
| 
      
 317 
     | 
    
         
            +
                  source        = source['tag_attribute_value'] if source
         
     | 
| 
      
 318 
     | 
    
         
            +
                  tag           = Tag.new(json['tag_name'], json['tag_type'], json['tag_id'])
         
     | 
| 
      
 319 
     | 
    
         
            +
                  tag.color     = color
         
     | 
| 
      
 320 
     | 
    
         
            +
                  tag.source    = source
         
     | 
| 
       326 
321 
     | 
    
         
             
                  tag.asset_ids = json['asset_ids']
         
     | 
| 
       327 
322 
     | 
    
         
             
                  if json['tag_config']
         
     | 
| 
       328 
     | 
    
         
            -
                    tag.site_ids 
     | 
| 
      
 323 
     | 
    
         
            +
                    tag.site_ids             = json['tag_config']['site_ids']
         
     | 
| 
       329 
324 
     | 
    
         
             
                    tag.associated_asset_ids = json['tag_config']['tag_associated_asset_ids']
         
     | 
| 
       330 
     | 
    
         
            -
                    tag.asset_group_ids 
     | 
| 
       331 
     | 
    
         
            -
                    criteria 
     | 
| 
       332 
     | 
    
         
            -
                    tag.search_criteria  
     | 
| 
      
 325 
     | 
    
         
            +
                    tag.asset_group_ids      = json['tag_config']['asset_group_ids']
         
     | 
| 
      
 326 
     | 
    
         
            +
                    criteria                 = json['tag_config']['search_criteria']
         
     | 
| 
      
 327 
     | 
    
         
            +
                    tag.search_criteria      = criteria ? Criteria.parse(criteria) : nil
         
     | 
| 
       333 
328 
     | 
    
         
             
                  end
         
     | 
| 
       334 
329 
     | 
    
         
             
                  modifier = json['attributes'].find { |attr| attr['tag_attribute_name'] == 'RISK_MODIFIER' }
         
     | 
| 
       335 
     | 
    
         
            -
                  if modifier
         
     | 
| 
       336 
     | 
    
         
            -
                    tag.risk_modifier = modifier['tag_attribute_value'].to_i
         
     | 
| 
       337 
     | 
    
         
            -
                  end
         
     | 
| 
      
 330 
     | 
    
         
            +
                  tag.risk_modifier = modifier['tag_attribute_value'].to_i if modifier
         
     | 
| 
       338 
331 
     | 
    
         
             
                  tag
         
     | 
| 
       339 
332 
     | 
    
         
             
                end
         
     | 
| 
       340 
333 
     | 
    
         | 
| 
         @@ -346,9 +339,9 @@ module Nexpose 
     | 
|
| 
       346 
339 
     | 
    
         
             
                #
         
     | 
| 
       347 
340 
     | 
    
         
             
                def add_to_asset(connection, asset_id)
         
     | 
| 
       348 
341 
     | 
    
         
             
                  params = to_json_for_add
         
     | 
| 
       349 
     | 
    
         
            -
                  url 
     | 
| 
       350 
     | 
    
         
            -
                  uri 
     | 
| 
       351 
     | 
    
         
            -
                  @id 
     | 
| 
      
 342 
     | 
    
         
            +
                  url    = "/api/2.0/assets/#{asset_id}/tags"
         
     | 
| 
      
 343 
     | 
    
         
            +
                  uri    = AJAX.post(connection, url, params, AJAX::CONTENT_TYPE::JSON)
         
     | 
| 
      
 344 
     | 
    
         
            +
                  @id    = uri.split('/').last.to_i
         
     | 
| 
       352 
345 
     | 
    
         
             
                end
         
     | 
| 
       353 
346 
     | 
    
         | 
| 
       354 
347 
     | 
    
         
             
                # Adds a tag to a site
         
     | 
| 
         @@ -359,9 +352,9 @@ module Nexpose 
     | 
|
| 
       359 
352 
     | 
    
         
             
                #
         
     | 
| 
       360 
353 
     | 
    
         
             
                def add_to_site(connection, site_id)
         
     | 
| 
       361 
354 
     | 
    
         
             
                  params = to_json_for_add
         
     | 
| 
       362 
     | 
    
         
            -
                  url 
     | 
| 
       363 
     | 
    
         
            -
                  uri 
     | 
| 
       364 
     | 
    
         
            -
                  @id 
     | 
| 
      
 355 
     | 
    
         
            +
                  url    = "/api/2.0/sites/#{site_id}/tags"
         
     | 
| 
      
 356 
     | 
    
         
            +
                  uri    = AJAX.post(connection, url, params, AJAX::CONTENT_TYPE::JSON)
         
     | 
| 
      
 357 
     | 
    
         
            +
                  @id    = uri.split('/').last.to_i
         
     | 
| 
       365 
358 
     | 
    
         
             
                end
         
     | 
| 
       366 
359 
     | 
    
         | 
| 
       367 
360 
     | 
    
         
             
                # Adds a tag to an asset group
         
     | 
| 
         @@ -372,11 +365,11 @@ module Nexpose 
     | 
|
| 
       372 
365 
     | 
    
         
             
                #
         
     | 
| 
       373 
366 
     | 
    
         
             
                def add_to_group(connection, group_id)
         
     | 
| 
       374 
367 
     | 
    
         
             
                  params = to_json_for_add
         
     | 
| 
       375 
     | 
    
         
            -
                  url 
     | 
| 
       376 
     | 
    
         
            -
                  uri 
     | 
| 
       377 
     | 
    
         
            -
                  @id 
     | 
| 
      
 368 
     | 
    
         
            +
                  url    = "/api/2.0/asset_groups/#{group_id}/tags"
         
     | 
| 
      
 369 
     | 
    
         
            +
                  uri    = AJAX.post(connection, url, params, AJAX::CONTENT_TYPE::JSON)
         
     | 
| 
      
 370 
     | 
    
         
            +
                  @id    = uri.split('/').last.to_i
         
     | 
| 
       378 
371 
     | 
    
         
             
                end
         
     | 
| 
       379 
     | 
    
         
            -
                 
     | 
| 
      
 372 
     | 
    
         
            +
                alias add_to_asset_group add_to_group
         
     | 
| 
       380 
373 
     | 
    
         | 
| 
       381 
374 
     | 
    
         
             
                private
         
     | 
| 
       382 
375 
     | 
    
         |