Skip to content

Commit 09d0c36

Browse files
committed
use connect_timeout when establishing an openssl connection
1 parent 3bf849d commit 09d0c36

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

lib/net/ldap/connection.rb

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,27 @@ def socket_class=(socket_class)
3131
@socket_class = socket_class
3232
end
3333

34-
def prepare_socket(server)
34+
def prepare_socket(server, timeout=nil)
3535
socket = server[:socket]
3636
encryption = server[:encryption]
3737

3838
@conn = socket
39-
setup_encryption encryption if encryption
39+
setup_encryption(encryption, timeout) if encryption
4040
end
4141

4242
def open_connection(server)
4343
hosts = server[:hosts]
4444
encryption = server[:encryption]
4545

46+
timeout = server[:connect_timeout] || DefaultConnectTimeout
4647
socket_opts = {
47-
connect_timeout: server[:connect_timeout] || DefaultConnectTimeout,
48+
connect_timeout: timeout,
4849
}
4950

5051
errors = []
5152
hosts.each do |host, port|
5253
begin
53-
prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)))
54+
prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout)
5455
return
5556
rescue Net::LDAP::Error, SocketError, SystemCallError,
5657
OpenSSL::SSL::SSLError => e
@@ -76,7 +77,7 @@ def close
7677
end
7778
end
7879

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

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

8889
conn = OpenSSL::SSL::SSLSocket.new(io, ctx)
89-
conn.connect
90+
91+
begin
92+
conn.connect_nonblock
93+
rescue IO::WaitReadable
94+
if IO.select([conn], nil, nil, timeout)
95+
retry
96+
else
97+
raise Net::LDAP::LdapError, "OpenSSL connection read timeout"
98+
end
99+
rescue IO::WaitWritable
100+
if IO.select(nil, [conn], nil, timeout)
101+
retry
102+
else
103+
raise Net::LDAP::LdapError, "OpenSSL connection write timeout"
104+
end
105+
end
90106

91107
# Doesn't work:
92108
# conn.sync_close = true
@@ -123,11 +139,11 @@ def self.wrap_with_ssl(io, tls_options = {})
123139
# communications, as with simple_tls. Thanks for Kouhei Sutou for
124140
# generously contributing the :start_tls path.
125141
#++
126-
def setup_encryption(args)
142+
def setup_encryption(args, timeout=nil)
127143
args[:tls_options] ||= {}
128144
case args[:method]
129145
when :simple_tls
130-
@conn = self.class.wrap_with_ssl(@conn, args[:tls_options])
146+
@conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
131147
# additional branches requiring server validation and peer certs, etc.
132148
# go here.
133149
when :start_tls
@@ -144,7 +160,7 @@ def setup_encryption(args)
144160
end
145161

146162
if pdu.result_code.zero?
147-
@conn = self.class.wrap_with_ssl(@conn, args[:tls_options])
163+
@conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
148164
else
149165
raise Net::LDAP::StartTLSError, "start_tls failed: #{pdu.result_code}"
150166
end

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy