@@ -321,6 +321,7 @@ class LdapError < Exception; end
321321 DefaultAuth = { :method => :anonymous }
322322 DefaultTreebase = "dc=com"
323323
324+ StartTlsOid = "1.3.6.1.4.1.1466.20037"
324325
325326 ResultStrings = {
326327 0 => "Success" ,
@@ -473,8 +474,9 @@ def authenticate username, password
473474 # unencrypted connections.]</i>
474475 #
475476 def encryption args
476- if args == :simple_tls
477- args = { :method => :simple_tls }
477+ case args
478+ when :simple_tls , :start_tls
479+ args = { :method => args }
478480 end
479481 @encryption = args
480482 end
@@ -1114,6 +1116,11 @@ def initialize server
11141116 # OBSERVE: WE REPLACE the value of @conn, which is presumed to be a connected
11151117 # TCPsocket object.
11161118 #
1119+ # The start_tls method is supported by many servers over the standard LDAP port.
1120+ # It does not require an alternative port for encrypted communications, as with
1121+ # simple_tls.
1122+ # Thanks for Kouhei Sutou for generously contributing the :start_tls path.
1123+ #
11171124 def setup_encryption args
11181125 case args [ :method ]
11191126 when :simple_tls
@@ -1123,6 +1130,24 @@ def setup_encryption args
11231130 @conn . connect
11241131 @conn . sync_close = true
11251132 # additional branches requiring server validation and peer certs, etc. go here.
1133+ when :start_tls
1134+ raise LdapError . new ( "openssl unavailable" ) unless $net_ldap_openssl_available
1135+ msgid = next_msgid . to_ber
1136+ request = [ StartTlsOid . to_ber ] . to_ber_appsequence ( Net ::LdapPdu ::ExtendedRequest )
1137+ request_pkt = [ msgid , request ] . to_ber_sequence
1138+ @conn . write request_pkt
1139+ be = @conn . read_ber ( AsnSyntax )
1140+ raise LdapError . new ( "no start_tls result" ) if be . nil?
1141+ pdu = Net ::LdapPdu . new ( be )
1142+ raise LdapError . new ( "no start_tls result" ) if pdu . nil?
1143+ if pdu . result_code . zero?
1144+ ctx = OpenSSL ::SSL ::SSLContext . new
1145+ @conn = OpenSSL ::SSL ::SSLSocket . new ( @conn , ctx )
1146+ @conn . connect
1147+ @conn . sync_close = true
1148+ else
1149+ raise LdapError . new ( "start_tls failed: #{ pdu . result_code } " )
1150+ end
11261151 else
11271152 raise LdapError . new ( "unsupported encryption method #{ args [ :method ] } " )
11281153 end
0 commit comments