Skip to content

Commit

Permalink
Add min/max_version for supporting adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
mrpasquini committed Jul 7, 2020
1 parent 2fbd6b1 commit 260d8d2
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/httpi/adapter/curb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ def setup_ssl_auth
when :SSLv23 then 2
when :SSLv3 then 3
end
if ssl.min_version || ssl.max_version
raise NotImplementedError, "Method Not Implemented"
end
end

def respond_with(client)
Expand Down
2 changes: 2 additions & 0 deletions lib/httpi/adapter/excon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def client_opts
end

opts[:ssl_version] = ssl.ssl_version if ssl.ssl_version
opts[:ssl_min_version] = ssl.min_version if ssl.min_version
opts[:ssl_max_version] = ssl.max_version if ssl.max_version

opts
end
Expand Down
2 changes: 2 additions & 0 deletions lib/httpi/adapter/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def create_client
context.cert = @request.auth.ssl.cert
context.key = @request.auth.ssl.cert_key
context.ssl_version = @request.auth.ssl.ssl_version if @request.auth.ssl.ssl_version != nil
context.min_version = @request.auth.ssl.min_version if @request.auth.ssl.min_version != nil
context.max_version = @request.auth.ssl.max_version if @request.auth.ssl.max_version != nil
context.verify_mode = @request.auth.ssl.openssl_verify_mode

client = ::HTTP::Client.new(:ssl_context => context)
Expand Down
3 changes: 3 additions & 0 deletions lib/httpi/adapter/httpclient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ def setup_ssl_auth
end

@client.ssl_config.ssl_version = ssl.ssl_version.to_s if ssl.ssl_version
if ssl.min_version || ssl.max_version
raise NotImplementedError, "Method Not Implemented"
end
end

def respond_with(response)
Expand Down
2 changes: 2 additions & 0 deletions lib/httpi/adapter/net_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ def setup_ssl_auth
end

@client.ssl_version = ssl.ssl_version if ssl.ssl_version
@client.min_version = ssl.min_version if ssl.min_version
@client.max_version = ssl.max_version if ssl.max_version
end

def ssl_cert_store(ssl)
Expand Down
33 changes: 33 additions & 0 deletions lib/httpi/auth/ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class SSL
ssl_context::METHODS.reject { |method| method.match(/server|client/) }
end.sort.reverse

# Returns OpenSSL::SSL::*_VERSION values for min_version and max_version
MIN_MAX_VERSIONS = OpenSSL::SSL.constants.select{|constant| constant =~/_VERSION$/}.map{|version| version[0..-9].to_sym}.reverse

# Returns whether SSL configuration is present.
def present?
(verify_mode == :none) || (cert && cert_key) || ca_cert_file
Expand Down Expand Up @@ -90,6 +93,36 @@ def ssl_version=(version)
@ssl_version = version
end

# Returns the SSL min_version number. Defaults to <tt>nil</tt> (auto-negotiate).
def min_version
@min_version ||= nil
end

# Sets the SSL min_version number. Expects one of <tt>HTTPI::Auth::SSL::SSL_VERSIONS</tt>.
def min_version=(version)
unless MIN_MAX_VERSIONS.include? version
raise ArgumentError, "Invalid SSL min_version #{version.inspect}\n" +
"Please specify one of #{MIN_MAX_VERSIONS.inspect}"
end

@min_version = version
end

# Returns the SSL min_version number. Defaults to <tt>nil</tt> (auto-negotiate).
def max_version
@max_version ||= nil
end

# Sets the SSL min_version number. Expects one of <tt>HTTPI::Auth::SSL::SSL_VERSIONS</tt>.
def max_version=(version)
unless MIN_MAX_VERSIONS.include? version
raise ArgumentError, "Invalid SSL max_version #{version.inspect}\n" +
"Please specify one of #{MIN_MAX_VERSIONS.inspect}"
end

@max_version = version
end

