nexpose 6.1.1 → 7.0.0
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 +772 -0
- data/COPYING +27 -31
- data/Gemfile.lock +72 -30
- data/README.markdown +3 -1
- data/Rakefile +9 -0
- data/lib/nexpose.rb +1 -0
- data/lib/nexpose/ajax.rb +8 -6
- data/lib/nexpose/api_request.rb +27 -26
- data/lib/nexpose/connection.rb +28 -20
- data/lib/nexpose/credential.rb +16 -218
- data/lib/nexpose/credential_helper.rb +169 -0
- data/lib/nexpose/dag.rb +3 -3
- data/lib/nexpose/filter.rb +3 -1
- data/lib/nexpose/scan.rb +5 -1
- data/lib/nexpose/shared_credential.rb +13 -5
- data/lib/nexpose/site_credentials.rb +55 -9
- data/lib/nexpose/version.rb +1 -1
- metadata +32 -2
data/COPYING
CHANGED
@@ -1,33 +1,29 @@
|
|
1
|
-
|
2
|
-
All rights reserved.
|
3
|
-
|
4
|
-
Redistribution and use in source and binary forms, with or without modification,
|
5
|
-
are permitted provided that the following conditions are met:
|
6
|
-
|
7
|
-
* Redistributions of source code must retain the above copyright notice,
|
8
|
-
this list of conditions and the following disclaimer.
|
9
|
-
|
10
|
-
* Redistributions in binary form must reproduce the above copyright notice,
|
11
|
-
this list of conditions and the following disclaimer in the documentation
|
12
|
-
and/or other materials provided with the distribution.
|
1
|
+
BSD 3-Clause License
|
13
2
|
|
14
|
-
|
15
|
-
|
16
|
-
without specific prior written permission.
|
17
|
-
|
18
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19
|
-
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20
|
-
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
22
|
-
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
-
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
24
|
-
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
25
|
-
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
26
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27
|
-
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
-
|
29
|
-
================================================================================
|
30
|
-
|
31
|
-
The nexpose-client gem is provided under the 3-clause BSD license above.
|
3
|
+
Copyright (c) 2014-2017, Rapid7, Inc.
|
4
|
+
All rights reserved.
|
32
5
|
|
33
|
-
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
10
|
+
list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
14
|
+
and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
17
|
+
contributors may be used to endorse or promote products derived from
|
18
|
+
this software without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Gemfile.lock
CHANGED
@@ -1,53 +1,93 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nexpose (
|
4
|
+
nexpose (7.0.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
activesupport (4.2.8)
|
10
|
+
i18n (~> 0.7)
|
11
|
+
minitest (~> 5.1)
|
12
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
13
|
+
tzinfo (~> 1.1)
|
14
|
+
addressable (2.5.1)
|
15
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
16
|
+
ast (2.3.0)
|
17
|
+
codeclimate-test-reporter (0.4.8)
|
14
18
|
simplecov (>= 0.7.1, < 1.0.0)
|
15
|
-
|
19
|
+
coderay (1.1.1)
|
20
|
+
crack (0.4.3)
|
16
21
|
safe_yaml (~> 1.0.0)
|
17
|
-
diff-lcs (1.
|
22
|
+
diff-lcs (1.3)
|
18
23
|
docile (1.1.5)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
faraday (0.12.0.1)
|
25
|
+
multipart-post (>= 1.2, < 3)
|
26
|
+
faraday-http-cache (2.0.0)
|
27
|
+
faraday (~> 0.8)
|
28
|
+
github_changelog_generator (1.14.3)
|
29
|
+
activesupport
|
30
|
+
faraday-http-cache
|
31
|
+
multi_json
|
32
|
+
octokit (~> 4.6)
|
33
|
+
rainbow (>= 2.1)
|
34
|
+
rake (>= 10.0)
|
35
|
+
retriable (~> 2.1)
|
36
|
+
i18n (0.8.1)
|
37
|
+
method_source (0.8.2)
|
38
|
+
minitest (5.10.1)
|
39
|
+
multi_json (1.12.1)
|
40
|
+
multipart-post (2.0.0)
|
41
|
+
octokit (4.7.0)
|
42
|
+
sawyer (~> 0.8.0, >= 0.5.3)
|
43
|
+
parallel (1.12.0)
|
44
|
+
parser (2.4.0.0)
|
45
|
+
ast (~> 2.2)
|
46
|
+
powerpack (0.1.1)
|
47
|
+
pry (0.9.12.6)
|
48
|
+
coderay (~> 1.0)
|
49
|
+
method_source (~> 0.8)
|
50
|
+
slop (~> 3.4)
|
51
|
+
public_suffix (2.0.5)
|
52
|
+
rainbow (2.2.2)
|
53
|
+
rake
|
54
|
+
rake (12.0.0)
|
55
|
+
retriable (2.1.0)
|
56
|
+
rspec (3.6.0)
|
57
|
+
rspec-core (~> 3.6.0)
|
58
|
+
rspec-expectations (~> 3.6.0)
|
59
|
+
rspec-mocks (~> 3.6.0)
|
60
|
+
rspec-core (3.6.0)
|
61
|
+
rspec-support (~> 3.6.0)
|
62
|
+
rspec-expectations (3.6.0)
|
32
63
|
diff-lcs (>= 1.2.0, < 2.0)
|
33
|
-
rspec-support (~> 3.
|
34
|
-
rspec-mocks (3.
|
64
|
+
rspec-support (~> 3.6.0)
|
65
|
+
rspec-mocks (3.6.0)
|
35
66
|
diff-lcs (>= 1.2.0, < 2.0)
|
36
|
-
rspec-support (~> 3.
|
37
|
-
rspec-support (3.
|
38
|
-
rubocop (0.
|
39
|
-
|
40
|
-
parser (>= 2.
|
67
|
+
rspec-support (~> 3.6.0)
|
68
|
+
rspec-support (3.6.0)
|
69
|
+
rubocop (0.49.1)
|
70
|
+
parallel (~> 1.10)
|
71
|
+
parser (>= 2.3.3.1, < 3.0)
|
41
72
|
powerpack (~> 0.1)
|
42
73
|
rainbow (>= 1.99.1, < 3.0)
|
43
|
-
ruby-progressbar (~> 1.
|
44
|
-
|
74
|
+
ruby-progressbar (~> 1.7)
|
75
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
76
|
+
ruby-progressbar (1.8.1)
|
45
77
|
safe_yaml (1.0.4)
|
78
|
+
sawyer (0.8.1)
|
79
|
+
addressable (>= 2.3.5, < 2.6)
|
80
|
+
faraday (~> 0.8, < 1.0)
|
46
81
|
simplecov (0.9.2)
|
47
82
|
docile (~> 1.1.0)
|
48
83
|
multi_json (~> 1.0)
|
49
84
|
simplecov-html (~> 0.9.0)
|
50
85
|
simplecov-html (0.9.0)
|
86
|
+
slop (3.6.0)
|
87
|
+
thread_safe (0.3.6)
|
88
|
+
tzinfo (1.2.3)
|
89
|
+
thread_safe (~> 0.1)
|
90
|
+
unicode-display_width (1.3.0)
|
51
91
|
vcr (2.9.3)
|
52
92
|
webmock (1.20.4)
|
53
93
|
addressable (>= 2.3.6)
|
@@ -59,7 +99,9 @@ PLATFORMS
|
|
59
99
|
DEPENDENCIES
|
60
100
|
bundler (~> 1.3)
|
61
101
|
codeclimate-test-reporter (~> 0.4.6)
|
102
|
+
github_changelog_generator
|
62
103
|
nexpose!
|
104
|
+
pry (= 0.9.12.6)
|
63
105
|
rake
|
64
106
|
rspec (~> 3.2)
|
65
107
|
rubocop
|
data/README.markdown
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
This is the official gem package for the Ruby Nexpose API client library.
|
5
5
|
|
6
|
-
For assistance with using the gem
|
6
|
+
For assistance with using the gem or to discuss different approaches, please open an issue. To share or discuss scripts which use the gem head over to the [Nexpose Resources](https://github.com/rapid7/nexpose-resources) project.
|
7
7
|
|
8
8
|
Check out the [wiki](https://github.com/rapid7/nexpose-client/wiki) for walk-throughs and other documentation. Submit bugs and feature requests on the [issues](https://github.com/rapid7/nexpose-client/issues) page.
|
9
9
|
|
@@ -25,6 +25,8 @@ Our coding standards include:
|
|
25
25
|
* Unless otherwise noted, code should adhere to the Ruby Style Guide: https://github.com/bbatsov/ruby-style-guide
|
26
26
|
* Use YARDoc comment style to improve the API documentation of the gem.
|
27
27
|
|
28
|
+
Full usage examples or task-oriented scripts should be submitted to the [Nexpose Resources](https://github.com/rapid7/nexpose-resources) project. Smaller examples can be added to the [wiki](https://github.com/rapid7/nexpose-client/wiki).
|
29
|
+
|
28
30
|
## License
|
29
31
|
|
30
32
|
The nexpose-client gem is provided under the 3-Clause BSD License. See [COPYING](COPYING) for details.
|
data/Rakefile
CHANGED
@@ -4,3 +4,12 @@ require 'bundler/gem_tasks'
|
|
4
4
|
task :clean do
|
5
5
|
system "rm *.gem &> /dev/null"
|
6
6
|
end
|
7
|
+
|
8
|
+
|
9
|
+
require 'github_changelog_generator/task'
|
10
|
+
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
11
|
+
token = ENV['CHANGELOG_GITHUB_TOKEN']
|
12
|
+
if token.nil?
|
13
|
+
warn "!!WARNING!! Missing Github Token Environment Variable. Fix before you run rake changelog. !!WARNING!!"
|
14
|
+
end
|
15
|
+
end
|
data/lib/nexpose.rb
CHANGED
data/lib/nexpose/ajax.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Nexpose
|
3
4
|
# Accessor to the Nexpose AJAX API.
|
4
5
|
# These core methods should allow direct access to underlying controllers
|
@@ -133,7 +134,8 @@ module Nexpose
|
|
133
134
|
# Use the Nexpose::Connection to establish a correct HTTPS object.
|
134
135
|
def https(nsc, timeout = nil)
|
135
136
|
http = Net::HTTP.new(nsc.host, nsc.port)
|
136
|
-
http.read_timeout = timeout
|
137
|
+
http.read_timeout = (timeout || nsc.timeout)
|
138
|
+
http.open_timeout = nsc.open_timeout
|
137
139
|
http.use_ssl = true
|
138
140
|
if nsc.trust_store.nil?
|
139
141
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
@@ -183,8 +185,8 @@ module Nexpose
|
|
183
185
|
def get_request_api_version(request)
|
184
186
|
matches = request.path.match(API_PATTERN)
|
185
187
|
matches[:version].to_f
|
186
|
-
|
187
|
-
|
188
|
+
rescue
|
189
|
+
0.0
|
188
190
|
end
|
189
191
|
|
190
192
|
# Get an error message from the response body if the request url api version
|
@@ -192,7 +194,7 @@ module Nexpose
|
|
192
194
|
def get_error_message(request, response)
|
193
195
|
version = get_request_api_version(request)
|
194
196
|
data_request = use_response_error_message?(request, response)
|
195
|
-
return_response = (version >= 2.1 || data_request
|
197
|
+
return_response = (version >= 2.1 || data_request)
|
196
198
|
(return_response && response.body) ? "response body: #{response.body}" : "request body: #{request.body}"
|
197
199
|
end
|
198
200
|
|
@@ -202,7 +204,7 @@ module Nexpose
|
|
202
204
|
if (request.path.include?('/data/') && !response.content_type.nil?)
|
203
205
|
response.content_type.include? 'text/plain'
|
204
206
|
else
|
205
|
-
|
207
|
+
false
|
206
208
|
end
|
207
209
|
end
|
208
210
|
|
@@ -253,7 +255,7 @@ module Nexpose
|
|
253
255
|
pref_key = "#{pref}.rows"
|
254
256
|
resp = get(nsc, uri)
|
255
257
|
json = JSON.parse(resp)
|
256
|
-
if json.
|
258
|
+
if json.key?(pref_key)
|
257
259
|
rows = json[pref_key].to_i
|
258
260
|
rows > 0 ? rows : 10
|
259
261
|
else
|
data/lib/nexpose/api_request.rb
CHANGED
@@ -42,17 +42,16 @@ module Nexpose
|
|
42
42
|
else
|
43
43
|
@http.cert_store = @trust_store
|
44
44
|
end
|
45
|
-
@headers = {'Content-Type' => 'text/xml'}
|
45
|
+
@headers = { 'Content-Type' => 'text/xml' }
|
46
46
|
@success = false
|
47
47
|
end
|
48
48
|
|
49
49
|
def execute(options = {})
|
50
50
|
@conn_tries = 0
|
51
|
-
|
52
51
|
begin
|
53
52
|
prepare_http_client
|
54
|
-
@http.read_timeout = options
|
55
|
-
@http.open_timeout = options.key?(:open_timeout) ? options[:open_timeout] :
|
53
|
+
@http.read_timeout = options.key?(:timeout) ? options[:timeout] : 120
|
54
|
+
@http.open_timeout = options.key?(:open_timeout) ? options[:open_timeout] : 120
|
56
55
|
@raw_response = @http.post(@uri.path, @req, @headers)
|
57
56
|
@raw_response_data = @raw_response.read_body
|
58
57
|
|
@@ -62,7 +61,7 @@ module Nexpose
|
|
62
61
|
@success = true
|
63
62
|
else
|
64
63
|
@success = false
|
65
|
-
@error =
|
64
|
+
@error = 'User requested raw XML response. Not parsing failures.'
|
66
65
|
end
|
67
66
|
else
|
68
67
|
@res = parse_xml(@raw_response_data)
|
@@ -74,19 +73,19 @@ module Nexpose
|
|
74
73
|
|
75
74
|
@sid = attributes['session-id']
|
76
75
|
|
77
|
-
if (attributes['success']
|
76
|
+
if (attributes['success'] && attributes['success'].to_i == 1)
|
78
77
|
@success = true
|
79
|
-
elsif @api_version =~ /1.2/
|
78
|
+
elsif @api_version =~ /1.2/ && @res && (@res.get_elements '//Exception').count < 1
|
80
79
|
@success = true
|
81
80
|
else
|
82
81
|
@success = false
|
83
82
|
if @api_version =~ /1.2/
|
84
83
|
@res.elements.each('//Exception/Message') do |message|
|
85
|
-
|
84
|
+
@error = message.text.sub(/.*Exception: */, '')
|
85
|
+
end
|
86
|
+
@res.elements.each('//Exception/Stacktrace') do |stacktrace|
|
87
|
+
@trace = stacktrace.text
|
86
88
|
end
|
87
|
-
@res.elements.each('//Exception/Stacktrace') do |stacktrace|
|
88
|
-
@trace = stacktrace.text
|
89
|
-
end
|
90
89
|
else
|
91
90
|
@res.elements.each('//message') do |message|
|
92
91
|
@error = message.text.sub(/.*Exception: */, '')
|
@@ -97,27 +96,29 @@ module Nexpose
|
|
97
96
|
end
|
98
97
|
end
|
99
98
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
rescue OpenSSL::SSL::SSLError =>
|
99
|
+
# This is a hack to handle corner cases where a heavily loaded Nexpose instance
|
100
|
+
# drops our HTTP connection before processing. We try 5 times to establish a
|
101
|
+
# connection in these situations. The actual exception occurs in the Ruby
|
102
|
+
# http library, which is why we use such generic error classes.
|
103
|
+
rescue OpenSSL::SSL::SSLError => error
|
105
104
|
if @conn_tries < 5
|
106
105
|
@conn_tries += 1
|
106
|
+
$stderr.puts "\n\nRetrying the request due to #{error}. If you see this message please open an Issue on Github with the error.\n\n"
|
107
107
|
retry
|
108
108
|
end
|
109
|
-
rescue ::ArgumentError, ::NoMethodError =>
|
109
|
+
rescue ::ArgumentError, ::NoMethodError => error
|
110
110
|
if @conn_tries < 5
|
111
111
|
@conn_tries += 1
|
112
|
+
$stderr.puts "\n\nRetrying the request due to #{error}. If you see this message please open an Issue on Github with the error.\n\n"
|
112
113
|
retry
|
113
114
|
end
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
@error = "Nexpose did not respond within #{@http.read_timeout} seconds."
|
115
|
+
### HTTP Specific Timeout Errors.
|
116
|
+
rescue ::Net::ReadTimeout, ::Net::OpenTimeout => error
|
117
|
+
timeout_value = error.instance_of?(Net::ReadTimeout) ? @http.read_timeout : @http.open_timeout
|
118
|
+
@error = "Nexpose did not respond within #{timeout_value} seconds #{error}. Reference the Wiki for information on setting the different Timeout values."
|
119
|
+
### Catch all Timeout Error.
|
120
|
+
rescue ::Timeout::Error => error
|
121
|
+
@error = "Nexpose did not respond within #{@http.read_timeout} seconds #{error}. Reference the Wiki for information on setting the different Timeout values."
|
121
122
|
rescue ::Errno::EHOSTUNREACH, ::Errno::ENETDOWN, ::Errno::ENETUNREACH, ::Errno::ENETRESET, ::Errno::EHOSTDOWN, ::Errno::EACCES, ::Errno::EINVAL, ::Errno::EADDRNOTAVAIL
|
122
123
|
@error = 'Nexpose host is unreachable.'
|
123
124
|
# Handle console-level interrupts
|
@@ -129,7 +130,7 @@ module Nexpose
|
|
129
130
|
@error = "Error parsing response: #{exc.message}"
|
130
131
|
end
|
131
132
|
|
132
|
-
if !(@success
|
133
|
+
if !(@success || @error)
|
133
134
|
@error = "Nexpose service returned an unrecognized response: #{@raw_response_data.inspect}"
|
134
135
|
end
|
135
136
|
|
@@ -137,7 +138,7 @@ module Nexpose
|
|
137
138
|
end
|
138
139
|
|
139
140
|
def attributes(*args)
|
140
|
-
return
|
141
|
+
return unless @res.root
|
141
142
|
@res.root.attributes(*args)
|
142
143
|
end
|
143
144
|
|
data/lib/nexpose/connection.rb
CHANGED
@@ -51,14 +51,20 @@ module Nexpose
|
|
51
51
|
attr_reader :url
|
52
52
|
# The token used to login to the NSC
|
53
53
|
attr_reader :token
|
54
|
-
|
55
54
|
# The last XML request sent by this object, useful for debugging.
|
56
55
|
attr_reader :request_xml
|
57
56
|
# The last XML response received by this object, useful for debugging.
|
58
57
|
attr_reader :response_xml
|
59
|
-
|
60
58
|
# The trust store to validate connections against if any
|
61
59
|
attr_reader :trust_store
|
60
|
+
# The main HTTP read_timeout value
|
61
|
+
# For more information visit the link below:
|
62
|
+
# https://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#read_timeout-attribute-method
|
63
|
+
attr_accessor :timeout
|
64
|
+
# The optional HTTP open_timeout value
|
65
|
+
# For more information visit the link below:
|
66
|
+
# http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#open_timeout-attribute-method
|
67
|
+
attr_accessor :open_timeout
|
62
68
|
|
63
69
|
# A constructor to load a Connection object from a URI
|
64
70
|
def self.from_uri(uri, user, pass, silo_id = nil, token = nil, trust_cert = nil)
|
@@ -76,23 +82,23 @@ module Nexpose
|
|
76
82
|
# @param [String] token The two-factor authentication (2FA) token for Nexpose sessions.
|
77
83
|
# @param [String] trust_cert The PEM-formatted web certificate of the Nexpose console. Used for SSL validation.
|
78
84
|
def initialize(ip, user, pass, port = 3780, silo_id = nil, token = nil, trust_cert = nil)
|
79
|
-
@host
|
80
|
-
@
|
81
|
-
@
|
82
|
-
@
|
83
|
-
@
|
84
|
-
@
|
85
|
-
unless trust_cert.nil?
|
86
|
-
|
87
|
-
|
88
|
-
@
|
89
|
-
@
|
85
|
+
@host = ip
|
86
|
+
@username = user
|
87
|
+
@password = pass
|
88
|
+
@port = port
|
89
|
+
@silo_id = silo_id
|
90
|
+
@token = token
|
91
|
+
@trust_store = create_trust_store(trust_cert) unless trust_cert.nil?
|
92
|
+
@session_id = nil
|
93
|
+
@url = "https://#{@host}:#{@port}/api/API_VERSION/xml"
|
94
|
+
@timeout = 120
|
95
|
+
@open_timeout = 120
|
90
96
|
end
|
91
97
|
|
92
98
|
# Establish a new connection and Session ID
|
93
99
|
def login
|
94
100
|
begin
|
95
|
-
login_hash = {'sync-id' => 0, 'password' => @password, 'user-id' => @username, 'token' => @token}
|
101
|
+
login_hash = { 'sync-id' => 0, 'password' => @password, 'user-id' => @username, 'token' => @token }
|
96
102
|
login_hash['silo-id'] = @silo_id if @silo_id
|
97
103
|
r = execute(make_xml('LoginRequest', login_hash))
|
98
104
|
if r.success
|
@@ -106,13 +112,15 @@ module Nexpose
|
|
106
112
|
|
107
113
|
# Logout of the current connection
|
108
114
|
def logout
|
109
|
-
r = execute(make_xml('LogoutRequest', {'sync-id' => 0}))
|
115
|
+
r = execute(make_xml('LogoutRequest', { 'sync-id' => 0 }))
|
110
116
|
return true if r.success
|
111
117
|
raise APIError.new(r, 'Logout failed')
|
112
118
|
end
|
113
119
|
|
114
120
|
# Execute an API request
|
115
121
|
def execute(xml, version = '1.1', options = {})
|
122
|
+
options.store(:timeout, @timeout) unless options.key?(:timeout)
|
123
|
+
options.store(:open_timeout, @open_timeout)
|
116
124
|
@request_xml = xml.to_s
|
117
125
|
@api_version = version
|
118
126
|
response = APIRequest.execute(@url, @request_xml, @api_version, options, @trust_store)
|
@@ -127,17 +135,17 @@ module Nexpose
|
|
127
135
|
# Would need to do something more sophisticated to grab
|
128
136
|
# all the associated image files.
|
129
137
|
def download(url, file_name = nil)
|
130
|
-
return nil if url.nil?
|
131
|
-
uri
|
132
|
-
http
|
138
|
+
return nil if (url.nil? || url.empty?)
|
139
|
+
uri = URI.parse(url)
|
140
|
+
http = Net::HTTP.new(@host, @port)
|
133
141
|
http.use_ssl = true
|
134
142
|
if @trust_store.nil?
|
135
143
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # XXX: security issue
|
136
144
|
else
|
137
145
|
http.cert_store = @trust_store
|
138
146
|
end
|
139
|
-
headers = {'Cookie' => "nexposeCCSessionID=#{@session_id}"}
|
140
|
-
resp
|
147
|
+
headers = { 'Cookie' => "nexposeCCSessionID=#{@session_id}" }
|
148
|
+
resp = http.get(uri.to_s, headers)
|
141
149
|
|
142
150
|
if file_name
|
143
151
|
::File.open(file_name, 'wb') { |file| file.write(resp.body) }
|