Annotation of 43BSDReno/kerberosIV/krb/krb_get_in_tkt.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * $Source: /usr/src/kerberosIV/krb/RCS/krb_get_in_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_krb_get_in_tkt_c =
        !            14: "$Header: /usr/src/kerberosIV/krb/RCS/krb_get_in_tkt.c,v 4.20 90/06/25 20:56:45 kfall Exp $";
        !            15: #endif /* lint */
        !            16: 
        !            17: #include <mit-copyright.h>
        !            18: #include <des.h>
        !            19: #include <krb.h>
        !            20: #include <prot.h>
        !            21: 
        !            22: #include <stdio.h>
        !            23: #include <strings.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: int     swap_bytes;
        !            31: 
        !            32: /*
        !            33:  * decrypt_tkt(): Given user, instance, realm, passwd, key_proc
        !            34:  * and the cipher text sent from the KDC, decrypt the cipher text
        !            35:  * using the key returned by key_proc.
        !            36:  */
        !            37: 
        !            38: static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
        !            39:   char *user;
        !            40:   char *instance;
        !            41:   char *realm;
        !            42:   char *arg;
        !            43:   int (*key_proc)();
        !            44:   KTEXT *cipp;
        !            45: {
        !            46:     KTEXT cip = *cipp;
        !            47:     C_Block key;               /* Key for decrypting cipher */
        !            48:     Key_schedule key_s;
        !            49: 
        !            50: #ifndef NOENCRYPTION
        !            51:     /* Attempt to decrypt it */
        !            52: #endif
        !            53:     
        !            54:     /* generate a key */
        !            55:     
        !            56:     {
        !            57:        register int rc;
        !            58:        rc = (*key_proc)(user,instance,realm,arg,key);
        !            59:        if (rc)
        !            60:            return(rc);
        !            61:     }
        !            62:     
        !            63: #ifndef NOENCRYPTION
        !            64:     key_sched(key,key_s);
        !            65:     pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
        !            66:                 (long) cip->length,key_s,key,0);
        !            67: #endif /* !NOENCRYPTION */
        !            68:     /* Get rid of all traces of key */
        !            69:     bzero((char *)key,sizeof(key));
        !            70:     bzero((char *)key_s,sizeof(key_s));
        !            71: 
        !            72:     return(0);
        !            73: }
        !            74: 
        !            75: /*
        !            76:  * krb_get_in_tkt() gets a ticket for a given principal to use a given
        !            77:  * service and stores the returned ticket and session key for future
        !            78:  * use.
        !            79:  *
        !            80:  * The "user", "instance", and "realm" arguments give the identity of
        !            81:  * the client who will use the ticket.  The "service" and "sinstance"
        !            82:  * arguments give the identity of the server that the client wishes
        !            83:  * to use.  (The realm of the server is the same as the Kerberos server
        !            84:  * to whom the request is sent.)  The "life" argument indicates the
        !            85:  * desired lifetime of the ticket; the "key_proc" argument is a pointer
        !            86:  * to the routine used for getting the client's private key to decrypt
        !            87:  * the reply from Kerberos.  The "decrypt_proc" argument is a pointer
        !            88:  * to the routine used to decrypt the reply from Kerberos; and "arg"
        !            89:  * is an argument to be passed on to the "key_proc" routine.
        !            90:  *
        !            91:  * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
        !            92:  * returns an error code:  If an AUTH_MSG_ERR_REPLY packet is returned
        !            93:  * by Kerberos, then the error code it contains is returned.  Other
        !            94:  * error codes returned by this routine include INTK_PROT to indicate
        !            95:  * wrong protocol version, INTK_BADPW to indicate bad password (if
        !            96:  * decrypted ticket didn't make sense), INTK_ERR if the ticket was for
        !            97:  * the wrong server or the ticket store couldn't be initialized.
        !            98:  *
        !            99:  * The format of the message sent to Kerberos is as follows:
        !           100:  *
        !           101:  * Size                        Variable                Field
        !           102:  * ----                        --------                -----
        !           103:  *
        !           104:  * 1 byte              KRB_PROT_VERSION        protocol version number
        !           105:  * 1 byte              AUTH_MSG_KDC_REQUEST |  message type
        !           106:  *                     HOST_BYTE_ORDER         local byte order in lsb
        !           107:  * string              user                    client's name
        !           108:  * string              instance                client's instance
        !           109:  * string              realm                   client's realm
        !           110:  * 4 bytes             tlocal.tv_sec           timestamp in seconds
        !           111:  * 1 byte              life                    desired lifetime
        !           112:  * string              service                 service's name
        !           113:  * string              sinstance               service's instance
        !           114:  */
        !           115: 
        !           116: krb_get_in_tkt(user, instance, realm, service, sinstance, life,
        !           117:               key_proc, decrypt_proc, arg)
        !           118:     char *user;
        !           119:     char *instance;
        !           120:     char *realm;
        !           121:     char *service;
        !           122:     char *sinstance;
        !           123:     int life;
        !           124:     int (*key_proc)();
        !           125:     int (*decrypt_proc)();
        !           126:     char *arg;
        !           127: {
        !           128:     KTEXT_ST pkt_st;
        !           129:     KTEXT pkt = &pkt_st;       /* Packet to KDC */
        !           130:     KTEXT_ST rpkt_st;
        !           131:     KTEXT rpkt = &rpkt_st;     /* Returned packet */
        !           132:     KTEXT_ST cip_st;
        !           133:     KTEXT cip = &cip_st;       /* Returned Ciphertext */
        !           134:     KTEXT_ST tkt_st;
        !           135:     KTEXT tkt = &tkt_st;       /* Current ticket */
        !           136:     C_Block ses;                /* Session key for tkt */
        !           137:     int kvno;                  /* Kvno for session key */
        !           138:     unsigned char *v = pkt->dat; /* Prot vers no */
        !           139:     unsigned char *t = (pkt->dat+1); /* Prot msg type */
        !           140: 
        !           141:     char s_name[SNAME_SZ];
        !           142:     char s_instance[INST_SZ];
        !           143:     char rlm[REALM_SZ];
        !           144:     int lifetime;
        !           145:     int msg_byte_order;
        !           146:     int kerror;
        !           147:     unsigned long exp_date;
        !           148:     char *ptr;
        !           149: 
        !           150:     struct timeval t_local;
        !           151: 
        !           152:     unsigned long rep_err_code;
        !           153: 
        !           154:     unsigned long kdc_time;   /* KDC time */
        !           155: 
        !           156:     /* BUILD REQUEST PACKET */
        !           157: 
        !           158:     /* Set up the fixed part of the packet */
        !           159:     *v = (unsigned char) KRB_PROT_VERSION;
        !           160:     *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
        !           161:     *t |= HOST_BYTE_ORDER;
        !           162: 
        !           163:     /* Now for the variable info */
        !           164:     (void) strcpy((char *)(pkt->dat+2),user); /* aname */
        !           165:     pkt->length = 3 + strlen(user);
        !           166:     (void) strcpy((char *)(pkt->dat+pkt->length),
        !           167:                  instance);    /* instance */
        !           168:     pkt->length += 1 + strlen(instance);
        !           169:     (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
        !           170:     pkt->length += 1 + strlen(realm);
        !           171: 
        !           172:     (void) gettimeofday(&t_local,(struct timezone *) 0);
        !           173:     /* timestamp */
        !           174:     bcopy((char *)&(t_local.tv_sec),(char *)(pkt->dat+pkt->length), 4);
        !           175:     pkt->length += 4;
        !           176: 
        !           177:     *(pkt->dat+(pkt->length)++) = (char) life;
        !           178:     (void) strcpy((char *)(pkt->dat+pkt->length),service);
        !           179:     pkt->length += 1 + strlen(service);
        !           180:     (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
        !           181:     pkt->length += 1 + strlen(sinstance);
        !           182: 
        !           183:     rpkt->length = 0;
        !           184: 
        !           185:     /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
        !           186: 
        !           187:     if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
        !           188: 
        !           189:     /* check packet version of the returned packet */
        !           190:     if (pkt_version(rpkt) != KRB_PROT_VERSION)
        !           191:         return(INTK_PROT);
        !           192: 
        !           193:     /* Check byte order */
        !           194:     msg_byte_order = pkt_msg_type(rpkt) & 1;
        !           195:     swap_bytes = 0;
        !           196:     if (msg_byte_order != HOST_BYTE_ORDER) {
        !           197:         swap_bytes++;
        !           198:     }
        !           199: 
        !           200:     switch (pkt_msg_type(rpkt) & ~1) {
        !           201:     case AUTH_MSG_KDC_REPLY:
        !           202:         break;
        !           203:     case AUTH_MSG_ERR_REPLY:
        !           204:         bcopy(pkt_err_code(rpkt),(char *) &rep_err_code,4);
        !           205:         if (swap_bytes) swap_u_long(rep_err_code);
        !           206:         return((int)rep_err_code);
        !           207:     default:
        !           208:         return(INTK_PROT);
        !           209:     }
        !           210: 
        !           211:     /* EXTRACT INFORMATION FROM RETURN PACKET */
        !           212: 
        !           213:     /* get the principal's expiration date */
        !           214:     bcopy(pkt_x_date(rpkt),(char *) &exp_date,sizeof(exp_date));
        !           215:     if (swap_bytes) swap_u_long(exp_date);
        !           216: 
        !           217:     /* Extract the ciphertext */
        !           218:     cip->length = pkt_clen(rpkt);       /* let clen do the swap */
        !           219: 
        !           220:     if ((cip->length < 0) || (cip->length > sizeof(cip->dat)))
        !           221:        return(INTK_ERR);               /* no appropriate error code
        !           222:                                         currently defined for INTK_ */
        !           223:     /* copy information from return packet into "cip" */
        !           224:     bcopy((char *) pkt_cipher(rpkt),(char *)(cip->dat),cip->length);
        !           225: 
        !           226:     /* Attempt to decrypt the reply. */
        !           227:     if (decrypt_proc == NULL)
        !           228:        decrypt_proc = decrypt_tkt;
        !           229:     (*decrypt_proc)(user, instance, realm, arg, key_proc, &cip);
        !           230: 
        !           231:     ptr = (char *) cip->dat;
        !           232: 
        !           233:     /* extract session key */
        !           234:     bcopy(ptr,(char *)ses,8);
        !           235:     ptr += 8;
        !           236: 
        !           237:     if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
        !           238:        return(INTK_BADPW);
        !           239: 
        !           240:     /* extract server's name */
        !           241:     (void) strcpy(s_name,ptr);
        !           242:     ptr += strlen(s_name) + 1;
        !           243: 
        !           244:     if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
        !           245:        return(INTK_BADPW);
        !           246: 
        !           247:     /* extract server's instance */
        !           248:     (void) strcpy(s_instance,ptr);
        !           249:     ptr += strlen(s_instance) + 1;
        !           250: 
        !           251:     if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length)
        !           252:        return(INTK_BADPW);
        !           253: 
        !           254:     /* extract server's realm */
        !           255:     (void) strcpy(rlm,ptr);
        !           256:     ptr += strlen(rlm) + 1;
        !           257: 
        !           258:     /* extract ticket lifetime, server key version, ticket length */
        !           259:     /* be sure to avoid sign extension on lifetime! */
        !           260:     lifetime = (unsigned char) ptr[0];
        !           261:     kvno = (unsigned char) ptr[1];
        !           262:     tkt->length = (unsigned char) ptr[2];
        !           263:     ptr += 3;
        !           264:     
        !           265:     if ((tkt->length < 0) ||
        !           266:        ((tkt->length + (ptr - (char *) cip->dat)) > cip->length))
        !           267:        return(INTK_BADPW);
        !           268: 
        !           269:     /* extract ticket itself */
        !           270:     bcopy(ptr,(char *)(tkt->dat),tkt->length);
        !           271:     ptr += tkt->length;
        !           272: 
        !           273:     if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
        !           274:         strcmp(rlm, realm))    /* not what we asked for */
        !           275:        return(INTK_ERR);       /* we need a better code here XXX */
        !           276: 
        !           277:     /* check KDC time stamp */
        !           278:     bcopy(ptr,(char *)&kdc_time,4); /* Time (coarse) */
        !           279:     if (swap_bytes) swap_u_long(kdc_time);
        !           280: 
        !           281:     ptr += 4;
        !           282: 
        !           283:     (void) gettimeofday(&t_local,(struct timezone *) 0);
        !           284:     if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
        !           285:         return(RD_AP_TIME);            /* XXX should probably be better
        !           286:                                           code */
        !           287:     }
        !           288: 
        !           289:     /* initialize ticket cache */
        !           290:     if (in_tkt(user,instance) != KSUCCESS)
        !           291:        return(INTK_ERR);
        !           292: 
        !           293:     /* stash ticket, session key, etc. for future use */
        !           294:     if (kerror = save_credentials(s_name, s_instance, rlm, ses,
        !           295:                                  lifetime, kvno, tkt, t_local.tv_sec))
        !           296:        return(kerror);
        !           297: 
        !           298:     return(INTK_OK);
        !           299: }

unix.superglobalmegacorp.com

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