Preauth interface change proposals

ghudson@MIT.EDU ghudson at MIT.EDU
Thu Sep 29 13:34:39 EDT 2011

Before the 1.10 branch, I'd like to make some changes to the preauth
plugin interface while we have the freedom to make incompatible
revisions.  Here are three specific proposals:

e-data as pa-data

RFC 6113 requires that e-data from plugins be encoded as padata, so
that it can be transmitted in the padata field of a FAST reply.
Previously, RFC 4120 said that e-data encoding was code-dependent or
implementation-defined, and MAY be encoded as typed-data.  I think the
only traditional padata type to specify e-data is PKINIT, which
mandates that its e-data be encoded as typed data.  (I believe that
encrypted timestamp and SAM never generate e-data when verifying

The specific changes here would be:

1. Change the e_data parameter of krb5_kdcpreauth_verify_fn from a
krb5_data ** to a krb5_pa_data ***.

2. Add a preauth module flag PA_TYPED_DATA_ERROR, which would be set
by the pkinit module to indicate that its e-data should be encoded as
typed data in non-FAST replies.

3. Change the DAL interface check_policy_as and check_policy_tgs
functions to take e_data as krb5_pa_data *** instead of krb5_data *.
Alternatively, we could remove the e_data arguments entirely, as I
don't think there are any use cases for the KDB module generating

Make kdcpreauth get_data more like clpreauth get_data

The clpreauth interface has a callback function named get_data which
receives a "rock" (opaque request handle).  The kdcpreauth interface
also has a callback function, but instead of a "rock" it takes a KDC
request and a DB entry.  This is problematic for FAST, which needs a
third piece of state to identify the FAST state.  Currently we hack
around this by including a FAST state pointer in KDC requests.

The proposal is to introduce a kdcpreauth "rock" object which is
opaque to the preauth module.  In the KDC, it would contain pointers
to the KDC request, client DB entry, and the FAST state.

This proposal slightly narrows the scope of what kdcpreauth plugins
can do.  Currently a kdcpreauth edata function can request the key
data for the server DB entry.  Sam and I don't think there's any
reason for it to do so.

Type-safe get_data callbacks

The current get_data callback functions aren't type-safe; callers have
to wrap parameters and responses in a krb5_data container.  This makes
them cumbersome to use as well as unsafe.  The upside is that it makes
the callbacks extensible in two ways: (1) new callbacks can be added
without breaking old modules, and (2) modules can use new callbacks
and still operate against old KDCs or libkrb5s, as long as they can
deal with the new callback returning ENOENT.

My proposal is to replace the get_data_fn parameters with vtable
pointers, where the vtable begins with a version field.

    typedef krb5_enctype
    (*krb5_clpreauth_get_etype_fn)(krb5_context context,
                                   krb5_clpreauth_rock rock);

    struct krb5_clpreauth_callbacks {
        int vers;
        krb5_clpreauth_get_etype_fn get_etype;
        krb5_clpreauth_get_fast_armor get_fast_armor;
        /* End of version 1 methods */

A module using a newer callback would have to check the version number
first.  The controversial part is that modules might neglect to check,
and then wouldn't fail gracefully when operating against older KDCs or

More information about the krbdev mailing list