Annotation of 43BSDReno/kerberosIV/krb/get_ad_tkt.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * $Source: /usr/src/kerberosIV/krb/RCS/get_ad_tkt.c,v $
                      3:  * $Author: kfall $
                      4:  *
                      5:  * Copyright 1986, 1987, 1988 by the Massachusetts Institute
                      6:  * of Technology.
                      7:  *
                      8:  * For copying and distribution information, please see the file
                      9:  * <mit-copyright.h>.
                     10:  */
                     11: 
                     12: #ifndef lint
                     13: static char *rcsid_get_ad_tkt_c =
                     14: "$Header: /usr/src/kerberosIV/krb/RCS/get_ad_tkt.c,v 4.16 90/06/25 20:55:44 kfall Exp $";
                     15: #endif /* lint */
                     16: 
                     17: #include <mit-copyright.h>
                     18: #include <des.h>
                     19: #include <krb.h>
                     20: #include <prot.h>
                     21: #include <strings.h>
                     22: 
                     23: #include <stdio.h>
                     24: #include <errno.h>
                     25: 
                     26: /* use the bsd time.h struct defs for PC too! */
                     27: #include <sys/time.h>
                     28: #include <sys/types.h>
                     29: 
                     30: extern int krb_debug;
                     31: 
                     32: struct timeval tt_local = { 0, 0 };
                     33: 
                     34: int swap_bytes;
                     35: unsigned long rep_err_code;
                     36: 
                     37: /*
                     38:  * get_ad_tkt obtains a new service ticket from Kerberos, using
                     39:  * the ticket-granting ticket which must be in the ticket file.
                     40:  * It is typically called by krb_mk_req() when the client side
                     41:  * of an application is creating authentication information to be
                     42:  * sent to the server side.
                     43:  *
                     44:  * get_ad_tkt takes four arguments: three pointers to strings which
                     45:  * contain the name, instance, and realm of the service for which the
                     46:  * ticket is to be obtained; and an integer indicating the desired
                     47:  * lifetime of the ticket.
                     48:  *
                     49:  * It returns an error status if the ticket couldn't be obtained,
                     50:  * or AD_OK if all went well.  The ticket is stored in the ticket
                     51:  * cache.
                     52:  *
                     53:  * The request sent to the Kerberos ticket-granting service looks
                     54:  * like this:
                     55:  *
                     56:  * pkt->dat
                     57:  *
                     58:  * TEXT                        original contents of    authenticator+ticket
                     59:  *                     pkt->dat                built in krb_mk_req call
                     60:  * 
                     61:  * 4 bytes             time_ws                 always 0 (?)
                     62:  * char                        lifetime                lifetime argument passed
                     63:  * string              service                 service name argument
                     64:  * string              sinstance               service instance arg.
                     65:  *
                     66:  * See "prot.h" for the reply packet layout and definitions of the
                     67:  * extraction macros like pkt_version(), pkt_msg_type(), etc.
                     68:  */
                     69: 
                     70: get_ad_tkt(service,sinstance,realm,lifetime)
                     71:     char    *service;
                     72:     char    *sinstance;
                     73:     char    *realm;
                     74:     int     lifetime;
                     75: {
                     76:     static KTEXT_ST pkt_st;
                     77:     KTEXT pkt = & pkt_st;      /* Packet to KDC */
                     78:     static KTEXT_ST rpkt_st;
                     79:     KTEXT rpkt = &rpkt_st;     /* Returned packet */
                     80:     static KTEXT_ST cip_st;
                     81:     KTEXT cip = &cip_st;       /* Returned Ciphertext */
                     82:     static KTEXT_ST tkt_st;
                     83:     KTEXT tkt = &tkt_st;       /* Current ticket */
                     84:     C_Block ses;                /* Session key for tkt */
                     85:     CREDENTIALS cr;
                     86:     int kvno;                  /* Kvno for session key */
                     87:     char lrealm[REALM_SZ];
                     88:     C_Block key;               /* Key for decrypting cipher */
                     89:     Key_schedule key_s;
                     90:     long time_ws = 0;
                     91: 
                     92:     char s_name[SNAME_SZ];
                     93:     char s_instance[INST_SZ];
                     94:     int msg_byte_order;
                     95:     int kerror;
                     96:     char rlm[REALM_SZ];
                     97:     char *ptr;
                     98: 
                     99:     unsigned long kdc_time;   /* KDC time */
                    100: 
                    101:     if ((kerror = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
                    102:        return(kerror);
                    103: 
                    104:     /* Create skeleton of packet to be sent */
                    105:     (void) gettimeofday(&tt_local,(struct timezone *) 0);
                    106: 
                    107:     pkt->length = 0;
                    108: 
                    109:     /*
                    110:      * Look for the session key (and other stuff we don't need)
                    111:      * in the ticket file for krbtgt.realm@lrealm where "realm" 
                    112:      * is the service's realm (passed in "realm" argument) and 
                    113:      * lrealm is the realm of our initial ticket.  If we don't 
                    114:      * have this, we will try to get it.
                    115:      */
                    116:     
                    117:     if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS) {
                    118:        /*
                    119:         * If realm == lrealm, we have no hope, so let's not even try.
                    120:         */
                    121:        if ((strncmp(realm, lrealm, REALM_SZ)) == 0)
                    122:            return(AD_NOTGT);
                    123:        else{
                    124:            if ((kerror = 
                    125:                 get_ad_tkt("krbtgt",realm,lrealm,lifetime)) != KSUCCESS)
                    126:                return(kerror);
                    127:            if ((kerror = krb_get_cred("krbtgt",realm,lrealm,&cr)) != KSUCCESS)
                    128:                return(kerror);
                    129:        }
                    130:     }
                    131:     
                    132:     /*
                    133:      * Make up a request packet to the "krbtgt.realm@lrealm".
                    134:      * Start by calling krb_mk_req() which puts ticket+authenticator
                    135:      * into "pkt".  Then tack other stuff on the end.
                    136:      */
                    137:     
                    138:     kerror = krb_mk_req(pkt,"krbtgt",realm,lrealm,0L);
                    139: 
                    140:     if (kerror)
                    141:        return(AD_NOTGT);
                    142: 
                    143:     /* timestamp */
                    144:     bcopy((char *) &time_ws,(char *) (pkt->dat+pkt->length),4);
                    145:     pkt->length += 4;
                    146:     *(pkt->dat+(pkt->length)++) = (char) lifetime;
                    147:     (void) strcpy((char *) (pkt->dat+pkt->length),service);
                    148:     pkt->length += 1 + strlen(service);
                    149:     (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
                    150:     pkt->length += 1 + strlen(sinstance);
                    151: 
                    152:     rpkt->length = 0;
                    153: 
                    154:     /* Send the request to the local ticket-granting server */
                    155:     if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
                    156: 
                    157:     /* check packet version of the returned packet */
                    158:     if (pkt_version(rpkt) != KRB_PROT_VERSION )
                    159:         return(INTK_PROT);
                    160: 
                    161:     /* Check byte order */
                    162:     msg_byte_order = pkt_msg_type(rpkt) & 1;
                    163:     swap_bytes = 0;
                    164:     if (msg_byte_order != HOST_BYTE_ORDER)
                    165:        swap_bytes++;
                    166: 
                    167:     switch (pkt_msg_type(rpkt) & ~1) {
                    168:     case AUTH_MSG_KDC_REPLY:
                    169:        break;
                    170:     case AUTH_MSG_ERR_REPLY:
                    171:        bcopy(pkt_err_code(rpkt), (char *) &rep_err_code, 4);
                    172:        if (swap_bytes)
                    173:            swap_u_long(rep_err_code);
                    174:        return(rep_err_code);
                    175: 
                    176:     default:
                    177:        return(INTK_PROT);
                    178:     }
                    179: 
                    180:     /* Extract the ciphertext */
                    181:     cip->length = pkt_clen(rpkt);       /* let clen do the swap */
                    182: 
                    183:     bcopy((char *) pkt_cipher(rpkt),(char *) (cip->dat),cip->length);
                    184: 
                    185: #ifndef NOENCRYPTION
                    186:     /* Attempt to decrypt it */
                    187: 
                    188:     key_sched(cr.session,key_s);
                    189:     if (krb_debug)  printf("About to do decryption ...");
                    190:     pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
                    191:                  (long) cip->length,key_s,cr.session,0);
                    192: #endif /* !NOENCRYPTION */
                    193:     /* Get rid of all traces of key */
                    194:     bzero((char *) cr.session, sizeof(key));
                    195:     bzero((char *) key_s, sizeof(key_s));
                    196: 
                    197:     ptr = (char *) cip->dat;
                    198: 
                    199:     bcopy(ptr,(char *)ses,8);
                    200:     ptr += 8;
                    201: 
                    202:     (void) strcpy(s_name,ptr);
                    203:     ptr += strlen(s_name) + 1;
                    204: 
                    205:     (void) strcpy(s_instance,ptr);
                    206:     ptr += strlen(s_instance) + 1;
                    207: 
                    208:     (void) strcpy(rlm,ptr);
                    209:     ptr += strlen(rlm) + 1;
                    210: 
                    211:     lifetime = (unsigned long) ptr[0];
                    212:     kvno = (unsigned long) ptr[1];
                    213:     tkt->length = (int) ptr[2];
                    214:     ptr += 3;
                    215:     bcopy(ptr,(char *)(tkt->dat),tkt->length);
                    216:     ptr += tkt->length;
                    217: 
                    218:     if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
                    219:         strcmp(rlm, realm))    /* not what we asked for */
                    220:        return(INTK_ERR);       /* we need a better code here XXX */
                    221: 
                    222:     /* check KDC time stamp */
                    223:     bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
                    224:     if (swap_bytes) swap_u_long(kdc_time);
                    225: 
                    226:     ptr += 4;
                    227: 
                    228:     (void) gettimeofday(&tt_local,(struct timezone *) 0);
                    229:     if (abs((int)(tt_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
                    230:         return(RD_AP_TIME);            /* XXX should probably be better
                    231:                                           code */
                    232:     }
                    233: 
                    234:     if (kerror = save_credentials(s_name,s_instance,rlm,ses,lifetime,
                    235:                                  kvno,tkt,tt_local.tv_sec))
                    236:        return(kerror);
                    237: 
                    238:     return(AD_OK);
                    239: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.