qualys 0.1.4 → 0.1.5

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -2
  3. data/.rubocop.yml +7 -0
  4. data/.rubocop_todo.yml +71 -0
  5. data/.travis.yml +13 -1
  6. data/Gemfile +3 -1
  7. data/Gemfile.lock +91 -0
  8. data/README.md +50 -10
  9. data/Rakefile +3 -4
  10. data/lib/qualys.rb +10 -11
  11. data/lib/qualys/api.rb +38 -47
  12. data/lib/qualys/auth.rb +11 -20
  13. data/lib/qualys/compliance.rb +3 -7
  14. data/lib/qualys/config.rb +3 -5
  15. data/lib/qualys/host.rb +17 -0
  16. data/lib/qualys/report.rb +90 -0
  17. data/lib/qualys/scans.rb +10 -22
  18. data/lib/qualys/version.rb +1 -1
  19. data/lib/qualys/vulnerability.rb +74 -0
  20. data/qualys.gemspec +18 -19
  21. data/spec/fixtures/vcr_cassettes/api_get.yml +52 -0
  22. data/spec/fixtures/vcr_cassettes/create_global_report.yml +68 -0
  23. data/spec/fixtures/vcr_cassettes/emptyscans.yml +35 -0
  24. data/spec/fixtures/vcr_cassettes/get.yml +107 -0
  25. data/spec/fixtures/vcr_cassettes/global_report.yml +17800 -0
  26. data/spec/fixtures/vcr_cassettes/load_global_report.yml +625 -0
  27. data/spec/fixtures/vcr_cassettes/login.yml +50 -0
  28. data/spec/fixtures/vcr_cassettes/logout.yml +50 -0
  29. data/spec/fixtures/vcr_cassettes/scan.yml +73 -0
  30. data/spec/fixtures/vcr_cassettes/scans.yml +89 -0
  31. data/spec/fixtures/vcr_cassettes/templates.yml +121 -0
  32. data/spec/fixtures/vcr_cassettes/try_load_not_existing_report.yml +63 -0
  33. data/spec/fixtures/vcr_cassettes/unlogged.yml +45 -0
  34. data/spec/fixtures/vcr_cassettes/wrong.yml +101 -0
  35. data/spec/qualys/api_spec.rb +27 -0
  36. data/spec/qualys/report_spec.rb +65 -0
  37. data/spec/qualys/scans_spec.rb +75 -0
  38. data/spec/qualys/version_spec.rb +11 -0
  39. data/spec/qualys/vulnerability_spec.rb +53 -0
  40. data/spec/qualys_spec.rb +20 -0
  41. data/spec/spec_helper.rb +37 -0
  42. metadata +61 -15
  43. data/.rock.yml +0 -17
  44. data/lib/qualys/reports.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ac602898aecbc4ee66fe92c1bcb23cebe9bf745c
4
- data.tar.gz: 57bb46bc7f9f685085252481c6beb1190446775a
3
+ metadata.gz: 7d239fdef1e63e56d32021e4a56638200fcb71fb
4
+ data.tar.gz: 8943a665c47520cb349caf0c3d92d2931abf41fe
5
5
  SHA512:
6
- metadata.gz: ce3ecaaa399130b1d9b4d38b8321401b510f2cd729062dcc50758255b379be3097f3945335ca0d7fb8d2eb70801c320c7f5b3c5fe49e5f0be0be6126159c107b
7
- data.tar.gz: 06c36c291e5aa06c2d0ba59581af9dcd1c229be65da84ce07dc1ccfade804668202e75fec8e044e216ca8a5c5b1d2c008ce408cda75bc7ad03ff00bd9c60afd6
6
+ metadata.gz: d646857008c5095b373aa90216ffc03ef5ba1459e3e0ef65cdf12834a2b3aced1dccc08d6d12b14e8181572dcbb5c305434c316ad18004ac876b11d37fa5cca3
7
+ data.tar.gz: 9364b0a37083e4da14da213a5e3de308bbc0e2c20059e327db5bbafcd478a370d1e381ba1d1b349a0fe85075d4722dfa269cd7f6a758e18766e4dcac562e5cec
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  /.bundle/
2
2
  /vendor/
3
- Gemfile.lock
4
3
  *.gem
