logo_kerberos.gif

Difference between revisions of "Projects/Responder"

From K5Wiki
Jump to: navigation, search
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{project-early}}
+
{{project-rel|1.11}}
   
 
== Description ==
 
== Description ==
The response set mechanism is an alternative to the prompting interface for libkrb5 client preauth plugins.
 
  +
 
The responder mechanism is an alternative to the prompting interface for libkrb5 client preauth plugins.
   
 
== Problem ==
 
== 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 drastically. This results in a situation where the prompter interface is not the most efficient way to answer complex questions.
 
   
Further, the prompter interface requires linear interaction. If multiple questions are required, they have to be asked in serial. However, graphical interfaces present to option to answer multiple questions atomically.
 
 
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. This results in a situation where the prompter interface is not the most efficient way to answer complex questions.
   
The solution to this is to present the consumer of libkrb5 with a full list of all data needing to be processed and allow libkrb5 to resolve any questions in a global manner. 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.
 
 
Further, the prompter interface requires linear interaction. If multiple questions are required, they have to be asked in serial. However, graphical interfaces present to option to answer multiple questions simultaneously.
  +
  +
The responder mechanism presents the consumer of libkrb5 with a full list of questions needing answers. The responder callback can consider the list and answer whichever questions it chooses to. Each named question is a string contract between the preauth mechanism and the responder callback, allowing complex questions to be handled.
   
 
== Proposal ==
 
== Proposal ==
libkrb5 will add a new callback to gic_opts:
 
<nowiki>
 
typedef void *
 
(*krb5_response_set_get_item_fn)(krb5_context context, krb5_response_set *rset,
 
const char *name);
 
   
typedef krb5_error_code
 
  +
The responder allows client preauth plugins to define questions (and optional structured/encoded challenge data) which will be collected and asked once for the entire set from a libkrb5 callback. This callback can view which questions have been asked, optionally inspect the challenge data and then provide structured/encoded answers back to libkrb5. The end result is that inside the responder callback, the application has full knowledge of every question asked, including complex questions, and can provide back a single set of potentially complex answers.
(*krb5_responder_fn)(krb5_context context, void *data, krb5_response_set *rset,
 
krb5_response_set_get_item_fn get_item);
 
   
 
libkrb5 will add the following new functions and types to gic_opts:
 
<nowiki>
  +
typedef struct krb5_responder_context_st *krb5_responder_context;
  +
  +
const char * const * KRB5_CALLCONV
  +
krb5_responder_list_questions(krb5_context ctx, krb5_responder_context rctx);
  +
  +
const char * KRB5_CALLCONV
  +
krb5_responder_get_challenge(krb5_context ctx, krb5_responder_context rctx,
 
const char *question);
  +
  +
krb5_error_code KRB5_CALLCONV
  +
krb5_responder_set_answer(krb5_context ctx, krb5_responder_context rctx,
  +
const char *question, const char *answer);
  +
 
typedef krb5_error_code
  +
(*krb5_responder_fn)(krb5_context ctx, krb5_responder_context rctx,
  +
void *data);
   
 
krb5_error_code KRB5_CALLCONV
 
krb5_error_code KRB5_CALLCONV
Line 28: Line 41:
 
krb5_responder_fn responder, void *data);</nowiki>
 
krb5_responder_fn responder, void *data);</nowiki>
   
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.
+
The responder callback will be called after libkrb5 receives padata, but before the process() function of the clpreauth interface is called. The responder function will process some or all of the values contained in the response set.
   
In order to populate the response set, a new (optional) function will be added to the clpreauth interface:
+
In order to populate the set of questions, a new (optional) function will be added to the clpreauth interface:
<nowiki>
+
<nowiki>
 
typedef krb5_error_code
 
