Skip to content

Commit

Permalink
use connect_timeout when establishing an openssl connection
Browse files Browse the repository at this point in the history
  • Loading branch information
tmm1 committed Jun 15, 2016
1 parent 3bf849d commit 22fa81c
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions lib/net/ldap/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,27 @@ def socket_class=(socket_class)
@socket_class = socket_class
end

def prepare_socket(server)
def prepare_socket(server, timeout)
socket = server[:socket]
encryption = server[:encryption]

@conn = socket
setup_encryption encryption if encryption
setup_encryption(encryption, timeout) if encryption
end

def open_connection(server)
hosts = server[:hosts]
encryption = server[:encryption]

timeout = server[:connect_timeout] || DefaultConnectTimeout
socket_opts = {
connect_timeout: server[:connect_timeout] || DefaultConnectTimeout,
connect_timeout: timeout,
}

errors = []
hosts.each do |host, port|
begin
prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)))
prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout)
return
rescue Net::LDAP::Error, SocketError, SystemCallError,
OpenSSL::SSL::SSLError => e
Expand All @@ -76,7 +77,7 @@ def close
end
end

def self.wrap_with_ssl(io, tls_options = {})
def self.wrap_with_ssl(io, tls_options = {}, timeout=nil)
raise Net::LDAP::NoOpenSSLError, "OpenSSL is unavailable" unless Net::LDAP::HasOpenSSL

ctx = OpenSSL::SSL::SSLContext.new
Expand All @@ -86,7 +87,22 @@ def self.wrap_with_ssl(io, tls_options = {})
ctx.set_params(tls_options) unless tls_options.empty?

conn = OpenSSL::SSL::SSLSocket.new(io, ctx)
conn.connect

begin
conn.connect_nonblock
rescue IO::WaitReadable
if IO.select([conn], nil, nil, timeout)
retry
else
raise Net::LDAP::LdapError, "OpenSSL connection read timeout"
end
rescue IO::WaitWritable
if IO.select(nil, [conn], nil, timeout)
retry
else
raise Net::LDAP::LdapError, "OpenSSL connection write timeout"
end
end

# Doesn't work:
# conn.sync_close = true
Expand Down Expand Up @@ -123,11 +139,11 @@ def self.wrap_with_ssl(io, tls_options = {})
# communications, as with simple_tls. Thanks for Kouhei Sutou for
# generously contributing the :start_tls path.
#++
def setup_encryption(args)
def setup_encryption(args, timeout)
args[:tls_options] ||= {}
case args[:method]
when :simple_tls
@conn = self.class.wrap_with_ssl(@conn, args[:tls_options])
@conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
# additional branches requiring server validation and peer certs, etc.
# go here.
when :start_tls
Expand All @@ -144,7 +160,7 @@ def setup_encryption(args)
end

if pdu.result_code.zero?
@conn = self.class.wrap_with_ssl(@conn, args[:tls_options])
@conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
else
raise Net::LDAP::StartTLSError, "start_tls failed: #{pdu.result_code}"
end
Expand Down

0 comments on commit 22fa81c

Please sign in to comment.