From: John Kohl Date: Fri, 23 Mar 1990 16:39:20 +0000 (+0000) Subject: major work checkpoint X-Git-Tag: krb5-1.0-alpha2~986 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=fdc30531334cc3c8bf3a5a0d766232c5a08667cf;p=krb5.git major work checkpoint git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@402 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/krb5/krb/gc_via_tgt.c b/src/lib/krb5/krb/gc_via_tgt.c index 70180974c..e00c88c43 100644 --- a/src/lib/krb5/krb/gc_via_tgt.c +++ b/src/lib/krb5/krb/gc_via_tgt.c @@ -16,41 +16,164 @@ static char rcsid_gcvtgt_c[] = #endif /* !lint & !SABER */ #include +#include +#include -/* - * Warning: here lie eggs in search of their chickens, and chickens in - * search of the eggs they hatched from. - * - * This code is incomplete. - * - * Don't even think about finishing it until this C&E problem is resolved. - * - */ - +#include + +#include +#include +#include + +static krb5_flags +creds_to_kdcoptions(creds) +krb5_creds *creds; +{ + krb5_flags result; + + /* XXX this is a hack; we don't necessarily want all these! */ + result = creds->ticket_flags & KDC_TKT_COMMON_MASK; + result |= KDC_OPT_RENEWABLE_OK; + return result; +} krb5_error_code krb5_get_cred_via_tgt (tgt, cred) krb5_creds *tgt; /* IN */ - krb5_creds *cred /* IN OUT */ + krb5_creds *cred; /* IN OUT */ { - krb5_tgs_req_enc_part tgs_enc; - krb5_tgs_req tgs; - krb5_ap_req ap; - + krb5_tgs_req tgsreq; + krb5_real_tgs_req realreq; + krb5_error_code retval; + krb5f_principal tempprinc; + krb5_data *scratch, reply; + krb5_checksum ap_checksum; + krb5_kdc_rep *dec_rep; + krb5_error *err_reply; + /* tgt->client must be equal to cred->client */ /* tgt->server must be equal to krbtgt/realmof(cred->client) */ + if (!krb5_principal_compare(tgt->client, cred->client)) + return KRB5_PRINC_NOMATCH; + + if (!tgt->ticket.length) + return(KRB5_NO_TKT_SUPPLIED); + + if (retval = krb5_tgtname(cred->server, cred->client, &tempprinc)) + return(retval); + + if (!krb5_principal_compare(tempprinc, tgt->server)) { + krb5_free_principal(tempprinc); + return KRB5_PRINC_NOMATCH; + } + krb5_free_principal(tempprinc); + + + bzero((char *)&realreq, sizeof(realreq)); + + realreq.kdc_options = creds_to_kdcoptions(cred); + realreq.from = cred->times.starttime; + realreq.till = cred->times.endtime; + realreq.rtime = cred->times.renew_till; + + if (retval = krb5_timeofday(&realreq.ctime)) + return(retval); + realreq.etype = xxx; + realreq.server = cred->server; + realreq.addresses = xxx; + /* enc_part & enc_part2 are left blank for the moment. */ + + if (retval = encode_krb5_real_tgs_req(&realreq, &scratch)) + return(retval); + + /* xxx choose a checksum type */ + if (retval = (*(krb5_cksumarray[xxx]->sum_func))(scratch->data, + 0, /* XXX? */ + (krb5_pointer) cred->keyblock.contents, + scratch->length, + cred->keyblock.length, + &ap_checksum)) { + krb5_free_data(scratch); + return retval; + } + tgsreq.tgs_request = *scratch; + xfree(scratch); + +#define cleanup() {(void) free(tgsreq.tgs_request.data);} /* - * Construct a KRB_TGS_REQ. - * - * The first thing is an ap_req + * Now get an ap_req. */ - code = krb5_mk_req_int (/* flags */, /* checksum */, /* times */, - /* flags */, &tgt, &ap); - if (code != 0) goto out; + if (retval = krb5_mk_req_extended (0L /* no ap options */, + &ap_checksum, + 0, /* don't need times */ + 0L, /* don't need kdc_options for this */ + 0, /* XXX no ccache */ + tgt, + &tgsreq.header)) { + cleanup(); + return retval; + } - abort(); - -out: - return code; + /* now the TGS_REQ is assembled in tgsreq */ + if (retval = encode_krb5_tgs_req(&tgsreq, &scratch)) { + cleanup(); + return(retval); + } +#undef cleanup +#define cleanup() {(void) free(tgsreq.header.data); \ + (void) free(tgsreq.tgs_request.data);} + + /* now send request & get response from KDC */ + retval = krb5_sendto_kdc(scratch, krb5_princ_realm(tgt->server), + &reply); + krb5_free_data(scratch); + cleanup(); + if (retval) { + return retval; + } +#undef cleanup +#define cleanup() {(void) free(reply.data);} + + /* we expect *reply to be either an error or a proper reply */ + if (retval = krb5_decode_kdc_rep(&reply, + &tgt->keyblock, + xxx, /* enctype */ + &dec_rep)) { + if (decode_krb5_error(&reply, &err_reply)) { + cleanup(); + return retval; /* neither proper reply nor error! */ + } + + /* XXX check to make sure the timestamps match, etc. */ + + retval = err_reply->error + ERROR_TABLE_BASE_krb5; + krb5_free_error(err_reply); + cleanup(); + return retval; + } + cleanup(); +#undef cleanup +#define cleanup() krb5_free_kdc_rep(dec_rep) + + /* now it's decrypted and ready for prime time */ + + if (!krb5_principal_compare(dec_rep->client, tgt->client)) { + cleanup(); + return XXX_MODIFIED; + } + /* put pieces into cred-> */ + if (retval = xxx_copy_keyblock(dec_rep->enc_part2->session, + &cred->keyblock)) { + cleanup(); + return retval; + } + cred->times = dec_rep->enc_part2->times; + /* check compatibility here first ? XXX */ + cred->ticket_flags = dec_rep->enc_part2->flags; + cred->is_skey = FALSE; + retval = xxx_copy_ticket(dec_rep->ticket, &cred->ticket); + + cleanup(); + return retval; }