From aa75cd71bd41afb2b5cb524bb4ef9ca5d6ab721c Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Sat, 11 Nov 2006 01:57:17 +0000 Subject: [PATCH] pull up r18790 from trunk r18790@cathode-dark-space: coffman | 2006-11-09 15:40:29 -0500 ticket: new subject: Add "get_data" function to the client preauth plugin interface Tags: pullup Modify the client preauth plugin interface to pass in a function pointer and data pointer so the plugin may request information otherwise unavailable. ticket: 4690 version_fixed: 1.6 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@18796 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/k5-int.h | 21 +++++- src/include/krb5/preauth_plugin.h | 22 ++++++ src/lib/krb5/krb/get_in_tkt.c | 14 +++- src/lib/krb5/krb/preauth2.c | 72 ++++++++++++++++++- .../preauth/cksum_body/cksum_body_main.c | 2 + src/plugins/preauth/wpse/wpse_main.c | 2 + 6 files changed, 126 insertions(+), 7 deletions(-) diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 884bd23c8..13109e291 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -843,6 +843,17 @@ error(MIT_DES_KEYSIZE does not equal KRB5_MIT_DES_KEYSIZE) #include +#define CLIENT_ROCK_MAGIC 0x4352434b +/* This structure is passed into the client preauth functions and passed + * back to the "get_data_proc" function so that it can locate the + * requested information. It is opaque to the plugin code and can be + * expanded in the future as new types of requests are defined which + * may require other things to be passed through. */ +typedef struct _krb5_preauth_client_rock { + krb5_magic magic; + krb5_kdc_rep *as_reply; +} krb5_preauth_client_rock; + /* This structure lets us keep track of all of the modules which are loaded, * turning the list of modules and their lists of implemented preauth types * into a single list which we can walk easily. */ @@ -867,6 +878,8 @@ typedef struct _krb5_preauth_context { krb5_error_code (*client_process)(krb5_context context, void *plugin_context, void *request_context, + preauth_get_client_data_proc get_data_proc, + krb5_preauth_client_rock *rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, @@ -882,6 +895,8 @@ typedef struct _krb5_preauth_context { krb5_error_code (*client_tryagain)(krb5_context context, void *plugin_context, void *request_context, + preauth_get_client_data_proc get_data_proc, + krb5_preauth_client_rock *rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, @@ -1041,7 +1056,8 @@ krb5_error_code KRB5_CALLCONV krb5_do_preauth krb5_data *salt, krb5_data *s2kparams, krb5_enctype *etype, krb5_keyblock *as_key, krb5_prompter_fct prompter, void *prompter_data, - krb5_gic_get_as_key_fct gak_fct, void *gak_data); + krb5_gic_get_as_key_fct gak_fct, void *gak_data, + krb5_preauth_client_rock *get_data_rock); krb5_error_code KRB5_CALLCONV krb5_do_preauth_tryagain (krb5_context context, krb5_kdc_req *request, @@ -1052,7 +1068,8 @@ krb5_error_code KRB5_CALLCONV krb5_do_preauth_tryagain krb5_data *salt, krb5_data *s2kparams, krb5_enctype *etype, krb5_keyblock *as_key, krb5_prompter_fct prompter, void *prompter_data, - krb5_gic_get_as_key_fct gak_fct, void *gak_data); + krb5_gic_get_as_key_fct gak_fct, void *gak_data, + krb5_preauth_client_rock *get_data_rock); void KRB5_CALLCONV krb5_init_preauth_context (krb5_context); void KRB5_CALLCONV krb5_free_preauth_context diff --git a/src/include/krb5/preauth_plugin.h b/src/include/krb5/preauth_plugin.h index d164192af..f1b7dd334 100644 --- a/src/include/krb5/preauth_plugin.h +++ b/src/include/krb5/preauth_plugin.h @@ -44,6 +44,7 @@ */ struct _krb5_db_entry_new; struct _krb5_key_data; +struct _krb5_preauth_client_rock; /* * Preauth mechanism property flags, unified from previous definitions in the @@ -121,6 +122,23 @@ typedef krb5_error_code krb5_int32 request_type, krb5_data **); +/* + * A client module's callback functions are allowed to request various + * information to enable it to process a request. + */ +enum krb5plugin_preauth_client_request_type { + /* The returned krb5_data item holds the enctype used to encrypt the + * encrypted portion of the AS_REP packet. */ + krb5plugin_preauth_client_get_etype = 1, + /* Free the data returned from krb5plugin_preauth_client_req_get_etype */ + krb5plugin_preauth_client_free_etype = 2, +}; +typedef krb5_error_code +(*preauth_get_client_data_proc)(krb5_context, + struct _krb5_preauth_client_rock *, + krb5_int32 request_type, + krb5_data **); + /* * A callback which will obtain the user's long-term AS key by prompting the * user for the password, then salting it properly, and so on. For the moment, @@ -189,6 +207,8 @@ typedef struct krb5plugin_preauth_client_ftable_v0 { krb5_error_code (*process)(krb5_context context, void *plugin_context, void *request_context, + preauth_get_client_data_proc get_data_proc, + struct _krb5_preauth_client_rock *rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, @@ -207,6 +227,8 @@ typedef struct krb5plugin_preauth_client_ftable_v0 { krb5_error_code (*tryagain)(krb5_context context, void *plugin_context, void *request_context, + preauth_get_client_data_proc get_data_proc, + struct _krb5_preauth_client_rock *rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index 947984f62..a71d98d41 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -865,6 +865,7 @@ krb5_get_init_creds(krb5_context context, krb5_kdc_rep *local_as_reply; krb5_timestamp time_now; krb5_enctype etype = 0; + krb5_preauth_client_rock get_data_rock; /* initialize everything which will be freed at cleanup */ @@ -1091,6 +1092,9 @@ krb5_get_init_creds(krb5_context context, if (ret) goto cleanup; + get_data_rock.magic = CLIENT_ROCK_MAGIC; + get_data_rock.as_reply = NULL; + /* now, loop processing preauth data and talking to the kdc */ for (loopcount = 0; loopcount < MAX_IN_TKT_LOOPS; loopcount++) { if (!err_reply) { @@ -1106,7 +1110,8 @@ krb5_get_init_creds(krb5_context context, preauth_to_use, &request.padata, &salt, &s2kparams, &etype, &as_key, prompter, prompter_data, - gak_fct, gak_data))) + gak_fct, gak_data, + &get_data_rock))) goto cleanup; } else { /* retrying after an error other than PREAUTH_NEEDED, using e-data @@ -1119,7 +1124,8 @@ krb5_get_init_creds(krb5_context context, err_reply, &salt, &s2kparams, &etype, &as_key, prompter, prompter_data, - gak_fct, gak_data)) { + gak_fct, gak_data, + &get_data_rock)) { /* couldn't come up with anything better */ ret = err_reply->error + ERROR_TABLE_BASE_krb5; krb5_free_error(context, err_reply); @@ -1193,12 +1199,14 @@ krb5_get_init_creds(krb5_context context, if ((ret = sort_krb5_padata_sequence(context, &request.server->realm, local_as_reply->padata))) goto cleanup; + get_data_rock.as_reply = local_as_reply; if ((ret = krb5_do_preauth(context, &request, encoded_request_body, encoded_previous_request, local_as_reply->padata, &kdc_padata, &salt, &s2kparams, &etype, &as_key, prompter, - prompter_data, gak_fct, gak_data))) + prompter_data, gak_fct, gak_data, + &get_data_rock))) goto cleanup; /* XXX For 1.1.1 and prior KDC's, when SAM is used w/ USE_SAD_AS_KEY, diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c index 64823732f..b2a513e20 100644 --- a/src/lib/krb5/krb/preauth2.c +++ b/src/lib/krb5/krb/preauth2.c @@ -327,6 +327,66 @@ grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size, return 0; } +/* + * Retrieve a specific piece of information required by the plugin and + * return it in a new krb5_data item. There are separate request_types + * to obtain the data and free it. + * + * This may require massaging data into a contrived format, but it will + * hopefully keep us from having to reveal library-internal functions + * or data to the plugin modules. + */ + +static krb5_error_code +client_data_proc(krb5_context kcontext, + krb5_preauth_client_rock *rock, + krb5_int32 request_type, + krb5_data **retdata) +{ + krb5_data *ret; + char *data; + + if (rock->magic != CLIENT_ROCK_MAGIC) + return EINVAL; + if (retdata == NULL) + return EINVAL; + + switch (request_type) { + case krb5plugin_preauth_client_get_etype: + { + krb5_enctype *eptr; + if (rock->as_reply == NULL) + return ENOENT; + ret = malloc(sizeof(krb5_data)); + if (ret == NULL) + return ENOMEM; + data = malloc(sizeof(krb5_enctype)); + if (data == NULL) { + free(ret); + return ENOMEM; + } + ret->data = data; + ret->length = sizeof(krb5_enctype); + eptr = (krb5_enctype *)data; + *eptr = rock->as_reply->enc_part.enctype; + *retdata = ret; + return 0; + } + break; + case krb5plugin_preauth_client_free_etype: + ret = *retdata; + if (ret == NULL) + return 0; + if (ret->data) + free(ret->data); + free(ret); + return 0; + break; + default: + return EINVAL; + } +} + /* Tweak the request body, for now adding any enctypes which the module claims * to add support for to the list, but in the future perhaps doing more * involved things. */ @@ -370,6 +430,7 @@ krb5_run_preauth_plugins(krb5_context kcontext, krb5_data *salt, krb5_data *s2kparams, void *gak_data, + krb5_preauth_client_rock *get_data_rock, krb5_keyblock *as_key, krb5_pa_data ***out_pa_list, int *out_pa_list_size, @@ -413,6 +474,8 @@ krb5_run_preauth_plugins(krb5_context kcontext, ret = module->client_process(kcontext, module->plugin_context, module->request_context, + client_data_proc, + get_data_rock, request, encoded_request_body, encoded_previous_request, @@ -1221,7 +1284,8 @@ krb5_do_preauth_tryagain(krb5_context kcontext, krb5_enctype *etype, krb5_keyblock *as_key, krb5_prompter_fct prompter, void *prompter_data, - krb5_gic_get_as_key_fct gak_fct, void *gak_data) + krb5_gic_get_as_key_fct gak_fct, void *gak_data, + krb5_preauth_client_rock *get_data_rock) { krb5_error_code ret; krb5_pa_data *out_padata; @@ -1251,6 +1315,8 @@ krb5_do_preauth_tryagain(krb5_context kcontext, if ((*module->client_tryagain)(kcontext, module->plugin_context, module->request_context, + client_data_proc, + get_data_rock, request, encoded_request_body, encoded_previous_request, @@ -1283,7 +1349,8 @@ krb5_do_preauth(krb5_context context, krb5_enctype *etype, krb5_keyblock *as_key, krb5_prompter_fct prompter, void *prompter_data, - krb5_gic_get_as_key_fct gak_fct, void *gak_data) + krb5_gic_get_as_key_fct gak_fct, void *gak_data, + krb5_preauth_client_rock *get_data_rock) { int h, i, j, out_pa_list_size; int seen_etype_info2 = 0; @@ -1471,6 +1538,7 @@ krb5_do_preauth(krb5_context context, gak_fct, salt, s2kparams, gak_data, + get_data_rock, as_key, &out_pa_list, &out_pa_list_size, diff --git a/src/plugins/preauth/cksum_body/cksum_body_main.c b/src/plugins/preauth/cksum_body/cksum_body_main.c index abf019a75..8d7aa00af 100644 --- a/src/plugins/preauth/cksum_body/cksum_body_main.c +++ b/src/plugins/preauth/cksum_body/cksum_body_main.c @@ -78,6 +78,8 @@ static krb5_error_code client_process(krb5_context kcontext, void *client_plugin_context, void *client_request_context, + preauth_get_client_data_proc client_get_data_proc, + struct _krb5_preauth_client_rock *rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, diff --git a/src/plugins/preauth/wpse/wpse_main.c b/src/plugins/preauth/wpse/wpse_main.c index e7d7b6d55..8ccd7cd12 100644 --- a/src/plugins/preauth/wpse/wpse_main.c +++ b/src/plugins/preauth/wpse/wpse_main.c @@ -90,6 +90,8 @@ static krb5_error_code client_process(krb5_context kcontext, void *plugin_context, void *request_context, + preauth_get_client_data_proc client_get_data_proc, + struct _krb5_preauth_client_rock *rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, -- 2.26.2