mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Fail hard if SSL certs or keys cannot be read by user (#2847)
* Fail hard if SSL certs or keys cannot be read by user Previously if an SSL cert or key could not be read, Puma would bind to the configured SSL port but not accept any connections. The only indication that something went awry is an obscure log message: ``` #<Puma::MiniSSL::SSLError: OpenSSL error: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher - 193> ``` We now fail hard with an exception if this happens to make it clear that the permissions need to be fixed. Relates to https://github.com/puma/puma/issues/1339 * minissl.rb - add check_file method Co-authored-by: MSP-Greg <Greg.mpls@gmail.com>
This commit is contained in:
parent
f7cad9816e
commit
f4fb51deb7
2 changed files with 56 additions and 7 deletions
|
@ -214,6 +214,11 @@ module Puma
|
||||||
@cert_pem = nil
|
@cert_pem = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_file(file, desc)
|
||||||
|
raise ArgumentError, "#{desc} file '#{file}' does not exist" unless File.exist? file
|
||||||
|
raise ArgumentError, "#{desc} file '#{file}' is not readable" unless File.readable? file
|
||||||
|
end
|
||||||
|
|
||||||
if IS_JRUBY
|
if IS_JRUBY
|
||||||
# jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair
|
# jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair
|
||||||
attr_reader :keystore
|
attr_reader :keystore
|
||||||
|
@ -221,7 +226,7 @@ module Puma
|
||||||
attr_accessor :ssl_cipher_list
|
attr_accessor :ssl_cipher_list
|
||||||
|
|
||||||
def keystore=(keystore)
|
def keystore=(keystore)
|
||||||
raise ArgumentError, "No such keystore file '#{keystore}'" unless File.exist? keystore
|
check_file keystore, 'Keystore'
|
||||||
@keystore = keystore
|
@keystore = keystore
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -240,17 +245,17 @@ module Puma
|
||||||
attr_accessor :verification_flags
|
attr_accessor :verification_flags
|
||||||
|
|
||||||
def key=(key)
|
def key=(key)
|
||||||
raise ArgumentError, "No such key file '#{key}'" unless File.exist? key
|
check_file key, 'Key'
|
||||||
@key = key
|
@key = key
|
||||||
end
|
end
|
||||||
|
|
||||||
def cert=(cert)
|
def cert=(cert)
|
||||||
raise ArgumentError, "No such cert file '#{cert}'" unless File.exist? cert
|
check_file cert, 'Cert'
|
||||||
@cert = cert
|
@cert = cert
|
||||||
end
|
end
|
||||||
|
|
||||||
def ca=(ca)
|
def ca=(ca)
|
||||||
raise ArgumentError, "No such ca file '#{ca}'" unless File.exist? ca
|
check_file ca, 'ca'
|
||||||
@ca = ca
|
@ca = ca
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,21 +9,54 @@ class TestMiniSSL < Minitest::Test
|
||||||
ctx = Puma::MiniSSL::Context.new
|
ctx = Puma::MiniSSL::Context.new
|
||||||
|
|
||||||
exception = assert_raises(ArgumentError) { ctx.keystore = "/no/such/keystore" }
|
exception = assert_raises(ArgumentError) { ctx.keystore = "/no/such/keystore" }
|
||||||
assert_equal("No such keystore file '/no/such/keystore'", exception.message)
|
assert_equal("Keystore file '/no/such/keystore' does not exist", exception.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_raises_with_unreadable_keystore_file
|
||||||
|
ctx = Puma::MiniSSL::Context.new
|
||||||
|
|
||||||
|
File.stub(:exist?, true) do
|
||||||
|
File.stub(:readable?, false) do
|
||||||
|
exception = assert_raises(ArgumentError) { ctx.keystore = "/unreadable/keystore" }
|
||||||
|
assert_equal("Keystore file '/unreadable/keystore' is not readable", exception.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
def test_raises_with_invalid_key_file
|
def test_raises_with_invalid_key_file
|
||||||
ctx = Puma::MiniSSL::Context.new
|
ctx = Puma::MiniSSL::Context.new
|
||||||
|
|
||||||
exception = assert_raises(ArgumentError) { ctx.key = "/no/such/key" }
|
exception = assert_raises(ArgumentError) { ctx.key = "/no/such/key" }
|
||||||
assert_equal("No such key file '/no/such/key'", exception.message)
|
assert_equal("Key file '/no/such/key' does not exist", exception.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_raises_with_unreadable_key_file
|
||||||
|
ctx = Puma::MiniSSL::Context.new
|
||||||
|
|
||||||
|
File.stub(:exist?, true) do
|
||||||
|
File.stub(:readable?, false) do
|
||||||
|
exception = assert_raises(ArgumentError) { ctx.key = "/unreadable/key" }
|
||||||
|
assert_equal("Key file '/unreadable/key' is not readable", exception.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_raises_with_invalid_cert_file
|
def test_raises_with_invalid_cert_file
|
||||||
ctx = Puma::MiniSSL::Context.new
|
ctx = Puma::MiniSSL::Context.new
|
||||||
|
|
||||||
exception = assert_raises(ArgumentError) { ctx.cert = "/no/such/cert" }
|
exception = assert_raises(ArgumentError) { ctx.cert = "/no/such/cert" }
|
||||||
assert_equal("No such cert file '/no/such/cert'", exception.message)
|
assert_equal("Cert file '/no/such/cert' does not exist", exception.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_raises_with_unreadable_cert_file
|
||||||
|
ctx = Puma::MiniSSL::Context.new
|
||||||
|
|
||||||
|
File.stub(:exist?, true) do
|
||||||
|
File.stub(:readable?, false) do
|
||||||
|
exception = assert_raises(ArgumentError) { ctx.key = "/unreadable/cert" }
|
||||||
|
assert_equal("Key file '/unreadable/cert' is not readable", exception.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_raises_with_invalid_key_pem
|
def test_raises_with_invalid_key_pem
|
||||||
|
@ -33,6 +66,17 @@ class TestMiniSSL < Minitest::Test
|
||||||
assert_equal("'key_pem' is not a String", exception.message)
|
assert_equal("'key_pem' is not a String", exception.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_raises_with_unreadable_ca_file
|
||||||
|
ctx = Puma::MiniSSL::Context.new
|
||||||
|
|
||||||
|
File.stub(:exist?, true) do
|
||||||
|
File.stub(:readable?, false) do
|
||||||
|
exception = assert_raises(ArgumentError) { ctx.ca = "/unreadable/cert" }
|
||||||
|
assert_equal("ca file '/unreadable/cert' is not readable", exception.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_raises_with_invalid_cert_pem
|
def test_raises_with_invalid_cert_pem
|
||||||
ctx = Puma::MiniSSL::Context.new
|
ctx = Puma::MiniSSL::Context.new
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue