|
|
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.