I recently merged Luke Howard’s work on the Microsoft S4U extensions into the krb5 trunk. This feature is primarily of interest to application developers. The S4U extensions are a combination of two services: S4U2Self, which allows a service to get a ticket to itself on behalf of a user, and S4U2Proxy, which allows a trusted service to get credentials to another service on behalf of a user.
To understand how these services are useful, consider the case of a webmail gateway. Let’s say an organization has an IMAP email service with krb5 support, via GSSAPI and SASL, and you want to provide a webmail interface to that service. Some power users might be able to authenticate to the webmail interface using HTTP Negotiate with krb5, but most will likely use certificates or passwords over TLS.
Fundamentally, a gateway service of this type must be trusted with users’ email, since there is no way to transmit commands end-to-end between the user and the IMAP service. So, how does the webmail service authenticate to the IMAP service? One possibility is for the webmail service to support authentication only by password, and use the password to obtain credentials for the user. This is how it is generally done today. This approach gives up the potential for single sign-on, teaches users to type their passwords into web pages which request them, and can’t work for user principals which require PKINIT or hardware preauth systems.
With the S4U extensions, the webmail service can operate in a more flexible manner.
- First, using S4U2Self, the webmail service can authenticate a user by whatever means, and then request a ticket from the user to itself, just as if the user had used HTTP Negotiate with krb5. Such a ticket allows the webmail service to examine any authorization data for the user. Most MIT krb5 deployments do not make use of KDC authorization data at this time, so that part isn’t especially interesting, but this ticket is also useful for the next step.
- Second, using either the ticket obtained from S4U2Self or from HTTP Negotiate, the webmail service can use S4U2Proxy to obtain credentials on behalf of the user to the IMAP service. Traditionally, this was only possible if the client used Kerberos authentication and forwarded a TGT to the webmail service.
To perform the first step, the webmail service would use the new API gss_acquire_cred_impersonate_name, passing its service credentials as the impersonator_cred_handle and the user’s name as the desired_name. The underlying GSSAPI code will perform an S4U2Self request to the KDC. Despite the word “impersonate,” this part of the authentication is pretty innocuous and requires no special privileges on the part of the service, since it only allows a service to impersonate users to itself. (In theory, a service can print arbitrary service tickets to itself without the help of the KDC, although that wouldn’t give it access to any authorization data.)
To perform the second step, the webmail service would use the existing gss_init_sec_context API. The claimant_cred_handle argument to this call would either be the credentials obtained with gss_acquire_cred_impersonate_name, or–if the user authenticated with HTTP Negotiate–the delegated_cred_handle returned by gss_accept_sec_context. Previously, delegated_cred_handle was only filled in if the user forwarded a TGT during authentication, but in 1.8 it is filled in whenever the application requests it. The GSSAPI code will perform an S4U2Proxy request to obtain credentials on behalf of the user. If the KDC is an MIT krb5 1.8 KDC, this request will only succeed if the webmail service principal has the new “ok_to_auth_as_delegate” flag set.
We hope this new feature encourages the development of better service intermediaries, as well as allowing better interoperability with Microsoft. For further information, see the project page for the S4U work or the Microsoft documentation of the S4U protocol extensions. krb5 1.8 is planned to be released around March 2010, plus or minus three months.