mirror of
https://github.com/rest-client/rest-client.git
synced 2022-11-09 13:49:40 -05:00
Merge pull request #277 from ab/ab-ssl-verify-callback
Expose verify_callback to users
This commit is contained in:
commit
e7592a65e3
4 changed files with 122 additions and 6 deletions
|
@ -17,5 +17,14 @@ module RestClient
|
|||
# library uses that to test what platform it's on.
|
||||
!!File::ALT_SEPARATOR
|
||||
end
|
||||
|
||||
# Return true if we are running on jruby.
|
||||
#
|
||||
# @return [Boolean]
|
||||
#
|
||||
def self.jruby?
|
||||
# defined on mri >= 1.9
|
||||
RUBY_ENGINE == 'jruby'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ module RestClient
|
|||
# * :timeout and :open_timeout are how long to wait for a response and to
|
||||
# open a connection, in seconds. Pass nil to disable the timeout.
|
||||
# * :ssl_client_cert, :ssl_client_key, :ssl_ca_file, :ssl_ca_path,
|
||||
# :ssl_cert_store
|
||||
# :ssl_cert_store, :ssl_verify_callback, :ssl_verify_callback_warnings
|
||||
# * :ssl_version specifies the SSL version for the underlying Net::HTTP connection
|
||||
# * :ssl_ciphers sets SSL ciphers for the connection. See
|
||||
# OpenSSL::SSL::SSLContext#ciphers=
|
||||
|
@ -100,7 +100,7 @@ module RestClient
|
|||
])
|
||||
|
||||
SSLOptionList = %w{client_cert client_key ca_file ca_path cert_store
|
||||
version ciphers}
|
||||
version ciphers verify_callback verify_callback_warnings}
|
||||
|
||||
def initialize args
|
||||
@method = args[:method] or raise ArgumentError, "must pass :method"
|
||||
|
@ -327,6 +327,20 @@ module RestClient
|
|||
cert_store
|
||||
end
|
||||
|
||||
def print_verify_callback_warnings
|
||||
warned = false
|
||||
if RestClient::Platform.mac?
|
||||
warn('warning: ssl_verify_callback return code is ignored on OS X')
|
||||
warned = true
|
||||
end
|
||||
if RestClient::Platform.jruby?
|
||||
warn('warning: SSL verify_callback may not work correctly in jruby')
|
||||
warn('see https://github.com/jruby/jruby/issues/597')
|
||||
warned = true
|
||||
end
|
||||
warned
|
||||
end
|
||||
|
||||
def transmit uri, req, payload, & block
|
||||
setup_credentials req
|
||||
|
||||
|
@ -335,8 +349,6 @@ module RestClient
|
|||
net.ssl_version = ssl_version if ssl_version
|
||||
net.ciphers = ssl_ciphers if ssl_ciphers
|
||||
|
||||
# we no longer set net.verify_callback because it's not well supported on
|
||||
# all platforms (see comments below)
|
||||
net.verify_mode = verify_ssl
|
||||
|
||||
net.cert = ssl_client_cert if ssl_client_cert
|
||||
|
@ -345,6 +357,26 @@ module RestClient
|
|||
net.ca_path = ssl_ca_path if ssl_ca_path
|
||||
net.cert_store = ssl_cert_store if ssl_cert_store
|
||||
|
||||
# We no longer rely on net.verify_callback for the main SSL verification
|
||||
# because it's not well supported on all platforms (see comments below).
|
||||
# But do allow users to set one if they want.
|
||||
if ssl_verify_callback
|
||||
net.verify_callback = ssl_verify_callback
|
||||
|
||||
# Hilariously, jruby only calls the callback when cert_store is set to
|
||||
# something, so make sure to set one.
|
||||
# https://github.com/jruby/jruby/issues/597
|
||||
if RestClient::Platform.jruby?
|
||||
net.cert_store ||= OpenSSL::X509::Store.new
|
||||
end
|
||||
|
||||
if ssl_verify_callback_warnings != false
|
||||
if print_verify_callback_warnings
|
||||
warn('pass :ssl_verify_callback_warnings => false to silence this')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE
|
||||
warn('WARNING: OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE')
|
||||
warn('This dangerous monkey patch leaves you open to MITM attacks!')
|
||||
|
|
|
@ -37,7 +37,7 @@ describe RestClient::Request do
|
|||
it "is unsuccessful with an incorrect ca_file", :unless => RestClient::Platform.mac? do
|
||||
request = RestClient::Request.new(
|
||||
:method => :get,
|
||||
:url => 'https://www.mozilla.com',
|
||||
:url => 'https://www.mozilla.org',
|
||||
:ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt")
|
||||
)
|
||||
expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
|
||||
|
@ -48,7 +48,7 @@ describe RestClient::Request do
|
|||
it "is unsuccessful with an incorrect ca_path", :unless => RestClient::Platform.mac? do
|
||||
request = RestClient::Request.new(
|
||||
:method => :get,
|
||||
:url => 'https://www.mozilla.com',
|
||||
:url => 'https://www.mozilla.org',
|
||||
:ssl_ca_path => File.join(File.dirname(__FILE__), "capath_verisign")
|
||||
)
|
||||
expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
|
||||
|
@ -62,5 +62,43 @@ describe RestClient::Request do
|
|||
)
|
||||
expect {request.execute }.to_not raise_error
|
||||
end
|
||||
|
||||
it "executes the verify_callack" do
|
||||
ran_callback = false
|
||||
request = RestClient::Request.new(
|
||||
:method => :get,
|
||||
:url => 'https://www.mozilla.org',
|
||||
:verify_ssl => true,
|
||||
:ssl_verify_callback => lambda { |preverify_ok, store_ctx|
|
||||
ran_callback = true
|
||||
preverify_ok
|
||||
},
|
||||
)
|
||||
expect {request.execute }.to_not raise_error
|
||||
ran_callback.should eq(true)
|
||||
end
|
||||
|
||||
it "fails verification when the callback returns false",
|
||||
:unless => RestClient::Platform.mac? do
|
||||
request = RestClient::Request.new(
|
||||
:method => :get,
|
||||
:url => 'https://www.mozilla.org',
|
||||
:verify_ssl => true,
|
||||
:ssl_verify_callback => lambda { |preverify_ok, store_ctx| false },
|
||||
)
|
||||
expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
|
||||
end
|
||||
|
||||
it "succeeds verification when the callback returns true",
|
||||
:unless => RestClient::Platform.mac? do
|
||||
request = RestClient::Request.new(
|
||||
:method => :get,
|
||||
:url => 'https://www.mozilla.org',
|
||||
:verify_ssl => true,
|
||||
:ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt"),
|
||||
:ssl_verify_callback => lambda { |preverify_ok, store_ctx| true },
|
||||
)
|
||||
expect { request.execute }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -834,6 +834,43 @@ describe RestClient::Request do
|
|||
@request.stub(:response_log)
|
||||
@request.transmit(@uri, 'req', 'payload')
|
||||
end
|
||||
|
||||
it "should not set the ssl_verify_callback by default" do
|
||||
@request = RestClient::Request.new(
|
||||
:method => :put,
|
||||
:url => 'https://some/resource',
|
||||
:payload => 'payload',
|
||||
)
|
||||
@net.should_not_receive(:verify_callback=)
|
||||
@http.stub(:request)
|
||||
@request.stub(:process_result)
|
||||
@request.stub(:response_log)
|
||||
@request.transmit(@uri, 'req', 'payload')
|
||||
end
|
||||
|
||||
it "should set the ssl_verify_callback if passed" do
|
||||
callback = lambda {}
|
||||
@request = RestClient::Request.new(
|
||||
:method => :put,
|
||||
:url => 'https://some/resource',
|
||||
:payload => 'payload',
|
||||
:ssl_verify_callback => callback,
|
||||
)
|
||||
@net.should_receive(:verify_callback=).with(callback)
|
||||
|
||||
# we'll read cert_store on jruby
|
||||
# https://github.com/jruby/jruby/issues/597
|
||||
if RestClient::Platform.jruby?
|
||||
allow(@net).to receive(:cert_store)
|
||||
end
|
||||
|
||||
@http.stub(:request)
|
||||
@request.stub(:process_result)
|
||||
@request.stub(:response_log)
|
||||
@request.transmit(@uri, 'req', 'payload')
|
||||
end
|
||||
|
||||
# </ssl>
|
||||
end
|
||||
|
||||
it "should still return a response object for 204 No Content responses" do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue