Annotation of 43BSDReno/kerberosIV/krb/rd_safe.c, revision 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.