155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2005 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "krb5_locl.h" 3555682Smarkm 36178825Sdfr/** 37178825Sdfr * Free content of krb5_creds. 38178825Sdfr * 39178825Sdfr * @param context Kerberos 5 context. 40178825Sdfr * @param c krb5_creds to free. 41178825Sdfr * 42178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 43178825Sdfr * error code is returned, see krb5_get_error_message(). 44178825Sdfr * 45178825Sdfr * @ingroup krb5 46178825Sdfr */ 47178825Sdfr 48233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 49178825Sdfrkrb5_free_cred_contents (krb5_context context, krb5_creds *c) 5055682Smarkm{ 5155682Smarkm krb5_free_principal (context, c->client); 5255682Smarkm c->client = NULL; 5355682Smarkm krb5_free_principal (context, c->server); 5455682Smarkm c->server = NULL; 5555682Smarkm krb5_free_keyblock_contents (context, &c->session); 5655682Smarkm krb5_data_free (&c->ticket); 5755682Smarkm krb5_data_free (&c->second_ticket); 5855682Smarkm free_AuthorizationData (&c->authdata); 5955682Smarkm krb5_free_addresses (context, &c->addresses); 60178825Sdfr memset(c, 0, sizeof(*c)); 6155682Smarkm return 0; 6255682Smarkm} 6355682Smarkm 64178825Sdfr/** 65178825Sdfr * Copy content of krb5_creds. 66178825Sdfr * 67178825Sdfr * @param context Kerberos 5 context. 68178825Sdfr * @param incred source credential 69178825Sdfr * @param c destination credential, free with krb5_free_cred_contents(). 70178825Sdfr * 71178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 72178825Sdfr * error code is returned, see krb5_get_error_message(). 73178825Sdfr * 74178825Sdfr * @ingroup krb5 75178825Sdfr */ 76178825Sdfr 77233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 7855682Smarkmkrb5_copy_creds_contents (krb5_context context, 7955682Smarkm const krb5_creds *incred, 8055682Smarkm krb5_creds *c) 8155682Smarkm{ 8255682Smarkm krb5_error_code ret; 8355682Smarkm 8455682Smarkm memset(c, 0, sizeof(*c)); 8555682Smarkm ret = krb5_copy_principal (context, incred->client, &c->client); 8655682Smarkm if (ret) 8755682Smarkm goto fail; 8855682Smarkm ret = krb5_copy_principal (context, incred->server, &c->server); 8955682Smarkm if (ret) 9055682Smarkm goto fail; 9155682Smarkm ret = krb5_copy_keyblock_contents (context, &incred->session, &c->session); 9255682Smarkm if (ret) 9355682Smarkm goto fail; 9455682Smarkm c->times = incred->times; 9555682Smarkm ret = krb5_data_copy (&c->ticket, 9655682Smarkm incred->ticket.data, 9755682Smarkm incred->ticket.length); 9855682Smarkm if (ret) 9955682Smarkm goto fail; 10055682Smarkm ret = krb5_data_copy (&c->second_ticket, 10155682Smarkm incred->second_ticket.data, 10255682Smarkm incred->second_ticket.length); 10355682Smarkm if (ret) 10455682Smarkm goto fail; 10555682Smarkm ret = copy_AuthorizationData(&incred->authdata, &c->authdata); 10655682Smarkm if (ret) 10755682Smarkm goto fail; 10855682Smarkm ret = krb5_copy_addresses (context, 10955682Smarkm &incred->addresses, 11055682Smarkm &c->addresses); 11155682Smarkm if (ret) 11255682Smarkm goto fail; 11355682Smarkm c->flags = incred->flags; 11455682Smarkm return 0; 11555682Smarkm 11655682Smarkmfail: 117178825Sdfr krb5_free_cred_contents (context, c); 11855682Smarkm return ret; 11955682Smarkm} 12055682Smarkm 121178825Sdfr/** 122178825Sdfr * Copy krb5_creds. 123178825Sdfr * 124178825Sdfr * @param context Kerberos 5 context. 125178825Sdfr * @param incred source credential 126178825Sdfr * @param outcred destination credential, free with krb5_free_creds(). 127178825Sdfr * 128178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 129178825Sdfr * error code is returned, see krb5_get_error_message(). 130178825Sdfr * 131178825Sdfr * @ingroup krb5 132178825Sdfr */ 133178825Sdfr 134233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 13555682Smarkmkrb5_copy_creds (krb5_context context, 13655682Smarkm const krb5_creds *incred, 13755682Smarkm krb5_creds **outcred) 13855682Smarkm{ 13955682Smarkm krb5_creds *c; 14055682Smarkm 14155682Smarkm c = malloc (sizeof (*c)); 14278527Sassar if (c == NULL) { 143233294Sstas krb5_set_error_message (context, ENOMEM, 144233294Sstas N_("malloc: out of memory", "")); 14555682Smarkm return ENOMEM; 14678527Sassar } 14755682Smarkm memset (c, 0, sizeof(*c)); 14855682Smarkm *outcred = c; 14955682Smarkm return krb5_copy_creds_contents (context, incred, c); 15055682Smarkm} 15155682Smarkm 152178825Sdfr/** 153178825Sdfr * Free krb5_creds. 154178825Sdfr * 155178825Sdfr * @param context Kerberos 5 context. 156178825Sdfr * @param c krb5_creds to free. 157178825Sdfr * 158178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 159178825Sdfr * error code is returned, see krb5_get_error_message(). 160178825Sdfr * 161178825Sdfr * @ingroup krb5 162178825Sdfr */ 163178825Sdfr 164233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 16555682Smarkmkrb5_free_creds (krb5_context context, krb5_creds *c) 16655682Smarkm{ 167178825Sdfr krb5_free_cred_contents (context, c); 16855682Smarkm free (c); 16955682Smarkm return 0; 17055682Smarkm} 17155682Smarkm 172178825Sdfr/* XXX this do not belong here */ 173178825Sdfrstatic krb5_boolean 174178825Sdfrkrb5_times_equal(const krb5_times *a, const krb5_times *b) 175178825Sdfr{ 176178825Sdfr return a->starttime == b->starttime && 177178825Sdfr a->authtime == b->authtime && 178178825Sdfr a->endtime == b->endtime && 179178825Sdfr a->renew_till == b->renew_till; 180178825Sdfr} 181178825Sdfr 182178825Sdfr/** 18355682Smarkm * Return TRUE if `mcreds' and `creds' are equal (`whichfields' 18455682Smarkm * determines what equal means). 185178825Sdfr * 186233294Sstas * 187233294Sstas * The following flags, set in whichfields affects the comparison: 188233294Sstas * - KRB5_TC_MATCH_SRV_NAMEONLY Consider all realms equal when comparing the service principal. 189233294Sstas * - KRB5_TC_MATCH_KEYTYPE Compare enctypes. 190233294Sstas * - KRB5_TC_MATCH_FLAGS_EXACT Make sure that the ticket flags are identical. 191233294Sstas * - KRB5_TC_MATCH_FLAGS Make sure that all ticket flags set in mcreds are also present in creds . 192233294Sstas * - KRB5_TC_MATCH_TIMES_EXACT Compares the ticket times exactly. 193233294Sstas * - KRB5_TC_MATCH_TIMES Compares only the expiration times of the creds. 194233294Sstas * - KRB5_TC_MATCH_AUTHDATA Compares the authdata fields. 195233294Sstas * - KRB5_TC_MATCH_2ND_TKT Compares the second tickets (used by user-to-user authentication). 196233294Sstas * - KRB5_TC_MATCH_IS_SKEY Compares the existance of the second ticket. 197233294Sstas * 198178825Sdfr * @param context Kerberos 5 context. 199178825Sdfr * @param whichfields which fields to compare. 200178825Sdfr * @param mcreds cred to compare with. 201178825Sdfr * @param creds cred to compare with. 202178825Sdfr * 203178825Sdfr * @return return TRUE if mcred and creds are equal, FALSE if not. 204178825Sdfr * 205178825Sdfr * @ingroup krb5 20655682Smarkm */ 20755682Smarkm 208233294SstasKRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 209178825Sdfrkrb5_compare_creds(krb5_context context, krb5_flags whichfields, 210178825Sdfr const krb5_creds * mcreds, const krb5_creds * creds) 21155682Smarkm{ 212178825Sdfr krb5_boolean match = TRUE; 213233294Sstas 214178825Sdfr if (match && mcreds->server) { 215233294Sstas if (whichfields & (KRB5_TC_DONT_MATCH_REALM | KRB5_TC_MATCH_SRV_NAMEONLY)) 216233294Sstas match = krb5_principal_compare_any_realm (context, mcreds->server, 217178825Sdfr creds->server); 218178825Sdfr else 219233294Sstas match = krb5_principal_compare (context, mcreds->server, 220178825Sdfr creds->server); 221178825Sdfr } 22255682Smarkm 223178825Sdfr if (match && mcreds->client) { 224178825Sdfr if(whichfields & KRB5_TC_DONT_MATCH_REALM) 225233294Sstas match = krb5_principal_compare_any_realm (context, mcreds->client, 226178825Sdfr creds->client); 227178825Sdfr else 228233294Sstas match = krb5_principal_compare (context, mcreds->client, 229178825Sdfr creds->client); 230178825Sdfr } 231233294Sstas 232178825Sdfr if (match && (whichfields & KRB5_TC_MATCH_KEYTYPE)) 233233294Sstas match = mcreds->session.keytype == creds->session.keytype; 234178825Sdfr 235178825Sdfr if (match && (whichfields & KRB5_TC_MATCH_FLAGS_EXACT)) 236178825Sdfr match = mcreds->flags.i == creds->flags.i; 237178825Sdfr 238178825Sdfr if (match && (whichfields & KRB5_TC_MATCH_FLAGS)) 239178825Sdfr match = (creds->flags.i & mcreds->flags.i) == mcreds->flags.i; 240178825Sdfr 241178825Sdfr if (match && (whichfields & KRB5_TC_MATCH_TIMES_EXACT)) 242178825Sdfr match = krb5_times_equal(&mcreds->times, &creds->times); 243233294Sstas 244178825Sdfr if (match && (whichfields & KRB5_TC_MATCH_TIMES)) 245178825Sdfr /* compare only expiration times */ 246178825Sdfr match = (mcreds->times.renew_till <= creds->times.renew_till) && 247178825Sdfr (mcreds->times.endtime <= creds->times.endtime); 248178825Sdfr 249178825Sdfr if (match && (whichfields & KRB5_TC_MATCH_AUTHDATA)) { 250178825Sdfr unsigned int i; 251178825Sdfr if(mcreds->authdata.len != creds->authdata.len) 252178825Sdfr match = FALSE; 253178825Sdfr else 254178825Sdfr for(i = 0; match && i < mcreds->authdata.len; i++) 255233294Sstas match = (mcreds->authdata.val[i].ad_type == 256178825Sdfr creds->authdata.val[i].ad_type) && 257178825Sdfr (krb5_data_cmp(&mcreds->authdata.val[i].ad_data, 258178825Sdfr &creds->authdata.val[i].ad_data) == 0); 259178825Sdfr } 260178825Sdfr if (match && (whichfields & KRB5_TC_MATCH_2ND_TKT)) 261178825Sdfr match = (krb5_data_cmp(&mcreds->second_ticket, &creds->second_ticket) == 0); 262178825Sdfr 263178825Sdfr if (match && (whichfields & KRB5_TC_MATCH_IS_SKEY)) 264233294Sstas match = ((mcreds->second_ticket.length == 0) == 265178825Sdfr (creds->second_ticket.length == 0)); 266178825Sdfr 26755682Smarkm return match; 26855682Smarkm} 269233294Sstas 270233294Sstas/** 271233294Sstas * Returns the ticket flags for the credentials in creds. 272233294Sstas * See also krb5_ticket_get_flags(). 273233294Sstas * 274233294Sstas * @param creds credential to get ticket flags from 275233294Sstas * 276233294Sstas * @return ticket flags 277233294Sstas * 278233294Sstas * @ingroup krb5 279233294Sstas */ 280233294Sstas 281233294SstasKRB5_LIB_FUNCTION unsigned long KRB5_LIB_CALL 282233294Sstaskrb5_creds_get_ticket_flags(krb5_creds *creds) 283233294Sstas{ 284233294Sstas return TicketFlags2int(creds->flags.b); 285233294Sstas} 286