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,
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,
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,
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)
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",
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;
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:
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;
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;
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;
krb5_cksumtype *cksumtypes;
krb5_error_code status;
struct server_stats *stats;
+ krb5_data *test_edata;
stats = pa_module_context;
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++;
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;
* 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;
}
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. */