(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; 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_error_code
krb5_get_in_cred(krb5_context context, krb5_get_in_cred(krb5_context context,
krb5_flags options, krb5_flags options,
@@ -587,62 +627,85 @@ krb5_get_in_cred(krb5_context context,
krb5_kdc_flags opts; krb5_kdc_flags opts;
PA_DATA *pa; PA_DATA *pa;
krb5_enctype etype; krb5_enctype etype;
const krb5_preauthdata *my_preauth = NULL;
unsigned nonce; unsigned nonce;
int done;
opts.i = options; opts.i = options;
krb5_generate_random_block (&nonce, sizeof(nonce)); krb5_generate_random_block (&nonce, sizeof(nonce));
nonce &= 0xffffffff; nonce &= 0xffffffff;
ret = init_as_req (context, do {
opts, done = 1;
creds, ret = init_as_req (context,
addrs, opts,
etypes, creds,
ptypes, addrs,
preauth, etypes,
key_proc, ptypes,
keyseed, preauth,
nonce, key_proc,
&a); keyseed,
if (ret) nonce,
return ret; &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, ret = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
sizeof(buf), sizeof(buf),
&a, &a,
&req.length); &req.length);
free_AS_REQ(&a); free_AS_REQ(&a);
if (ret) if (ret)
return 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); ret = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
if (ret) if (ret)
return ret; return ret;
memset (&rep, 0, sizeof(rep)); memset (&rep, 0, sizeof(rep));
if((ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size))) { ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size);
/* let's try to parse it as a KRB-ERROR */ if(ret) {
KRB_ERROR error; /* let's try to parse it as a KRB-ERROR */
int ret2; KRB_ERROR error;
int ret2;
ret2 = krb5_rd_error(context, &resp, &error); ret2 = krb5_rd_error(context, &resp, &error);
if(ret2 && resp.data && ((char*)resp.data)[0] == 4) if(ret2 && resp.data && ((char*)resp.data)[0] == 4)
ret = KRB5KRB_AP_ERR_V4_REPLY; ret = KRB5KRB_AP_ERR_V4_REPLY;
krb5_data_free(&resp); krb5_data_free(&resp);
if (ret2 == 0) { if (ret2 == 0) {
ret = error.error_code; ret = error.error_code;
if(ret_as_reply) /* if no preauth was set and KDC requires it, give it
ret_as_reply->error = error; one more try */
else if (!ptypes && !preauth
free_KRB_ERROR (&error); && 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;
} }
return ret; krb5_data_free(&resp);
} } while(!done);
krb5_data_free(&resp);
pa = NULL; pa = NULL;
etype = rep.kdc_rep.enc_part.etype; etype = rep.kdc_rep.enc_part.etype;