# Returns an <tt>OpenSSL::X509::Certificate</tt> for the +cert_file+.
def cert
@cert ||= (OpenSSL::X509::Certificate.new File.read(cert_file) if cert_file)
Expand Down
10 changes: 10 additions & 0 deletions spec/httpi/adapter/curb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,16 @@
adapter.request(:get)
end
end
it 'raises error when min_version not nil' do
request.auth.ssl.min_version = :TLS1_2
expect{ adapter.request(:get) }.
to raise_error(HTTPI::NotImplementedError, 'Method Not Implemented')
end
it 'raises error when max_version not nil' do
request.auth.ssl.max_version = :TLS1_2
expect{ adapter.request(:get) }.
to raise_error(HTTPI::NotImplementedError, 'Method Not Implemented')
end
end

context "(for SSL client auth)" do
Expand Down
11 changes: 11 additions & 0 deletions spec/httpi/adapter/httpclient_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,17 @@

adapter.request(:get)
end

it 'raises error when min_version not nil' do
request.auth.ssl.min_version = :TLS1_2
expect{ adapter.request(:get) }.
to raise_error(HTTPI::NotImplementedError, 'Method Not Implemented')
end
it 'raises error when max_version not nil' do
request.auth.ssl.max_version = :TLS1_2
expect{ adapter.request(:get) }.
to raise_error(HTTPI::NotImplementedError, 'Method Not Implemented')
end
end

context "(for SSL client auth with a verify mode of :none with no certs provided)" do
Expand Down
31 changes: 31 additions & 0 deletions spec/httpi/auth/ssl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
describe HTTPI::Auth::SSL do
before(:all) do
@ssl_versions = HTTPI::Auth::SSL::SSL_VERSIONS
@min_max_versions = HTTPI::Auth::SSL::MIN_MAX_VERSIONS
end

describe "VERIFY_MODES" do
Expand Down Expand Up @@ -158,6 +159,36 @@
end
end

describe "#min_version" do
subject { HTTPI::Auth::SSL.new }

it "returns the min_version" do
subject.min_version = @min_max_versions.first
expect(subject.min_version).to eq(@min_max_versions.first)
end

it 'raises ArgumentError if the version is unsupported' do
expect { ssl.min_version = :ssl_fail }.
to raise_error(ArgumentError, "Invalid SSL min_version :ssl_fail\n" +
"Please specify one of #{@min_max_versions}")
end
end

describe "#max_version" do
subject { HTTPI::Auth::SSL.new }

it "returns the SSL version" do
subject.max_version = @min_max_versions.first
expect(subject.max_version).to eq(@min_max_versions.first)
end

it 'raises ArgumentError if the version is unsupported' do
expect { ssl.max_version = :ssl_fail }.
to raise_error(ArgumentError, "Invalid SSL max_version :ssl_fail\n" +
"Please specify one of #{@min_max_versions}")
end
end

def ssl
ssl = HTTPI::Auth::SSL.new
ssl.cert_key_file = "spec/fixtures/client_key.pem"
Expand Down
10 changes: 10 additions & 0 deletions spec/integration/excon_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@
expect(response.body).to eq("get")
end

it "works with min_version/max_version" do
request = HTTPI::Request.new(@server.url)
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
request.auth.ssl.min_version = "TLS1_2"
request.auth.ssl.max_version = "TLS1_2"

response = HTTPI.get(request, adapter)
expect(response.body).to eq("get")
end

it "works with client cert and key provided as file path" do
request = HTTPI::Request.new(@server.url)
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
Expand Down
10 changes: 10 additions & 0 deletions spec/integration/http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@
response = HTTPI.get(request, adapter)
expect(response.body).to eq("get")
end

it "works with min_version/max_version" do
request = HTTPI::Request.new(@server.url)
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
request.auth.ssl.min_version = "TLS1_2"
request.auth.ssl.max_version = "TLS1_2"

response = HTTPI.get(request, adapter)
expect(response.body).to eq("get")
end
end
end

Expand Down
10 changes: 10 additions & 0 deletions spec/integration/net_http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,16 @@
response = HTTPI.get(request, adapter)
expect(response.body).to eq("get")
end

it "works with min_version/max_version" do
request = HTTPI::Request.new(@server.url)
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
request.auth.ssl.min_version = "TLS1_2"
request.auth.ssl.max_version = "TLS1_2"

response = HTTPI.get(request, adapter)
expect(response.body).to eq("get")
end
end
end

Expand Down

0 comments on commit 260d8d2

Please sign in to comment.