root/source4/heimdal/lib/krb5/ticket.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. krb5_free_ticket
  2. krb5_copy_ticket
  3. krb5_ticket_get_client
  4. krb5_ticket_get_server
  5. krb5_ticket_get_endtime
  6. krb5_ticket_get_flags
  7. find_type_in_ad
  8. krb5_ticket_get_authorization_data_type

   1 /*
   2  * Copyright (c) 1997 - 2001 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$");
  37 
  38 krb5_error_code KRB5_LIB_FUNCTION
  39 krb5_free_ticket(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  40                  krb5_ticket *ticket)
  41 {
  42     free_EncTicketPart(&ticket->ticket);
  43     krb5_free_principal(context, ticket->client);
  44     krb5_free_principal(context, ticket->server);
  45     free(ticket);
  46     return 0;
  47 }
  48 
  49 krb5_error_code KRB5_LIB_FUNCTION
  50 krb5_copy_ticket(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  51                  const krb5_ticket *from,
  52                  krb5_ticket **to)
  53 {
  54     krb5_error_code ret;
  55     krb5_ticket *tmp;
  56 
  57     *to = NULL;
  58     tmp = malloc(sizeof(*tmp));
  59     if(tmp == NULL) {
  60         krb5_set_error_message(context, ENOMEM,
  61                                N_("malloc: out of memory", ""));
  62         return ENOMEM;
  63     }
  64     if((ret = copy_EncTicketPart(&from->ticket, &tmp->ticket))){
  65         free(tmp);
  66         return ret;
  67     }
  68     ret = krb5_copy_principal(context, from->client, &tmp->client);
  69     if(ret){
  70         free_EncTicketPart(&tmp->ticket);
  71         free(tmp);
  72         return ret;
  73     }
  74     ret = krb5_copy_principal(context, from->server, &tmp->server);
  75     if(ret){
  76         krb5_free_principal(context, tmp->client);
  77         free_EncTicketPart(&tmp->ticket);
  78         free(tmp);
  79         return ret;
  80     }
  81     *to = tmp;
  82     return 0;
  83 }
  84 
  85 krb5_error_code KRB5_LIB_FUNCTION
  86 krb5_ticket_get_client(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  87                        const krb5_ticket *ticket,
  88                        krb5_principal *client)
  89 {
  90     return krb5_copy_principal(context, ticket->client, client);
  91 }
  92 
  93 krb5_error_code KRB5_LIB_FUNCTION
  94 krb5_ticket_get_server(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  95                        const krb5_ticket *ticket,
  96                        krb5_principal *server)
  97 {
  98     return krb5_copy_principal(context, ticket->server, server);
  99 }
 100 
 101 time_t KRB5_LIB_FUNCTION
 102 krb5_ticket_get_endtime(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 103                         const krb5_ticket *ticket)
 104 {
 105     return ticket->ticket.endtime;
 106 }
 107 
 108 /**
 109  * Get the flags from the Kerberos ticket
 110  *
 111  * @param context Kerberos context
 112  * @param ticket Kerberos ticket
 113  *
 114  * @return ticket flags
 115  *
 116  * @ingroup krb5_ticket
 117  */
 118 unsigned long
 119 krb5_ticket_get_flags(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 120                       const krb5_ticket *ticket)
 121 {
 122     return TicketFlags2int(ticket->ticket.flags);
 123 }
 124 
 125 static int
 126 find_type_in_ad(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 127                 int type,
 128                 krb5_data *data,
 129                 krb5_boolean *found,
 130                 krb5_boolean failp,
 131                 krb5_keyblock *sessionkey,
 132                 const AuthorizationData *ad,
 133                 int level)
 134 {
 135     krb5_error_code ret = 0;
 136     int i;
 137 
 138     if (level > 9) {
 139         ret = ENOENT; /* XXX */
 140         krb5_set_error_message(context, ret,
 141                                N_("Authorization data nested deeper "
 142                                   "then %d levels, stop searching", ""),
 143                                level);
 144         goto out;
 145     }
 146 
 147     /*
 148      * Only copy out the element the first time we get to it, we need
 149      * to run over the whole authorization data fields to check if
 150      * there are any container clases we need to care about.
 151      */
 152     for (i = 0; i < ad->len; i++) {
 153         if (!*found && ad->val[i].ad_type == type) {
 154             ret = der_copy_octet_string(&ad->val[i].ad_data, data);
 155             if (ret) {
 156                 krb5_set_error_message(context, ret,
 157                                        N_("malloc: out of memory", ""));
 158                 goto out;
 159             }
 160             *found = TRUE;
 161             continue;
 162         }
 163         switch (ad->val[i].ad_type) {
 164         case KRB5_AUTHDATA_IF_RELEVANT: {
 165             AuthorizationData child;
 166             ret = decode_AuthorizationData(ad->val[i].ad_data.data,
 167                                            ad->val[i].ad_data.length,
 168                                            &child,
 169                                            NULL);
 170             if (ret) {
 171                 krb5_set_error_message(context, ret,
 172                                        N_("Failed to decode "
 173                                           "IF_RELEVANT with %d", ""),
 174                                        (int)ret);
 175                 goto out;
 176             }
 177             ret = find_type_in_ad(context, type, data, found, FALSE,
 178                                   sessionkey, &child, level + 1);
 179             free_AuthorizationData(&child);
 180             if (ret)
 181                 goto out;
 182             break;
 183         }
 184 #if 0 /* XXX test */
 185         case KRB5_AUTHDATA_KDC_ISSUED: {
 186             AD_KDCIssued child;
 187 
 188             ret = decode_AD_KDCIssued(ad->val[i].ad_data.data,
 189                                       ad->val[i].ad_data.length,
 190                                       &child,
 191                                       NULL);
 192             if (ret) {
 193                 krb5_set_error_message(context, ret,
 194                                        N_("Failed to decode "
 195                                           "AD_KDCIssued with %d", ""),
 196                                        ret);
 197                 goto out;
 198             }
 199             if (failp) {
 200                 krb5_boolean valid;
 201                 krb5_data buf;
 202                 size_t len;
 203 
 204                 ASN1_MALLOC_ENCODE(AuthorizationData, buf.data, buf.length,
 205                                    &child.elements, &len, ret);
 206                 if (ret) {
 207                     free_AD_KDCIssued(&child);
 208                     krb5_clear_error_message(context);
 209                     goto out;
 210                 }
 211                 if(buf.length != len)
 212                     krb5_abortx(context, "internal error in ASN.1 encoder");
 213 
 214                 ret = krb5_c_verify_checksum(context, sessionkey, 19, &buf,
 215                                              &child.ad_checksum, &valid);
 216                 krb5_data_free(&buf);
 217                 if (ret) {
 218                     free_AD_KDCIssued(&child);
 219                     goto out;
 220                 }
 221                 if (!valid) {
 222                     krb5_clear_error_message(context);
 223                     ret = ENOENT;
 224                     free_AD_KDCIssued(&child);
 225                     goto out;
 226                 }
 227             }
 228             ret = find_type_in_ad(context, type, data, found, failp, sessionkey,
 229                                   &child.elements, level + 1);
 230             free_AD_KDCIssued(&child);
 231             if (ret)
 232                 goto out;
 233             break;
 234         }
 235 #endif
 236         case KRB5_AUTHDATA_AND_OR:
 237             if (!failp)
 238                 break;
 239             ret = ENOENT; /* XXX */
 240             krb5_set_error_message(context, ret,
 241                                    N_("Authorization data contains "
 242                                       "AND-OR element that is unknown to the "
 243                                       "application", ""));
 244             goto out;
 245         default:
 246             if (!failp)
 247                 break;
 248             ret = ENOENT; /* XXX */
 249             krb5_set_error_message(context, ret,
 250                                    N_("Authorization data contains "
 251                                       "unknown type (%d) ", ""),
 252                                    ad->val[i].ad_type);
 253             goto out;
 254         }
 255     }
 256 out:
 257     if (ret) {
 258         if (*found) {
 259             krb5_data_free(data);
 260             *found = 0;
 261         }
 262     }
 263     return ret;
 264 }
 265 
 266 /*
 267  * Extract the authorization data type of `type' from the
 268  * 'ticket'. Store the field in `data'. This function is to use for
 269  * kerberos applications.
 270  */
 271 
 272 krb5_error_code KRB5_LIB_FUNCTION
 273 krb5_ticket_get_authorization_data_type(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 274                                         krb5_ticket *ticket,
 275                                         int type,
 276                                         krb5_data *data)
 277 {
 278     AuthorizationData *ad;
 279     krb5_error_code ret;
 280     krb5_boolean found = FALSE;
 281 
 282     krb5_data_zero(data);
 283 
 284     ad = ticket->ticket.authorization_data;
 285     if (ticket->ticket.authorization_data == NULL) {
 286         krb5_set_error_message(context, ENOENT,
 287                                N_("Ticket have not authorization data", ""));
 288         return ENOENT; /* XXX */
 289     }
 290 
 291     ret = find_type_in_ad(context, type, data, &found, TRUE,
 292                           &ticket->ticket.key, ad, 0);
 293     if (ret)
 294         return ret;
 295     if (!found) {
 296         krb5_set_error_message(context, ENOENT,
 297                                N_("Ticket have not "
 298                                   "authorization data of type %d", ""),
 299                                type);
 300         return ENOENT; /* XXX */
 301     }
 302     return 0;
 303 }

/* [<][>][^][v][top][bottom][index][help] */