Projects/Responder
Description
The response set mechanism is an alternative to the prompting interface for libkrb5 client preauth plugins.
Problem
The existing prompting interface permits client preauth plugins to ask questions of the user in order to resolve conflicts or ascertain data in order to properly process padata. Most commonly this is something akin to asking the user for a password. However, as time has progressed, user interfaces have moved from text based to graphical and the complexity of questions has increased markedly. This results in a situation where the prompter interface isn't adequate to resolve these complex question with subtle user interfaces. Specifically, client preauth plugins need a way to expose a well known API to the consumers of libkrb5 without libkrb5 knowing the details of this API.
Proposal
libkrb5 will add a new callback to gic_opts: typedef void * (*krb5_response_set_get_item_fn)(krb5_context context, krb5_response_set *rset, const char *name); typedef krb5_error_code (*krb5_responder_fn)(krb5_context context, void *data, krb5_response_set *rset, krb5_response_set_get_item_fn get_item); krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_responder(krb5_context context, krb5_get_init_creds_opt *opt, krb5_responder_fn responder, void *data);
This callback will be called after libkrb5 receives padata, but before the process() function of the clpreauth interface is called. The main purpose of the responder function is to process any values contained in the interfaces contained in the krb5_response_set. This data type is essentially a name to value mapping. The name is the unique name of some interface a clpreauth plugin wishes to expose to the consumer of libkrb5 and the (void*) value is a handle for the interface. The interface should be detailed in a public header and used both inside the clpreauth plugin and by the responder.
In order to populate the response set, a new (optional) function will be added to the clpreauth interface: typedef krb5_error_code (*krb5_clpreauth_fill_rset_fn)(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_pa_data *pa_data);
This function will be called after receiving padata, but before the process() function is called. Its responsibility is to identify any decisions that need to be made and to expose these decisions via the krb5_response_set data structure.
Expected Behavior
All memory stored within the interface exposed via krb5_response_set should be allocated and freed by the clpreauth plugin. The plugin should anticipate that the responder may not process one or more of its exposed interfaces. The plugin may fall back to the prompter interface in that case.