|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.