From 14c3db9b83b0aa4da8e685d777252cbd9d194aa4 Mon Sep 17 00:00:00 2001 From: blackhedd Date: Sat, 30 Sep 2006 13:28:05 +0000 Subject: [PATCH] provisionally implemented NTLM authentication. --- lib/net/ldap.rb | 28 ++++++++++++++++++++++------ lib/net/ldap/pdu.rb | 6 ++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb index 5d813eb..e3f9513 100644 --- a/lib/net/ldap.rb +++ b/lib/net/ldap.rb @@ -1159,21 +1159,37 @@ module Net #-- # bind_sasl - # PROVISIONAL, only for testing SASL implementations. Will disappear, so DON'T USE THIS. + # PROVISIONAL, only for testing SASL implementations. DON'T USE THIS YET. + # Uses Kohei Kajimoto's Ruby/NTLM. We have to find a clean way to integrate it without + # introducing an external dependency. + # This is also wrong for another reason: we're assuming Microsoft GSSAPI negotiation. + # Wee need to introduce some extra parameters to select that mode. def bind_sasl auth - user = auth[:username] or raise LdapError.new( "invalid username" ) + require 'ntlm.rb' + user,psw = [auth[:username] || auth[:dn], auth[:password]] + raise LdapError.new( "invalid binding information" ) unless (user && psw) msgid = next_msgid.to_ber - sasl = ["GSS-SPNEGO".to_ber, "NTLMSSP\000\001\000\000\000\227\202\010\340\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000".to_ber].to_ber_contextspecific(3) - sasl = ["GSSAPI".to_ber].to_ber_contextspecific(3) + sasl = ["GSS-SPNEGO".to_ber, NTLM::Message::Type1.new.serialize.to_ber].to_ber_contextspecific(3) + request = [LdapVersion.to_ber, "".to_ber, sasl].to_ber_appsequence(0) + request_pkt = [msgid, request].to_ber_sequence + @conn.write request_pkt + + (be = @conn.read_ber(AsnSyntax) and pdu = Net::LdapPdu.new( be )) or raise LdapError.new( "no bind result" ) + return pdu.result_code unless pdu.result_code == 14 # saslBindInProgress + + t2 = NTLM::Message.parse( pdu.result_server_sasl_creds ) # WARNING, can Kajimoto's code throw nasty errors? + t3 = t2.response( {:user => user, :password => psw}, {:ntlmv2 => true} ) + + msgid = next_msgid.to_ber + sasl = ["GSS-SPNEGO".to_ber, t3.serialize.to_ber].to_ber_contextspecific(3) request = [LdapVersion.to_ber, "".to_ber, sasl].to_ber_appsequence(0) request_pkt = [msgid, request].to_ber_sequence @conn.write request_pkt -p request_pkt (be = @conn.read_ber(AsnSyntax) and pdu = Net::LdapPdu.new( be )) or raise LdapError.new( "no bind result" ) -p pdu pdu.result_code end + private :bind_sasl #-- # search diff --git a/lib/net/ldap/pdu.rb b/lib/net/ldap/pdu.rb index 4372727..ac8438e 100644 --- a/lib/net/ldap/pdu.rb +++ b/lib/net/ldap/pdu.rb @@ -119,6 +119,12 @@ class LdapPdu @ldap_controls || [] end + # Return serverSaslCreds, which are only present in BindResponse packets. + # Messy. Does this functionality belong somewhere else? + # We ought to refactor the accessors of this class before they get any kludgier. + def result_server_sasl_creds + @ldap_result && @ldap_result[:serverSaslCreds] + end # # parse_ldap_result