Check authenticator. Even more generalized keytype functionality.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@2090 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1997-07-09 04:06:17 +00:00
parent aec79ba8cd
commit 7391e922bb

View File

@@ -117,7 +117,7 @@ as_rep(krb5_context context,
ret = hdb_etype2key(context, client, b->etype.val[i], &ckey); ret = hdb_etype2key(context, client, b->etype.val[i], &ckey);
if(ret) if(ret)
continue; continue;
ret = hdb_etype2key(context, client, b->etype.val[i], &skey); ret = hdb_etype2key(context, server, b->etype.val[i], &skey);
if(ret) if(ret)
continue; continue;
break; break;
@@ -281,6 +281,9 @@ tgs_rep(krb5_context context,
TGS_REP rep; TGS_REP rep;
EncTicketPart *et = calloc(1, sizeof(*et)); EncTicketPart *et = calloc(1, sizeof(*et));
EncKDCRepPart *ek = calloc(1, sizeof(*ek)); EncKDCRepPart *ek = calloc(1, sizeof(*ek));
int i;
krb5_keyblock *skey;
krb5_enctype etype;
if(req->padata == NULL || req->padata->len < 1) if(req->padata == NULL || req->padata->len < 1)
return KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */ return KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
@@ -292,17 +295,17 @@ tgs_rep(krb5_context context,
krb5_principal princ; krb5_principal princ;
krb5_flags ap_req_options; krb5_flags ap_req_options;
krb5_ticket *ticket; krb5_ticket *ticket;
krb5_error_code err; krb5_error_code ret;
hdb_entry *ent; hdb_entry *ent;
err = krb5_build_principal(context, ret = krb5_build_principal(context,
&princ, &princ,
strlen(req->req_body.realm), strlen(req->req_body.realm),
req->req_body.realm, req->req_body.realm,
"krbtgt", "krbtgt",
req->req_body.realm, req->req_body.realm,
NULL); NULL);
if(err) return err; if(ret) return ret;
{ {
PrincipalName p; PrincipalName p;
@@ -313,24 +316,42 @@ tgs_rep(krb5_context context,
krbtgt = db_fetch(context, &p, req->req_body.realm); krbtgt = db_fetch(context, &p, req->req_body.realm);
free(p.name_string.val); free(p.name_string.val);
} }
if(ent == NULL) if(krbtgt == NULL)
return KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; return KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
err = krb5_rd_req_with_keyblock(context, &ac, ret = krb5_rd_req_with_keyblock(context, &ac,
&req->padata->val->padata_value, &req->padata->val->padata_value,
princ, princ,
&krbtgt->keyblock, &krbtgt->keyblock,
&ap_req_options, &ap_req_options,
&ticket); &ticket);
if(err) if(ret)
return err; return ret;
/* XXX Check authenticator */ {
krb5_authenticator auth;
size_t len;
unsigned char buf[1024];
krb5_auth_getauthenticator(context, ac, &auth);
if(auth->cksum == NULL)
return KRB5KRB_AP_ERR_INAPP_CKSUM;
/* XXX check for keyed and collision-proof */
/* XXX */
encode_KDC_REQ_BODY(buf + sizeof(buf) - 1, sizeof(buf),
b, &len);
ret = krb5_verify_checksum(context, buf + sizeof(buf) - len, len,
auth->cksum);
if(ret)
return ret;
free_Authenticator(auth);
}
server = db_fetch(context, b->sname, b->realm); server = db_fetch(context, b->sname, b->realm);
if(server == NULL) if(server == NULL){
/* do foreign realm stuff */
return KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; return KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
}
tgt = &ticket->tkt; tgt = &ticket->tkt;
@@ -338,6 +359,18 @@ tgs_rep(krb5_context context,
if(client == NULL) if(client == NULL)
return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
/* Find appropriate key */
for(i = 0; i < b->etype.len; i++){
ret = hdb_etype2key(context, server, b->etype.val[i], &skey);
if(ret == 0)
break;
}
if(ret)
return KRB5KDC_ERR_ETYPE_NOSUPP;
etype = b->etype.val[i];
memset(&rep, 0, sizeof(rep)); memset(&rep, 0, sizeof(rep));
rep.pvno = 5; rep.pvno = 5;
rep.msg_type = krb_tgs_rep; rep.msg_type = krb_tgs_rep;
@@ -361,7 +394,8 @@ tgs_rep(krb5_context context,
et->caddr = req->req_body.addresses; et->caddr = req->req_body.addresses;
/* resp.caddr := req.addresses */ /* resp.caddr := req.addresses */
} }
et->flags.forwarded = tgt->flags.forwarded; if(tgt->flags.forwarded)
et->flags.forwarded = 1;
if(f.proxiable){ if(f.proxiable){
if(!tgt->flags.proxiable) if(!tgt->flags.proxiable)
@@ -458,10 +492,11 @@ tgs_rep(krb5_context context,
krb5_generate_random_keyblock(context, krb5_generate_random_keyblock(context,
KEYTYPE_DES, /* XXX */ skey->keytype,
&et->key); &et->key);
et->crealm = tgt->crealm; et->crealm = tgt->crealm;
et->cname = tgt->cname; et->cname = tgt->cname;
/* do cross realm stuff */
et->transited = tgt->transited; et->transited = tgt->transited;
@@ -490,28 +525,33 @@ tgs_rep(krb5_context context,
sizeof(buf), et, &len); sizeof(buf), et, &len);
if(e) if(e)
return e; return e;
rep.ticket.enc_part.etype = ETYPE_DES_CBC_CRC; krb5_encrypt_EncryptedData(context, buf + sizeof(buf) - len, len,
rep.ticket.enc_part.kvno = NULL; etype,
krb5_encrypt(context, buf + sizeof(buf) - len, len, skey,
rep.ticket.enc_part.etype, &rep.ticket.enc_part);
&server->keyblock,
&rep.ticket.enc_part.cipher);
e = encode_EncTGSRepPart(buf + sizeof(buf) - 1, e = encode_EncTGSRepPart(buf + sizeof(buf) - 1,
sizeof(buf), ek, &len); sizeof(buf), ek, &len);
if(e) if(e)
return e; return e;
rep.enc_part.etype = ETYPE_DES_CBC_CRC;
rep.enc_part.kvno = NULL; /* It is somewhat unclear where the etype in the following
{ encryption should come from. What we have is a session
krb5_keyblock kb; key in the passed tgt, and a list of preferred etypes
kb.keytype = tgt->key.keytype; *for the new ticket*. Should we pick the best possible
kb.keyvalue = tgt->key.keyvalue; etype, given the keytype in the tgt, or should we look
krb5_encrypt(context, buf + sizeof(buf) - len, len, at the etype list here as well? What if the tgt
rep.enc_part.etype, session key is DES3 and we want a ticket with a (say)
&kb, CAST session key. Should the DES3 etype be added to the
&rep.enc_part.cipher); etype list, even if we don't want a session key with
} DES3? */
krb5_encrypt_EncryptedData(context,
buf + sizeof(buf) - len, len,
ETYPE_DES_CBC_MD5, /* XXX */
&tgt->key,
&rep.enc_part);
e = encode_TGS_REP(buf + sizeof(buf) - 1, sizeof(buf), &rep, &len); e = encode_TGS_REP(buf + sizeof(buf) - 1, sizeof(buf), &rep, &len);
if(e) if(e)