def secure(options=nil)
return if secured?
defaults = {
:timeout => nil,
:ciphers => FTW::Agent::Configuration::SSL_CIPHER_MAP["MOZILLA_MODERN"],
:ssl_version => "TLSv1.1"
}
settings = defaults.merge(options) unless options.nil?
@logger.info("Securing this connection", :peer => peer, :options => settings)
sslcontext = OpenSSL::SSL::SSLContext.new
sslcontext.verify_mode = OpenSSL::SSL::VERIFY_PEER
ssloptions = OpenSSL::SSL::OP_ALL
if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
ssloptions &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
end
if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
ssloptions |= OpenSSL::SSL::OP_NO_COMPRESSION
end
version = OpenSSL::SSL::SSLContext::METHODS.find { |x| x.to_s.gsub("_",".") == settings[:ssl_version] }
raise InvalidConfiguration, "Invalid SSL/TLS version '#{settings[:ssl_version]}'" if version.nil?
sslcontext.ssl_version = version
sslcontext.options = ssloptions
sslcontext.ciphers = settings[:ciphers]
sslcontext.verify_callback = proc do |*args|
@logger.debug("Verify peer via FTW::Connection#secure", :callback => settings[:verify_callback])
if settings[:verify_callback].respond_to?(:call)
settings[:verify_callback].call(*args)
end
end
sslcontext.cert_store = settings[:certificate_store]
if settings.include?(:certificate) && settings.include?(:key)
sslcontext.cert = settings[:certificate]
sslcontext.key = settings[:key]
end
@socket = OpenSSL::SSL::SSLSocket.new(@socket, sslcontext)
if client?
do_secure(:connect_nonblock, settings[:timeout])
else
do_secure(:accept_nonblock, settings[:timeout])
end
end