logo_kerberos.gif

Projects/Input CCache

From K5Wiki
< Projects
Revision as of 14:29, 11 October 2012 by Nalin (talk | contribs) (Implementation)

Jump to: navigation, search

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 list of preauth challenge types sent to the KDC to an output ccache when credentials are successfully obtained (working name pa_types, on a per-service-principal basis).
  • Provide a means of reading this list from a ccache and displaying it.
  • When a list of preauth challenge types is found in an input ccache, limit the types of preauth data the client will attempt to generate for the KDC to types from that list. 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 list of previously-used preauth types and the list of currently-being-used preauth types.
  • Add a read_allowed_preauth_types() helper to retrieve the previously-used list 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 list of previously-used preauth types, skip over plugins for types that aren't in the list. Make sure the list is clear, so that any plugin can assist in processing the AS-REP, before running through the list while processing a KDC reply.
  • Add a create_selected_preauth_types() helper to rebuild the currently-being-used list before sending a KDC request.
  • If we successfully process a KDC reply, and we have an out_ccache, save the currently-being-used list to it 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_update_signer_identity() function to store that identity's name in a location where crypto_retrieve_signer_identity() can be used to retrieve it later, after we've verified that it worked.
  • If pkinit preauth succeeds, save the client identity that was used as a X509_user_identity configuration value using the new clpreauth callback.


  • When the OTP client prepares to make a request, have it retrieve a vendor configuration value from the input_ccache using the new clpreauth callback, and if one is found, prune tokeninfos which contain different vendor names before deciding whether or not the user needs to be asked to select one.
  • After the OTP client creates a challenge, save the vendor name from the tokeninfo which was used as a vendor value 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 types list set to [encrypted_challenge], without FAST.
      • Expected to fail because encrypted_challenge won't be offered by the KDC when FAST isn't being used.
    • Preauth types list set to [encrypted_challenge,OTP], without FAST.
      • Expected to fail because neither mechanism will be offered by the KDC.
    • Preauth types list set to [encrypted_timestamp], with FAST enabled.
      • Expected to fail because encrypted_timestamp won't be available when FAST is being used.
    • Preauth types list set to [encrypted_challenge,encrypted_timestamp, OTP], without FAST.
      • Expected to succeed.
      • Expect saved preauth types list to include encrypted_timestamp.
    • Preauth types list set to [encrypted_challenge,encrypted_timestamp, OTP], with FAST.
      • Expected to succeed.
      • Expect saved preauth types list to include encrypted_challenge.

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_data() and set_cc_config_data() clpreauth callbacks for getting string attribute values from an in_ccache and storing them in an out_ccache, respectively.