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

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: }

unix.superglobalmegacorp.com

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