Class: Net::SSH::Authentication::Methods::GssapiWithMic

Inherits:
Abstract
  • Object
show all
Includes:
Kerberos::Constants
Defined in:
lib/net/ssh/authentication/methods/gssapi_with_mic.rb

Overview

Implements the Kerberos 5 SSH authentication method.

Constant Summary

Constants included from Kerberos::Constants

Kerberos::Constants::GSS_KRB5_MECH, Kerberos::Constants::GSS_KRB5_MECH_USER2USER, Kerberos::Constants::KEXGSS_COMPLETE, Kerberos::Constants::KEXGSS_CONTINUE, Kerberos::Constants::KEXGSS_ERROR, Kerberos::Constants::KEXGSS_GROUP, Kerberos::Constants::KEXGSS_GROUPREQ, Kerberos::Constants::KEXGSS_HOSTKEY, Kerberos::Constants::KEXGSS_INIT, Kerberos::Constants::USERAUTH_GSSAPI_ERROR, Kerberos::Constants::USERAUTH_GSSAPI_ERRTOK, Kerberos::Constants::USERAUTH_GSSAPI_EXCHANGE_COMPLETE, Kerberos::Constants::USERAUTH_GSSAPI_MIC, Kerberos::Constants::USERAUTH_GSSAPI_RESPONSE, Kerberos::Constants::USERAUTH_GSSAPI_TOKEN

Instance Method Summary collapse

Instance Method Details

#authenticate(next_service, username, password = nil) ⇒ Object

Attempts to perform gssapi-with-mic Kerberos authentication



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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/net/ssh/authentication/methods/gssapi_with_mic.rb', line 14

def authenticate(next_service, username, password=nil)
  gss_klass = (defined?(Net::SSH::Kerberos::Drivers::SSPI::Context) ?
                  Net::SSH::Kerberos::Drivers::SSPI::Context : Net::SSH::Kerberos::Drivers::GSS::Context)
  gss = nil
  
  # Try to start gssapi-with-mic authentication.
 debug { "trying kerberos authentication" }
 req = userauth_request(username, next_service, "gssapi-with-mic")
 req.write_long(1)
 req.write_string(supported_oid = 6.chr + GSS_KRB5_MECH.length.chr + GSS_KRB5_MECH)
 send_message req
 message = session.next_message
 case message.type
   when USERAUTH_GSSAPI_RESPONSE
     debug { "gssapi-with-mic proceeding" }
   when USERAUTH_FAILURE
     info { "gssapi-with-mic failed (USERAUTH_FAILURE)" }
     return false
   else
     raise Net::SSH::Exception, "unexpected server response to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
 end
 
 # Try to match the OID.
 oid = message.read_string
 if oid != supported_oid
    info { "gssapi-with-mic failed (USERAUTH_GSSAPI_RESPONSE)" }
    return false
 end
 
 # Try to complete the handshake.
 gss = gss_klass.new
 gss.create username, hostname
			      debug { "gssapi-with-mic handshaking" }
 until gss.established?
   token = gss.init(token)
   if token && token.length > 0
 send_message Net::SSH::Buffer.from(:byte, USERAUTH_GSSAPI_TOKEN, :string, token)
     unless gss.established?
       message = session.next_message
    case message.type
    when USERAUTH_GSSAPI_ERROR
       message = session.next_message
       message.get_long
       message.get_long
      info { "gssapi-with-mic error (USERAUTH_GSSAPI_ERROR) (#{message.read_string})" }
    when USERAUTH_GSSAPI_ERRTOK
       message = session.next_message
      info { "gssapi-with-mic error (USERAUTH_GSSAPI_ERRTOK) (#{message.read_string})" }
    when USERAUTH_FAILURE
      info { "gssapi-with-mic failed (USERAUTH_FAILURE)" }
      return false
    end
       token = message.read_string
     end
   end
 end
 
 # Attempt the actual authentication.
			      debug { "gssapi-with-mic authenticating" }
					  mic = gss.get_mic Net::SSH::Buffer.from(:string, session_id, :byte, USERAUTH_REQUEST, :string, username, 
                                       :string, next_service, :string, "gssapi-with-mic").to_s
  if mic.nil?
    info { "gssapi-with-mic failed (context#get_mic)" }
    return false
  end
			      send_message Net::SSH::Buffer.from(:byte, USERAUTH_GSSAPI_MIC, :string, mic)
  message = session.next_message
 case message.type
   when USERAUTH_SUCCESS
     info { "gssapi-with-mic success" }
     return true
   when USERAUTH_FAILURE
     info { "gssapi-with-mic partial failure (USERAUTH_FAILURE)" }
     return false
   else
     raise Net::SSH::Exception, "unexpected server response to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
 end
ensure
			      gss and gss.dispose
end