@@ -224,6 +224,8 @@ def bind(auth)
224224 bind_sasl ( auth )
225225 elsif meth == :gss_spnego
226226 bind_gss_spnego ( auth )
227+ elsif meth == :gssapi
228+ bind_gssapi ( auth )
227229 else
228230 raise Net ::LDAP ::AuthMethodUnsupportedError , "Unsupported auth method (#{ meth } )"
229231 end
@@ -341,6 +343,50 @@ def bind_gss_spnego(auth)
341343 end
342344 private :bind_gss_spnego
343345
346+ #--
347+ # Like #bind_gss_spnego, this is PROVISIONAL, only for testing, DON'T USE
348+ # THIS YET. Uses Dan Wanek's GSSAPI FFI wrapper.
349+ #
350+ # This authentication method is accessed by calling #bind with a :method
351+ # parameter of :gss_spnego. It requires a :hostname attribute, and uses an
352+ # optional :servicename attribute which defaults to "ldap". It performs
353+ # GSSAPI authentication (which almost always means Kerberos authentication)
354+ # with the server.
355+ #++
356+ def bind_gssapi ( auth )
357+ require 'gssapi'
358+
359+ host , svc = [ auth [ :hostname ] , auth [ :servicename ] || "ldap" ]
360+ raise Net ::LDAP ::BindingInformationInvalidError , "Invalid binding information" unless ( host && svc )
361+
362+ gsscli = GSSAPI ::Simple . new ( host , svc )
363+ context_established = nil
364+ challenge_response = proc { |challenge |
365+ if !context_established
366+ resp = gsscli . init_context ( challenge )
367+ raise "Failed to establish GSSAPI security context" unless resp
368+ context_established = true if resp . equal? ( true )
369+ resp
370+ else
371+ # After the security context has been established, the LDAP server will
372+ # offer to negotiate the security strength factor (SSF) and maximum
373+ # output size. We request an SSF of 0, i.e. no protection (integrity
374+ # and confidentiality protections aren't implemented here, yet) and no
375+ # size limit.
376+ #
377+ # N.b. your LDAP server may reject the bind request with an error
378+ # message like "protocol violation: client requested invalid layer."
379+ # That means that it is configured to require stronger protection.
380+ gsscli . wrap_message ( "\x01 \xff \xff \xff " . force_encoding ( "binary" ) , false )
381+ end
382+ }
383+
384+ bind_sasl ( :method => :sasl , :mechanism => "GSSAPI" ,
385+ :initial_credential => gsscli . init_context ,
386+ :challenge_response => challenge_response )
387+ end
388+ private :bind_gssapi
389+
344390
345391 #--
346392 # Allow the caller to specify a sort control
0 commit comments