Bug Summary

File:rxkad/rxkad_common.c
Location:line 405, column 5
Description:Value stored to 'checkCksum' is never read

Annotated Source Code

1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10/* The rxkad security object. Routines used by both client and servers. */
11
12#include <afsconfig.h>
13#include <afs/param.h>
14#include <afs/stds.h>
15
16#ifdef AFS_SUN59_ENV
17#include <sys/time_impl.h>
18#endif
19
20#define INCLUDE_RXKAD_PRIVATE_DECLS
21
22#ifdef KERNEL1
23#ifndef UKERNEL
24#include "afs/afs_osi.h"
25#if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV)
26#include "h/systm.h"
27#endif
28#if defined(AFS_DARWIN_ENV) || defined(AFS_OBSD_ENV)
29#include "h/kernel.h"
30#endif
31#include "h/types.h"
32#include "h/time.h"
33#else /* !UKERNEL */
34#include "afs/sysincludes.h"
35#include "afsincludes.h"
36#endif /* !UKERNEL */
37#else /* KERNEL */
38#include <roken.h>
39#if defined(AFS_NT40_ENV) && defined(AFS_PTHREAD_ENV)
40#define RXKAD_STATS_DECLSPECextern __declspec(dllexport)
41#endif
42#include <afs/afsutil.h>
43#endif /* KERNEL */
44
45#include <rx/rx.h>
46#include <rx/xdr.h>
47
48#include "stats.h"
49#include "private_data.h"
50#define XPRT_RXKAD_COMMON
51
52#ifndef afs_max
53#define afs_max(a,b)((a) < (b)? (b) : (a)) ((a) < (b)? (b) : (a))
54#endif /* afs_max */
55
56#ifndef KERNEL1
57#define osi_Time()time_second time(0)
58#endif
59/* variable initialization for the benefit of darwin compiler; if it causes
60 problems elsewhere, conditionalize for darwin or fc_test compile breaks */
61#ifdef AFS_PTHREAD_ENV
62struct rxkad_global_stats rxkad_global_stats = { 0 };
63pthread_mutex_t rxkad_global_stats_lock;
64pthread_key_t rxkad_stats_key;
65#else /* AFS_PTHREAD_ENV */
66struct rxkad_stats rxkad_stats = { { 0 } };
67#endif /* AFS_PTHREAD_ENV */
68
69#ifdef AFS_PTHREAD_ENV
70/* rxkad_stats related stuff */
71
72/*
73 * Macro to insert an element at the tail of a doubly linked list
74 */
75#define DLL_INSERT_TAIL(ptr,head,tail,next,prev) \
76 do { \
77 (ptr)->next = NULL((void *)0); \
78 (ptr)->prev = (tail); \
79 (tail) = (ptr); \
80 if ((ptr)->prev) \
81 (ptr)->prev->next = (ptr); \
82 else \
83 (head) = (ptr); \
84 osi_Assert((head) && ((head)->prev == NULL))(void)(((head) && ((head)->prev == ((void *)0))) ||
(osi_AssertFailK( "(head) && ((head)->prev == NULL)"
, "/home/wollman/openafs/src/rxkad/rxkad_common.c", 84), 0))
; \
85 } while(0)
86
87void rxkad_global_stats_init(void) {
88 osi_Assert(pthread_mutex_init(&rxkad_global_stats_lock, (const pthread_mutexattr_t *)0) == 0)(void)((pthread_mutex_init(&rxkad_global_stats_lock, (const
pthread_mutexattr_t *)0) == 0) || (osi_AssertFailK( "pthread_mutex_init(&rxkad_global_stats_lock, (const pthread_mutexattr_t *)0) == 0"
, "/home/wollman/openafs/src/rxkad/rxkad_common.c", 88), 0))
;
89 osi_Assert(pthread_key_create(&rxkad_stats_key, NULL) == 0)(void)((pthread_key_create(&rxkad_stats_key, ((void *)0))
== 0) || (osi_AssertFailK( "pthread_key_create(&rxkad_stats_key, NULL) == 0"
, "/home/wollman/openafs/src/rxkad/rxkad_common.c", 89), 0))
;
90 memset(&rxkad_global_stats, 0, sizeof(rxkad_global_stats));
91}
92
93rxkad_stats_t *
94rxkad_thr_stats_init(void) {
95 rxkad_stats_t * rxkad_stats;
96 rxkad_stats = (rxkad_stats_t *)malloc(sizeof(rxkad_stats_t));
97 osi_Assert(rxkad_stats != NULL && pthread_setspecific(rxkad_stats_key,rxkad_stats) == 0)(void)((rxkad_stats != ((void *)0) && pthread_setspecific
(rxkad_stats_key,rxkad_stats) == 0) || (osi_AssertFailK( "rxkad_stats != NULL && pthread_setspecific(rxkad_stats_key,rxkad_stats) == 0"
, "/home/wollman/openafs/src/rxkad/rxkad_common.c", 97), 0))
;
98 memset(rxkad_stats,0,sizeof(rxkad_stats_t));
99 RXKAD_GLOBAL_STATS_LOCK;
100 DLL_INSERT_TAIL(rxkad_stats, rxkad_global_stats.first, rxkad_global_stats.last, next, prev);
101 RXKAD_GLOBAL_STATS_UNLOCK;
102 return rxkad_stats;
103}
104
105int rxkad_stats_agg(rxkad_stats_t * rxkad_stats) {
106 rxkad_stats_t * thr_stats;
107 osi_Assert(rxkad_stats != NULL)(void)((rxkad_stats != ((void *)0)) || (osi_AssertFailK( "rxkad_stats != NULL"
, "/home/wollman/openafs/src/rxkad/rxkad_common.c", 107), 0)
)
;
108 memset(rxkad_stats, 0, sizeof(rxkad_stats_t));
109 RXKAD_GLOBAL_STATS_LOCK;
110 for (thr_stats = rxkad_global_stats.first; thr_stats != NULL((void *)0); thr_stats = thr_stats->next) {
111 rxkad_stats->connections[0] += thr_stats->connections[0];
112 rxkad_stats->connections[1] += thr_stats->connections[1];
113 rxkad_stats->connections[2] += thr_stats->connections[2];
114 rxkad_stats->destroyObject += thr_stats->destroyObject;
115 rxkad_stats->destroyClient += thr_stats->destroyClient;
116 rxkad_stats->destroyUnused += thr_stats->destroyUnused;
117 rxkad_stats->destroyUnauth += thr_stats->destroyUnauth;
118 rxkad_stats->destroyConn[0] += thr_stats->destroyConn[0];
119 rxkad_stats->destroyConn[1] += thr_stats->destroyConn[1];
120 rxkad_stats->destroyConn[2] += thr_stats->destroyConn[2];
121 rxkad_stats->expired += thr_stats->expired;
122 rxkad_stats->challengesSent += thr_stats->challengesSent;
123 rxkad_stats->challenges[0] += thr_stats->challenges[0];
124 rxkad_stats->challenges[1] += thr_stats->challenges[1];
125 rxkad_stats->challenges[2] += thr_stats->challenges[2];
126 rxkad_stats->responses[0] += thr_stats->responses[0];
127 rxkad_stats->responses[1] += thr_stats->responses[1];
128 rxkad_stats->responses[2] += thr_stats->responses[2];
129 rxkad_stats->preparePackets[0] += thr_stats->preparePackets[0];
130 rxkad_stats->preparePackets[1] += thr_stats->preparePackets[1];
131 rxkad_stats->preparePackets[2] += thr_stats->preparePackets[2];
132 rxkad_stats->preparePackets[3] += thr_stats->preparePackets[3];
133 rxkad_stats->preparePackets[4] += thr_stats->preparePackets[4];
134 rxkad_stats->preparePackets[5] += thr_stats->preparePackets[5];
135 rxkad_stats->checkPackets[0] += thr_stats->checkPackets[0];
136 rxkad_stats->checkPackets[1] += thr_stats->checkPackets[1];
137 rxkad_stats->checkPackets[2] += thr_stats->checkPackets[2];
138 rxkad_stats->checkPackets[3] += thr_stats->checkPackets[3];
139 rxkad_stats->checkPackets[4] += thr_stats->checkPackets[4];
140 rxkad_stats->checkPackets[5] += thr_stats->checkPackets[5];
141 rxkad_stats->bytesEncrypted[0] += thr_stats->bytesEncrypted[0];
142 rxkad_stats->bytesEncrypted[1] += thr_stats->bytesEncrypted[1];
143 rxkad_stats->bytesDecrypted[0] += thr_stats->bytesDecrypted[0];
144 rxkad_stats->bytesDecrypted[1] += thr_stats->bytesDecrypted[1];
145 rxkad_stats->fc_encrypts[0] += thr_stats->fc_encrypts[0];
146 rxkad_stats->fc_encrypts[1] += thr_stats->fc_encrypts[1];
147 rxkad_stats->fc_key_scheds += thr_stats->fc_key_scheds;
148 rxkad_stats->des_encrypts[0] += thr_stats->des_encrypts[0];
149 rxkad_stats->des_encrypts[1] += thr_stats->des_encrypts[1];
150 rxkad_stats->des_key_scheds += thr_stats->des_key_scheds;
151 rxkad_stats->des_randoms += thr_stats->des_randoms;
152 rxkad_stats->clientObjects += thr_stats->clientObjects;
153 rxkad_stats->serverObjects += thr_stats->serverObjects;
154 rxkad_stats->spares[0] += thr_stats->spares[0];
155 rxkad_stats->spares[1] += thr_stats->spares[1];
156 rxkad_stats->spares[2] += thr_stats->spares[2];
157 rxkad_stats->spares[3] += thr_stats->spares[3];
158 rxkad_stats->spares[4] += thr_stats->spares[4];
159 rxkad_stats->spares[5] += thr_stats->spares[5];
160 rxkad_stats->spares[6] += thr_stats->spares[6];
161 rxkad_stats->spares[7] += thr_stats->spares[7];
162 }
163 RXKAD_GLOBAL_STATS_UNLOCK;
164 return 0;
165}
166#endif /* AFS_PTHREAD_ENV */
167
168/* static prototypes */
169static afs_int32 ComputeSum(struct rx_packet *apacket,
170 fc_KeySchedule * aschedule, afs_int32 * aivec);
171static afs_int32 FreeObject(struct rx_securityClass *aobj);
172
173/* this call sets up an endpoint structure, leaving it in *network* byte
174 * order so that it can be used quickly for encryption.
175 */
176int
177rxkad_SetupEndpoint(struct rx_connection *aconnp,
178 struct rxkad_endpoint *aendpointp)
179{
180 afs_int32 i;
181
182 aendpointp->cuid[0] = htonl(aconnp->epoch)(__builtin_constant_p(aconnp->epoch) ? ((((__uint32_t)(aconnp
->epoch)) >> 24) | ((((__uint32_t)(aconnp->epoch)
) & (0xff << 16)) >> 8) | ((((__uint32_t)(aconnp
->epoch)) & (0xff << 8)) << 8) | (((__uint32_t
)(aconnp->epoch)) << 24)) : __bswap32_var(aconnp->
epoch))
;
183 i = aconnp->cid & RX_CIDMASK(~(4 -1));
184 aendpointp->cuid[1] = htonl(i)(__builtin_constant_p(i) ? ((((__uint32_t)(i)) >> 24) |
((((__uint32_t)(i)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(i)) & (0xff << 8)) << 8) | (((
__uint32_t)(i)) << 24)) : __bswap32_var(i))
;
185 aendpointp->cksum = 0; /* used as cksum only in chal resp. */
186 aendpointp->securityIndex = htonl(aconnp->securityIndex)(__builtin_constant_p(aconnp->securityIndex) ? ((((__uint32_t
)(aconnp->securityIndex)) >> 24) | ((((__uint32_t)(aconnp
->securityIndex)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(aconnp->securityIndex)) & (0xff <<
8)) << 8) | (((__uint32_t)(aconnp->securityIndex)) <<
24)) : __bswap32_var(aconnp->securityIndex))
;
187 return 0;
188}
189
190/* setup xor information based on session key */
191int
192rxkad_DeriveXORInfo(struct rx_connection *aconnp, fc_KeySchedule * aschedule,
193 char *aivec, char *aresult)
194{
195 struct rxkad_endpoint tendpoint;
196 afs_uint32 xor[2];
197
198 rxkad_SetupEndpoint(aconnp, &tendpoint);
199 memcpy((void *)xor, aivec, 2 * sizeof(afs_int32));
200 fc_cbc_encrypt(&tendpoint, &tendpoint, sizeof(tendpoint), *aschedule, xor,
201 ENCRYPT1);
202 memcpy(aresult,
203 ((char *)&tendpoint) + sizeof(tendpoint) - ENCRYPTIONBLOCKSIZE8,
204 ENCRYPTIONBLOCKSIZE8);
205 return 0;
206}
207
208/* rxkad_CksumChallengeResponse - computes a checksum of the components of a
209 * challenge response packet (which must be unencrypted and in network order).
210 * The endpoint.cksum field is omitted and treated as zero. The cksum is
211 * returned in network order. */
212
213afs_uint32
214rxkad_CksumChallengeResponse(struct rxkad_v2ChallengeResponse * v2r)
215{
216 int i;
217 afs_uint32 cksum;
218 u_char *cp = (u_char *) v2r;
219 afs_uint32 savedCksum = v2r->encrypted.endpoint.cksum;
220
221 v2r->encrypted.endpoint.cksum = 0;
222
223 /* this function captured from budb/db_hash.c */
224 cksum = 1000003;
225 for (i = 0; i < sizeof(*v2r); i++)
226 cksum = (*cp++) + cksum * 0x10204081;
227
228 v2r->encrypted.endpoint.cksum = savedCksum;
229 return htonl(cksum)(__builtin_constant_p(cksum) ? ((((__uint32_t)(cksum)) >>
24) | ((((__uint32_t)(cksum)) & (0xff << 16)) >>
8) | ((((__uint32_t)(cksum)) & (0xff << 8)) <<
8) | (((__uint32_t)(cksum)) << 24)) : __bswap32_var(cksum
))
;
230}
231
232void
233rxkad_SetLevel(struct rx_connection *conn, rxkad_level level)
234{
235 if (level == rxkad_auth1) {
236 rx_SetSecurityHeaderSize(conn, 4)((conn)->securityHeaderSize = (4));
237 rx_SetSecurityMaxTrailerSize(conn, 4)((conn)->securityMaxTrailerSize = (4));
238 } else if (level == rxkad_crypt2) {
239 rx_SetSecurityHeaderSize(conn, 8)((conn)->securityHeaderSize = (8));
240 rx_SetSecurityMaxTrailerSize(conn, 8)((conn)->securityMaxTrailerSize = (8)); /* XXX was 7, but why screw with
241 * unaligned accesses? */
242 }
243}
244
245/* returns a short integer in host byte order representing a good checksum of
246 * the packet header.
247 */
248static afs_int32
249ComputeSum(struct rx_packet *apacket, fc_KeySchedule * aschedule,
250 afs_int32 * aivec)
251{
252 afs_uint32 word[2];
253 afs_uint32 t;
254
255 t = apacket->header.callNumber;
256 word[0] = htonl(t)(__builtin_constant_p(t) ? ((((__uint32_t)(t)) >> 24) |
((((__uint32_t)(t)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(t)) & (0xff << 8)) << 8) | (((
__uint32_t)(t)) << 24)) : __bswap32_var(t))
;
257 /* note that word [1] includes the channel # */
258 t = ((apacket->header.cid & 0x3) << 30)
259 | ((apacket->header.seq & 0x3fffffff));
260 word[1] = htonl(t)(__builtin_constant_p(t) ? ((((__uint32_t)(t)) >> 24) |
((((__uint32_t)(t)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(t)) & (0xff << 8)) << 8) | (((
__uint32_t)(t)) << 24)) : __bswap32_var(t))
;
261 /* XOR in the ivec from the per-endpoint encryption */
262 word[0] ^= aivec[0];
263 word[1] ^= aivec[1];
264 /* encrypts word as if it were a character string */
265 fc_ecb_encrypt(word, word, *aschedule, ENCRYPT1);
266 t = ntohl(word[1])(__builtin_constant_p(word[1]) ? ((((__uint32_t)(word[1])) >>
24) | ((((__uint32_t)(word[1])) & (0xff << 16)) >>
8) | ((((__uint32_t)(word[1])) & (0xff << 8)) <<
8) | (((__uint32_t)(word[1])) << 24)) : __bswap32_var(
word[1]))
;
267 t = (t >> 16) & 0xffff;
268 if (t == 0)
269 t = 1; /* so that 0 means don't care */
270 return t;
271}
272
273
274static afs_int32
275FreeObject(struct rx_securityClass *aobj)
276{
277 struct rxkad_cprivate *tcp; /* both structs start w/ type field */
278
279 if (aobj->refCount > 0)
280 return 0; /* still in use */
281 tcp = (struct rxkad_cprivate *)aobj->privateData;
282 rxi_Free(aobj, sizeof(struct rx_securityClass));
283 if (tcp->type & rxkad_client1) {
284 afs_int32 psize = PDATA_SIZE(tcp->ticketLen)(sizeof(struct rxkad_cprivate) - 12000 + (tcp->ticketLen));
285 rxi_Free(tcp, psize);
286 } else if (tcp->type & rxkad_server2) {
287 rxi_Free(tcp, sizeof(struct rxkad_sprivate));
288 } else {
289 return RXKADINCONSISTENCY(19270400L);
290 } /* unknown type */
291 INC_RXKAD_STATS(destroyObject)rxkad_stats.destroyObject++;
292 return 0;
293}
294
295/* rxkad_Close - called by rx with the security class object as a parameter
296 * when a security object is to be discarded */
297
298int
299rxkad_Close(struct rx_securityClass *aobj)
300{
301 afs_int32 code;
302 aobj->refCount--;
303 code = FreeObject(aobj);
304 return code;
305}
306
307/* either: called to (re)create a new connection. */
308
309int
310rxkad_NewConnection(struct rx_securityClass *aobj,
311 struct rx_connection *aconn)
312{
313 if (aconn->securityData)
314 return RXKADINCONSISTENCY(19270400L); /* already allocated??? */
315
316 if (rx_IsServerConn(aconn)((aconn)->type == 1)) {
317 int size = sizeof(struct rxkad_sconn);
318 aconn->securityData = rxi_Alloc(size);
319 memset(aconn->securityData, 0, size); /* initialize it conveniently */
320 } else { /* client */
321 struct rxkad_cprivate *tcp;
322 struct rxkad_cconn *tccp;
323 int size = sizeof(struct rxkad_cconn);
324 tccp = rxi_Alloc(size);
325 aconn->securityData = (char *)tccp;
326 memset(aconn->securityData, 0, size); /* initialize it conveniently */
327 tcp = (struct rxkad_cprivate *)aobj->privateData;
328 if (!(tcp->type & rxkad_client1))
329 return RXKADINCONSISTENCY(19270400L);
330 rxkad_SetLevel(aconn, tcp->level); /* set header and trailer sizes */
331 rxkad_AllocCID(aobj, aconn); /* CHANGES cid AND epoch!!!! */
332 rxkad_DeriveXORInfo(aconn, (fc_KeySchedule *)tcp->keysched, (char *)tcp->ivec, (char *)tccp->preSeq);
333 INC_RXKAD_STATS(connections[rxkad_LevelIndex(tcp->level)])rxkad_stats.connections[((((tcp->level) >= 0) &&
((tcp->level) <= 2)) ? (tcp->level) : 0)]++
;
334 }
335
336 aobj->refCount++; /* attached connection */
337 return 0;
338}
339
340/* either: called to destroy a connection. */
341
342int
343rxkad_DestroyConnection(struct rx_securityClass *aobj,
344 struct rx_connection *aconn)
345{
346 if (rx_IsServerConn(aconn)((aconn)->type == 1)) {
347 struct rxkad_sconn *sconn;
348 struct rxkad_serverinfo *rock;
349 sconn = (struct rxkad_sconn *)aconn->securityData;
350 if (sconn) {
351 aconn->securityData = 0;
352 if (sconn->authenticated)
353 INC_RXKAD_STATS(destroyConn[rxkad_LevelIndex(sconn->level)])rxkad_stats.destroyConn[((((sconn->level) >= 0) &&
((sconn->level) <= 2)) ? (sconn->level) : 0)]++
;
354 else
355 INC_RXKAD_STATS(destroyUnauth)rxkad_stats.destroyUnauth++;
356 rock = sconn->rock;
357 if (rock)
358 rxi_Free(rock, sizeof(struct rxkad_serverinfo));
359 rxi_Free(sconn, sizeof(struct rxkad_sconn));
360 } else {
361 INC_RXKAD_STATS(destroyUnused)rxkad_stats.destroyUnused++;
362 }
363 } else { /* client */
364 struct rxkad_cconn *cconn;
365 struct rxkad_cprivate *tcp;
366 cconn = (struct rxkad_cconn *)aconn->securityData;
367 tcp = (struct rxkad_cprivate *)aobj->privateData;
368 if (!(tcp->type & rxkad_client1))
369 return RXKADINCONSISTENCY(19270400L);
370 if (cconn) {
371 aconn->securityData = 0;
372 rxi_Free(cconn, sizeof(struct rxkad_cconn));
373 }
374 INC_RXKAD_STATS(destroyClient)rxkad_stats.destroyClient++;
375 }
376 aobj->refCount--; /* decrement connection counter */
377 if (aobj->refCount <= 0) {
378 afs_int32 code;
379 code = FreeObject(aobj);
380 if (code)
381 return code;
382 }
383 return 0;
384}
385
386/* either: decode packet */
387
388int
389rxkad_CheckPacket(struct rx_securityClass *aobj, struct rx_call *acall,
390 struct rx_packet *apacket)
391{
392 struct rx_connection *tconn;
393 rxkad_level level;
394 const fc_KeySchedule *schedule;
395 fc_InitializationVector *ivec;
396 int len;
397 int nlen = 0;
398 u_int word; /* so we get unsigned right-shift */
399 int checkCksum;
400 afs_int32 *preSeq;
401 afs_int32 code;
402
403 tconn = rx_ConnectionOf(acall)((acall)->conn);
404 len = rx_GetDataSize(apacket)((apacket)->length);
405 checkCksum = 0; /* init */
Value stored to 'checkCksum' is never read
406 if (rx_IsServerConn(tconn)((tconn)->type == 1)) {
407 struct rxkad_sconn *sconn;
408 sconn = (struct rxkad_sconn *)tconn->securityData;
409 if (rx_GetPacketCksum(apacket)((apacket)->header.spare) != 0)
410 sconn->cksumSeen = 1;
411 checkCksum = sconn->cksumSeen;
412 if (sconn && sconn->authenticated
413 && (osi_Time()time_second < sconn->expirationTime)) {
414 level = sconn->level;
415 INC_RXKAD_STATS(checkPackets[rxkad_StatIndex(rxkad_server, level)])rxkad_stats.checkPackets[(((((2) == 1) || ((2) == 2)) &&
((level) >= 0) && ((level) <= 2)) ? (((level)<<
1)+(2)-1) : 0)]++
;
416 sconn->stats.packetsReceived++;
417 sconn->stats.bytesReceived += len;
418 schedule = (const fc_KeySchedule *) sconn->keysched;
419 ivec = (fc_InitializationVector *) sconn->ivec;
420 } else {
421 INC_RXKAD_STATS(expired)rxkad_stats.expired++;
422 return RXKADEXPIRED(19270409L);
423 }
424 preSeq = sconn->preSeq;
425 } else { /* client connection */
426 struct rxkad_cconn *cconn;
427 struct rxkad_cprivate *tcp;
428 cconn = (struct rxkad_cconn *)tconn->securityData;
429 if (rx_GetPacketCksum(apacket)((apacket)->header.spare) != 0)
430 cconn->cksumSeen = 1;
431 checkCksum = cconn->cksumSeen;
432 tcp = (struct rxkad_cprivate *)aobj->privateData;
433 if (!(tcp->type & rxkad_client1))
434 return RXKADINCONSISTENCY(19270400L);
435 level = tcp->level;
436 INC_RXKAD_STATS(checkPackets[rxkad_StatIndex(rxkad_client, level)])rxkad_stats.checkPackets[(((((1) == 1) || ((1) == 2)) &&
((level) >= 0) && ((level) <= 2)) ? (((level)<<
1)+(1)-1) : 0)]++
;
437 cconn->stats.packetsReceived++;
438 cconn->stats.bytesReceived += len;
439 preSeq = cconn->preSeq;
440 schedule = (const fc_KeySchedule *) tcp->keysched;
441 ivec = (fc_InitializationVector *) tcp->ivec;
442 }
443
444 if (checkCksum) {
445 code = ComputeSum(apacket, (fc_KeySchedule *)schedule, preSeq);
446 if (code != rx_GetPacketCksum(apacket)((apacket)->header.spare))
447 return RXKADSEALEDINCON(19270410L);
448 }
449
450 switch (level) {
451 case rxkad_clear0:
452 return 0; /* shouldn't happen */
453 case rxkad_auth1:
454 rx_Pullup(apacket, 8); /* the following encrypts 8 bytes only */
455 fc_ecb_encrypt(rx_DataOf(apacket)((char *) (apacket)->wirevec[1].iov_base), rx_DataOf(apacket)((char *) (apacket)->wirevec[1].iov_base), *schedule,
456 DECRYPT0);
457 break;
458 case rxkad_crypt2:
459 code = rxkad_DecryptPacket(tconn, schedule, (const fc_InitializationVector *)ivec, len, apacket);
460 if (code)
461 return code;
462 break;
463 }
464 word = ntohl(rx_GetInt32(apacket, 0))(__builtin_constant_p((( (0) >= (apacket)->wirevec[1].iov_len
) ? rx_SlowGetInt32((apacket), (0)) : *((afs_int32 *)((char *
)((apacket)->wirevec[1].iov_base) + (0))))) ? ((((__uint32_t
)((( (0) >= (apacket)->wirevec[1].iov_len) ? rx_SlowGetInt32
((apacket), (0)) : *((afs_int32 *)((char *)((apacket)->wirevec
[1].iov_base) + (0)))))) >> 24) | ((((__uint32_t)((( (0
) >= (apacket)->wirevec[1].iov_len) ? rx_SlowGetInt32((
apacket), (0)) : *((afs_int32 *)((char *)((apacket)->wirevec
[1].iov_base) + (0)))))) & (0xff << 16)) >> 8
) | ((((__uint32_t)((( (0) >= (apacket)->wirevec[1].iov_len
) ? rx_SlowGetInt32((apacket), (0)) : *((afs_int32 *)((char *
)((apacket)->wirevec[1].iov_base) + (0)))))) & (0xff <<
8)) << 8) | (((__uint32_t)((( (0) >= (apacket)->
wirevec[1].iov_len) ? rx_SlowGetInt32((apacket), (0)) : *((afs_int32
*)((char *)((apacket)->wirevec[1].iov_base) + (0)))))) <<
24)) : __bswap32_var((( (0) >= (apacket)->wirevec[1].iov_len
) ? rx_SlowGetInt32((apacket), (0)) : *((afs_int32 *)((char *
)((apacket)->wirevec[1].iov_base) + (0))))))
; /* get first sealed word */
465 if ((word >> 16) !=
466 ((apacket->header.seq ^ apacket->header.callNumber) & 0xffff))
467 return RXKADSEALEDINCON(19270410L);
468 nlen = word & 0xffff; /* get real user data length */
469
470 /* The sealed length should be no larger than the initial length, since the
471 * reverse (round-up) occurs in ...PreparePacket */
472 if (nlen > len)
473 return RXKADDATALEN(19270411L);
474 rx_SetDataSize(apacket, nlen)((apacket)->length = (nlen));
475 return 0;
476}
477
478/* either: encode packet */
479
480int
481rxkad_PreparePacket(struct rx_securityClass *aobj, struct rx_call *acall,
482 struct rx_packet *apacket)
483{
484 struct rx_connection *tconn;
485 rxkad_level level;
486 fc_KeySchedule *schedule;
487 fc_InitializationVector *ivec;
488 int len;
489 int nlen = 0;
490 int word;
491 afs_int32 code;
492 afs_int32 *preSeq;
493
494 tconn = rx_ConnectionOf(acall)((acall)->conn);
495 len = rx_GetDataSize(apacket)((apacket)->length);
496 if (rx_IsServerConn(tconn)((tconn)->type == 1)) {
497 struct rxkad_sconn *sconn;
498 sconn = (struct rxkad_sconn *)tconn->securityData;
499 if (sconn && sconn->authenticated
500 && (osi_Time()time_second < sconn->expirationTime)) {
501 level = sconn->level;
502 INC_RXKAD_STATS(preparePackets[rxkad_StatIndex(rxkad_server, level)])rxkad_stats.preparePackets[(((((2) == 1) || ((2) == 2)) &&
((level) >= 0) && ((level) <= 2)) ? (((level)<<
1)+(2)-1) : 0)]++
;
503 sconn->stats.packetsSent++;
504 sconn->stats.bytesSent += len;
505 schedule = (fc_KeySchedule *) sconn->keysched;
506 ivec = (fc_InitializationVector *) sconn->ivec;
507 } else {
508 INC_RXKAD_STATS(expired)rxkad_stats.expired++; /* this is a pretty unlikely path... */
509 return RXKADEXPIRED(19270409L);
510 }
511 preSeq = sconn->preSeq;
512 } else { /* client connection */
513 struct rxkad_cconn *cconn;
514 struct rxkad_cprivate *tcp;
515 cconn = (struct rxkad_cconn *)tconn->securityData;
516 tcp = (struct rxkad_cprivate *)aobj->privateData;
517 if (!(tcp->type & rxkad_client1))
518 return RXKADINCONSISTENCY(19270400L);
519 level = tcp->level;
520 INC_RXKAD_STATS(preparePackets[rxkad_StatIndex(rxkad_client, level)])rxkad_stats.preparePackets[(((((1) == 1) || ((1) == 2)) &&
((level) >= 0) && ((level) <= 2)) ? (((level)<<
1)+(1)-1) : 0)]++
;
521 cconn->stats.packetsSent++;
522 cconn->stats.bytesSent += len;
523 preSeq = cconn->preSeq;
524 schedule = (fc_KeySchedule *) tcp->keysched;
525 ivec = (fc_InitializationVector *) tcp->ivec;
526 }
527
528 /* compute upward compatible checksum */
529 rx_SetPacketCksum(apacket, ComputeSum(apacket, schedule, preSeq))((apacket)->header.spare = (ComputeSum(apacket, schedule, preSeq
)))
;
530 if (level == rxkad_clear0)
531 return 0;
532
533 len = rx_GetDataSize(apacket)((apacket)->length);
534 word = (((apacket->header.seq ^ apacket->header.callNumber)
535 & 0xffff) << 16) | (len & 0xffff);
536 rx_PutInt32(apacket, 0, htonl(word)){ if ((0) >= (apacket)->wirevec[1].iov_len) rx_SlowPutInt32
((apacket), (0), ((__builtin_constant_p(word) ? ((((__uint32_t
)(word)) >> 24) | ((((__uint32_t)(word)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(word)) & (0xff <<
8)) << 8) | (((__uint32_t)(word)) << 24)) : __bswap32_var
(word)))); else *((afs_int32 *)((char *)((apacket)->wirevec
[1].iov_base) + (0))) = (__builtin_constant_p(word) ? ((((__uint32_t
)(word)) >> 24) | ((((__uint32_t)(word)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(word)) & (0xff <<
8)) << 8) | (((__uint32_t)(word)) << 24)) : __bswap32_var
(word)); }
;
537
538 switch (level) {
539 case rxkad_clear0:
540 return 0; /* shouldn't happen */
541 case rxkad_auth1:
542 nlen =
543 afs_max(ENCRYPTIONBLOCKSIZE,((8) < (len + ((tconn)->securityHeaderSize))? (len + ((
tconn)->securityHeaderSize)) : (8))
544 len + rx_GetSecurityHeaderSize(tconn))((8) < (len + ((tconn)->securityHeaderSize))? (len + ((
tconn)->securityHeaderSize)) : (8))
;
545 if (nlen > (len + rx_GetSecurityHeaderSize(tconn)((tconn)->securityHeaderSize))) {
546 rxi_RoundUpPacket(apacket,
547 nlen - (len + rx_GetSecurityHeaderSize(tconn)((tconn)->securityHeaderSize)));
548 }
549 rx_Pullup(apacket, 8); /* the following encrypts 8 bytes only */
550 fc_ecb_encrypt(rx_DataOf(apacket)((char *) (apacket)->wirevec[1].iov_base), rx_DataOf(apacket)((char *) (apacket)->wirevec[1].iov_base), *schedule,
551 ENCRYPT1);
552 break;
553 case rxkad_crypt2:
554 nlen = round_up_to_ebs(len + rx_GetSecurityHeaderSize(tconn))(((len + ((tconn)->securityHeaderSize)) + 7) & (~7));
555 if (nlen > (len + rx_GetSecurityHeaderSize(tconn)((tconn)->securityHeaderSize))) {
556 rxi_RoundUpPacket(apacket,
557 nlen - (len + rx_GetSecurityHeaderSize(tconn)((tconn)->securityHeaderSize)));
558 }
559 code = rxkad_EncryptPacket(tconn, (const fc_KeySchedule *)schedule, (const fc_InitializationVector *)ivec, nlen, apacket);
560 if (code)
561 return code;
562 break;
563 }
564 rx_SetDataSize(apacket, nlen)((apacket)->length = (nlen));
565 return 0;
566}
567
568/* either: return connection stats */
569
570int
571rxkad_GetStats(struct rx_securityClass *aobj, struct rx_connection *aconn,
572 struct rx_securityObjectStats *astats)
573{
574 astats->type = 3;
575 astats->level = ((struct rxkad_cprivate *)aobj->privateData)->level;
576 if (!aconn->securityData) {
577 astats->flags |= 1;
578 return 0;
579 }
580 if (rx_IsServerConn(aconn)((aconn)->type == 1)) {
581 struct rxkad_sconn *sconn;
582 sconn = (struct rxkad_sconn *)aconn->securityData;
583 astats->level = sconn->level;
584 if (sconn->authenticated)
585 astats->flags |= 2;
586 if (sconn->cksumSeen)
587 astats->flags |= 8;
588 astats->expires = sconn->expirationTime;
589 astats->bytesReceived = sconn->stats.bytesReceived;
590 astats->packetsReceived = sconn->stats.packetsReceived;
591 astats->bytesSent = sconn->stats.bytesSent;
592 astats->packetsSent = sconn->stats.packetsSent;
593 } else { /* client connection */
594 struct rxkad_cconn *cconn;
595 cconn = (struct rxkad_cconn *)aconn->securityData;
596 if (cconn->cksumSeen)
597 astats->flags |= 8;
598 astats->bytesReceived = cconn->stats.bytesReceived;
599 astats->packetsReceived = cconn->stats.packetsReceived;
600 astats->bytesSent = cconn->stats.bytesSent;
601 astats->packetsSent = cconn->stats.packetsSent;
602 }
603 return 0;
604}
605
606rxkad_level
607rxkad_StringToLevel(char *name)
608{
609 if (strcmp(name, "clear") == 0)
610 return rxkad_clear0;
611 if (strcmp(name, "auth") == 0)
612 return rxkad_auth1;
613 if (strcmp(name, "crypt") == 0)
614 return rxkad_crypt2;
615 return -1;
616}
617
618char *
619rxkad_LevelToString(rxkad_level level)
620{
621 if (level == rxkad_clear0)
622 return "clear";
623 if (level == rxkad_auth1)
624 return "auth";
625 if (level == rxkad_crypt2)
626 return "crypt";
627 return "unknown";
628}