forked from ruby-ldap/ruby-net-ldap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsasl.rb
62 lines (53 loc) · 2.48 KB
/
sasl.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
require 'net/ldap/auth_adapter'
module Net
class LDAP
class AuthAdapter
class Sasl < Net::LDAP::AuthAdapter
MaxSaslChallenges = 10
#--
# Required parameters: :mechanism, :initial_credential and
# :challenge_response
#
# Mechanism is a string value that will be passed in the SASL-packet's
# "mechanism" field.
#
# Initial credential is most likely a string. It's passed in the initial
# BindRequest that goes to the server. In some protocols, it may be empty.
#
# Challenge-response is a Ruby proc that takes a single parameter and
# returns an object that will typically be a string. The
# challenge-response block is called when the server returns a
# BindResponse with a result code of 14 (saslBindInProgress). The
# challenge-response block receives a parameter containing the data
# returned by the server in the saslServerCreds field of the LDAP
# BindResponse packet. The challenge-response block may be called multiple
# times during the course of a SASL authentication, and each time it must
# return a value that will be passed back to the server as the credential
# data in the next BindRequest packet.
#++
def bind(auth)
mech, cred, chall = auth[:mechanism], auth[:initial_credential],
auth[:challenge_response]
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (mech && cred && chall)
message_id = @connection.next_msgid
n = 0
loop do
sasl = [mech.to_ber, cred.to_ber].to_ber_contextspecific(3)
request = [
Net::LDAP::Connection::LdapVersion.to_ber, "".to_ber, sasl
].to_ber_appsequence(Net::LDAP::PDU::BindRequest)
@connection.send(:write, request, nil, message_id)
pdu = @connection.queued_read(message_id)
if !pdu || pdu.app_tag != Net::LDAP::PDU::BindResult
raise Net::LDAP::NoBindResultError, "no bind result"
end
return pdu unless pdu.result_code == Net::LDAP::ResultCodeSaslBindInProgress
raise Net::LDAP::SASLChallengeOverflowError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
cred = chall.call(pdu.result_server_sasl_creds)
end
raise Net::LDAP::SASLChallengeOverflowError, "why are we here?"
end
end
end
end
end