5
- /config/qualys.yaml
4
+ /config/qualys.yaml
5
+ .idea
6
+ coverage
@@ -0,0 +1,7 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.3
5
+
6
+ Metrics/BlockLength:
7
+ ExcludedMethods: ['describe', 'context']
@@ -0,0 +1,71 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2017-12-06 13:40:31 +0100 using RuboCop version 0.51.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 2
10
+ Metrics/AbcSize:
11
+ Max: 21
12
+
13
+ # Offense count: 13
14
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
15
+ # URISchemes: http, https
16
+ Metrics/LineLength:
17
+ Max: 126
18
+
19
+ # Offense count: 2
20
+ # Configuration parameters: CountComments.
21
+ Metrics/MethodLength:
22
+ Max: 12
23
+
24
+ # Offense count: 10
25
+ Style/Documentation:
26
+ Exclude:
27
+ - 'spec/**/*'
28
+ - 'test/**/*'
29
+ - 'lib/qualys.rb'
30
+ - 'lib/qualys/api.rb'
31
+ - 'lib/qualys/auth.rb'
32
+ - 'lib/qualys/compliance.rb'
33
+ - 'lib/qualys/config.rb'
34
+ - 'lib/qualys/report.rb'
35
+ - 'lib/qualys/scans.rb'
36
+
37
+ # Offense count: 13
38
+ # Cop supports --auto-correct.
39
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
40
+ # SupportedStyles: when_needed, always, never
41
+ Style/FrozenStringLiteralComment:
42
+ Exclude:
43
+ - 'Gemfile'
44
+ - 'Rakefile'
45
+ - 'lib/qualys.rb'
46
+ - 'lib/qualys/api.rb'
47
+ - 'lib/qualys/auth.rb'
48
+ - 'lib/qualys/compliance.rb'
49
+ - 'lib/qualys/config.rb'
50
+ - 'lib/qualys/reports.rb'
51
+ - 'lib/qualys/scans.rb'
52
+ - 'lib/qualys/version.rb'
53
+ - 'qualys.gemspec'
54
+ - 'spec/qualys_spec.rb'
55
+ - 'spec/spec_helper.rb'
56
+
57
+ # Offense count: 4
58
+ # Configuration parameters: MinBodyLength.
59
+ Style/GuardClause:
60
+ Exclude:
61
+ - 'lib/qualys/api.rb'
62
+ - 'lib/qualys/config.rb'
63
+ - 'lib/qualys/reports.rb'
64
+
65
+ # Offense count: 2
66
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
67
+ # SupportedStyles: module_function, extend_self
68
+ Style/ModuleFunction:
69
+ Exclude:
70
+ - 'lib/qualys.rb'
71
+ - 'lib/qualys/config.rb'
@@ -1 +1,13 @@
1
- language: ruby
1
+ language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ rvm:
5
+ - 2.3.4
6
+ - 2.4.1
7
+
8
+ script:
9
+ - bundle exec rubocop -F --fail-level C -f s
10
+ - bundle exec rspec spec
11
+
12
+ notifications:
13
+ email: false
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gemspec
3
+ gemspec
4
+
5
+ gem 'coveralls', require: false
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ qualys (0.1.5)
5
+ erubis
6
+ httparty (~> 0.15)
7
+ json
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.5.2)
13
+ public_suffix (>= 2.0.2, < 4.0)
14
+ ast (2.3.0)
15
+ coveralls (0.8.21)
16
+ json (>= 1.8, < 3)
17
+ simplecov (~> 0.14.1)
18
+ term-ansicolor (~> 1.3)
19
+ thor (~> 0.19.4)
20
+ tins (~> 1.6)
21
+ crack (0.4.3)
22
+ safe_yaml (~> 1.0.0)
23
+ diff-lcs (1.3)
24
+ docile (1.1.5)
25
+ erubis (2.7.0)
26
+ hashdiff (0.3.7)
27
+ httparty (0.15.6)
28
+ multi_xml (>= 0.5.2)
29
+ json (2.1.0)
30
+ multi_xml (0.6.0)
31
+ parallel (1.12.0)
32
+ parser (2.4.0.2)
33
+ ast (~> 2.3)
34
+ powerpack (0.1.1)
35
+ public_suffix (3.0.1)
36
+ rainbow (2.2.2)
37
+ rake
38
+ rake (12.3.0)
39
+ rspec (3.7.0)
40
+ rspec-core (~> 3.7.0)
41
+ rspec-expectations (~> 3.7.0)
42
+ rspec-mocks (~> 3.7.0)
43
+ rspec-core (3.7.0)
44
+ rspec-support (~> 3.7.0)
45
+ rspec-expectations (3.7.0)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.7.0)
48
+ rspec-mocks (3.7.0)
49
+ diff-lcs (>= 1.2.0, < 2.0)
50
+ rspec-support (~> 3.7.0)
51
+ rspec-support (3.7.0)
52
+ rubocop (0.51.0)
53
+ parallel (~> 1.10)
54
+ parser (>= 2.3.3.1, < 3.0)
55
+ powerpack (~> 0.1)
56
+ rainbow (>= 2.2.2, < 3.0)
57
+ ruby-progressbar (~> 1.7)
58
+ unicode-display_width (~> 1.0, >= 1.0.1)
59
+ ruby-progressbar (1.9.0)
60
+ safe_yaml (1.0.4)
61
+ simplecov (0.14.1)
62
+ docile (~> 1.1.0)
63
+ json (>= 1.8, < 3)
64
+ simplecov-html (~> 0.10.0)
65
+ simplecov-html (0.10.2)
66
+ term-ansicolor (1.6.0)
67
+ tins (~> 1.0)
68
+ thor (0.19.4)
69
+ tins (1.16.1)
70
+ unicode-display_width (1.3.0)
71
+ vcr (4.0.0)
72
+ webmock (3.1.1)
73
+ addressable (>= 2.3.6)
74
+ crack (>= 0.3.2)
75
+ hashdiff
76
+
77
+ PLATFORMS
78
+ ruby
79
+
80
+ DEPENDENCIES
81
+ bundler
82
+ coveralls
83
+ qualys!
84
+ rake
85
+ rspec
86
+ rubocop
87
+ vcr
88
+ webmock
89
+
90
+ BUNDLED WITH
91
+ 1.16.0
data/README.md CHANGED
@@ -1,11 +1,9 @@
1
- # Ruby Qualys API v2
2
- A Ruby extension for interfacing with Qualys v2 API.
1
+ [![Build Status](https://travis-ci.org/Cyberwatch/ruby-qualys.svg?branch=master)](https://travis-ci.org/Cyberwatch/ruby-qualys)
2
+ [![Coverage Status](https://coveralls.io/repos/github/Cyberwatch/ruby-qualys/badge.svg?branch=master)](https://coveralls.io/github/Cyberwatch/ruby-qualys?branch=master)
3
3
 
4
- [![](http://ruby-gem-downloads-badge.herokuapp.com/qualys?type=total)](https://rubygems.org/gems/qualys)
5
-
6
- [![Dependency Status](https://gemnasium.com/mikemackintosh/ruby-qualys.svg)](https://gemnasium.com/mikemackintosh/ruby-qualys)
4
+ # Ruby Qualys API v2
7
5
 
8
- [![Gem Version](https://badge.fury.io/rb/qualys.svg)](https://rubygems.org/gems/qualys)
6
+ A Ruby extension for interfacing with Qualys v2 API.
9
7
 
10
8
  ### Introduction
11
9
 
@@ -13,11 +11,13 @@ I had the need to pull stats and details from Qualys automatically to collect an
13
11
 
14
12
  ## Installation
15
13
 
16
- Like any other gem:
14
+ Add this line to your application's Gemfile:
17
15
 
18
- ```shell
19
- gem install qualys
20
- ```
16
+ gem 'ruby-qualys', git: 'https://github.com/Cyberwatch/ruby-qualys.git'
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
21
 
22
22
  ## Usage
23
23
 
@@ -72,7 +72,47 @@ If your URL differs from the default, set it using:
72
72
  ```ruby
73
73
  Qualys::Api.base_uri = OTHER_PRODUCTION_ENDPOINT
74
74
  ```
75
+ ### Getting vulnerabilities
76
+
77
+ You can load all vulnerability detected by qualys so far for the logged user
78
+ Here an example printing some information on the vulnerabilities for two hosts :
75
79
 
80
+ ```ruby
81
+ Qualys::Reports.global_report.hosts.each{ |host|
82
+ p "ip:#{ host.ip }"
83
+ p "vulns : (#{ host.vulnerabilities.count })"
84
+ host.vulnerabilities.each{ |vuln|
85
+ p vuln.to_s
86
+ }
87
+ }
88
+ ```
89
+
90
+ Output :
91
+ ```
92
+ "ip:12.34.156.89"
93
+ "vulns : (16)"
94
+ "qid_38173, SSL Certificate - Signature Verification Failed Vulnerability, severity : 2, cves: no cve"
95
+ "qid_38685, SSL Certificate - Invalid Maximum Validity Date Detected, severity : 2, cves: no cve"
96
+ "qid_38169, SSL Certificate - Self-Signed Certificate, severity : 2, cves: no cve"
97
+ "qid_38170, SSL Certificate - Subject Common Name Does Not Match Server FQDN, severity : 2, cves: no cve"
98
+ "qid_38628, SSL/TLS Server supports TLSv1.0, severity : 3, cves: no cve"
99
+ "qid_38601, SSL/TLS use of weak RC4 cipher, severity : 3, cves: CVE-2013-2566, CVE-2015-2808"
100
+ "qid_38140, SSL Server Supports Weak Encryption Vulnerability, severity : 3, cves: no cve"
101
+ "qid_38142, SSL Server Allows Anonymous Authentication Vulnerability, severity : 4, cves: no cve"
102
+ "qid_38657, Birthday attacks against TLS ciphers with 64bit block size vulnerability (Sweet32), severity : 3, cves: CVE-2016-2183"
103
+ "qid_38606, SSL Server Has SSLv3 Enabled Vulnerability, severity : 3, cves: no cve"
104
+ "qid_82003, ICMP Timestamp Request, severity : 1, cves: CVE-1999-0524"
105
+ "qid_38603, SSLv3 Padding Oracle Attack Information Disclosure Vulnerability (POODLE), severity : 3, cves: CVE-2014-3566"
106
+ "qid_11827, HTTP Security Header Not Detected, severity : 2, cves: no cve"
107
+ "qid_11827, HTTP Security Header Not Detected, severity : 2, cves: no cve"
108
+ "qid_38628, SSL/TLS Server supports TLSv1.0, severity : 3, cves: no cve"
109
+ "qid_38657, Birthday attacks against TLS ciphers with 64bit block size vulnerability (Sweet32), severity : 3, cves: CVE-2016-2183"
110
+ "ip:10.34.156.89"
111
+ "vulns : (3)"
112
+ "qid_11827, HTTP Security Header Not Detected, severity : 2, cves: no cve"
113
+ "qid_11827, HTTP Security Header Not Detected, severity : 2, cves: no cve"
114
+ "qid_38628, SSL/TLS Server supports TLSv1.0, severity : 3, cves: no cve"
115
+ ```
76
116
 
77
117
  ## References
78
118
 
data/Rakefile CHANGED
@@ -1,9 +1,8 @@
1
- #encoding: utf-8
2
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
3
2
  require 'rspec/core/rake_task'
4
3
  require 'rubocop/rake_task'
5
4
 
6
- task :default => :test
5
+ task default: :test
7
6
 
8
7
  RSpec::Core::RakeTask.new do |spec|
9
8
  spec.verbose = false
@@ -24,4 +23,4 @@ RuboCop::RakeTask.new(:rubocop) do |task|
24
23
  task.formatters = ['progress']
25
24
  # don't abort rake on failure
26
25
  task.fail_on_error = false
27
- end
26
+ end
@@ -10,23 +10,22 @@ require 'qualys/auth'
10
10
 
11
11
  require 'qualys/scans'
12
12
  require 'qualys/compliance'
13
- require 'qualys/reports'
13
+ require 'qualys/report'
14
14
 
15
+ require 'qualys/host'
16
+ require 'qualys/vulnerability'
15
17
 
16
18
  module Qualys
17
-
18
19
  extend self
19
20
 
20
21
  def configure
21
22
  block_given? ? yield(Config) : Config
22
- %w(username password).each do |key|
23
- if Qualys::Config.instance_variable_get("@#{key}").nil?
24
- raise Qualys::Config::RequiredOptionMissing,
25
- "Configuration parameter missing: '#{key}'. " +
26
- "Please add it to the Qualys.configure block"
27
- end
23
+ %w[username password].each do |key|
24
+ next unless Qualys::Config.instance_variable_get("@#{key}").nil?
25
+ raise Qualys::Config::RequiredOptionMissing,
26
+ "Configuration parameter missing: '#{key}'. " \
27
+ 'Please add it to the Qualys.configure block'
28
28
  end
29
29
  end
30
- alias_method :config, :configure
31
-
32
- end
30
+ alias config configure
31
+ end
@@ -1,71 +1,62 @@
1
1
  module Qualys
2
2
  class Api
3
-
4
3
  class InvalidResponse < RuntimeError; end
5
4
  class AuthorizationRequired < RuntimeError; end
6
5
  class Exception < RuntimeError; end
7
6
 
8
7
  # Set the current production endpoint
9
- PRODUCTION_ENDPOINT = 'https://qualysapi.qualys.com/api/2.0/fo/'
8
+ PRODUCTION_ENDPOINT = 'https://qualysapi.qualys.com/api/2.0/fo/'.freeze
10
9
 
11
10
  # Set HTTParty defaults
12
11
  HTTParty::Basement.default_options.update(base_uri: PRODUCTION_ENDPOINT)
13
12
  HTTParty::Basement.default_options.update(headers: {
14
- "X-Requested-With" => "Qualys Ruby Client v#{Qualys::VERSION}"
15
- })
16
-
17
- #
18
- #
19
- def self.api_get(url, options={})
13
+ 'X-Requested-With' => "Qualys Ruby Client v#{Qualys::VERSION}"
14
+ })
20
15
 
21
- unless Qualys::Config.session_key.nil?
22
- HTTParty::Basement.default_cookies.add_cookies(Qualys::Config.session_key)
23
- end
16
+ class << self
17
+ def api_get(url, options = {})
18
+ HTTParty::Basement.default_cookies.add_cookies(Qualys::Config.session_key) unless Qualys::Config.session_key.nil?
24
19
 
25
- # Send Request
26
- response = HTTParty.get(url, options)
20
+ # Send Request
21
+ response = HTTParty.get(url, options)
27
22
 
28
- # Check if you need to be authorized
29
- if response.code.eql?(401)
30
- raise Qualys::Api::AuthorizationRequired, "Please Login Before Communicating With The API"
31
- elsif response.code.eql?(403)
32
- raise Qualys::Api::Exception, response.parsed_response['SIMPLE_RETURN']['RESPONSE']['TEXT']
33
- elsif !response.code.eql?(200)
34
- raise Qualys::Api::InvalidResponse, "Invalid Response Received"
23
+ # Check if you need to be authorized
24
+ check_response(response)
25
+ # return the response
26
+ response
35
27
  end
36
28
 
37
- # return the response
38
- response
39
- end
29
+ #
30
+ #
31
+ def api_post(url, options = {})
32
+ HTTParty::Basement.default_cookies.add_cookies(Qualys::Config.session_key) unless Qualys::Config.session_key.nil?
40
33
 
41
- #
42
- #
43
- def self.api_post(url, options={})
44
-
45
- unless Qualys::Config.session_key.nil?
46
- HTTParty::Basement.default_cookies.add_cookies(Qualys::Config.session_key)
47
- end
34
+ # Send Request
35
+ response = HTTParty.post(url, options)
48
36
 
49
- # Send Request
50
- response = HTTParty.post(url, options)
37
+ # Check if you need to be authorized
38
+ check_response(response)
39
+ # return the response
40
+ response
41
+ end
51
42
 
52
- # Check if you need to be authorized
53
- if response.code.eql?(401)
54
- raise Qualys::Api::AuthorizationRequired, "Please Configure A Username and Password Before Communicating With The API"
55
- elsif response.code.eql?(403)
56
- raise Qualys::Api::Exception, response.parsed_response['SIMPLE_RETURN']['RESPONSE']['TEXT']
57
- elsif response.code.eql?(500)
58
- raise Qualys::Api::InvalidResponse, "Invalid Response Received"
43
+ #
44
+ # Sets the base URI.
45
+ def base_uri=(base_uri)
46
+ HTTParty::Basement.default_options.update(base_uri: base_uri)
59
47
  end
60
48
 
61
- # return the response
62
- response
63
- end
49
+ private
64
50
 
65
- #
66
- # Sets the base URI.
67
- def self.base_uri=(base_uri)
68
- HTTParty::Basement.default_options.update(base_uri: base_uri)
51
+ def check_response(response)
52
+ code = response.code
53
+ raise(Qualys::Api::AuthorizationRequired, 'Please Login Before Communicating With The API') if code.eql?(401)
54
+ raise(Qualys::Api::Exception, response.parsed_response['SIMPLE_RETURN']['RESPONSE']['TEXT']) if code.eql?(403)
55
+ unless code.eql?(200)
56
+ raise(Qualys::Api::InvalidResponse, 'Invalid Response Received' + response.code.to_s + ' ' +
57
+ response.request.last_uri.to_s)
58
+ end
59
+ end
69
60
  end
70
61
  end
71
- end
62
+ end