logo_kerberos.gif

Projects/Input CCache

From K5Wiki
Jump to: navigation, search
This project was completed in release 1.11.


Background

The addition of preauth mechanisms which aren't password-based to the Kerberos protocol leads to a more complicated user experience when a user attempts to obtain initial credentials.

When PKINIT is in use, this can include prompting the user for a password needed for accessing encrypted keying material and for a PIN for logging in to a cryptographic token. Depending on the system configuration, a user may be prompted several times for this information for multiple candidate identities.

When OTP tokens are used, the user may also be required to first select which token to use.

Problem

In some applications, particularly in screen unlocking, asking or permitting the user to reauthenticate in a different manner than was used for initial login confuses people.

Goals

The least surprising behavior in that scenario is to attempt to repeat the authentication choices which were made at the time the user logged in: if the user used a smart card, ideally the user would only be prompted for that same card's PIN, but if the user used a password, the presence of a smart card in a reader attached to the system would be ignored.

To that end, the intent is to provide a way for an application to indicate to the client library that it would like to use the same preauth mechanism that was used to obtain a previously-obtained TGT, and to provide a means of allowing mechanisms to record non-sensitive information which will allow them to reduce the number of requests they make to the user. For PKINIT and OTP mechanisms, for example, this would involve caching credential or token selection information, but not PIN or password values.

Design

This feature has several parts:

  • Add an "input" ccache get_init_creds option.
  • While input ccaches won't be used by default, give kinit a way to specify one.
  • Save the preauth challenge type which the client attempted to produce to send to the KDC to an output ccache when credentials are successfully obtained (working name pa_type, on a per-service-principal basis).
  • Provide a means of reading this value from a ccache and displaying it.
  • When a preauth challenge type is found in an input ccache, only call preauth mechanisms which will claim to be able to produce padata which corresponds to that type. This will alter the client's behavior to skip over mechanisms which weren't used the last time.
  • Add client preauth plugin callbacks for setting data items that will be stored to the ccache if credentials are obtained (working name pa_config_data, on a per-server-principal basis), and for reading them when called to generate preauth data.
  • Modify the PKINIT plugin to use this facility to save the client's chosen identity while generating PKINIT AS-REQ data (working name X509_user_identity, despite being handled differently than the preauth option of the same name).
  • Modify the PKINIT plugin to check for this saved value, and if one is found, to bypass the default searching of multiple possible client identities in favor of the recorded value.
  • Modify the OTP plugin to use this facility to save information sufficient to identify which token is being used while generating OTP AS-REQ data (proposed name vendor).
  • Modify the OTP plugin to use this facility to check for this saved value, and if one is found, to use it to decide which token's code it should request the user to provide.

Implementation

  • Add a krb5_get_init_creds_opt_set_in_ccache() function and a field in the krb5_get_init_creds_opt's private area to store the value.
  • Add a -I flag to kinit to allow an input ccache to be supplied, expected to be used mainly for troubleshooting.


  • Modify the client preauth rock to add a field to hold the previously-used preauth type and the currently-being-used preauth type.
  • Add a read_allowed_preauth_type() helper to retrieve the previously-used value before generating preauth data when sending a KDC request.
  • When running through the list of preauth plugins to produce a KDC request, if we have a previously-used preauth type, skip over plugins which don't handle that type. Reset the value, so that it appears unset (i.e., holding the value KRB5_PADATA_NONE) before processing a KDC response, so that any plugin can assist in processing the AS-REP, before running through the list while processing a KDC reply.
  • If we successfully process a KDC reply, and we have an out_ccache, save the currently-being-supplied padata type to the ccache right after saving the fast_avail info.


  • Modify the client preauth rock to add a field to hold the preauth config data that was read from an in_ccache, and another to hold preauth config data that will be saved to an out_ccache.
  • Add a reset_cc_config_data() helper to retrieve the previously-saved preauth config data and reset the to-be-saved preauth config data before generating preauth data when sending a KDC request.
  • Add client preauth callbacks to retrieve an item from the previously-saved preauth config data or add an item to the to-be-saved preauth config data.


  • Teach PKINIT to not discard the names of client identities after loading them.
  • When reading PKINIT configuration, try to retrieve a X509_user_identity configuration value from an input ccache. If one is found, short-circuit the selection process, as the server does with its configured value.
  • After selecting a specific identity, have pkinit call a new crypto_retrieve_signer_identity() function and save the value it returns as a X509_user_identity configuration value using the new clpreauth callback.


  • When the OTP client prepares to fill in response questions, have it retrieve vendor, algID, and tokenID configuration values from the input_ccache using the new clpreauth callback, and if exactly one tokeninfo is found which matches all of the values which were retrieved, prune from its list of tokeninfos all other entries.
  • After the OTP client generates a request, save all of the vendor name, algorithm ID, and token ID, or rather all of those which the KDC supplied, as vendor, algID, and tokenID values in the out_ccache.

Testing

  • A test program will be needed. It will need to be able to
    • Read or write (overwrite) stored configuration data used by preauth plugins.
    • Attempt to obtain credentials, answering prompts using pre-supplied answers.
    • Report status.
  • Expected tests:
    • Preauth type set to 138 (encrypted_challenge), without FAST.
      • Expected to fail because encrypted_challenge won't be offered by the KDC when FAST isn't being used.
    • Preauth type set to 2 (encrypted_timestamp), with FAST enabled.
      • Expected to fail because encrypted_timestamp won't be available when FAST is being used.
    • Preauth type set to 138, with FAST enabled.
      • Expected to succeed.
      • Expect saved preauth type to indicate encrypted_challenge.
    • Preauth type set to 2, without FAST.
      • Expected to succeed.
      • Expect saved preauth type to indicate encrypted_timestamp.

Documentation

  • Man page for kinit's new use-an-in-ccache -I flag.
  • Man page for klist's new show-config-data -C flag.
  • In-header documentation for new krb5_get_init_creds_opt_set_in_ccache().
  • In-header documentation for new client preauth callbacks.

Release Notes

  • Developer experience:
    • Adds a krb5_get_init_creds_opt_set_in_ccache() option.
    • Adds get_cc_config() and set_cc_config() clpreauth callbacks for getting string attribute values from an in_ccache and storing them in an out_ccache, respectively.