17c478bd9Sstevel@tonic-gate /*
2159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate * lib/krb5/ccache/cc_retr.c
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Copyright 1990,1991,1999 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate * All Rights Reserved.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
17*55fea89dSDan Cross *
187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
307c478bd9Sstevel@tonic-gate * or implied warranty.
31*55fea89dSDan Cross *
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate
35159d09a2SMark Phalan #include "k5-int.h"
36505d05c7Sgtb #include "cc-int.h"
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #define KRB5_OK 0
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate #define set(bits) (whichfields & bits)
417c478bd9Sstevel@tonic-gate #define flags_match(a,b) (((a) & (b)) == (a))
427c478bd9Sstevel@tonic-gate #define times_match_exact(t1,t2) (memcmp((char *)(t1), (char *)(t2), sizeof(*(t1))) == 0)
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate static krb5_boolean
times_match(const krb5_ticket_times * t1,const krb5_ticket_times * t2)45505d05c7Sgtb times_match(const krb5_ticket_times *t1, const krb5_ticket_times *t2)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate if (t1->renew_till) {
487c478bd9Sstevel@tonic-gate if (t1->renew_till > t2->renew_till)
497c478bd9Sstevel@tonic-gate return FALSE; /* this one expires too late */
507c478bd9Sstevel@tonic-gate }
517c478bd9Sstevel@tonic-gate if (t1->endtime) {
527c478bd9Sstevel@tonic-gate if (t1->endtime > t2->endtime)
537c478bd9Sstevel@tonic-gate return FALSE; /* this one expires too late */
547c478bd9Sstevel@tonic-gate }
557c478bd9Sstevel@tonic-gate /* only care about expiration on a times_match */
567c478bd9Sstevel@tonic-gate return TRUE;
577c478bd9Sstevel@tonic-gate }
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate static krb5_boolean
standard_fields_match(krb5_context context,const krb5_creds * mcreds,const krb5_creds * creds)60505d05c7Sgtb standard_fields_match(krb5_context context, const krb5_creds *mcreds, const krb5_creds *creds)
617c478bd9Sstevel@tonic-gate {
627c478bd9Sstevel@tonic-gate return (krb5_principal_compare(context, mcreds->client,creds->client)
637c478bd9Sstevel@tonic-gate && krb5_principal_compare(context, mcreds->server,creds->server));
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate /* only match the server name portion, not the server realm portion */
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate static krb5_boolean
srvname_match(krb5_context context,const krb5_creds * mcreds,const krb5_creds * creds)69505d05c7Sgtb srvname_match(krb5_context context, const krb5_creds *mcreds, const krb5_creds *creds)
707c478bd9Sstevel@tonic-gate {
717c478bd9Sstevel@tonic-gate krb5_boolean retval;
727c478bd9Sstevel@tonic-gate krb5_principal_data p1, p2;
73*55fea89dSDan Cross
747c478bd9Sstevel@tonic-gate retval = krb5_principal_compare(context, mcreds->client,creds->client);
757c478bd9Sstevel@tonic-gate if (retval != TRUE)
767c478bd9Sstevel@tonic-gate return retval;
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate * Hack to ignore the server realm for the purposes of the compare.
797c478bd9Sstevel@tonic-gate */
807c478bd9Sstevel@tonic-gate p1 = *mcreds->server;
817c478bd9Sstevel@tonic-gate p2 = *creds->server;
827c478bd9Sstevel@tonic-gate p1.realm = p2.realm;
837c478bd9Sstevel@tonic-gate return krb5_principal_compare(context, &p1, &p2);
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate static krb5_boolean
authdata_match(krb5_authdata * const * mdata,krb5_authdata * const * data)87159d09a2SMark Phalan authdata_match(krb5_authdata *const *mdata, krb5_authdata *const *data)
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate const krb5_authdata *mdatap, *datap;
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate if (mdata == data)
927c478bd9Sstevel@tonic-gate return TRUE;
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate if (mdata == NULL)
957c478bd9Sstevel@tonic-gate return *data == NULL;
96*55fea89dSDan Cross
977c478bd9Sstevel@tonic-gate if (data == NULL)
987c478bd9Sstevel@tonic-gate return *mdata == NULL;
99*55fea89dSDan Cross
1007c478bd9Sstevel@tonic-gate /*LINTED*/
1017c478bd9Sstevel@tonic-gate while ((mdatap = *mdata) && (datap = *data)) {
1027c478bd9Sstevel@tonic-gate if ((mdatap->ad_type != datap->ad_type) ||
1037c478bd9Sstevel@tonic-gate (mdatap->length != datap->length) ||
1047c478bd9Sstevel@tonic-gate (memcmp ((char *)mdatap->contents,
105159d09a2SMark Phalan (char *)datap->contents, (unsigned) mdatap->length) != 0))
1067c478bd9Sstevel@tonic-gate return FALSE;
1077c478bd9Sstevel@tonic-gate mdata++;
1087c478bd9Sstevel@tonic-gate data++;
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate return (*mdata == NULL) && (*data == NULL);
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate static krb5_boolean
data_match(const krb5_data * data1,const krb5_data * data2)114505d05c7Sgtb data_match(const krb5_data *data1, const krb5_data *data2)
1157c478bd9Sstevel@tonic-gate {
1167c478bd9Sstevel@tonic-gate if (!data1) {
1177c478bd9Sstevel@tonic-gate if (!data2)
1187c478bd9Sstevel@tonic-gate return TRUE;
1197c478bd9Sstevel@tonic-gate else
1207c478bd9Sstevel@tonic-gate return FALSE;
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate if (!data2) return FALSE;
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate if (data1->length != data2->length)
1257c478bd9Sstevel@tonic-gate return FALSE;
1267c478bd9Sstevel@tonic-gate else
127*55fea89dSDan Cross return memcmp(data1->data, data2->data, (unsigned) data1->length)
128159d09a2SMark Phalan ? FALSE : TRUE;
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate static int
pref(krb5_enctype my_ktype,int nktypes,krb5_enctype * ktypes)1327c478bd9Sstevel@tonic-gate pref (krb5_enctype my_ktype, int nktypes, krb5_enctype *ktypes)
1337c478bd9Sstevel@tonic-gate {
1347c478bd9Sstevel@tonic-gate int i;
1357c478bd9Sstevel@tonic-gate for (i = 0; i < nktypes; i++)
1367c478bd9Sstevel@tonic-gate if (my_ktype == ktypes[i])
1377c478bd9Sstevel@tonic-gate return i;
1387c478bd9Sstevel@tonic-gate return -1;
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate /*
1427c478bd9Sstevel@tonic-gate * Effects:
1437c478bd9Sstevel@tonic-gate * Searches the credentials cache for a credential matching mcreds,
1447c478bd9Sstevel@tonic-gate * with the fields specified by whichfields. If one if found, it is
1457c478bd9Sstevel@tonic-gate * returned in creds, which should be freed by the caller with
1467c478bd9Sstevel@tonic-gate * krb5_free_credentials().
147*55fea89dSDan Cross *
1487c478bd9Sstevel@tonic-gate * The fields are interpreted in the following way (all constants are
1497c478bd9Sstevel@tonic-gate * preceded by KRB5_TC_). MATCH_IS_SKEY requires the is_skey field to
1507c478bd9Sstevel@tonic-gate * match exactly. MATCH_TIMES requires the requested lifetime to be
1517c478bd9Sstevel@tonic-gate * at least as great as that specified; MATCH_TIMES_EXACT requires the
1527c478bd9Sstevel@tonic-gate * requested lifetime to be exactly that specified. MATCH_FLAGS
1537c478bd9Sstevel@tonic-gate * requires only the set bits in mcreds be set in creds;
1547c478bd9Sstevel@tonic-gate * MATCH_FLAGS_EXACT requires all bits to match.
1557c478bd9Sstevel@tonic-gate *
1567c478bd9Sstevel@tonic-gate * Flag SUPPORTED_KTYPES means check all matching entries that have
1577c478bd9Sstevel@tonic-gate * any supported enctype (according to tgs_enctypes) and return the one
1587c478bd9Sstevel@tonic-gate * with the enctype listed earliest. Return CC_NOT_KTYPE if a match
1597c478bd9Sstevel@tonic-gate * is found *except* for having a supported enctype.
1607c478bd9Sstevel@tonic-gate *
1617c478bd9Sstevel@tonic-gate * Errors:
1627c478bd9Sstevel@tonic-gate * system errors
1637c478bd9Sstevel@tonic-gate * permission errors
1647c478bd9Sstevel@tonic-gate * KRB5_CC_NOMEM
1657c478bd9Sstevel@tonic-gate * KRB5_CC_NOT_KTYPE
1667c478bd9Sstevel@tonic-gate */
1677c478bd9Sstevel@tonic-gate
168505d05c7Sgtb krb5_boolean
krb5int_cc_creds_match_request(krb5_context context,krb5_flags whichfields,krb5_creds * mcreds,krb5_creds * creds)169505d05c7Sgtb krb5int_cc_creds_match_request(krb5_context context, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds)
170505d05c7Sgtb {
171505d05c7Sgtb if (((set(KRB5_TC_MATCH_SRV_NAMEONLY) &&
172505d05c7Sgtb srvname_match(context, mcreds, creds)) ||
173505d05c7Sgtb standard_fields_match(context, mcreds, creds))
174505d05c7Sgtb &&
175505d05c7Sgtb (! set(KRB5_TC_MATCH_IS_SKEY) ||
176505d05c7Sgtb mcreds->is_skey == creds->is_skey)
177505d05c7Sgtb &&
178505d05c7Sgtb (! set(KRB5_TC_MATCH_FLAGS_EXACT) ||
179505d05c7Sgtb mcreds->ticket_flags == creds->ticket_flags)
180505d05c7Sgtb &&
181505d05c7Sgtb (! set(KRB5_TC_MATCH_FLAGS) ||
182505d05c7Sgtb flags_match(mcreds->ticket_flags, creds->ticket_flags))
183505d05c7Sgtb &&
184505d05c7Sgtb (! set(KRB5_TC_MATCH_TIMES_EXACT) ||
185505d05c7Sgtb times_match_exact(&mcreds->times, &creds->times))
186505d05c7Sgtb &&
187505d05c7Sgtb (! set(KRB5_TC_MATCH_TIMES) ||
188505d05c7Sgtb times_match(&mcreds->times, &creds->times))
189505d05c7Sgtb &&
190505d05c7Sgtb ( ! set(KRB5_TC_MATCH_AUTHDATA) ||
191505d05c7Sgtb authdata_match(mcreds->authdata, creds->authdata))
192505d05c7Sgtb &&
193505d05c7Sgtb (! set(KRB5_TC_MATCH_2ND_TKT) ||
194505d05c7Sgtb data_match (&mcreds->second_ticket, &creds->second_ticket))
195505d05c7Sgtb &&
196505d05c7Sgtb ((! set(KRB5_TC_MATCH_KTYPE))||
197505d05c7Sgtb (mcreds->keyblock.enctype == creds->keyblock.enctype)))
198505d05c7Sgtb return TRUE;
199505d05c7Sgtb return FALSE;
200505d05c7Sgtb }
201505d05c7Sgtb
2027c478bd9Sstevel@tonic-gate static krb5_error_code
krb5_cc_retrieve_cred_seq(krb5_context context,krb5_ccache id,krb5_flags whichfields,krb5_creds * mcreds,krb5_creds * creds,int nktypes,krb5_enctype * ktypes)203159d09a2SMark Phalan krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id,
204159d09a2SMark Phalan krb5_flags whichfields, krb5_creds *mcreds,
205159d09a2SMark Phalan krb5_creds *creds, int nktypes, krb5_enctype *ktypes)
2067c478bd9Sstevel@tonic-gate {
2077c478bd9Sstevel@tonic-gate /* This function could be considerably faster if it kept indexing */
2087c478bd9Sstevel@tonic-gate /* information.. sounds like a "next version" idea to me. :-) */
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate krb5_cc_cursor cursor;
2117c478bd9Sstevel@tonic-gate krb5_error_code kret;
2127c478bd9Sstevel@tonic-gate krb5_error_code nomatch_err = KRB5_CC_NOTFOUND;
2137c478bd9Sstevel@tonic-gate struct {
2147c478bd9Sstevel@tonic-gate krb5_creds creds;
2157c478bd9Sstevel@tonic-gate int pref;
2167c478bd9Sstevel@tonic-gate } fetched, best;
2177c478bd9Sstevel@tonic-gate int have_creds = 0;
218159d09a2SMark Phalan krb5_flags oflags = 0;
2197c478bd9Sstevel@tonic-gate #define fetchcreds (fetched.creds)
2207c478bd9Sstevel@tonic-gate
221159d09a2SMark Phalan /* Solaris Kerberos */
2227c478bd9Sstevel@tonic-gate memset(&best, 0, sizeof (best));
2237c478bd9Sstevel@tonic-gate memset(&fetched, 0, sizeof (fetched));
2247c478bd9Sstevel@tonic-gate
225159d09a2SMark Phalan kret = krb5_cc_get_flags(context, id, &oflags);
2267c478bd9Sstevel@tonic-gate if (kret != KRB5_OK)
2277c478bd9Sstevel@tonic-gate return kret;
228159d09a2SMark Phalan if (oflags & KRB5_TC_OPENCLOSE)
229159d09a2SMark Phalan (void) krb5_cc_set_flags(context, id, oflags & ~KRB5_TC_OPENCLOSE);
230159d09a2SMark Phalan kret = krb5_cc_start_seq_get(context, id, &cursor);
231159d09a2SMark Phalan if (kret != KRB5_OK) {
232159d09a2SMark Phalan if (oflags & KRB5_TC_OPENCLOSE)
233159d09a2SMark Phalan krb5_cc_set_flags(context, id, oflags);
234159d09a2SMark Phalan return kret;
235159d09a2SMark Phalan }
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate while ((kret = krb5_cc_next_cred(context, id, &cursor, &fetchcreds)) == KRB5_OK) {
238159d09a2SMark Phalan if (krb5int_cc_creds_match_request(context, whichfields, mcreds, &fetchcreds))
239159d09a2SMark Phalan {
2407c478bd9Sstevel@tonic-gate if (ktypes) {
2417c478bd9Sstevel@tonic-gate fetched.pref = pref (fetchcreds.keyblock.enctype,
2427c478bd9Sstevel@tonic-gate nktypes, ktypes);
2437c478bd9Sstevel@tonic-gate if (fetched.pref < 0)
2447c478bd9Sstevel@tonic-gate nomatch_err = KRB5_CC_NOT_KTYPE;
2457c478bd9Sstevel@tonic-gate else if (!have_creds || fetched.pref < best.pref) {
2467c478bd9Sstevel@tonic-gate if (have_creds)
2477c478bd9Sstevel@tonic-gate krb5_free_cred_contents (context, &best.creds);
2487c478bd9Sstevel@tonic-gate else
2497c478bd9Sstevel@tonic-gate have_creds = 1;
2507c478bd9Sstevel@tonic-gate best = fetched;
2517c478bd9Sstevel@tonic-gate continue;
2527c478bd9Sstevel@tonic-gate }
2537c478bd9Sstevel@tonic-gate } else {
254159d09a2SMark Phalan krb5_cc_end_seq_get(context, id, &cursor);
2557c478bd9Sstevel@tonic-gate *creds = fetchcreds;
256159d09a2SMark Phalan /* Solaris Kerberos */
2577c478bd9Sstevel@tonic-gate creds->keyblock.hKey = CK_INVALID_HANDLE;
258159d09a2SMark Phalan if (oflags & KRB5_TC_OPENCLOSE)
259159d09a2SMark Phalan krb5_cc_set_flags(context, id, oflags);
2607c478bd9Sstevel@tonic-gate return KRB5_OK;
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate
2647c478bd9Sstevel@tonic-gate /* This one doesn't match */
2657c478bd9Sstevel@tonic-gate krb5_free_cred_contents(context, &fetchcreds);
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate /* If we get here, a match wasn't found */
269159d09a2SMark Phalan krb5_cc_end_seq_get(context, id, &cursor);
270159d09a2SMark Phalan if (oflags & KRB5_TC_OPENCLOSE)
271159d09a2SMark Phalan krb5_cc_set_flags(context, id, oflags);
2727c478bd9Sstevel@tonic-gate if (have_creds) {
2737c478bd9Sstevel@tonic-gate *creds = best.creds;
274159d09a2SMark Phalan /* Solaris Kerberos */
2757c478bd9Sstevel@tonic-gate creds->keyblock.hKey = CK_INVALID_HANDLE;
2767c478bd9Sstevel@tonic-gate return KRB5_OK;
2777c478bd9Sstevel@tonic-gate } else
2787c478bd9Sstevel@tonic-gate return nomatch_err;
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate krb5_error_code KRB5_CALLCONV
krb5_cc_retrieve_cred_default(krb5_context context,krb5_ccache id,krb5_flags flags,krb5_creds * mcreds,krb5_creds * creds)282505d05c7Sgtb krb5_cc_retrieve_cred_default (krb5_context context, krb5_ccache id, krb5_flags flags, krb5_creds *mcreds, krb5_creds *creds)
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate krb5_enctype *ktypes;
2857c478bd9Sstevel@tonic-gate int nktypes;
2867c478bd9Sstevel@tonic-gate krb5_error_code ret;
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate if (flags & KRB5_TC_SUPPORTED_KTYPES) {
2897c478bd9Sstevel@tonic-gate ret = krb5_get_tgs_ktypes (context, mcreds->server, &ktypes);
2907c478bd9Sstevel@tonic-gate if (ret)
2917c478bd9Sstevel@tonic-gate return ret;
2927c478bd9Sstevel@tonic-gate nktypes = 0;
2937c478bd9Sstevel@tonic-gate while (ktypes[nktypes])
2947c478bd9Sstevel@tonic-gate nktypes++;
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate ret = krb5_cc_retrieve_cred_seq (context, id, flags, mcreds, creds,
2977c478bd9Sstevel@tonic-gate nktypes, ktypes);
2987c478bd9Sstevel@tonic-gate free (ktypes);
2997c478bd9Sstevel@tonic-gate return ret;
3007c478bd9Sstevel@tonic-gate } else {
301159d09a2SMark Phalan /* Solaris Kerberos */
3027c478bd9Sstevel@tonic-gate return krb5_cc_retrieve_cred_seq (context, id, flags, mcreds, creds,
3037c478bd9Sstevel@tonic-gate 0, (krb5_enctype *)NULL);
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate }
306159d09a2SMark Phalan
307159d09a2SMark Phalan /* The following function duplicates some of the functionality above and */
308159d09a2SMark Phalan /* should probably be merged with it at some point. It is used by the */
309159d09a2SMark Phalan /* CCAPI krb5_cc_remove to figure out if the opaque credentials object */
310159d09a2SMark Phalan /* returned by the CCAPI is the same creds as the caller passed in. */
311159d09a2SMark Phalan /* Unlike the code above it requires that all structures be identical. */
312159d09a2SMark Phalan
313*55fea89dSDan Cross krb5_boolean KRB5_CALLCONV
krb5_creds_compare(krb5_context in_context,krb5_creds * in_creds,krb5_creds * in_compare_creds)314159d09a2SMark Phalan krb5_creds_compare (krb5_context in_context,
315159d09a2SMark Phalan krb5_creds *in_creds,
316159d09a2SMark Phalan krb5_creds *in_compare_creds)
317159d09a2SMark Phalan {
318159d09a2SMark Phalan /* Set to 0 when we hit the first mismatch and then fall through */
319159d09a2SMark Phalan int equal = 1;
320*55fea89dSDan Cross
321159d09a2SMark Phalan if (equal) {
322*55fea89dSDan Cross equal = krb5_principal_compare (in_context, in_creds->client,
323159d09a2SMark Phalan in_compare_creds->client);
324159d09a2SMark Phalan }
325*55fea89dSDan Cross
326159d09a2SMark Phalan if (equal) {
327*55fea89dSDan Cross equal = krb5_principal_compare (in_context, in_creds->server,
328159d09a2SMark Phalan in_compare_creds->server);
329159d09a2SMark Phalan }
330*55fea89dSDan Cross
331159d09a2SMark Phalan if (equal) {
332159d09a2SMark Phalan equal = (in_creds->keyblock.enctype == in_compare_creds->keyblock.enctype &&
333159d09a2SMark Phalan in_creds->keyblock.length == in_compare_creds->keyblock.length &&
334159d09a2SMark Phalan (!in_creds->keyblock.length ||
335159d09a2SMark Phalan !memcmp (in_creds->keyblock.contents, in_compare_creds->keyblock.contents,
336159d09a2SMark Phalan in_creds->keyblock.length)));
337159d09a2SMark Phalan }
338*55fea89dSDan Cross
339*55fea89dSDan Cross if (equal) {
340159d09a2SMark Phalan equal = (in_creds->times.authtime == in_compare_creds->times.authtime &&
341159d09a2SMark Phalan in_creds->times.starttime == in_compare_creds->times.starttime &&
342159d09a2SMark Phalan in_creds->times.endtime == in_compare_creds->times.endtime &&
343159d09a2SMark Phalan in_creds->times.renew_till == in_compare_creds->times.renew_till);
344159d09a2SMark Phalan }
345*55fea89dSDan Cross
346159d09a2SMark Phalan if (equal) {
347159d09a2SMark Phalan equal = (in_creds->is_skey == in_compare_creds->is_skey);
348*55fea89dSDan Cross }
349*55fea89dSDan Cross
350159d09a2SMark Phalan if (equal) {
351159d09a2SMark Phalan equal = (in_creds->ticket_flags == in_compare_creds->ticket_flags);
352159d09a2SMark Phalan }
353*55fea89dSDan Cross
354159d09a2SMark Phalan if (equal) {
355159d09a2SMark Phalan krb5_address **addresses = in_creds->addresses;
356159d09a2SMark Phalan krb5_address **compare_addresses = in_compare_creds->addresses;
357159d09a2SMark Phalan unsigned int i;
358*55fea89dSDan Cross
359159d09a2SMark Phalan if (addresses && compare_addresses) {
360159d09a2SMark Phalan for (i = 0; (equal && addresses[i] && compare_addresses[i]); i++) {
361159d09a2SMark Phalan equal = krb5_address_compare (in_context, addresses[i],
362159d09a2SMark Phalan compare_addresses[i]);
363159d09a2SMark Phalan }
364159d09a2SMark Phalan if (equal) { equal = (!addresses[i] && !compare_addresses[i]); }
365159d09a2SMark Phalan } else {
366159d09a2SMark Phalan if (equal) { equal = (!addresses && !compare_addresses); }
367159d09a2SMark Phalan }
368159d09a2SMark Phalan }
369*55fea89dSDan Cross
370159d09a2SMark Phalan if (equal) {
371159d09a2SMark Phalan equal = (in_creds->ticket.length == in_compare_creds->ticket.length &&
372159d09a2SMark Phalan (!in_creds->ticket.length ||
373159d09a2SMark Phalan !memcmp (in_creds->ticket.data, in_compare_creds->ticket.data,
374159d09a2SMark Phalan in_creds->ticket.length)));
375159d09a2SMark Phalan }
376*55fea89dSDan Cross
377159d09a2SMark Phalan if (equal) {
378159d09a2SMark Phalan equal = (in_creds->second_ticket.length == in_compare_creds->second_ticket.length &&
379159d09a2SMark Phalan (!in_creds->second_ticket.length ||
380159d09a2SMark Phalan !memcmp (in_creds->second_ticket.data, in_compare_creds->second_ticket.data,
381159d09a2SMark Phalan in_creds->second_ticket.length)));
382159d09a2SMark Phalan }
383*55fea89dSDan Cross
384159d09a2SMark Phalan if (equal) {
385159d09a2SMark Phalan krb5_authdata **authdata = in_creds->authdata;
386159d09a2SMark Phalan krb5_authdata **compare_authdata = in_compare_creds->authdata;
387159d09a2SMark Phalan unsigned int i;
388*55fea89dSDan Cross
389*55fea89dSDan Cross if (authdata && compare_authdata) {
390159d09a2SMark Phalan for (i = 0; (equal && authdata[i] && compare_authdata[i]); i++) {
391159d09a2SMark Phalan equal = (authdata[i]->ad_type == compare_authdata[i]->ad_type &&
392159d09a2SMark Phalan authdata[i]->length == compare_authdata[i]->length &&
393*55fea89dSDan Cross (!authdata[i]->length ||
394159d09a2SMark Phalan !memcmp (authdata[i]->contents, compare_authdata[i]->contents,
395159d09a2SMark Phalan authdata[i]->length)));
396159d09a2SMark Phalan }
397159d09a2SMark Phalan if (equal) { equal = (!authdata[i] && !compare_authdata[i]); }
398159d09a2SMark Phalan } else {
399159d09a2SMark Phalan if (equal) { equal = (!authdata && !compare_authdata); }
400159d09a2SMark Phalan }
401159d09a2SMark Phalan }
402*55fea89dSDan Cross
403159d09a2SMark Phalan return equal;
404159d09a2SMark Phalan }
405