Projects/Password expiration API
This project is to add a client API giving programmatic access to password expiration as conveyed in an AS request.
Background
There are two places in the encrypted part of a KDC reply which can indicate the time of password expiration: the key-expiration field, which is a timestamp, and the last-req field, which is a sequence of tagged timestamps. These fields exist for both AS and TGS requests, but are typically omitted in TGS requests.
According to RFC 4120, the key-expiration field is deprecated, and should contain the minimum of the password and account expiration fields. The MIT KDC fills this field in with the account expiration time; this is a bug (#2032 in RT). The Heimdal KDC correctly fills in this field.
last-req entries with tags of 6 or -6 convey password expiration time; last-req entries with tags 7 or -7 convey account expiration time. Positive tags refer to all servers and negative tags to only one server for the realm; this distinction has meaning for other kinds of last-req entries but not for expiry. The MIT KDC never includes last-req information. The Heimdal KDC provides last-req information for account expiration, and for password expiration only if the password will expire within a configurable amount of time from the current time.
In the MIT krb5 client code as of release 1.8, krb5_get_init_creds_password examines the key-expiration and last-req fields with the following behavior:
- If the key-expiration field indicates a positive timestamp within the next seven days, the prompter is invoked with no prompts, and a banner containing an English string in one of three formats. Each format indicates that the password will expire and roughly when.
- Otherwise, if a last-req entry with tag 6 or -6 exists, the prompter is invoked as above, using one of three slightly different formats. No bounds check on the last-req value is performed since it is assumed that such a last-req entry would only be included if the KDC desires a warning to be issued (as in Heimdal).
The current client behavior does not give applications programmatic control over expiration warnings.
Proposal
Bug #2032 should be fixed in the KDC. This is a simple matter and is out of scope for the project.
A new get_init_creds option will be added as follows:
typedef void krb5_expire_callback_func(krb5_context context, void *data, krb5_timestamp password_expiration, krb5_timestamp account_expiration, krb5_boolean is_last_req);
krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_expire_callback(krb5_context context, krb5_get_init_creds_opt *opt, krb5_expire_callback_func cb, void *data);
If this callback is provided, the prompter will not be invoked with warning messages. Instead, upon successful acquisition of credentials, the callback will be invoked as follows:
- If last-req entries with tags 6, -6, 7, or -7 exist, those will be used for the password and account expiration timestamps (0 if one or the other is not specified), and is_last_req will be true.
- Otherwise, password_expiration will be the key-expiration value (which may be 0), account_expiration will be 0, and is_last_req will be false.
If a caller does not set the expiration callback, the prompter will be invoked as before, but the banners will use consistent string formats independent of whether the expiration time came from key-expiration or last-req values.
Tests
A C harness and Python test program will test that the callback is invoked when provided, and that appropriate warnings are sent to the prompter if no callback is provided.