From: Tom Yu Date: Tue, 14 Nov 2006 22:47:21 +0000 (+0000) Subject: pull up r18801 from trunk X-Git-Tag: krb5-1.6-alpha1~4 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=cb2e6a113c60eb2872c2c97ef4156a026778065b;p=krb5.git pull up r18801 from trunk r18801@cathode-dark-space: coffman | 2006-11-13 17:59:55 -0500 ticket: new subject: allow server preauth plugin verify_padata function to return e-data Component: krb5-kdc Target_Version: 1.6 Tags: pullup Change server-side preauth plugin interface to allow the plugin's verify_padata function to return e-data to be returned to the client. (Patch from Nalin Dahyabhai ) Update sample plugins to return e-data to exercise the code. Fix memory leak in the wpse plugin. ticket: 4738 version_fixed: 1.6 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@18804 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/krb5/preauth_plugin.h b/src/include/krb5/preauth_plugin.h index f1b7dd334..f7ecd3be0 100644 --- a/src/include/krb5/preauth_plugin.h +++ b/src/include/krb5/preauth_plugin.h @@ -298,7 +298,8 @@ typedef struct krb5plugin_preauth_server_ftable_v0 { krb5_pa_data *data, preauth_get_entry_data_proc, void *pa_module_context, - void **pa_request_context); + void **pa_request_context, + krb5_data **e_data); /* Generate preauthentication response data to send to the client as part * of the AS-REP. If it needs to override the key which is used to encrypt * the response, it can do so. The module is expected (but not required, diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 38118d4cb..37bd9e319 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -262,7 +262,7 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt, */ if (request->padata) { errcode = check_padata(kdc_context, &client, req_pkt, request, - &enc_tkt_reply, &pa_context); + &enc_tkt_reply, &pa_context, &e_data); if (errcode) { #ifdef KRBCONF_KDC_MODIFIES_KDB /* diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index dfbb5fcc9..9994ae3ea 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -84,7 +84,8 @@ typedef krb5_error_code (*verify_proc) krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data, preauth_get_entry_data_proc get_entry_data, void *pa_module_context, - void **pa_request_context); + void **pa_request_context, + krb5_data **e_data); typedef krb5_error_code (*edata_proc) (krb5_context, krb5_kdc_req *request, @@ -133,7 +134,8 @@ static krb5_error_code verify_enc_timestamp krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data, preauth_get_entry_data_proc get_entry_data, void *pa_system_context, - void **pa_request_context); + void **pa_request_context, + krb5_data **e_data); static krb5_error_code get_etype_info (krb5_context, krb5_kdc_req *request, @@ -200,7 +202,8 @@ static krb5_error_code verify_sam_response krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data, preauth_get_entry_data_proc get_entry_data, void *pa_module_context, - void **pa_request_context); + void **pa_request_context, + krb5_data **e_data); static krb5_error_code get_sam_edata (krb5_context, krb5_kdc_req *request, @@ -873,12 +876,13 @@ errout: krb5_error_code check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, - void **padata_context) + void **padata_context, krb5_data *e_data) { krb5_error_code retval = 0; krb5_pa_data **padata; krb5_preauth_systems *pa_sys; void **pa_context; + krb5_data *pa_e_data = NULL; int pa_ok = 0, pa_found = 0; if (request->padata == 0) @@ -908,7 +912,7 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, retval = pa_sys->verify_padata(context, client, req_pkt, request, enc_tkt_reply, *padata, get_entry_data, pa_sys->plugin_context, - pa_context); + pa_context, &pa_e_data); if (retval) { const char * emsg = krb5_get_error_message (context, retval); krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s", @@ -926,7 +930,29 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, if (pa_sys->flags & PA_SUFFICIENT) break; } + /* + * If we're looping and e_data was returned, free it here + * since we won't be returning it anyway + */ + if (pa_e_data != NULL) { + krb5_free_data(context, pa_e_data); + pa_e_data = NULL; + } } + + /* Return any e_data from the preauth that caused us to exit the loop */ + if (pa_e_data != NULL) { + e_data->data = malloc(pa_e_data->length); + if (e_data->data == NULL) { + krb5_free_data(context, pa_e_data); + return KRB5KRB_ERR_GENERIC; + } + memcpy(e_data->data, pa_e_data->data, pa_e_data->length); + e_data->length = pa_e_data->length; + krb5_free_data(context, pa_e_data); + pa_e_data = NULL; + } + if (pa_ok) return 0; @@ -941,9 +967,9 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, krb5_klog_syslog (LOG_INFO, "no valid preauth type found: %s", emsg); krb5_free_error_message(context, emsg); } -/* The following switch statement allows us - * to return some preauth system errors back to the client. - */ + /* The following switch statement allows us + * to return some preauth system errors back to the client. + */ switch(retval) { case KRB5KRB_AP_ERR_BAD_INTEGRITY: case KRB5KRB_AP_ERR_SKEW: @@ -1117,7 +1143,8 @@ verify_enc_timestamp(krb5_context context, krb5_db_entry *client, krb5_pa_data *pa, preauth_get_entry_data_proc ets_get_entry_data, void *pa_system_context, - void **pa_request_context) + void **pa_request_context, + krb5_data **e_data) { krb5_pa_enc_ts * pa_enc = 0; krb5_error_code retval; @@ -2104,7 +2131,8 @@ verify_sam_response(krb5_context context, krb5_db_entry *client, krb5_pa_data *pa, preauth_get_entry_data_proc sam_get_entry_data, void *pa_system_context, - void **pa_request_context) + void **pa_request_context, + krb5_data **e_data) { krb5_error_code retval; krb5_data scratch; diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 21f7e88f3..7fefb964e 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -152,7 +152,7 @@ krb5_error_code unload_preauth_plugins(krb5_context context); krb5_error_code check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, - void **padata_context); + void **padata_context, krb5_data *e_data); krb5_error_code return_padata (krb5_context context, krb5_db_entry *client, diff --git a/src/plugins/preauth/cksum_body/cksum_body_main.c b/src/plugins/preauth/cksum_body/cksum_body_main.c index 8d7aa00af..6b46b00a3 100644 --- a/src/plugins/preauth/cksum_body/cksum_body_main.c +++ b/src/plugins/preauth/cksum_body/cksum_body_main.c @@ -289,7 +289,8 @@ server_verify(krb5_context kcontext, krb5_pa_data *data, preauth_get_entry_data_proc server_get_entry_data, void *pa_module_context, - void **pa_request_context) + void **pa_request_context, + krb5_data **e_data) { krb5_int32 cksumtype; krb5_checksum checksum; @@ -302,6 +303,7 @@ server_verify(krb5_context kcontext, krb5_cksumtype *cksumtypes; krb5_error_code status; struct server_stats *stats; + krb5_data *test_edata; stats = pa_module_context; @@ -425,10 +427,35 @@ server_verify(krb5_context kcontext, fprintf(stderr, "Checksum mismatch.\n"); } #endif + /* Return edata to exercise code that handles edata... */ + test_edata = malloc(sizeof(*test_edata)); + if (test_edata != NULL) { + test_edata->data = malloc(20); + if (test_edata->data == NULL) { + free(test_edata); + } else { + test_edata->length = 20; + memset(test_edata->data, 'F', 20); /* fill it with junk */ + *e_data = test_edata; + } + } stats->failures++; return KRB5KDC_ERR_PREAUTH_FAILED; } + /* Return edata to exercise code that handles edata... */ + test_edata = malloc(sizeof(*test_edata)); + if (test_edata != NULL) { + test_edata->data = malloc(20); + if (test_edata->data == NULL) { + free(test_edata); + } else { + test_edata->length = 20; + memset(test_edata->data, 'S', 20); /* fill it with junk */ + *e_data = test_edata; + } + } + /* Note that preauthentication succeeded. */ enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; stats->successes++; diff --git a/src/plugins/preauth/wpse/wpse_main.c b/src/plugins/preauth/wpse/wpse_main.c index 8ccd7cd12..46ea66230 100644 --- a/src/plugins/preauth/wpse/wpse_main.c +++ b/src/plugins/preauth/wpse/wpse_main.c @@ -247,9 +247,12 @@ server_verify(krb5_context kcontext, krb5_pa_data *data, preauth_get_entry_data_proc server_get_entry_data, void *pa_module_context, - void **pa_request_context) + void **pa_request_context, + krb5_data **e_data) { krb5_int32 nnonce; + krb5_data *test_edata; + /* Verify the preauth data. */ if (data->length != 4) return KRB5KDC_ERR_PREAUTH_FAILED; @@ -264,6 +267,19 @@ server_verify(krb5_context kcontext, * per-request cleanup. */ if (*pa_request_context == NULL) *pa_request_context = malloc(4); + + /* Return edata to exercise code that handles edata... */ + test_edata = malloc(sizeof(*test_edata)); + if (test_edata != NULL) { + test_edata->data = malloc(20); + if (test_edata->data == NULL) { + free(test_edata); + } else { + test_edata->length = 20; + memset(test_edata->data, '#', 20); /* fill it with junk */ + *e_data = test_edata; + } + } return 0; } @@ -333,6 +349,7 @@ server_return(krb5_context kcontext, enctype = htonl(kb->enctype); memcpy((*send_pa)->contents, &enctype, 4); memcpy((*send_pa)->contents + 4, kb->contents, kb->length); + krb5_free_keyblock_contents(kcontext, encrypting_key); krb5_copy_keyblock_contents(kcontext, kb, encrypting_key); /* Clean up. */