Authenticate via GSS API (including Kerberos)
SSH / SFTP client components support authentication through Generic Security Services Application Program Interface (GSSAPI, also GSS-API). GSSAPI is an application programming interface that provides security services for applications in a mechanism-independent way. This allows different security mechanisms to be used via one standardized API. GSSAPI is often linked with Kerberos, which is the most common mechanism of GSSAPI.
MIT Kerberos libraries are available for Unix as well as for Windows platforms. Also, Windows platforms support authentication using SSPI (Security Support Provider Interface) that is Microsoft's implementation of GSSAPI. SSPI supports Kerberos and NTLM authentication protocols.
To setup authentication via GSSAPI for SSH and SFTP client components you would need to set GSSMechanism, GSSHostName, GSSDelegateCredentials, AuthenticationTypes and UserName properties.
For GSSMechanism property you need to create and set GSSAPI mechanism instance. The following GSSAPI mechanisms are supported:
TElGSSAPIMechanism class implements Generic Security Service Application Program Interface (GSSAPI) as specified in RFC 2743 and RFC 2744. You can either specify a library to load GSSAPI functions using LibraryName property (for example: MIT Kerberos library) or handle accept_sec_context, ... verify_mic events and implement those functions. The events match the functions of the external library as defined by the API.
TElGSSWinAuthMechanism class implements Security Support Provider Interface (SSPI). Using AuthProtocols property you can select which authentication protocols (Kerberos and/or NTLM) are enabled. TElGSSMechanismCollection class allows to register several mechanisms using RegisterMechanism(), UnregisterMechanism(), GetMechByOID() functions.
For GSSHostName property you need to set a fully qualified domain name (FQDN, for example: 'hostname.com') or a principal name (for example: 'firstname.lastname@example.org') or a cross-realm ticket-granting ticket (TGT) (for example: 'email@example.com'). For GSSDelegateCredentials property you need to set boolean value that turns on/off credential delegation.
For AuthenticationTypes property you need to enable either GSSAPI user authentication and/or GSS-API-authenticated Diffie-Hellman key exchange. The following authentication types constants are defined:
Sample code that setup user authentication using gssapi-with-mic and MIT Kerberos library:
var Mech : TElGSSAPIMechanism; ... Mech := TElGSSAPIMechanism.Create(); Mech.LibraryName := 'C:\Program Files\MIT\Kerberos\bin\gssapi32.dll'; SSHClient.GSSMechanism := Mech; SSHClient.AuthenticationTypes := SSHClient.AuthenticationTypes or SSH_AUTH_TYPE_GSSAPI_WITH_MIC; ... // Open/Work/Close ... // Cleanup: SSHClient.GSSMechanism := nil; FreeAndNil(Mech); FreeAndNil(SSHClient);
Sample code that uses GSSAPI to authenticate a Diffie-Hellman key exchange (gssapi-keyex) and SSPI mechanism:
var Mech : TElGSSWinAuthMechanism; ... Mech := TElGSSWinAuthMechanism.Create(); Mech.AuthProtocols := [apKerberos, apNTLM]; // e.g. enabling Kerberos and NTLM protocols SSHClient.GSSMechanism := Mech; SSHClient.AuthenticationTypes := SSHClient.AuthenticationTypes or SSH_AUTH_TYPE_GSSAPI_KEYEX; // enabling GSS-API-authenticated Diffie-Hellman key exchange methods and raising priority: // gss-group1-sha1-* method SSHClient.KexAlgorithms[SSH_KEX_GSS_GROUP] := True; SSHClient.KexAlgorithmPriorities[SSH_KEX_GSS_GROUP] := 1; // gss-group14-sha1-* method SSHClient.KexAlgorithms[SSH_KEX_GSS_GROUP_14] := True; SSHClient.KexAlgorithmPriorities[SSH_KEX_GSS_GROUP_14] := 1; // gss-gex-sha1-* method SSHClient.KexAlgorithms[SSH_KEX_GSS_GROUP_EXCHANGE] := True; SSHClient.KexAlgorithmPriorities[SSH_KEX_GSS_GROUP_EXCHANGE] := 1; ... // Open/Work/Close ... // Cleanup: SSHClient.GSSMechanism := nil; FreeAndNil(Mech); FreeAndNil(SSHClient);
To get the last error, for example in client's OnAuthenticationFailed event handler, you can use GetLastMajorStatus() and GetLastMinorStatus() functions for mechanism. Major status values provide a mechanism-independent indication of call status and minor status provides more detailed status information which may include status codes specific to the underlying security mechanism.
Also, you can catch mechanism errors using OnError event handler, for example:
SSHClient.GSSMechanism.OnError := HandleGSSError; ... procedure TForm1.HandleGSSError(Sender : TObject; const Operation : string; MajorStatus, MinorStatus : LongWord; const MajorErrorMsg, MinorErrorMsg : string); begin Log('Operation ' + Operation + ' failed'); Log('GSS-API MajorStatus=' + IntToHex(MajorStatus, 8) + ', ' + MajorErrorMsg); Log('GSS-API MinorStatus=' + IntToHex(MinorStatus, 8) + ', ' + MinorErrorMsg); end;