Skip to content

Commit a5cb3d2

Browse files
author
Luiz Angelo Daros de Luca
committed
- added :sasl_opts for extra SASL options (passed to SASL lib)
- improved secure_layer treatment. Now gssapi (krb5) and digest-md5 works.
1 parent 1429d03 commit a5cb3d2

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

lib/net/ldap.rb

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,8 +1306,10 @@ def bind_simple(auth)
13061306
#
13071307
# If ruby-sasl is avaiable, :host is used to setup digest-url and defaults to
13081308
# connection hostname. Also, for some mechs, the :username and :password are used.
1309+
# :secure_layer define if SASL should atempt to use secure layer (similar to SSL)
13091310
# :initial_credential and :challenge_response are optional and filled by
1310-
# setup_auth_sasl.
1311+
# setup_auth_sasl. Extra preferences for sasl library like :gss_opts be defined as
1312+
# a hash in :sasl_opts.
13111313
#
13121314
# If ruby-sasl is not avaiable, :initial_credential and :challenge_response
13131315
# are required.
@@ -1353,36 +1355,54 @@ def bind_sasl(auth)
13531355
@conn.write request_pkt
13541356

13551357
(be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
1356-
if securelayer_wrapper
1357-
$stderr.puts "secure lay"
1358-
@conn = self.class.wrap_with_sasl(@conn, securelayer_wrapper)
1358+
1359+
case pdu.result_code
1360+
when 14 # SASLBindInProgress
1361+
cred = chall.call(pdu.result_server_sasl_creds, :challenge)
1362+
when 0 # Authenticated
1363+
securelayer_wrapper = chall.call(pdu.result_server_sasl_creds, :success)
1364+
if securelayer_wrapper
1365+
@conn = self.class.wrap_with_sasl(@conn, securelayer_wrapper)
1366+
end
1367+
return pdu
1368+
else # Error
1369+
chall.call(pdu.result_server_sasl_creds, :failure)
1370+
return pdu
13591371
end
1360-
return pdu unless pdu.result_code == 14 # saslBindInProgress
1361-
raise Net::LDAP::LdapError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
13621372

1363-
(cred, securelayer_wrapper) = chall.call(pdu.result_server_sasl_creds)
1373+
raise Net::LDAP::LdapError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
13641374
}
13651375

13661376
raise Net::LDAP::LdapError, "why are we here?"
13671377
end
13681378
private :bind_sasl
13691379

1370-
SASL_SERVICE_NAME="ldap"
1380+
SASL_SERVICE_TYPE="ldap"
13711381

13721382
def self.setup_auth_sasl(auth)
13731383
raise Net::LDAP::LdapError, "SASL library (gem ruby-sasl) is unavailable" unless Net::LDAP::HasSASL
13741384
raise Net::LDAP::LdapError, "Invalid binding information. auth[:host] is required" unless auth.include?(:host)
13751385

1376-
pref = SASL::Preferences.new(
1377-
:digest_uri =>"#{SASL_SERVICE_NAME}/#{auth[:host]}",
1378-
:username => auth[:username] || auth[:dn],
1379-
:password => auth[:password],
1380-
)
1381-
sasl = SASL.new_mechanism(auth[:mechanism], pref)
1382-
1383-
challenge_response = Proc.new do |cred|
1384-
response = sasl.receive("challenge", cred)
1385-
response[1]
1386+
opts = {:digest_uri =>"#{SASL_SERVICE_TYPE}/#{auth[:host]}",
1387+
:username => auth[:username] || auth[:dn],
1388+
:password => auth[:password],
1389+
:secure_layer => auth[:secure_layer],
1390+
}
1391+
opts.merge!(auth[:sasl_opts]) if auth.include? :sasl_opts
1392+
1393+
sasl = SASL.new_mechanism(auth[:mechanism], SASL::Preferences.new(opts))
1394+
1395+
challenge_response = Proc.new do |cred,result|
1396+
case result
1397+
when :challenge
1398+
response = sasl.receive("challenge", cred)
1399+
response[1]
1400+
when :success
1401+
response = sasl.receive("success", cred)
1402+
response[1] if response
1403+
when :failure
1404+
response = sasl.receive("failure", cred)
1405+
end
13861406
end
13871407

13881408
initial_credential = sasl.start[1]

0 commit comments

Comments
 (0)