1 /* 2 * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <krb5_locl.h> 35 36 RCSID("$Id: rd_cred.c,v 1.9 2000/02/06 05:19:52 assar Exp $"); 37 38 krb5_error_code 39 krb5_rd_cred (krb5_context context, 40 krb5_auth_context auth_context, 41 krb5_ccache ccache, 42 krb5_data *in_data) 43 { 44 krb5_error_code ret; 45 size_t len; 46 KRB_CRED cred; 47 EncKrbCredPart enc_krb_cred_part; 48 krb5_data enc_krb_cred_part_data; 49 krb5_crypto crypto; 50 int i; 51 52 ret = decode_KRB_CRED (in_data->data, in_data->length, 53 &cred, &len); 54 if (ret) 55 return ret; 56 57 if (cred.pvno != 5) { 58 ret = KRB5KRB_AP_ERR_BADVERSION; 59 goto out; 60 } 61 62 if (cred.msg_type != krb_cred) { 63 ret = KRB5KRB_AP_ERR_MSG_TYPE; 64 goto out; 65 } 66 67 krb5_crypto_init(context, auth_context->remote_subkey, 0, &crypto); 68 ret = krb5_decrypt_EncryptedData(context, 69 crypto, 70 KRB5_KU_KRB_CRED, 71 &cred.enc_part, 72 &enc_krb_cred_part_data); 73 krb5_crypto_destroy(context, crypto); 74 if (ret) 75 goto out; 76 77 78 ret = krb5_decode_EncKrbCredPart (context, 79 enc_krb_cred_part_data.data, 80 enc_krb_cred_part_data.length, 81 &enc_krb_cred_part, 82 &len); 83 if (ret) 84 goto out; 85 86 /* check sender address */ 87 88 if (enc_krb_cred_part.s_address 89 && auth_context->remote_address) { 90 krb5_address *a; 91 int cmp; 92 93 ret = krb5_make_addrport (&a, 94 auth_context->remote_address, 95 auth_context->remote_port); 96 if (ret) 97 goto out; 98 99 100 cmp = krb5_address_compare (context, 101 a, 102 enc_krb_cred_part.s_address); 103 104 krb5_free_address (context, a); 105 free (a); 106 107 if (cmp == 0) { 108 ret = KRB5KRB_AP_ERR_BADADDR; 109 goto out; 110 } 111 } 112 113 /* check receiver address */ 114 115 if (enc_krb_cred_part.r_address 116 && !krb5_address_compare (context, 117 auth_context->local_address, 118 enc_krb_cred_part.r_address)) { 119 ret = KRB5KRB_AP_ERR_BADADDR; 120 goto out; 121 } 122 123 /* check timestamp */ 124 if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) { 125 krb5_timestamp sec; 126 127 krb5_timeofday (context, &sec); 128 129 if (enc_krb_cred_part.timestamp == NULL || 130 enc_krb_cred_part.usec == NULL || 131 abs(*enc_krb_cred_part.timestamp - sec) 132 > context->max_skew) { 133 ret = KRB5KRB_AP_ERR_SKEW; 134 goto out; 135 } 136 } 137 138 /* XXX - check replay cache */ 139 140 /* Store the creds in the ccache */ 141 142 for (i = 0; i < enc_krb_cred_part.ticket_info.len; ++i) { 143 KrbCredInfo *kci = &enc_krb_cred_part.ticket_info.val[i]; 144 krb5_creds creds; 145 u_char buf[1024]; 146 size_t len; 147 148 memset (&creds, 0, sizeof(creds)); 149 150 ret = encode_Ticket (buf + sizeof(buf) - 1, sizeof(buf), 151 &cred.tickets.val[i], 152 &len); 153 if (ret) 154 goto out; 155 krb5_data_copy (&creds.ticket, buf + sizeof(buf) - len, len); 156 copy_EncryptionKey (&kci->key, &creds.session); 157 if (kci->prealm && kci->pname) 158 principalname2krb5_principal (&creds.client, 159 *kci->pname, 160 *kci->prealm); 161 if (kci->flags) 162 creds.flags.b = *kci->flags; 163 if (kci->authtime) 164 creds.times.authtime = *kci->authtime; 165 if (kci->starttime) 166 creds.times.starttime = *kci->starttime; 167 if (kci->endtime) 168 creds.times.endtime = *kci->endtime; 169 if (kci->renew_till) 170 creds.times.renew_till = *kci->renew_till; 171 if (kci->srealm && kci->sname) 172 principalname2krb5_principal (&creds.server, 173 *kci->sname, 174 *kci->srealm); 175 if (kci->caddr) 176 krb5_copy_addresses (context, 177 kci->caddr, 178 &creds.addresses); 179 krb5_cc_store_cred (context, ccache, &creds); 180 } 181 182 out: 183 free_KRB_CRED (&cred); 184 return ret; 185 } 186