1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
require 'spec_helper'
require 'puppet_spec/https'
require 'puppet_spec/files'
require 'puppet/network/http_pool'
describe Puppet::Network::HttpPool do
include PuppetSpec::Files
before :all do
WebMock.disable!
end
after :all do
WebMock.enable!
end
before :each do
# make sure we don't take too long
Puppet[:http_connect_timeout] = '5s'
end
let(:hostname) { '127.0.0.1' }
let(:wrong_hostname) { 'localhost' }
let(:server) { PuppetSpec::HTTPSServer.new }
context "when calling deprecated HttpPool methods" do
let(:ssl_host) {
# use server's cert/key as the client cert/key
host = Puppet::SSL::Host.new
host.key = Puppet::SSL::Key.from_instance(server.server_key, host.name)
host.certificate = Puppet::SSL::Certificate.from_instance(server.server_cert, host.name)
host
}
before(:each) do
ssldir = tmpdir('http_pool')
Puppet[:ssldir] = ssldir
Puppet.settings.use(:main, :ssl)
File.write(Puppet[:localcacert], server.ca_cert.to_pem)
File.write(Puppet[:hostcrl], server.ca_crl.to_pem)
File.write(Puppet[:hostcert], server.server_cert.to_pem)
File.write(Puppet[:hostprivkey], server.server_key.to_pem)
end
# Can't use `around(:each)` because it will cause ssl_host to be
# created outside of any rspec example, and $confdir won't be set
before(:each) do
Puppet.push_context(ssl_host: ssl_host)
end
after (:each) do
Puppet.pop_context
end
def connection(host, port)
Puppet::Network::HttpPool.http_instance(host, port, use_ssl: true)
end
shared_examples_for 'HTTPS client' do
it "connects over SSL" do
server.start_server do |port|
http = connection(hostname, port)
res = http.get('/')
expect(res.code).to eq('200')
end
end
it "raises if the server's cert doesn't match the hostname we connected to" do
server.start_server do |port|
http = connection(wrong_hostname, port)
expect {
http.get('/')
}.to raise_error { |err|
expect(err).to be_instance_of(Puppet::Error)
expect(err.message).to match(/\AServer hostname '#{wrong_hostname}' did not match server certificate; expected one of (.+)/)
md = err.message.match(/expected one of (.+)/)
expect(md[1].split(', ')).to contain_exactly('127.0.0.1', 'DNS:127.0.0.1', 'DNS:127.0.0.2')
}
end
end
it "raises if the server's CA is unknown" do
# File must exist and by not empty so DefaultValidator doesn't
# downgrade to VERIFY_NONE, so use a different CA that didn't
# issue the server's cert
capath = tmpfile('empty')
File.write(capath, PuppetSpec::HTTPSServer::UNKNOWN_CA)
Puppet[:localcacert] = capath
Puppet[:certificate_revocation] = false
server.start_server do |port|
http = connection(hostname, port)
expect {
http.get('/')
}.to raise_error(Puppet::Error,
%r{certificate verify failed.* .self signed certificate in certificate chain for /CN=Test CA.})
end
end
end
context "when using single use HTTPS connections" do
include_examples 'HTTPS client'
end
context "when using persistent HTTPS connections" do
around :each do |example|
pool = Puppet::Network::HTTP::Pool.new
Puppet.override(:http_pool => pool) do
example.run
end
pool.close
end
include_examples 'HTTPS client'
end
end
end
|