Annotation of 43BSDReno/kerberosIV/krb/get_ad_tkt.c, revision 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.