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

1.1       root        1: /*
                      2:  * $Source: /mit/kerberos/src/lib/krb/RCS/rd_safe.c,v $
                      3:  * $Author: steiner $
                      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 'safe msg', checking its
                     12:  * integrity, and returning a pointer to the application data
                     13:  * contained and its length.
                     14:  *
                     15:  * Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...)
                     16:  *
                     17:  * Steve Miller    Project Athena  MIT/DEC
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char *rcsid_rd_safe_c=
                     22: "$Header: rd_safe.c,v 4.12 89/01/23 15:16:16 steiner Exp $";
                     23: #endif /* lint */
                     24: 
                     25: #include <mit-copyright.h>
                     26: 
                     27: /* system include files */
                     28: #include <stdio.h>
                     29: #include <errno.h>
                     30: #include <sys/types.h>
                     31: #include <netinet/in.h>
                     32: #include <sys/time.h>
                     33: 
                     34: /* application include files */
                     35: #include <des.h>
                     36: #include <krb.h>
                     37: #include <prot.h>
                     38: #include "lsb_addr_comp.h"
                     39: 
                     40: extern char *errmsg();
                     41: extern int errno;
                     42: extern int krb_debug;
                     43: 
                     44: /* static storage */
                     45: 
                     46: static C_Block calc_cksum[2];
                     47: static C_Block big_cksum[2];
                     48: static int swap_bytes;
                     49: static struct timeval local_time;
                     50: static u_long delta_t;
                     51: 
                     52: /*
                     53:  * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message.
                     54:  * Given the message received, "in", the length of that message,
                     55:  * "in_length", the "key" to compute the checksum with, and the
                     56:  * network addresses of the "sender" and "receiver" of the message,
                     57:  * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise
                     58:  * some error code.
                     59:  *
                     60:  * The message data retrieved from "in" is returned in the structure
                     61:  * "m_data".  The pointer to the application data (m_data->app_data)
                     62:  * refers back to the appropriate place in "in".
                     63:  *
                     64:  * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE
                     65:  * message.  The structure containing the extracted message
                     66:  * information, MSG_DAT, is defined in "krb.h".
                     67:  */
                     68: 
                     69: long krb_rd_safe(in,in_length,key,sender,receiver,m_data)
                     70:     u_char *in;                 /* pointer to the msg received */
                     71:     u_long in_length;           /* length of "in" msg */
                     72:     C_Block *key;               /* encryption key for seed and ivec */
                     73:     struct sockaddr_in *sender; /* sender's address */
                     74:     struct sockaddr_in *receiver; /* receiver's address -- me */
                     75:     MSG_DAT *m_data;           /* where to put message information */
                     76: {
                     77:     register u_char     *p,*q;
                     78:     static      u_long  src_addr; /* Can't send structs since no
                     79:                                    * guarantees on size */
                     80:     /* Be very conservative */
                     81:     if (sizeof(u_long) != sizeof(struct in_addr)) {
                     82:         fprintf(stderr,"\n\
                     83: krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
                     84:         exit(-1);
                     85:     }
                     86: 
                     87:     if (gettimeofday(&local_time,(struct timezone *)0))
                     88:         return  -1;
                     89: 
                     90:     p = in;                     /* beginning of message */
                     91:     swap_bytes = 0;
                     92: 
                     93:     if (*p++ != KRB_PROT_VERSION)       return RD_AP_VERSION;
                     94:     if (((*p) & ~1) != AUTH_MSG_SAFE) return RD_AP_MSG_TYPE;
                     95:     if ((*p++ & 1) != HOST_BYTE_ORDER) swap_bytes++;
                     96: 
                     97:     q = p;                      /* mark start of cksum stuff */
                     98: 
                     99:     /* safely get length */
                    100:     bcopy((char *)p,(char *)&(m_data->app_length),
                    101:           sizeof(m_data->app_length));
                    102:     if (swap_bytes) swap_u_long(m_data->app_length);
                    103:     p += sizeof(m_data->app_length); /* skip over */
                    104: 
                    105:     if (m_data->app_length + sizeof(in_length)
                    106:         + sizeof(m_data->time_sec) + sizeof(m_data->time_5ms)
                    107:         + sizeof(big_cksum) + sizeof(src_addr)
                    108:         + VERSION_SZ + MSG_TYPE_SZ > in_length)
                    109:         return(RD_AP_MODIFIED);
                    110: 
                    111:     m_data->app_data = p;       /* we're now at the application data */
                    112: 
                    113:     /* skip app data */
                    114:     p += m_data->app_length;
                    115: 
                    116:     /* safely get time_5ms */
                    117:     bcopy((char *)p, (char *)&(m_data->time_5ms),
                    118:           sizeof(m_data->time_5ms));
                    119: 
                    120:     /* don't need to swap-- one byte for now */
                    121:     p += sizeof(m_data->time_5ms);
                    122: 
                    123:     /* safely get src address */
                    124:     bcopy((char *)p,(char *)&src_addr,sizeof(src_addr));
                    125: 
                    126:     /* don't swap, net order always */
                    127:     p += sizeof(src_addr);
                    128: 
                    129:     if (src_addr != (u_long) sender->sin_addr.s_addr)
                    130:         return RD_AP_MODIFIED;
                    131: 
                    132:     /* safely get time_sec */
                    133:     bcopy((char *)p, (char *)&(m_data->time_sec),
                    134:           sizeof(m_data->time_sec));
                    135:     if (swap_bytes)
                    136:         swap_u_long(m_data->time_sec);
                    137:     p += sizeof(m_data->time_sec);
                    138: 
                    139:     /* check direction bit is the sign bit */
                    140:     /* For compatibility with broken old code, compares are done in VAX 
                    141:        byte order (LSBFIRST) */ 
                    142:     if (lsb_net_ulong_less(sender->sin_addr.s_addr,
                    143:                           receiver->sin_addr.s_addr)==-1) 
                    144:        /* src < recv */ 
                    145:        m_data->time_sec =  - m_data->time_sec; 
                    146:     else if (lsb_net_ulong_less(sender->sin_addr.s_addr, 
                    147:                                receiver->sin_addr.s_addr)==0) 
                    148:        if (lsb_net_ushort_less(sender->sin_port,receiver->sin_port)==-1)
                    149:            /* src < recv */
                    150:            m_data->time_sec =  - m_data->time_sec; 
                    151: 
                    152:     /*
                    153:      * All that for one tiny bit!  Heaven help those that talk to
                    154:      * themselves.
                    155:      */
                    156: 
                    157:     /* check the time integrity of the msg */
                    158:     delta_t = abs((int)((long) local_time.tv_sec - m_data->time_sec));
                    159:     if (delta_t > CLOCK_SKEW) return RD_AP_TIME;
                    160: 
                    161:     /*
                    162:      * caller must check timestamps for proper order and replays, since
                    163:      * server might have multiple clients each with its own timestamps
                    164:      * and we don't assume tightly synchronized clocks.
                    165:      */
                    166: 
                    167:     bcopy((char *)p,(char *)big_cksum,sizeof(big_cksum));
                    168:     if (swap_bytes) swap_u_16(big_cksum);
                    169: 
                    170: #ifdef NOENCRYPTION
                    171:     bzero(calc_cksum, sizeof(calc_cksum));
                    172: #else /* Do encryption */
                    173:     /* calculate the checksum of the length, timestamps, and
                    174:      * input data, on the sending byte order !! */
                    175:     quad_cksum(q,calc_cksum,p-q,2,key);
                    176: #endif /* NOENCRYPTION */
                    177: 
                    178:     if (krb_debug)
                    179:         printf("\ncalc_cksum = %u, received cksum = %u",
                    180:                (long) calc_cksum[0], (long) big_cksum[0]);
                    181:     if (bcmp((char *)big_cksum,(char *)calc_cksum,sizeof(big_cksum)))
                    182:         return(RD_AP_MODIFIED);
                    183: 
                    184:     return(RD_AP_OK);           /* OK == 0 */
                    185: }

unix.superglobalmegacorp.com

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