qualys_api 0.1.4

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e8bf69f413aab3dbba9bb8f5024877232de85fb9
4
+ data.tar.gz: 780302f4ae8b704f543cbe959ad906d81376f7cb
5
+ SHA512:
6
+ metadata.gz: f1d5cf468747754584462c2d887c7e1ee638829a9ed2b9f6e12956195826059275d85550cc82bc2e5c836583c4e23ab6c0682edad7c67ae235695e09137c652f
7
+ data.tar.gz: ecb6fc5ce33b2aa67df249d59a624eaba979ed6039ad6e45eee0211b1e1b70601128fbec1e654a07288e481af080b8410af552609c46e33e17006e2cb9d875bd
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in qualys_api.gemspec
4
+ gemspec
@@ -0,0 +1,35 @@
1
+ # QualysApi
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/qualys_api`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'qualys_api'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install qualys_api
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/qualys_api.
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "qualys_api"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,16 @@
1
+
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
+
5
+ require "qualys_api/version"
6
+
7
+ require "qualys_api/base"
8
+
9
+ require "qualys_api/types/scan"
10
+ require "qualys_api/types/host"
11
+ require "qualys_api/types/issue"
12
+ require "qualys_api/types/knowledge"
13
+
14
+ require "qualys_api/knowledge"
15
+ require "qualys_api/auth"
16
+ require "qualys_api/scan"
@@ -0,0 +1,19 @@
1
+ module Qualys
2
+ class Auth < Qualys::Base
3
+ def initialize(username, password, server=:na)
4
+ super(username, password, server)
5
+
6
+ @username = username
7
+ @password = password
8
+ end
9
+
10
+ def login
11
+ params = { action: 'login', username: @username, password: @password }
12
+ response = post('/api/2.0/fo/session/', params )
13
+
14
+ Qualys::Config.session_key = response.headers['set-cookie']
15
+
16
+ true
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,118 @@
1
+ module Qualys
2
+ class Exception < RuntimeError; end
3
+ class InvalidResponse < RuntimeError; end
4
+ class InvalidLogin < RuntimeError; end
5
+ class InvalidRegion < RuntimeError; end
6
+
7
+ class Base
8
+ PLATFORMS = {
9
+ na: 'https://qualysapi.qualys.com/api/2.0/fo/',
10
+ na2: 'https://qualysapi.qg2.apps.qualys.com/api/2.0/fo/',
11
+ na3: 'https://qualysapi.qg3.apps.qualys.com/api/2.0/fo/',
12
+ eu: 'https://qualysapi.qualys.eu/api/2.0/fo/',
13
+ eu1: 'https://qualysapi.qg2.apps.qualys.eu/api/2.0/fo/',
14
+ in: 'https://qualysapi.qg1.apps.qualys.in/api/2.0/fo/'
15
+ }.freeze
16
+
17
+ def initialize(username, password, server = :na)
18
+ raise Qualys::InvalidRegion if PLATFORMS[server].nil?
19
+
20
+ @server = PLATFORMS[server]
21
+
22
+ @conn = Faraday.new(url: @server) do |faraday|
23
+ faraday.request :url_encoded
24
+ faraday.adapter Faraday.default_adapter
25
+ faraday.response :xml, content_type: /\bxml$/
26
+ faraday.response :json, content_type: /\bjson$/
27
+ end
28
+
29
+ @conn.basic_auth(username, password)
30
+ end
31
+
32
+ def get(url, params = {})
33
+ response = @conn.get do |req|
34
+ req.url url
35
+ req.params = params
36
+ req.headers['X-Requested-With'] = 'ruby qualys_api'
37
+ end
38
+
39
+ if response.status.eql?(401)
40
+ raise Qualys::LoginRequired, 'Invalid Login Credentials'
41
+ elsif !response.status.eql?(200)
42
+ raise Qualys::InvalidResponse, 'Invalid Response Received'
43
+ end
44
+
45
+ response
46
+ end
47
+
48
+ def post(url, params = {})
49
+ response = @conn.post do |req|
50
+ req.url url
51
+ req.body = params
52
+ req.headers['X-Requested-With'] = 'ruby qualys_api'
53
+ end
54
+
55
+ if response.status.eql?(401)
56
+ raise Qualys::LoginRequired, 'Invalid Login Credentials'
57
+ elsif !response.status.eql?(200)
58
+ raise Qualys::InvalidResponse, 'Invalid Response Received'
59
+ end
60
+
61
+ response
62
+ end
63
+ end
64
+
65
+ module Config
66
+ extend self
67
+
68
+ attr_accessor :session_key
69
+ end
70
+
71
+ module Type
72
+ class Base
73
+ def initialize(hash)
74
+ @raw_hash = downcase_hash(hash)
75
+ end
76
+
77
+ def method_missing(name, *args, &block)
78
+ @raw_hash[name] if @raw_hash.key? name
79
+ @raw_hash.each { |k, v| return v if k.to_s.to_sym == name }
80
+ super.method_missing name
81
+ end
82
+
83
+ def respond_to?(name, include_private = false)
84
+ return true if @raw_hash.key? name
85
+ @raw_hash.each { |k, _v| return true if k.to_s.to_sym == name }
86
+ super
87
+ end
88
+
89
+ private
90
+
91
+ def downcase_hash(value)
92
+ case value
93
+ when Array
94
+ value.map { |v| downcase_hash(v) }
95
+ # or `value.map(&method(:convert_hash_keys))`
96
+ when Hash
97
+ Hash[value.map { |k, v| [k.downcase, downcase_hash(v)] }]
98
+ else
99
+ value
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ class Hash
107
+ def method_missing(name, *args, &block)
108
+ self[name] if key? name
109
+ each { |k, v| return v if k.to_s.to_sym == name }
110
+ super.method_missing name
111
+ end
112
+
113
+ def respond_to?(name, include_private = false)
114
+ return true if key? name
115
+ each { |k, _v| return true if k.to_s.to_sym == name }
116
+ super
117
+ end
118
+ end
@@ -0,0 +1,59 @@
1
+ module Qualys
2
+ class KnowledgeBase < Qualys::Base
3
+
4
+ def get_all
5
+ uri = '/api/2.0/fo/knowledge_base/vuln/'
6
+ params = {
7
+ action: 'list',
8
+ details: 'All'
9
+ }
10
+
11
+ response = get(uri, params)
12
+
13
+ unless response.body['KNOWLEDGE_BASE_VULN_LIST_OUTPUT']['RESPONSE'].has_key? 'VULN_LIST'
14
+ return []
15
+ end
16
+
17
+ kb = response.body['KNOWLEDGE_BASE_VULN_LIST_OUTPUT']['RESPONSE']['VULN_LIST']['VULN']
18
+
19
+ if kb.class == Hash
20
+ return [Qualys::Knowledge.new(kb)]
21
+ elsif kb.class == Array
22
+ kb.map! do |qid|
23
+ Qualys::Knowledge.new(qid)
24
+ end
25
+ else
26
+ return []
27
+ end
28
+ end
29
+
30
+ def get_qid(qids)
31
+ raise ArgumentError if qids.nil?
32
+
33
+ uri = '/api/2.0/fo/knowledge_base/vuln/'
34
+ params = {
35
+ action: 'list',
36
+ details: 'All',
37
+ ids: qids
38
+ }
39
+
40
+ response = get(uri, params)
41
+
42
+ unless response.body['KNOWLEDGE_BASE_VULN_LIST_OUTPUT']['RESPONSE'].has_key? 'VULN_LIST'
43
+ return []
44
+ end
45
+
46
+ kb = response.body['KNOWLEDGE_BASE_VULN_LIST_OUTPUT']['RESPONSE']['VULN_LIST']['VULN']
47
+
48
+ if kb.class == Hash
49
+ return [Qualys::Knowledge.new(kb)]
50
+ elsif kb.class == Array
51
+ kb.map! do |qid|
52
+ Qualys::Knowledge.new(qid)
53
+ end
54
+ else
55
+ return []
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,54 @@
1
+ module Qualys
2
+ class Scans < Qualys::Base
3
+ def get_scans
4
+ uri = '/api/2.0/fo/scan/'
5
+ params = {
6
+ action: 'list',
7
+ }
8
+
9
+ response = get(uri, params)
10
+
11
+ unless response.body['SCAN_LIST_OUTPUT']['RESPONSE'].has_key? 'SCAN_LIST'
12
+ return []
13
+ end
14
+
15
+ scans = response.body['SCAN_LIST_OUTPUT']['RESPONSE']['SCAN_LIST']['SCAN']
16
+
17
+ if scans.class == Hash
18
+ return [Qualys::Scan.new(scans)]
19
+ elsif scans.class == Array
20
+ scans.map! do |scan|
21
+ Qualys::Scan.new(scan)
22
+ end
23
+ else
24
+ return []
25
+ end
26
+ end
27
+
28
+ def get_scan(scan_ref)
29
+ raise ArgumentError if scan_ref.nil?
30
+
31
+ uri = '/api/2.0/fo/scan/'
32
+ params = {
33
+ action: 'fetch',
34
+ mode: 'extended',
35
+ output_format: 'json',
36
+ scan_ref: scan_ref
37
+ }
38
+
39
+ response = get(uri, params)
40
+
41
+ issues = JSON.parse(response.body)
42
+
43
+ if issues.class == Hash
44
+ return [Qualys::Issue.new(issues)]
45
+ elsif issues.class == Array
46
+ issues.map! do |issue|
47
+ Qualys::Issue.new(issue)
48
+ end
49
+ else
50
+ return []
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,4 @@
1
+ module Qualys
2
+ class Host < Qualys::Type::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Qualys
2
+ class Issue < Qualys::Type::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Qualys
2
+ class Knowledge < Qualys::Type::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Qualys
2
+ class Scan < Qualys::Type::Base
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Qualys
2
+ VERSION = "0.1.4"
3
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'qualys_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "qualys_api"
8
+ spec.version = Qualys::VERSION
9
+ spec.authors = ["Stephen Kapp"]
10
+ spec.email = ["mort666@virus.org"]
11
+
12
+ spec.summary = %q{Qualys API Wrapper}
13
+ spec.description = %q{Qualys API Wrapper, supports scan result download and knowledge base access}
14
+ spec.homepage = "https://github.com/mort666/qualys_api"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "faraday"
22
+ spec.add_dependency "faraday_middleware"
23
+ spec.add_dependency "multi_xml"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.10"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "minitest"
28
+ spec.add_development_dependency "vcr", "~> 3.0"
29
+ spec.add_development_dependency "webmock", "~> 1.22"
30
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qualys_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Kapp
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-09-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: multi_xml
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.10'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: vcr
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.22'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.22'
125
+ description: Qualys API Wrapper, supports scan result download and knowledge base
126
+ access
127
+ email:
128
+ - mort666@virus.org
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - Gemfile
135
+ - README.md
136
+ - Rakefile
137
+ - bin/console
138
+ - bin/setup
139
+ - lib/qualys_api.rb
140
+ - lib/qualys_api/auth.rb
141
+ - lib/qualys_api/base.rb
142
+ - lib/qualys_api/knowledge.rb
143
+ - lib/qualys_api/scan.rb
144
+ - lib/qualys_api/types/host.rb
145
+ - lib/qualys_api/types/issue.rb
146
+ - lib/qualys_api/types/knowledge.rb
147
+ - lib/qualys_api/types/scan.rb
148
+ - lib/qualys_api/version.rb
149
+ - qualys_api.gemspec
150
+ homepage: https://github.com/mort666/qualys_api
151
+ licenses: []
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.6.12
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: Qualys API Wrapper
173
+ test_files: []