| File: | rxkad/rxkad_common.c |
| Location: | line 405, column 5 |
| Description: | Value stored to 'checkCksum' is never read |
| 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 UKERNEL1 |
| 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(((void *)0))) 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 |
| 62 | struct rxkad_global_stats rxkad_global_stats = { 0 }; |
| 63 | pthread_mutex_t rxkad_global_stats_lock; |
| 64 | pthread_key_t rxkad_stats_key; |
| 65 | #else /* AFS_PTHREAD_ENV */ |
| 66 | struct 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 | |
| 87 | void 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 | |
| 93 | rxkad_stats_t * |
| 94 | rxkad_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 | |
| 105 | int 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 */ |
| 169 | static afs_int32 ComputeSum(struct rx_packet *apacket, |
| 170 | fc_KeySchedule * aschedule, afs_int32 * aivec); |
| 171 | static 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 | */ |
| 176 | int |
| 177 | rxkad_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 */ |
| 191 | int |
| 192 | rxkad_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 | |
| 213 | afs_uint32 |
| 214 | rxkad_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 | |
| 232 | void |
| 233 | rxkad_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 | */ |
| 248 | static afs_int32 |
| 249 | ComputeSum(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 | |
| 274 | static afs_int32 |
| 275 | FreeObject(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 | |
| 298 | int |
| 299 | rxkad_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 | |
| 309 | int |
| 310 | rxkad_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 | |
| 342 | int |
| 343 | rxkad_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 | |
| 388 | int |
| 389 | rxkad_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(((void *)0))) < 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 | |
| 480 | int |
| 481 | rxkad_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(((void *)0))) < 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 | |
| 570 | int |
| 571 | rxkad_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 | |
| 606 | rxkad_level |
| 607 | rxkad_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 | |
| 618 | char * |
| 619 | rxkad_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 | } |