Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

Commit

Permalink
Added SSLContext support for specifying SSL verification params. Clea…
Browse files Browse the repository at this point in the history
…ned up the documentation in SSL. Pass the SSL options to the SSL#connection method.
  • Loading branch information
Alex Eckermann authored and durran committed Sep 2, 2012
1 parent 7f33b41 commit dc21475
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
3 changes: 2 additions & 1 deletion lib/moped/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ def alive?
# @since 1.0.0
def connect
@sock = if !!@options[:ssl]
Sockets::SSL.connect @host, @port, @timeout
Sockets::SSL.connect @host, @port, @timeout, @options[:ssl]
else
Sockets::TCP.connect @host, @port, @timeout
end

end

# Is the connection connected?
Expand Down
73 changes: 69 additions & 4 deletions lib/moped/sockets/ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ class SSL < TCP
# Initialize the new TCPSocket with SSL.
#
# @example Initialize the socket.
# SSL.new("127.0.0.1", 27017)
# SSL.new("127.0.0.1", 27017, OpenSSL::SSL::SSLContext.new)
#
# @param [ String ] host The host.
# @param [ Integer ] port The port.
# @param [ OpenSSL::SSL::SSLContext ] context The SSLContext.
#
# @since 1.2.0
def initialize(host, port, *args)
super
@ssl = OpenSSL::SSL::SSLSocket.new(self)
def initialize(host, port, context, *args)
super host, port, *args

@ssl = OpenSSL::SSL::SSLSocket.new(self, context)
@ssl.sync_close = true

handle_socket_errors { @ssl.connect }
end

Expand Down Expand Up @@ -62,6 +65,68 @@ def handle_socket_errors
raise Errors::ConnectionFailure, "SSL Error '#{e.to_s}' for connection to Mongo on #{host}:#{port}"
end

class << self

# Connect to the tcp server.
#
# @example Connect to the server.
# SSL.connect("127.0.0.1", 27017, 30, true)
#
# @param [ String ] host The host to connect to.
# @param [ Integer ] post The server port.
# @param [ Integer ] timeout The connection timeout.
# @param [ Boolean ] ssl_options If boolean then assume default options.
# @param [ Hash ] ssl_options Supply custom SSL options to SSLContext.
#
# @option ssl_options [ Boolean ] :verify_peer Flag for SSLContext.verify_mode
# @option ssl_options [ String ] :ca_path
# @option ssl_options [ String ] :ca_file
# @option ssl_options [ String ] :client_cert
# @option ssl_options [ String ] :client_key
#
# @return [ TCPSocket ] The socket.
#
# @since 1.0.0
def connect(host, port, timeout, ssl_options = true)
Timeout::timeout(timeout) do

context = OpenSSL::SSL::SSLContext.new

if ssl_options.is_a?(Hash)

if !!ssl_options[:verify_peer]
context.verify_mode = OpenSSL::SSL::VERIFY_PEER

if ssl_options[:ca_path]
context.ca_path = ssl_options[:ca_path]
elsif ssl_options[:ca_file]
context.ca_file = ssl_options[:ca_file]
else
store = OpenSSL::X509::Store.new
store.set_default_paths
context.cert_store = store
end
else
context.verify_mode = OpenSSL::SSL::VERIFY_NONE
end

if ssl_options.has_key?(:client_cert) && ssl_options.has_key?(:client_key)
context.cert = OpenSSL::X509::Certificate.new(File.read(ssl_options[:client_cert]))
context.key = OpenSSL::PKey::RSA.new(File.read(ssl_options[:client_key]))
end

else
context.verify_mode = OpenSSL::SSL::VERIFY_NONE
end

sock = new(host, port, context)
sock.set_encoding('binary')
sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
sock
end
end
end

end
end
end

0 comments on commit dc21475

Please sign in to comment.