|
|
1.1 ! root 1: /* ! 2: * $Source: /mit/kerberos/src/lib/krb/RCS/rd_priv.c,v $ ! 3: * $Author: jtkohl $ ! 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: * This routine dissects a a Kerberos 'private msg', decrypting it, ! 12: * checking its integrity, and returning a pointer to the application ! 13: * data contained and its length. ! 14: * ! 15: * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If ! 16: * the return value is RD_AP_TIME, then either the times are too far ! 17: * out of synch, OR the packet was modified. ! 18: * ! 19: * Steve Miller Project Athena MIT/DEC ! 20: */ ! 21: ! 22: #ifndef lint ! 23: static char *rcsid_rd_priv_c= ! 24: "$Header: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $"; ! 25: #endif /* lint */ ! 26: ! 27: #include <mit-copyright.h> ! 28: ! 29: /* system include files */ ! 30: #include <stdio.h> ! 31: #include <errno.h> ! 32: #include <sys/types.h> ! 33: #include <netinet/in.h> ! 34: #include <sys/time.h> ! 35: ! 36: /* application include files */ ! 37: #include <des.h> ! 38: #include <krb.h> ! 39: #include <prot.h> ! 40: #include "lsb_addr_comp.h" ! 41: ! 42: extern char *errmsg(); ! 43: extern int errno; ! 44: extern int krb_debug; ! 45: ! 46: /* static storage */ ! 47: ! 48: static u_long c_length; ! 49: static int swap_bytes; ! 50: static struct timeval local_time; ! 51: static long delta_t; ! 52: int private_msg_ver = KRB_PROT_VERSION; ! 53: ! 54: /* ! 55: #ifdef NOENCRPYTION ! 56: * krb_rd_priv() checks the integrity of an ! 57: #else ! 58: * krb_rd_priv() decrypts and checks the integrity of an ! 59: #endif ! 60: * AUTH_MSG_PRIVATE message. Given the message received, "in", ! 61: * the length of that message, "in_length", the key "schedule" ! 62: #ifdef NOENCRYPTION ! 63: * and "key", and the network addresses of the ! 64: #else ! 65: * and "key" to decrypt with, and the network addresses of the ! 66: #endif ! 67: * "sender" and "receiver" of the message, krb_rd_safe() returns ! 68: * RD_AP_OK if the message is okay, otherwise some error code. ! 69: * ! 70: * The message data retrieved from "in" are returned in the structure ! 71: #ifdef NOENCRYPTION ! 72: * "m_data". The pointer to the application data ! 73: #else ! 74: * "m_data". The pointer to the decrypted application data ! 75: #endif ! 76: * (m_data->app_data) refers back to the appropriate place in "in". ! 77: * ! 78: * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE ! 79: * message. The structure containing the extracted message ! 80: * information, MSG_DAT, is defined in "krb.h". ! 81: */ ! 82: ! 83: long krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data) ! 84: u_char *in; /* pointer to the msg received */ ! 85: u_long in_length; /* length of "in" msg */ ! 86: Key_schedule schedule; /* precomputed key schedule */ ! 87: C_Block key; /* encryption key for seed and ivec */ ! 88: struct sockaddr_in *sender; ! 89: struct sockaddr_in *receiver; ! 90: MSG_DAT *m_data; /*various input/output data from msg */ ! 91: { ! 92: register u_char *p,*q; ! 93: static u_long src_addr; /* Can't send structs since no ! 94: * guarantees on size */ ! 95: ! 96: if (gettimeofday(&local_time,(struct timezone *)0)) ! 97: return -1; ! 98: ! 99: p = in; /* beginning of message */ ! 100: swap_bytes = 0; ! 101: ! 102: if (*p++ != KRB_PROT_VERSION && *(p-1) != 3) ! 103: return RD_AP_VERSION; ! 104: private_msg_ver = *(p-1); ! 105: if (((*p) & ~1) != AUTH_MSG_PRIVATE) ! 106: return RD_AP_MSG_TYPE; ! 107: if ((*p++ & 1) != HOST_BYTE_ORDER) ! 108: swap_bytes++; ! 109: ! 110: /* get cipher length */ ! 111: bcopy((char *)p,(char *)&c_length,sizeof(c_length)); ! 112: if (swap_bytes) ! 113: swap_u_long(c_length); ! 114: p += sizeof(c_length); ! 115: /* check for rational length so we don't go comatose */ ! 116: if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length) ! 117: return RD_AP_MODIFIED; ! 118: ! 119: #ifndef NOENCRYPTION ! 120: /* ! 121: * decrypt to obtain length, timestamps, app_data, and checksum ! 122: * use the session key as an ivec ! 123: */ ! 124: #endif ! 125: ! 126: q = p; /* mark start of encrypted stuff */ ! 127: ! 128: #ifndef NOENCRYPTION ! 129: /* pcbc decrypt, use key as ivec */ ! 130: pcbc_encrypt((C_Block *) q,(C_Block *) q, (long) c_length, ! 131: schedule,key,DECRYPT); ! 132: #endif ! 133: ! 134: /* safely get application data length */ ! 135: bcopy((char *) p,(char *)&(m_data->app_length), ! 136: sizeof(m_data->app_length)); ! 137: if (swap_bytes) ! 138: swap_u_long(m_data->app_length); ! 139: p += sizeof(m_data->app_length); /* skip over */ ! 140: ! 141: if (m_data->app_length + sizeof(c_length) + sizeof(in_length) + ! 142: sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) + ! 143: sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ ! 144: > in_length) ! 145: return RD_AP_MODIFIED; ! 146: ! 147: #ifndef NOENCRYPTION ! 148: /* we're now at the decrypted application data */ ! 149: #endif ! 150: m_data->app_data = p; ! 151: ! 152: p += m_data->app_length; ! 153: ! 154: /* safely get time_5ms */ ! 155: bcopy((char *) p, (char *)&(m_data->time_5ms), ! 156: sizeof(m_data->time_5ms)); ! 157: /* don't need to swap-- one byte for now */ ! 158: p += sizeof(m_data->time_5ms); ! 159: ! 160: /* safely get src address */ ! 161: bcopy((char *) p,(char *)&src_addr,sizeof(src_addr)); ! 162: /* don't swap, net order always */ ! 163: p += sizeof(src_addr); ! 164: ! 165: if (src_addr != (u_long) sender->sin_addr.s_addr) ! 166: return RD_AP_MODIFIED; ! 167: ! 168: /* safely get time_sec */ ! 169: bcopy((char *) p, (char *)&(m_data->time_sec), ! 170: sizeof(m_data->time_sec)); ! 171: if (swap_bytes) swap_u_long(m_data->time_sec); ! 172: ! 173: p += sizeof(m_data->time_sec); ! 174: ! 175: /* check direction bit is the sign bit */ ! 176: /* For compatibility with broken old code, compares are done in VAX ! 177: byte order (LSBFIRST) */ ! 178: if (lsb_net_ulong_less(sender->sin_addr.s_addr, ! 179: receiver->sin_addr.s_addr)==-1) ! 180: /* src < recv */ ! 181: m_data->time_sec = - m_data->time_sec; ! 182: else if (lsb_net_ulong_less(sender->sin_addr.s_addr, ! 183: receiver->sin_addr.s_addr)==0) ! 184: if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1) ! 185: /* src < recv */ ! 186: m_data->time_sec = - m_data->time_sec; ! 187: /* ! 188: * all that for one tiny bit! ! 189: * Heaven help those that talk to themselves. ! 190: */ ! 191: ! 192: /* check the time integrity of the msg */ ! 193: delta_t = abs((int)((long) local_time.tv_sec ! 194: - m_data->time_sec)); ! 195: if (delta_t > CLOCK_SKEW) ! 196: return RD_AP_TIME; ! 197: if (krb_debug) ! 198: printf("\ndelta_t = %d",delta_t); ! 199: ! 200: /* ! 201: * caller must check timestamps for proper order and ! 202: * replays, since server might have multiple clients ! 203: * each with its own timestamps and we don't assume ! 204: * tightly synchronized clocks. ! 205: */ ! 206: ! 207: #ifdef notdef ! 208: bcopy((char *) p,(char *)&cksum,sizeof(cksum)); ! 209: if (swap_bytes) swap_u_long(cksum) ! 210: /* ! 211: * calculate the checksum of the length, sequence, ! 212: * and input data, on the sending byte order!! ! 213: */ ! 214: calc_cksum = quad_cksum(q,NULL,p-q,0,key); ! 215: ! 216: if (krb_debug) ! 217: printf("\ncalc_cksum = %u, received cksum = %u", ! 218: calc_cksum, cksum); ! 219: if (cksum != calc_cksum) ! 220: return RD_AP_MODIFIED; ! 221: #endif ! 222: return RD_AP_OK; /* OK == 0 */ ! 223: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.