qualys 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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