summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKevin Coffman <kwc@citi.umich.edu>2006-11-01 22:40:30 +0000
committerKevin Coffman <kwc@citi.umich.edu>2006-11-01 22:40:30 +0000
commit2b2f711f2addee052253e4ff54fb7cdf3e20c0ae (patch)
treea3e86969623f704a21780e47936a7a0ee5cd15f0 /src
parent45fde258dbced00d2db9d999d5749cb186f2250d (diff)
downloadkrb5-2b2f711f2addee052253e4ff54fb7cdf3e20c0ae.tar.gz
krb5-2b2f711f2addee052253e4ff54fb7cdf3e20c0ae.tar.xz
krb5-2b2f711f2addee052253e4ff54fb7cdf3e20c0ae.zip
Modify the preath plugin interface so that a plugin's context is
global to all the modules within a plugin. Also, change the client-side interface so that the preauth plugin context (once created) lives the lifetime of a krb5_context. This will allow future changes that can set plugin parameters. The client side request context lives the lifetime of a call to krb5_get_init_creds(). Make the sample preauth plugins buildable outside the source tree. Fix minor memory leak in sort_krb5_padata_sequence(). Add a prototype for krb5_do_preauth_tryagain() and change the plugin interface. Incorporates fixes from Nalin Dahyabhai <nalin@redhat.com> for leaks of the function table pointers (rt #4566) and fix KDC crash (rt #4567) ticket: 4566 ticket: 4567 ticket: 4587 Target_Version: 1.6 Tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18754 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/include/k5-int.h113
-rw-r--r--src/include/krb5/preauth_plugin.h56
-rw-r--r--src/kdc/kdc_preauth.c98
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c30
-rw-r--r--src/lib/krb5/krb/init_ctx.c1
-rw-r--r--src/lib/krb5/krb/preauth2.c267
-rw-r--r--src/lib/krb5/os/init_os_ctx.c5
-rw-r--r--src/plugins/preauth/cksum_body/Makefile.in6
-rw-r--r--src/plugins/preauth/cksum_body/cksum_body_main.c (renamed from src/plugins/preauth/cksum_body/src/cksum_body.c)41
-rw-r--r--src/plugins/preauth/wpse/Makefile.in6
-rw-r--r--src/plugins/preauth/wpse/wpse_main.c (renamed from src/plugins/preauth/wpse/src/wpse.c)111
11 files changed, 435 insertions, 299 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index f659e2e1e5..884bd23c8a 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -552,9 +552,6 @@ krb5int_locate_server (krb5_context, const krb5_data *realm,
#endif /* KRB5_LIBOS_PROTO__ */
-#include <krb5/preauth_plugin.h>
-typedef struct _krb5_preauth_context krb5_preauth_context;
-
/* new encryption provider api */
struct krb5_enc_provider {
@@ -844,6 +841,71 @@ error(MIT_DES_KEYSIZE does not equal KRB5_MIT_DES_KEYSIZE)
#ifndef KRB5_PREAUTH__
#define KRB5_PREAUTH__
+#include <krb5/preauth_plugin.h>
+
+/* 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. */
+typedef struct _krb5_preauth_context {
+ int n_modules;
+ struct _krb5_preauth_context_module {
+ /* Which of the possibly more than one preauth types which the
+ * module supports we're using at this point in the list. */
+ krb5_preauthtype pa_type;
+ /* Encryption types which the client claims to support -- we
+ * copy them directly into the krb5_kdc_req structure during
+ * krb5_preauth_prepare_request(). */
+ krb5_enctype *enctypes;
+ /* The plugin's per-plugin context and a function to clear it. */
+ void *plugin_context;
+ void (*client_fini)(krb5_context context, void *plugin_context);
+ /* The module's table, and some of its members, copied here for
+ * convenience when we populated the list. */
+ struct krb5plugin_preauth_client_ftable_v0 *ftable;
+ const char *name;
+ int flags, use_count;
+ krb5_error_code (*client_process)(krb5_context context,
+ void *plugin_context,
+ void *request_context,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data *pa_data,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ preauth_get_as_key_proc gak_fct,
+ void *gak_data,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_keyblock *as_key,
+ krb5_pa_data **out_pa_data);
+ krb5_error_code (*client_tryagain)(krb5_context context,
+ void *plugin_context,
+ void *request_context,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data *old_pa_data,
+ krb5_error *err_reply,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ preauth_get_as_key_proc gak_fct,
+ void *gak_data,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_keyblock *as_key,
+ krb5_pa_data **new_pa_data);
+ void (*client_req_init)(krb5_context context, void *plugin_context,
+ void **request_context);
+ void (*client_req_fini)(krb5_context context, void *plugin_context,
+ void *request_context);
+ /* The per-pa_type context which the client_process() function
+ * might allocate, which we'll need to clean up later by
+ * calling the client_cleanup() function. */
+ void *request_context;
+ } *modules;
+} krb5_preauth_context;
+
typedef struct _krb5_pa_enc_ts {
krb5_timestamp patimestamp;
krb5_int32 pausec;
@@ -970,23 +1032,39 @@ void krb5int_populate_gic_opt (
krb5_preauthtype *pre_auth_types, krb5_creds *creds);
-krb5_error_code krb5_do_preauth
-(krb5_context, krb5_preauth_context **, krb5_kdc_req *, krb5_data *,
- krb5_data *, krb5_pa_data **, krb5_pa_data ***,
- krb5_data *salt, krb5_data *s2kparams,
- krb5_enctype *,
- krb5_keyblock *,
- krb5_prompter_fct, void *,
- krb5_gic_get_as_key_fct, void *);
+krb5_error_code KRB5_CALLCONV krb5_do_preauth
+ (krb5_context context,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data **in_padata, krb5_pa_data ***out_padata,
+ 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_error_code KRB5_CALLCONV krb5_do_preauth_tryagain
+ (krb5_context context,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data **in_padata,
+ krb5_error *err_reply,
+ 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);
void KRB5_CALLCONV krb5_init_preauth_context
- (krb5_context, krb5_preauth_context **);
+ (krb5_context);
+void KRB5_CALLCONV krb5_free_preauth_context
+ (krb5_context);
void KRB5_CALLCONV krb5_clear_preauth_context_use_counts
- (krb5_context, krb5_preauth_context *);
+ (krb5_context);
void KRB5_CALLCONV krb5_preauth_prepare_request
- (krb5_context, krb5_preauth_context **,
- krb5_get_init_creds_opt *, krb5_kdc_req *);
-void KRB5_CALLCONV krb5_free_preauth_context
- (krb5_context, krb5_preauth_context *);
+ (krb5_context, krb5_get_init_creds_opt *, krb5_kdc_req *);
+void KRB5_CALLCONV krb5_preauth_request_context_init
+ (krb5_context);
+void KRB5_CALLCONV krb5_preauth_request_context_fini
+ (krb5_context);
void KRB5_CALLCONV krb5_free_sam_challenge
(krb5_context, krb5_sam_challenge * );
@@ -1079,6 +1157,7 @@ struct _krb5_context {
/* preauth module stuff */
struct plugin_dir_handle preauth_plugins;
+ krb5_preauth_context *preauth_context;
/* error detail info */
struct errinfo err;
diff --git a/src/include/krb5/preauth_plugin.h b/src/include/krb5/preauth_plugin.h
index 63600fead2..d164192aff 100644
--- a/src/include/krb5/preauth_plugin.h
+++ b/src/include/krb5/preauth_plugin.h
@@ -157,20 +157,27 @@ typedef struct krb5plugin_preauth_client_ftable_v0 {
* to add support for. */
krb5_enctype *enctype_list;
- /* Per-module initialization/cleanup. The init function is called
- * by libkrb5 when the module is loaded, and the fini function is
- * called before the module is unloaded. Both are optional and
- * may be called multiple times in case the module is used in
- * multiple contexts.*/
- krb5_error_code (*init)(krb5_context, krb5_preauthtype, void **);
- void (*fini)(krb5_context, krb5_preauthtype, void *);
+ /* Per-plugin initialization/cleanup. The init function is called
+ * by libkrb5 when the plugin is loaded, and the fini function is
+ * called before the plugin is unloaded. Both are optional and
+ * may be called multiple times in case the plugin is used in
+ * multiple contexts. The returned context lives the lifetime of
+ * the krb5_context */
+ krb5_error_code (*init)(krb5_context context, void **plugin_context);
+ void (*fini)(krb5_context context, void *plugin_context);
/* A callback which returns flags indicating if the module is a "real" or
* an "info" mechanism, and so on. This function is called for each entry
* in the client_pa_type_list. */
- int (*flags)(krb5_context, krb5_preauthtype);
- /* Clean up a client context. Can be NULL. */
- void (*cleanup)(krb5_context context, void *module_context,
+ int (*flags)(krb5_context context, krb5_preauthtype pa_type);
+ /* Per-request initialization/cleanup. The request_init function is
+ * called when beginning to process a get_init_creds request and the
+ * request_fini function is called when processing of the request is
+ * complete. This is optional. It may be called multiple times in
+ * the lifetime of a krb5_context. */
+ void (*request_init)(krb5_context context, void *plugin_context,
void **request_context);
+ void (*request_fini)(krb5_context context, void *plugin_context,
+ void *request_context);
/* Client function which processes server-supplied data in pa_data,
* returns created data in out_pa_data, storing any of its own state in
* client_context if data for the associated preauthentication type is
@@ -180,8 +187,8 @@ typedef struct krb5plugin_preauth_client_ftable_v0 {
* function is called, because it is expected to only ever contain the data
* obtained from a previous call to this function. */
krb5_error_code (*process)(krb5_context context,
- void *module_context,
- void **request_context,
+ void *plugin_context,
+ void *request_context,
krb5_kdc_req *request,
krb5_data *encoded_request_body,
krb5_data *encoded_previous_request,
@@ -189,8 +196,8 @@ typedef struct krb5plugin_preauth_client_ftable_v0 {
krb5_prompter_fct prompter,
void *prompter_data,
preauth_get_as_key_proc gak_fct,
- krb5_data *salt, krb5_data *s2kparams,
void *gak_data,
+ krb5_data *salt, krb5_data *s2kparams,
krb5_keyblock *as_key,
krb5_pa_data **out_pa_data);
/* Client function which can attempt to use e-data in the error response to
@@ -198,12 +205,19 @@ typedef struct krb5plugin_preauth_client_ftable_v0 {
* it stores data in out_pa_data which is different data from the contents
* of in_pa_data, then the client library will retransmit the request. */
krb5_error_code (*tryagain)(krb5_context context,
- void *module_context,
- void **request_context,
+ void *plugin_context,
+ void *request_context,
krb5_kdc_req *request,
krb5_data *encoded_request_body,
- krb5_error *error,
+ krb5_data *encoded_previous_request,
krb5_pa_data *in_pa_data,
+ krb5_error *error,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ preauth_get_as_key_proc gak_fct,
+ void *gak_data,
+ krb5_data *salt, krb5_data *s2kparams,
+ krb5_keyblock *as_key,
krb5_pa_data **out_pa_data);
} krb5plugin_preauth_client_ftable_v0;
@@ -223,11 +237,11 @@ typedef struct krb5plugin_preauth_server_ftable_v0 {
* provide services for. */
krb5_preauthtype *pa_type_list;
- /* Per-module initialization/cleanup. The init function is called by the
- * KDC when the module is loaded, and the fini function is called before
- * the module is unloaded. Both are optional. */
- krb5_error_code (*init_proc)(krb5_context, krb5_preauthtype, void **);
- void (*fini_proc)(krb5_context, krb5_preauthtype, void *);
+ /* Per-plugin initialization/cleanup. The init function is called by the
+ * KDC when the plugin is loaded, and the fini function is called before
+ * the plugin is unloaded. Both are optional. */
+ krb5_error_code (*init_proc)(krb5_context, void **);
+ void (*fini_proc)(krb5_context, void *);
/* Return the flags which the KDC should use for this module. This is a
* callback instead of a static value because the module may or may not
* wish to count itself as a hardware preauthentication module (in other
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 16af527a64..dfbb5fcc90 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -109,15 +109,15 @@ typedef krb5_error_code (*freepa_proc)
(krb5_context, void *pa_module_context, void **pa_request_context);
typedef krb5_error_code (*init_proc)
- (krb5_context, krb5_preauthtype, void **);
+ (krb5_context, void **);
typedef void (*fini_proc)
- (krb5_context, krb5_preauthtype, void *);
+ (krb5_context, void *);
typedef struct _krb5_preauth_systems {
const char *name;
int type;
int flags;
- void *pa_sys_context;
+ void *plugin_context;
init_proc init;
fini_proc fini;
edata_proc get_edata;
@@ -301,8 +301,7 @@ load_preauth_plugins(krb5_context context)
void **preauth_plugins_ftables;
struct krb5plugin_preauth_server_ftable_v0 *ftable;
int module_count, i, j, k;
- krb5_preauthtype pa_type;
- void *pa_sys_context;
+ void *plugin_context;
init_proc server_init_proc;
memset(&err, 0, sizeof(err));
@@ -349,6 +348,7 @@ load_preauth_plugins(krb5_context context)
* leave room for a terminator entry. */
preauth_systems = malloc(sizeof(krb5_preauth_systems) * (module_count + 1));
if (preauth_systems == NULL) {
+ krb5int_free_plugin_dir_data(preauth_plugins_ftables);
return ENOMEM;
}
@@ -361,15 +361,14 @@ load_preauth_plugins(krb5_context context)
preauth_systems[k] = static_preauth_systems[i];
/* Try to initialize the preauth system. If it fails, we'll remove it
* from the list of systems we'll be using. */
- pa_sys_context = NULL;
- pa_type = static_preauth_systems[i].type;
+ plugin_context = NULL;
server_init_proc = static_preauth_systems[i].init;
if ((server_init_proc != NULL) &&
- ((*server_init_proc)(context, pa_type, &pa_sys_context) != 0)) {
+ ((*server_init_proc)(context, &plugin_context) != 0)) {
memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
continue;
}
- preauth_systems[k].pa_sys_context = pa_sys_context;
+ preauth_systems[k].plugin_context = plugin_context;
k++;
}
@@ -383,28 +382,34 @@ load_preauth_plugins(krb5_context context)
(ftable->return_proc == NULL)) {
continue;
}
+ plugin_context = NULL;
for (j = 0;
ftable->pa_type_list != NULL &&
ftable->pa_type_list[j] > 0;
j++) {
- /* Try to initialize the module. If it fails, we'll remove it
+ /* Try to initialize the plugin. If it fails, we'll remove it
* from the list of modules we'll be using. */
- pa_sys_context = NULL;
- server_init_proc = ftable->init_proc;
- pa_type = ftable->pa_type_list[j];
- if ((server_init_proc != NULL) &&
- ((*server_init_proc)(context, pa_type,
- &pa_sys_context) != 0)) {
- memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
- continue;
+ if (j == 0) {
+ server_init_proc = ftable->init_proc;
+ if ((server_init_proc != NULL) &&
+ ((*server_init_proc)(context, &plugin_context) != 0)) {
+ memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
+ continue;
+ }
}
preauth_systems[k].name = ftable->name;
- pa_type = ftable->pa_type_list[j];
- preauth_systems[k].type = pa_type;
- preauth_systems[k].flags = ftable->flags_proc(context, pa_type);
- preauth_systems[k].pa_sys_context = pa_sys_context;
+ preauth_systems[k].type = ftable->pa_type_list[j];
+ if (ftable->flags_proc != NULL)
+ preauth_systems[k].flags = ftable->flags_proc(context, preauth_systems[k].type);
+ else
+ preauth_systems[k].flags = 0;
+ preauth_systems[k].plugin_context = plugin_context;
preauth_systems[k].init = server_init_proc;
- preauth_systems[k].fini = ftable->fini_proc;
+ /* Only call fini once for each plugin */
+ if (j == 0)
+ preauth_systems[k].fini = ftable->fini_proc;
+ else
+ preauth_systems[k].fini = NULL;
preauth_systems[k].get_edata = ftable->edata_proc;
preauth_systems[k].verify_padata = ftable->verify_proc;
preauth_systems[k].return_padata = ftable->return_proc;
@@ -413,6 +418,7 @@ load_preauth_plugins(krb5_context context)
k++;
}
}
+ krb5int_free_plugin_dir_data(preauth_plugins_ftables);
}
n_preauth_systems = k;
/* Add the end-of-list marker. */
@@ -429,8 +435,7 @@ unload_preauth_plugins(krb5_context context)
for (i = 0; i < n_preauth_systems; i++) {
if (preauth_systems[i].fini != NULL) {
(*preauth_systems[i].fini)(context,
- preauth_systems[i].type,
- preauth_systems[i].pa_sys_context);
+ preauth_systems[i].plugin_context);
}
memset(&preauth_systems[i], 0, sizeof(preauth_systems[i]));
}
@@ -506,7 +511,7 @@ free_padata_context(krb5_context kcontext, void **padata_context)
for (i = 0; i < context->n_contexts; i++) {
if (context->contexts[i].pa_context != NULL) {
preauth_system = context->contexts[i].pa_system;
- mctx = preauth_system->pa_sys_context;
+ mctx = preauth_system->plugin_context;
if (preauth_system->free_pa_request_context != NULL) {
pctx = &context->contexts[i].pa_context;
(*preauth_system->free_pa_request_context)(kcontext, mctx,
@@ -721,25 +726,28 @@ sort_pa_order(krb5_context context, krb5_kdc_req *request, int *pa_order)
}
}
- /* Now sort just the modules which replace the key, placing those which
- * handle the pa_data types provided by the client ahead of the others. */
- for (i = 0; preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY; i++) {
- continue;
- }
- n_key_replacers = i;
- for (i = 0; i < n_key_replacers; i++) {
- if (pa_list_includes(request->padata,
- preauth_systems[pa_order[i]].type))
+ if (request->padata != NULL) {
+ /* Now reorder the subset of modules which replace the key,
+ * bubbling those which handle pa_data types provided by the
+ * client ahead of the others. */
+ for (i = 0; preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY; i++) {
continue;
- for (j = i + 1; j < n_key_replacers; j++) {
+ }
+ n_key_replacers = i;
+ for (i = 0; i < n_key_replacers; i++) {
if (pa_list_includes(request->padata,
- preauth_systems[pa_order[j]].type)) {
- k = pa_order[j];
- pa_order[j] = pa_order[i];
- pa_order[i] = k;
- break;
+ preauth_systems[pa_order[i]].type))
+ continue;
+ for (j = i + 1; j < n_key_replacers; j++) {
+ if (pa_list_includes(request->padata,
+ preauth_systems[pa_order[j]].type)) {
+ k = pa_order[j];
+ pa_order[j] = pa_order[i];
+ pa_order[i] = k;
+ break;
+ }
}
- }
+ }
}
#ifdef DEBUG
krb5_klog_syslog(LOG_DEBUG, "original preauth mechanism list:");
@@ -827,7 +835,7 @@ void get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
(*pa)->pa_type = ap->type;
if (ap->get_edata) {
retval = (ap->get_edata)(kdc_context, request, client, server,
- get_entry_data, ap->pa_sys_context, *pa);
+ get_entry_data, ap->plugin_context, *pa);
if (retval) {
/* just failed on this type, continue */
free(*pa);
@@ -899,7 +907,7 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
pa_found++;
retval = pa_sys->verify_padata(context, client, req_pkt, request,
enc_tkt_reply, *padata,
- get_entry_data, pa_sys->pa_sys_context,
+ get_entry_data, pa_sys->plugin_context,
pa_context);
if (retval) {
const char * emsg = krb5_get_error_message (context, retval);
@@ -1046,7 +1054,7 @@ return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
}
if ((retval = ap->return_padata(context, pa, client, req_pkt, request, reply,
client_key, encrypting_key, send_pa,
- get_entry_data, ap->pa_sys_context,
+ get_entry_data, ap->plugin_context,
pa_context))) {
goto cleanup;
}
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 8d75c60c37..947984f62a 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -774,6 +774,7 @@ sort_krb5_padata_sequence(krb5_context context, krb5_data *realm,
long l;
char *q, *preauth_types = NULL;
krb5_pa_data *tmp;
+ int need_free_string = 1;
if ((padata == NULL) || (padata[0] == NULL)) {
return 0;
@@ -784,6 +785,7 @@ sort_krb5_padata_sequence(krb5_context context, krb5_data *realm,
if ((ret != 0) || (preauth_types == NULL)) {
/* Try to use PKINIT first. */
preauth_types = "17, 16, 15, 14";
+ need_free_string = 0;
}
#ifdef DEBUG
@@ -820,6 +822,8 @@ sort_krb5_padata_sequence(krb5_context context, krb5_data *realm,
}
}
}
+ if (need_free_string)
+ free(preauth_types);
#ifdef DEBUG
fprintf (stderr, "preauth data types after sorting:");
@@ -861,7 +865,6 @@ krb5_get_init_creds(krb5_context context,
krb5_kdc_rep *local_as_reply;
krb5_timestamp time_now;
krb5_enctype etype = 0;
- krb5_preauth_context *preauth_context;
/* initialize everything which will be freed at cleanup */
@@ -881,7 +884,6 @@ krb5_get_init_creds(krb5_context context,
local_as_reply = 0;
- preauth_context = NULL;
err_reply = NULL;
/*
@@ -1017,7 +1019,7 @@ krb5_get_init_creds(krb5_context context,
goto cleanup;
}
- krb5_init_preauth_context(context, &preauth_context);
+ krb5_preauth_request_context_init(context);
/* nonce is filled in by send_as_request if we don't take care of it */
@@ -1084,7 +1086,7 @@ krb5_get_init_creds(krb5_context context,
request.nonce = (krb5_int32) time_now;
/* give the preauth plugins a chance to prep the request body */
- krb5_preauth_prepare_request(context, &preauth_context, options, &request);
+ krb5_preauth_prepare_request(context, options, &request);
ret = encode_krb5_kdc_req_body(&request, &encoded_request_body);
if (ret)
goto cleanup;
@@ -1097,7 +1099,7 @@ krb5_get_init_creds(krb5_context context,
krb5_free_pa_data(context, request.padata);
request.padata = NULL;
}
- if ((ret = krb5_do_preauth(context, &preauth_context,
+ if ((ret = krb5_do_preauth(context,
&request,
encoded_request_body,
encoded_previous_request,
@@ -1109,14 +1111,13 @@ krb5_get_init_creds(krb5_context context,
} else {
/* retrying after an error other than PREAUTH_NEEDED, using e-data
* to figure out what to change */
- if (krb5_do_preauth_tryagain(context, &preauth_context,
+ if (krb5_do_preauth_tryagain(context,
&request,
encoded_request_body,
encoded_previous_request,
- preauth_to_use, err_reply,
- &request.padata,
- &salt, &s2kparams,
- &etype, &as_key,
+ preauth_to_use,
+ err_reply,
+ &salt, &s2kparams, &etype, &as_key,
prompter, prompter_data,
gak_fct, gak_data)) {
/* couldn't come up with anything better */
@@ -1188,11 +1189,11 @@ krb5_get_init_creds(krb5_context context,
}
/* process any preauth data in the as_reply */
- krb5_clear_preauth_context_use_counts(context, preauth_context);
+ krb5_clear_preauth_context_use_counts(context);
if ((ret = sort_krb5_padata_sequence(context, &request.server->realm,
local_as_reply->padata)))
goto cleanup;
- if ((ret = krb5_do_preauth(context, &preauth_context,
+ if ((ret = krb5_do_preauth(context,
&request,
encoded_request_body, encoded_previous_request,
local_as_reply->padata, &kdc_padata,
@@ -1252,10 +1253,7 @@ krb5_get_init_creds(krb5_context context,
ret = 0;
cleanup:
- if (preauth_context != NULL) {
- krb5_free_preauth_context(context, preauth_context);
- preauth_context = NULL;
- }
+ krb5_preauth_request_context_fini(context);
if (encoded_previous_request != NULL) {
krb5_free_data(context, encoded_previous_request);
encoded_previous_request = NULL;
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 46c3068eee..5ce00169a3 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -535,6 +535,7 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out)
nctx->os_context->default_ccname = NULL;
memset(&nctx->preauth_plugins, 0, sizeof(nctx->preauth_plugins));
+ nctx->preauth_context = NULL;
memset(&nctx->libkrb5_plugins, 0, sizeof(nctx->libkrb5_plugins));
nctx->vtbl = NULL;
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index ce2bf68834..64823732fb 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -59,76 +59,25 @@ typedef struct _pa_types_t {
int flags;
} pa_types_t;
-/* 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. */
-struct _krb5_preauth_context {
- int n_modules;
- struct _krb5_preauth_context_module {
- /* Which of the possibly more than one preauth types which the
- * module supports we're using at this point in the list. */
- krb5_preauthtype pa_type;
- /* Encryption types which the client claims to support -- we
- * copy them directly into the krb5_kdc_req structure during
- * krb5_preauth_prepare_request(). */
- krb5_enctype *enctypes;
- /* The module's per-module context and a function to clear it. */
- void *module_context;
- void (*client_fini)(krb5_context context, krb5_preauthtype pa_type,
- void *module_context);
- /* The module's table, and some of its members, copied here for
- * convenience when we populated the list. */
- struct krb5plugin_preauth_client_ftable_v0 *ftable;
- const char *name;
- int flags, use_count;
- krb5_error_code (*client_process)(krb5_context context,
- void *module_context,
- void **request_context,
- krb5_kdc_req *request,
- krb5_data *encoded_request_body,
- krb5_data *encoded_previous_request,
- krb5_pa_data *pa_data,
- krb5_prompter_fct prompter,
- void *prompter_data,
- preauth_get_as_key_proc gak_fct,
- krb5_data *salt,
- krb5_data *s2kparams,
- void *gak_data,
- krb5_keyblock *as_key,
- krb5_pa_data **out_pa_data);
- krb5_error_code (*client_tryagain)(krb5_context context,
- void *module_context,
- void **request_context,
- krb5_kdc_req *request,
- krb5_data *encoded_request_body,
- krb5_error *err_reply,
- krb5_pa_data *old_pa_data,
- krb5_pa_data **new_pa_data);
- void (*client_cleanup)(krb5_context context, void *module_context,
- void **request_context);
- /* The per-pa_type context which the client_process() function
- * might allocate, which we'll need to clean up later by
- * calling the client_cleanup() function. */
- void *request_context;
- } *modules;
-};
-
-/* Create the per-AS-REQ context. This means loading the modules if we haven't
- * done that yet (applications which never obtain initial credentials should
- * never hit this routine), breaking up the module's list of support pa_types
- * so that we can iterate over the modules more easily, and copying over the
- * relevant parts of the module's table. */
+/* Create the per-krb5_context context. This means loading the modules
+ * if we haven't done that yet (applications which never obtain initial
+ * credentials should never hit this routine), breaking up the module's
+ * list of support pa_types so that we can iterate over the modules more
+ * easily, and copying over the relevant parts of the module's table. */
void
-krb5_init_preauth_context(krb5_context kcontext,
- krb5_preauth_context **preauth_context)
+krb5_init_preauth_context(krb5_context kcontext)
{
int n_modules, n_tables, i, j, k;
void **tables;
struct krb5plugin_preauth_client_ftable_v0 *table;
- krb5_preauth_context *context;
- void *module_context;
+ krb5_preauth_context *context = NULL;
+ void *plugin_context;
krb5_preauthtype pa_type;
+ /* Only do this once for each krb5_context */
+ if (kcontext->preauth_context != NULL)
+ return;
+
/* load the plugins for the current context */
if (PLUGIN_DIR_OPEN(&kcontext->preauth_plugins) == 0) {
if (krb5int_open_plugin_dirs(objdirs, NULL,
@@ -167,10 +116,12 @@ krb5_init_preauth_context(krb5_context kcontext,
/* allocate the space we need */
context = malloc(sizeof(*context));
if (context == NULL) {
+ krb5int_free_plugin_dir_data(tables);
return;
}
context->modules = malloc(sizeof(context->modules[0]) * n_modules);
if (context->modules == NULL) {
+ krb5int_free_plugin_dir_data(tables);
free(context);
return;
}
@@ -182,28 +133,40 @@ krb5_init_preauth_context(krb5_context kcontext,
for (i = 0; i < n_tables; i++) {
table = tables[i];
if ((table->pa_type_list != NULL) && (table->process != NULL)) {
- for (j = 0; table->pa_type_list[j] > 0; j++) {
- pa_type = table->pa_type_list[j];
- module_context = NULL;
- if ((table->init != NULL) &&
- ((*table->init)(kcontext, pa_type, &module_context) != 0)) {
+ plugin_context = NULL;
+ if ((table->init != NULL) &&
+ ((*table->init)(kcontext, &plugin_context) != 0)) {
#ifdef DEBUG
- fprintf (stderr, "skip module \"%s\", pa_type %d\n",
- table->name, pa_type);
+ fprintf (stderr, "init err, skipping module \"%s\"\n",
+ table->name);
#endif
- continue;
- }
+ continue;
+ }
+
+ for (j = 0; table->pa_type_list[j] > 0; j++) {
+ pa_type = table->pa_type_list[j];
context->modules[k].pa_type = pa_type;
context->modules[k].enctypes = table->enctype_list;
- context->modules[k].module_context = module_context;
- context->modules[k].client_fini = table->fini;
+ context->modules[k].plugin_context = plugin_context;
+ /* Only call client_fini once per plugin */
+ if (j == 0)
+ context->modules[k].client_fini = table->fini;
+ else
+ context->modules[k].client_fini = NULL;
context->modules[k].ftable = table;
context->modules[k].name = table->name;
context->modules[k].flags = (*table->flags)(kcontext, pa_type);
context->modules[k].use_count = 0;
context->modules[k].client_process = table->process;
context->modules[k].client_tryagain = table->tryagain;
- context->modules[k].client_cleanup = table->cleanup;
+ /* Only call request_init and request_fini once per plugin */
+ if (j == 0) {
+ context->modules[k].client_req_init = table->request_init;
+ context->modules[k].client_req_fini = table->request_fini;
+ } else {
+ context->modules[k].client_req_init = NULL;
+ context->modules[k].client_req_fini = NULL;
+ }
context->modules[k].request_context = NULL;
#ifdef DEBUG
fprintf (stderr, "init module \"%s\", pa_type %d, flag %d\n",
@@ -215,60 +178,92 @@ krb5_init_preauth_context(krb5_context kcontext,
}
}
}
+ krb5int_free_plugin_dir_data(tables);
/* return the result */
- *preauth_context = context;
+ kcontext->preauth_context = context;
}
/* Zero the use counts for the modules herein. Usually used before we
* start processing any data from the server, at which point every module
* will again be able to take a crack at whatever the server sent. */
void
-krb5_clear_preauth_context_use_counts(krb5_context context,
- krb5_preauth_context *preauth_context)
+krb5_clear_preauth_context_use_counts(krb5_context context)
{
int i;
- if (preauth_context != NULL) {
- for (i = 0; i < preauth_context->n_modules; i++) {
- preauth_context->modules[i].use_count = 0;
+ if (context->preauth_context != NULL) {
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ context->preauth_context->modules[i].use_count = 0;
}
}
}
-/* Free the per-AS-REQ context. This means clearing any module-specific or
- * request-specific context which the modules may have created, and then
+/* Free the per-krb5_context preauth_context. This means clearing any
+ * plugin-specific context which may have been created, and then
* freeing the context itself. */
void
-krb5_free_preauth_context(krb5_context context,
- krb5_preauth_context *preauth_context)
+krb5_free_preauth_context(krb5_context context)
{
int i;
- krb5_preauthtype pa_type;
- void **rctx, *mctx;
- if (preauth_context != NULL) {
- for (i = 0; i < preauth_context->n_modules; i++) {
- mctx = preauth_context->modules[i].module_context;
- if (preauth_context->modules[i].request_context != NULL) {
- if (preauth_context->modules[i].client_cleanup != NULL) {
- rctx = &preauth_context->modules[i].request_context;
- preauth_context->modules[i].client_cleanup(context,
- mctx, rctx);
- }
- preauth_context->modules[i].request_context = NULL;
+ void *pctx;
+ if (context->preauth_context != NULL) {
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ pctx = context->preauth_context->modules[i].plugin_context;
+ if (context->preauth_context->modules[i].client_fini != NULL) {
+ (*context->preauth_context->modules[i].client_fini)(context, pctx);
}
- if (preauth_context->modules[i].client_fini != NULL) {
- pa_type = preauth_context->modules[i].pa_type;
- (*preauth_context->modules[i].client_fini)(context, pa_type,
- mctx);
+ memset(&context->preauth_context->modules[i], 0,
+ sizeof(context->preauth_context->modules[i]));
+ }
+ if (context->preauth_context->modules != NULL) {
+ free(context->preauth_context->modules);
+ context->preauth_context->modules = NULL;
+ }
+ free(context->preauth_context);
+ context->preauth_context = NULL;
+ }
+}
+
+/* Initialize the per-AS-REQ context. This means calling the client_req_init
+ * function to give the plugin a chance to allocate a per-request context. */
+void
+krb5_preauth_request_context_init(krb5_context context)
+{
+ int i;
+ void *rctx, *pctx;
+
+ /* Limit this to only one attempt per context? */
+ if (context->preauth_context == NULL)
+ krb5_init_preauth_context(context);
+ if (context->preauth_context != NULL) {
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ pctx = context->preauth_context->modules[i].plugin_context;
+ if (context->preauth_context->modules[i].client_req_init != NULL) {
+ rctx = &context->preauth_context->modules[i].request_context;
+ (*context->preauth_context->modules[i].client_req_init) (context, pctx, rctx);
}
- memset(&preauth_context->modules[i], 0,
- sizeof(preauth_context->modules[i]));
}
- if (preauth_context->modules != NULL) {
- free(preauth_context->modules);
- preauth_context->modules = NULL;
+ }
+}
+
+/* Free the per-AS-REQ context. This means clearing any request-specific
+ * context which the plugin may have created. */
+void
+krb5_preauth_request_context_fini(krb5_context context)
+{
+ int i;
+ void *rctx, *pctx;
+ if (context->preauth_context != NULL) {
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ pctx = context->preauth_context->modules[i].plugin_context;
+ rctx = context->preauth_context->modules[i].request_context;
+ if (rctx != NULL) {
+ if (context->preauth_context->modules[i].client_req_fini != NULL) {
+ (*context->preauth_context->modules[i].client_req_fini)(context, pctx, rctx);
+ }
+ context->preauth_context->modules[i].request_context = NULL;
+ }
}
- free(preauth_context);
}
}
@@ -337,24 +332,23 @@ grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size,
* involved things. */
void
krb5_preauth_prepare_request(krb5_context kcontext,
- krb5_preauth_context **preauth_context,
krb5_get_init_creds_opt *options,
krb5_kdc_req *request)
{
int i, j;
- if ((preauth_context == NULL) || (*preauth_context == NULL)) {
+ if (kcontext->preauth_context == NULL) {
return;
}
/* Add the module-specific enctype list to the request, but only if
* it's something we can safely modify. */
if (!(options && (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST))) {
- for (i = 0; i < (*preauth_context)->n_modules; i++) {
- if ((*preauth_context)->modules[i].enctypes == NULL)
+ for (i = 0; i < kcontext->preauth_context->n_modules; i++) {
+ if (kcontext->preauth_context->modules[i].enctypes == NULL)
continue;
- for (j = 0; (*preauth_context)->modules[i].enctypes[j] != 0; j++) {
+ for (j = 0; kcontext->preauth_context->modules[i].enctypes[j] != 0; j++) {
grow_ktypes(&request->ktype, &request->nktypes,
- (*preauth_context)->modules[i].enctypes[j]);
+ kcontext->preauth_context->modules[i].enctypes[j]);
}
}
}
@@ -365,7 +359,6 @@ krb5_preauth_prepare_request(krb5_context kcontext,
* they don't generate preauth data), and run it. */
static krb5_error_code
krb5_run_preauth_plugins(krb5_context kcontext,
- krb5_preauth_context *preauth_context,
int module_required_flags,
krb5_kdc_req *request,
krb5_data *encoded_request_body,
@@ -388,12 +381,12 @@ krb5_run_preauth_plugins(krb5_context kcontext,
krb5_error_code ret;
struct _krb5_preauth_context_module *module;
- if (preauth_context == NULL) {
+ if (kcontext->preauth_context == NULL) {
return ENOENT;
}
/* iterate over all loaded modules */
- for (i = 0; i < preauth_context->n_modules; i++) {
- module = &preauth_context->modules[i];
+ for (i = 0; i < kcontext->preauth_context->n_modules; i++) {
+ module = &kcontext->preauth_context->modules[i];
/* skip over those which don't match the preauth type */
if (module->pa_type != in_padata->pa_type)
continue;
@@ -418,14 +411,14 @@ krb5_run_preauth_plugins(krb5_context kcontext,
module->name, module->pa_type, module->flags);
#endif
ret = module->client_process(kcontext,
- module->module_context,
- &module->request_context,
+ module->plugin_context,
+ module->request_context,
request,
encoded_request_body,
encoded_previous_request,
in_padata,
prompter, prompter_data,
- gak_fct, salt, s2kparams, gak_data,
+ gak_fct, gak_data, salt, s2kparams,
as_key,
&out_pa_data);
/* Make note of the module's flags and status. */
@@ -439,7 +432,7 @@ krb5_run_preauth_plugins(krb5_context kcontext,
}
break;
}
- if (i >= preauth_context->n_modules) {
+ if (i >= kcontext->preauth_context->n_modules) {
return ENOENT;
}
return 0;
@@ -1219,10 +1212,16 @@ static const pa_types_t pa_types[] = {
*/
krb5_error_code
krb5_do_preauth_tryagain(krb5_context kcontext,
- krb5_preauth_context **preauth_context,
krb5_kdc_req *request,
krb5_data *encoded_request_body,
- krb5_error *err_reply, krb5_pa_data **padata)
+ krb5_data *encoded_previous_request,
+ krb5_pa_data **padata,
+ krb5_error *err_reply,
+ 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_error_code ret;
krb5_pa_data *out_padata;
@@ -1231,10 +1230,10 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
int i, j;
ret = KRB_ERR_GENERIC;
- if (preauth_context == NULL) {
+ if (kcontext->preauth_context == NULL) {
return KRB_ERR_GENERIC;
}
- context = *preauth_context;
+ context = kcontext->preauth_context;
if (context == NULL) {
return KRB_ERR_GENERIC;
}
@@ -1250,12 +1249,16 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
continue;
}
if ((*module->client_tryagain)(kcontext,
- module->module_context,
+ module->plugin_context,
module->request_context,
request,
encoded_request_body,
- err_reply,
+ encoded_previous_request,
padata[i],
+ err_reply,
+ prompter, prompter_data,
+ gak_fct, gak_data, salt, s2kparams,
+ as_key,
&out_padata) == 0) {
if (out_padata != NULL) {
if (padata[i]->contents != NULL)
@@ -1272,7 +1275,6 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
krb5_error_code
krb5_do_preauth(krb5_context context,
- krb5_preauth_context **preauth_context,
krb5_kdc_req *request,
krb5_data *encoded_request_body,
krb5_data *encoded_previous_request,
@@ -1450,18 +1452,15 @@ krb5_do_preauth(krb5_context context,
}
/* Try to use plugins now. */
- if ((!realdone) && (preauth_context != NULL)) {
- if (*preauth_context == NULL) {
- krb5_init_preauth_context(context, preauth_context);
- }
- if (*preauth_context != NULL) {
+ if (!realdone) {
+ krb5_init_preauth_context(context);
+ if (context->preauth_context != NULL) {
int module_ret, module_flags;
#ifdef DEBUG
fprintf (stderr, "trying modules for pa_type %d, flag %d\n",
in_padata[i]->pa_type, paorder[h]);
#endif
ret = krb5_run_preauth_plugins(context,
- *preauth_context,
paorder[h],
request,
encoded_request_body,
diff --git a/src/lib/krb5/os/init_os_ctx.c b/src/lib/krb5/os/init_os_ctx.c
index bc7e007ff7..b3d8dcf8c5 100644
--- a/src/lib/krb5/os/init_os_ctx.c
+++ b/src/lib/krb5/os/init_os_ctx.c
@@ -392,6 +392,7 @@ krb5_os_init_context(krb5_context ctx, krb5_boolean kdc)
ctx->vtbl = 0;
PLUGIN_DIR_INIT(&ctx->libkrb5_plugins);
PLUGIN_DIR_INIT(&ctx->preauth_plugins);
+ ctx->preauth_context = NULL;
retval = os_init_paths(ctx, kdc);
/*
@@ -493,6 +494,10 @@ krb5_os_free_context(krb5_context ctx)
ctx->profile = 0;
}
+ if (ctx->preauth_context) {
+ krb5_free_preauth_context(ctx);
+ ctx->preauth_context = NULL;
+ }
krb5int_close_plugin_dirs (&ctx->preauth_plugins);
krb5int_close_plugin_dirs (&ctx->libkrb5_plugins);
diff --git a/src/plugins/preauth/cksum_body/Makefile.in b/src/plugins/preauth/cksum_body/Makefile.in
index ddac24dcad..83d7cdb5b5 100644
--- a/src/plugins/preauth/cksum_body/Makefile.in
+++ b/src/plugins/preauth/cksum_body/Makefile.in
@@ -9,7 +9,7 @@ PROG_RPATH=$(KRB5_LIBDIR)
MODULE_INSTALL_DIR = $(KRB5_PA_MODULE_DIR)
DEFS=@DEFS@
-LOCALINCLUDES = -I../../../include/krb5
+LOCALINCLUDES = -I../../../include/krb5 -I.
LIBBASE=cksum_body
LIBMAJOR=0
@@ -25,9 +25,9 @@ SHLIB_EXPLIBS= -lkrb5 -lcom_err -lk5crypto $(SUPPORT_LIB) $(LIBS)
SHLIB_DIRS=-L$(TOPLIBD)
SHLIB_RDIRS=$(KRB5_LIBDIR)
STOBJLISTS=OBJS.ST
-STLIBOBJS=src/cksum_body.o
+STLIBOBJS=cksum_body_main.o
-SRCS= $(srcdir)/src/cksum_body.c
+SRCS= $(srcdir)/cksum_body_main.c
all-unix:: $(LIBBASE)$(SO_EXT)
install-unix:: install-libs
diff --git a/src/plugins/preauth/cksum_body/src/cksum_body.c b/src/plugins/preauth/cksum_body/cksum_body_main.c
index 31ecaf839e..abf019a754 100644
--- a/src/plugins/preauth/cksum_body/src/cksum_body.c
+++ b/src/plugins/preauth/cksum_body/cksum_body_main.c
@@ -44,7 +44,7 @@
#ident "$Id$"
#ifdef HAVE_CONFIG_H
-#include "../config.h"
+#include "config.h"
#endif
#ifdef HAVE_ERRNO_H
@@ -76,8 +76,8 @@ client_get_flags(krb5_context kcontext, krb5_preauthtype pa_type)
static krb5_error_code
client_process(krb5_context kcontext,
- void *client_module_context,
- void **client_request_context,
+ void *client_plugin_context,
+ void *client_request_context,
krb5_kdc_req *request,
krb5_data *encoded_request_body,
krb5_data *encoded_previous_request,
@@ -85,8 +85,8 @@ client_process(krb5_context kcontext,
krb5_prompter_fct prompter,
void *prompter_data,
preauth_get_as_key_proc gak_fct,
- krb5_data *salt, krb5_data *s2kparams,
void *gak_data,
+ krb5_data *salt, krb5_data *s2kparams,
krb5_keyblock *as_key,
krb5_pa_data **out_pa_data)
{
@@ -94,7 +94,7 @@ client_process(krb5_context kcontext,
krb5_checksum checksum;
krb5_enctype enctype;
krb5_cksumtype *cksumtypes;
- krb5_error_code status;
+ krb5_error_code status = 0;
krb5_int32 cksumtype, *enctypes;
unsigned int i, n_enctypes, cksumtype_count;
@@ -193,8 +193,7 @@ client_process(krb5_context kcontext,
/* Initialize and tear down the server-side module, and do stat tracking. */
static krb5_error_code
-server_init(krb5_context kcontext, krb5_preauthtype pa_type,
- void **module_context)
+server_init(krb5_context kcontext, void **module_context)
{
struct server_stats *stats;
stats = malloc(sizeof(struct server_stats));
@@ -206,15 +205,14 @@ server_init(krb5_context kcontext, krb5_preauthtype pa_type,
return 0;
}
static void
-server_fini(krb5_context kcontext, krb5_preauthtype pa_type,
- void *module_context)
+server_fini(krb5_context kcontext, void *module_context)
{
struct server_stats *stats;
stats = module_context;
if (stats != NULL) {
#ifdef DEBUG
- fprintf(stderr, "Total %d clients failed pa_type %d, %d succeeded.\n",
- stats->failures, pa_type, stats->successes);
+ fprintf(stderr, "Total: %d clients failed, %d succeeded.\n",
+ stats->failures, stats->successes);
#endif
free(stats);
}
@@ -254,7 +252,7 @@ server_get_edata(krb5_context kcontext,
krb5_free_keyblock_contents(kcontext, &keys[i]);
/* Return the list of encryption types. */
- enctypes = malloc(i * 4);
+ enctypes = malloc((unsigned)i * 4);
if (enctypes == NULL) {
krb5_free_data(kcontext, key_data);
return ENOMEM;
@@ -469,15 +467,16 @@ static krb5_preauthtype supported_server_pa_types[] = {
};
struct krb5plugin_preauth_client_ftable_v0 preauthentication_client_0 = {
- "cksum_body",
- &supported_client_pa_types[0],
- NULL,
- NULL,
- NULL,
- client_get_flags,
- NULL,
- client_process,
- NULL,
+ "cksum_body", /* name */
+ &supported_client_pa_types[0], /* pa_type_list */
+ NULL, /* enctype_list */
+ NULL, /* plugin init function */
+ NULL, /* plugin fini function */
+ client_get_flags, /* get flags function */
+ NULL, /* request init function */
+ NULL, /* request fini function */
+ client_process, /* process function */
+ NULL, /* try_again function */
};
struct krb5plugin_preauth_server_ftable_v0 preauthentication_server_0 = {
diff --git a/src/plugins/preauth/wpse/Makefile.in b/src/plugins/preauth/wpse/Makefile.in
index 6b18a7c064..6c2830f50b 100644
--- a/src/plugins/preauth/wpse/Makefile.in
+++ b/src/plugins/preauth/wpse/Makefile.in
@@ -9,7 +9,7 @@ PROG_RPATH=$(KRB5_LIBDIR)
MODULE_INSTALL_DIR = $(KRB5_PA_MODULE_DIR)
DEFS=@DEFS@
-LOCALINCLUDES = -I../../../include/krb5
+LOCALINCLUDES = -I../../../include/krb5 -I.
LIBBASE=wpse
LIBMAJOR=0
@@ -25,9 +25,9 @@ SHLIB_EXPLIBS= -lkrb5 -lcom_err -lk5crypto $(SUPPORT_LIB) $(LIBS)
SHLIB_DIRS=-L$(TOPLIBD)
SHLIB_RDIRS=$(KRB5_LIBDIR)
STOBJLISTS=OBJS.ST
-STLIBOBJS=src/wpse.o
+STLIBOBJS=wpse_main.o
-SRCS= $(srcdir)/src/wpse.c
+SRCS=wpse_main.c
all-unix:: $(LIBBASE)$(SO_EXT)
install-unix:: install-libs
diff --git a/src/plugins/preauth/wpse/src/wpse.c b/src/plugins/preauth/wpse/wpse_main.c
index 07c52d95a3..e7d7b6d557 100644
--- a/src/plugins/preauth/wpse/src/wpse.c
+++ b/src/plugins/preauth/wpse/wpse_main.c
@@ -33,7 +33,7 @@
#ident "$Id$"
#ifdef HAVE_CONFIG_H
-#include "../config.h"
+#include "config.h"
#endif
#ifdef HAVE_ERRNO_H
@@ -60,36 +60,36 @@ client_get_flags(krb5_context kcontext, krb5_preauthtype pa_type)
}
static krb5_error_code
-client_init(krb5_context kcontext, krb5_preauthtype pa_type, void **ctx)
+client_init(krb5_context kcontext, void **ctx)
{
- int *mctx;
+ int *pctx;
- mctx = malloc(sizeof(int));
- if (mctx == NULL)
+ pctx = malloc(sizeof(int));
+ if (pctx == NULL)
return ENOMEM;
- *mctx = 0;
- *ctx = mctx;
+ *pctx = 0;
+ *ctx = pctx;
return 0;
}
static void
-client_fini(krb5_context kcontext, krb5_preauthtype pa_type, void *ctx)
+client_fini(krb5_context kcontext, void *ctx)
{
- int *mctx;
+ int *pctx;
- mctx = ctx;
- if (mctx) {
+ pctx = ctx;
+ if (pctx) {
#ifdef DEBUG
- fprintf(stderr, "wpse module called total of %d times\n", *mctx);
+ fprintf(stderr, "wpse module called total of %d times\n", *pctx);
#endif
- free(mctx);
+ free(pctx);
}
}
static krb5_error_code
client_process(krb5_context kcontext,
- void *module_context,
- void **request_context,
+ void *plugin_context,
+ void *request_context,
krb5_kdc_req *request,
krb5_data *encoded_request_body,
krb5_data *encoded_previous_request,
@@ -97,8 +97,8 @@ client_process(krb5_context kcontext,
krb5_prompter_fct prompter,
void *prompter_data,
preauth_get_as_key_proc gak_fct,
- krb5_data *salt, krb5_data *s2kparams,
void *gak_data,
+ krb5_data *salt, krb5_data *s2kparams,
krb5_keyblock *as_key,
krb5_pa_data **out_pa_data)
{
@@ -106,16 +106,16 @@ client_process(krb5_context kcontext,
krb5_int32 nnonce, enctype;
krb5_keyblock *kb;
krb5_error_code status;
- int *mctx;
+ int *pctx;
#ifdef DEBUG
fprintf(stderr, "%d bytes of preauthentication data (type %d)\n",
pa_data->length, pa_data->pa_type);
#endif
- mctx = module_context;
- if (mctx) {
- (*mctx)++;
+ pctx = plugin_context;
+ if (pctx) {
+ (*pctx)++;
}
if (pa_data->length == 0) {
@@ -134,10 +134,6 @@ client_process(krb5_context kcontext,
nnonce = htonl(request->nonce);
memcpy(send_pa->contents, &nnonce, 4);
*out_pa_data = send_pa;
- /* Allocate a context. Useful for verifying that we do in fact
- * do per-request cleanup. */
- if (*request_context == NULL)
- *request_context = malloc(4);
} else {
/* A reply from the KDC. Conventionally this would be
* indicated by a different preauthentication type, but this
@@ -163,20 +159,56 @@ client_process(krb5_context kcontext,
return 0;
}
+#define WPSE_MAGIC 0x77707365
+typedef struct _wpse_req_ctx
+{
+ int magic;
+ int value;
+} wpse_req_ctx;
+
static void
-client_cleanup(krb5_context kcontext, void *module_context,
- void **request_context)
+client_req_init(krb5_context kcontext, void *plugin_context, void **req_context_p)
{
- if (*request_context != NULL) {
- free(*request_context);
- *request_context = NULL;
+ wpse_req_ctx *ctx;
+
+ *req_context_p = NULL;
+
+ /* Allocate a request context. Useful for verifying that we do in fact
+ * do per-request cleanup. */
+ ctx = (wpse_req_ctx *) malloc(sizeof(*ctx));
+ if (ctx == NULL)
+ return;
+ ctx->magic = WPSE_MAGIC;
+ ctx->value = 0xc0dec0de;
+
+ *req_context_p = ctx;
+}
+
+static void
+client_req_cleanup(krb5_context kcontext, void *plugin_context, void *req_context)
+{
+ wpse_req_ctx *ctx = (wpse_req_ctx *)req_context;
+
+ if (ctx) {
+#ifdef DEBUG
+ fprintf(stderr, "client_req_cleanup: req_ctx at %p has magic %x and value %x\n",
+ ctx, ctx->magic, ctx->value);
+#endif
+ if (ctx->magic != WPSE_MAGIC) {
+#ifdef DEBUG
+ fprintf(stderr, "client_req_cleanup: req_context at %p has bad magic value %x\n",
+ ctx, ctx->magic);
+#endif
+ return;
+ }
+ free(ctx);
}
return;
}
/* Free state. */
static krb5_error_code
-server_free_pa_request_context(krb5_context kcontext, void *module_context,
+server_free_pa_request_context(krb5_context kcontext, void *plugin_context,
void **request_context)
{
if (*request_context != NULL) {
@@ -317,15 +349,16 @@ static krb5_preauthtype supported_client_pa_types[] = {KRB5_PADATA_WPSE_REQ, 0};
static krb5_preauthtype supported_server_pa_types[] = {KRB5_PADATA_WPSE_REQ, 0};
struct krb5plugin_preauth_client_ftable_v0 preauthentication_client_0 = {
- "wpse",
- &supported_client_pa_types[0],
- NULL,
- client_init,
- client_fini,
- client_get_flags,
- client_cleanup,
- client_process,
- NULL,
+ "wpse", /* name */
+ &supported_client_pa_types[0], /* pa_type_list */
+ NULL, /* enctype_list */
+ client_init, /* plugin init function */
+ client_fini, /* plugin fini function */
+ client_get_flags, /* get flags function */
+ client_req_init, /* request init function */
+ client_req_cleanup, /* request fini function */
+ client_process, /* process function */
+ NULL, /* try_again function */
};
struct krb5plugin_preauth_server_ftable_v0 preauthentication_server_0 = {