summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Coffman <kwc@citi.umich.edu>2006-11-09 20:40:29 +0000
committerKevin Coffman <kwc@citi.umich.edu>2006-11-09 20:40:29 +0000
commita01105065c1e6d28870205337cbe01b26b1cafde (patch)
tree4b28bd09621f21b5085c3283b0d55befd6cdb81e
parentaf11fb8369ed3db1e7c98844f926a0d4292d1567 (diff)
downloadkrb5-a01105065c1e6d28870205337cbe01b26b1cafde.tar.gz
krb5-a01105065c1e6d28870205337cbe01b26b1cafde.tar.xz
krb5-a01105065c1e6d28870205337cbe01b26b1cafde.zip
Add "get_data" function to the client preauth plugin interface
Modify the client preauth plugin interface to pass in a function pointer and data pointer so the plugin may request information otherwise unavailable. ticket: new Tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18790 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/include/k5-int.h21
-rw-r--r--src/include/krb5/preauth_plugin.h22
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c14
-rw-r--r--src/lib/krb5/krb/preauth2.c72
-rw-r--r--src/plugins/preauth/cksum_body/cksum_body_main.c2
-rw-r--r--src/plugins/preauth/wpse/wpse_main.c2
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 <krb5/preauth_plugin.h>
+#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
@@ -122,6 +123,23 @@ typedef krb5_error_code
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,
* it's identical to the get_as_key callback used inside of libkrb5, but we
@@ -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,