typedef krb5_error_code
(*krb5_clpreauth_fill_rset_fn)(krb5_context context,
+
(*krb5_clpreauth_prep_questions_fn)(krb5_context context,
krb5_clpreauth_moddata moddata,
+
krb5_clpreauth_moddata moddata,
krb5_clpreauth_modreq modreq,
+
krb5_clpreauth_modreq modreq,
krb5_get_init_creds_opt *opt,
+
krb5_get_init_creds_opt *opt,
krb5_clpreauth_callbacks cb,
+
krb5_clpreauth_callbacks cb,
krb5_clpreauth_rock rock,
+
krb5_clpreauth_rock rock,
krb5_kdc_req *request,
+
krb5_kdc_req *request,
krb5_data *encoded_request_body,
+
krb5_data *encoded_request_body,
krb5_data *encoded_previous_request,
+
krb5_data *encoded_previous_request,
krb5_pa_data *pa_data);</nowiki>
+
krb5_pa_data *pa_data);</nowiki>
   
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.
+
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 ==
 
== 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.
 
  +
  +
The questions, challenges and answers MUST all be printable UTF8. They can, however, contain encoded data. The preference for encoding is JSON.
  +
  +
== Testing ==
  +
  +
In lib/krb5/krb, a new program t_response_items will exercise the internal k5_response_items manipulation functions.
  +
  +
== Documentation ==
  +
  +
New API functions will have doxygen markup.
  +
  +
The new facility will be documented in init_creds.rst.
  +
  +
== Release notes ==
  +
  +
Developer experience:
  +
* Add an optional responder callback to the krb5_get_init_creds functions. The responder callback can consider and answer all preauth-related questions at once, and can process more complicated questions than the prompter.
  +
* Add a method to the clpreauth interface to allow modules to supply response items for consideration by the responder callback.

Latest revision as of 18:32, 17 September 2012

This project was completed in release 1.11.


Description

The responder 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. This results in a situation where the prompter interface is not the most efficient way to answer complex questions.

Further, the prompter interface requires linear interaction. If multiple questions are required, they have to be asked in serial. However, graphical interfaces present to option to answer multiple questions simultaneously.

The responder mechanism presents the consumer of libkrb5 with a full list of questions needing answers. The responder callback can consider the list and answer whichever questions it chooses to. Each named question is a string contract between the preauth mechanism and the responder callback, allowing complex questions to be handled.

Proposal

The responder allows client preauth plugins to define questions (and optional structured/encoded challenge data) which will be collected and asked once for the entire set from a libkrb5 callback. This callback can view which questions have been asked, optionally inspect the challenge data and then provide structured/encoded answers back to libkrb5. The end result is that inside the responder callback, the application has full knowledge of every question asked, including complex questions, and can provide back a single set of potentially complex answers.

libkrb5 will add the following new functions and types to gic_opts:

typedef struct krb5_responder_context_st *krb5_responder_context;

const char * const * KRB5_CALLCONV
krb5_responder_list_questions(krb5_context ctx, krb5_responder_context rctx);

const char * KRB5_CALLCONV
krb5_responder_get_challenge(krb5_context ctx, krb5_responder_context rctx,
                             const char *question);

krb5_error_code KRB5_CALLCONV
krb5_responder_set_answer(krb5_context ctx, krb5_responder_context rctx,
                          const char *question, const char *answer);

typedef krb5_error_code
(*krb5_responder_fn)(krb5_context ctx, krb5_responder_context rctx,
                     void *data);

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);

The responder callback will be called after libkrb5 receives padata, but before the process() function of the clpreauth interface is called. The responder function will process some or all of the values contained in the response set.

In order to populate the set of questions, a new (optional) function will be added to the clpreauth interface:

typedef krb5_error_code
(*krb5_clpreauth_prep_questions_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

The questions, challenges and answers MUST all be printable UTF8. They can, however, contain encoded data. The preference for encoding is JSON.

Testing

In lib/krb5/krb, a new program t_response_items will exercise the internal k5_response_items manipulation functions.

Documentation

New API functions will have doxygen markup.

The new facility will be documented in init_creds.rst.

Release notes

Developer experience:

  • Add an optional responder callback to the krb5_get_init_creds functions. The responder callback can consider and answer all preauth-related questions at once, and can process more complicated questions than the prompter.
  • Add a method to the clpreauth interface to allow modules to supply response items for consideration by the responder callback.