(krb5_get_in_cred): generate preauthentication information if we get

back ERR_PREAUTH_REQUIRED


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@7358 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1999-11-12 16:12:52 +00:00
parent 57e671a740
commit 4e5a924e40

View File

@@ -562,6 +562,46 @@ fail:
return ret;
}
static int
set_ptypes(krb5_context context,
KRB_ERROR *error,
krb5_preauthtype **ptypes,
krb5_preauthdata **preauth)
{
static krb5_preauthdata preauth2;
static krb5_preauthtype ptypes2[] = { KRB5_PADATA_ENC_TIMESTAMP, KRB5_PADATA_NONE };
if(error->e_data) {
METHOD_DATA md;
int i;
decode_METHOD_DATA(error->e_data->data,
error->e_data->length,
&md,
NULL);
for(i = 0; i < md.len; i++){
switch(md.val[i].padata_type){
case pa_enc_timestamp:
*ptypes = ptypes2;
break;
case pa_etype_info:
*preauth = &preauth2;
ALLOC_SEQ(*preauth, 1);
(*preauth)->val[0].type = KRB5_PADATA_ENC_TIMESTAMP;
krb5_decode_ETYPE_INFO(context,
md.val[i].padata_value.data,
md.val[i].padata_value.length,
&(*preauth)->val[0].info,
NULL);
break;
}
}
free_METHOD_DATA(&md);
} else {
*ptypes = ptypes2;
}
return(1);
}
krb5_error_code
krb5_get_in_cred(krb5_context context,
krb5_flags options,
@@ -587,62 +627,85 @@ krb5_get_in_cred(krb5_context context,
krb5_kdc_flags opts;
PA_DATA *pa;
krb5_enctype etype;
const krb5_preauthdata *my_preauth = NULL;
unsigned nonce;
int done;
opts.i = options;
krb5_generate_random_block (&nonce, sizeof(nonce));
nonce &= 0xffffffff;
ret = init_as_req (context,
opts,
creds,
addrs,
etypes,
ptypes,
preauth,
key_proc,
keyseed,
nonce,
&a);
if (ret)
return ret;
do {
done = 1;
ret = init_as_req (context,
opts,
creds,
addrs,
etypes,
ptypes,
preauth,
key_proc,
keyseed,
nonce,
&a);
if (my_preauth) {
free_ETYPE_INFO(&my_preauth->val[0].info);
free (my_preauth->val);
}
if (ret)
return ret;
ret = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
sizeof(buf),
&a,
&req.length);
free_AS_REQ(&a);
if (ret)
return ret;
ret = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
sizeof(buf),
&a,
&req.length);
free_AS_REQ(&a);
if (ret)
return ret;
req.data = buf + sizeof(buf) - req.length;
req.data = buf + sizeof(buf) - req.length;
ret = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
if (ret)
return ret;
ret = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
if (ret)
return ret;
memset (&rep, 0, sizeof(rep));
if((ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size))) {
/* let's try to parse it as a KRB-ERROR */
KRB_ERROR error;
int ret2;
memset (&rep, 0, sizeof(rep));
ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size);
if(ret) {
/* let's try to parse it as a KRB-ERROR */
KRB_ERROR error;
int ret2;
ret2 = krb5_rd_error(context, &resp, &error);
if(ret2 && resp.data && ((char*)resp.data)[0] == 4)
ret = KRB5KRB_AP_ERR_V4_REPLY;
krb5_data_free(&resp);
if (ret2 == 0) {
ret = error.error_code;
if(ret_as_reply)
ret_as_reply->error = error;
else
free_KRB_ERROR (&error);
ret2 = krb5_rd_error(context, &resp, &error);
if(ret2 && resp.data && ((char*)resp.data)[0] == 4)
ret = KRB5KRB_AP_ERR_V4_REPLY;
krb5_data_free(&resp);
if (ret2 == 0) {
ret = error.error_code;
/* if no preauth was set and KDC requires it, give it
one more try */
if (!ptypes && !preauth
&& ret == KRB5KDC_ERR_PREAUTH_REQUIRED
#if 0
|| ret == KRB5KDC_ERR_BADOPTION
#endif
&& set_ptypes(context, &error, &ptypes, &my_preauth)) {
done = 0;
preauth = my_preauth;
free_KRB_ERROR(&error);
continue;
}
if(ret_as_reply)
ret_as_reply->error = error;
else
free_KRB_ERROR (&error);
return ret;
}
return ret;
}
return ret;
}
krb5_data_free(&resp);
krb5_data_free(&resp);
} while(!done);
pa = NULL;
etype = rep.kdc_rep.enc_part.etype;