/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
/* The rxkad security object. Routines used by both client and servers. */
#include <afsconfig.h>
-#ifdef KERNEL
-#include "afs/param.h"
-#else
#include <afs/param.h>
-#endif
+#include <afs/stds.h>
#ifdef AFS_SUN59_ENV
#include <sys/time_impl.h>
#define INCLUDE_RXKAD_PRIVATE_DECLS
-RCSID
- ("$Header$");
-
#ifdef KERNEL
#ifndef UKERNEL
-#include "afs/stds.h"
#include "afs/afs_osi.h"
-#ifdef AFS_AIX_ENV
+#if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV)
#include "h/systm.h"
#endif
-#if defined(AFS_DARWIN60_ENV) || defined(AFS_OBSD_ENV)
+#if defined(AFS_DARWIN_ENV) || defined(AFS_OBSD_ENV)
#include "h/kernel.h"
#endif
#include "h/types.h"
#include "h/time.h"
-#ifndef AFS_LINUX22_ENV
-#include "rpc/types.h"
-#include "rx/xdr.h"
-#endif /* AFS_LINUX22_ENV */
#else /* !UKERNEL */
#include "afs/sysincludes.h"
#include "afsincludes.h"
#endif /* !UKERNEL */
-#include "rx/rx.h"
-
#else /* KERNEL */
-#include <afs/stds.h>
-#include <sys/types.h>
-#include <time.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#ifdef AFS_PTHREAD_ENV
+#include <roken.h>
+#include <afs/opr.h>
+#if defined(AFS_NT40_ENV) && defined(AFS_PTHREAD_ENV)
#define RXKAD_STATS_DECLSPEC __declspec(dllexport)
#endif
-#else
-#include <netinet/in.h>
-#endif
+#endif /* KERNEL */
+
#include <rx/rx.h>
+#include <rx/rx_packet.h>
#include <rx/xdr.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#endif /* KERNEL */
-
-#include <des/stats.h>
+#include "stats.h"
#include "private_data.h"
#define XPRT_RXKAD_COMMON
/* variable initialization for the benefit of darwin compiler; if it causes
problems elsewhere, conditionalize for darwin or fc_test compile breaks */
#ifdef AFS_PTHREAD_ENV
-struct rxkad_global_stats rxkad_global_stats = { 0 };
+struct rxkad_global_stats rxkad_global_stats;
pthread_mutex_t rxkad_global_stats_lock;
pthread_key_t rxkad_stats_key;
#else /* AFS_PTHREAD_ENV */
-/* Move delaration of this to des/key_sched.c */
-/* struct rxkad_stats rxkad_stats = { { 0 } }; */
+struct rxkad_stats rxkad_stats;
#endif /* AFS_PTHREAD_ENV */
#ifdef AFS_PTHREAD_ENV
+/* Pthread initialisation */
+static pthread_once_t rxkad_once_init = PTHREAD_ONCE_INIT;
+extern pthread_mutex_t rxkad_client_uid_mutex;
+extern pthread_mutex_t rxkad_random_mutex;
+
+static void
+rxkad_global_stats_init(void)
+{
+ osi_Assert(pthread_mutex_init(&rxkad_global_stats_lock, (const pthread_mutexattr_t *)0) == 0);
+ osi_Assert(pthread_key_create(&rxkad_stats_key, NULL) == 0);
+ memset(&rxkad_global_stats, 0, sizeof(rxkad_global_stats));
+}
+
+static void
+rxkad_InitPthread(void) {
+ MUTEX_INIT(&rxkad_client_uid_mutex, "uid", MUTEX_DEFAULT, 0);
+ MUTEX_INIT(&rxkad_random_mutex, "rxkad random", MUTEX_DEFAULT, 0);
+
+ rxkad_global_stats_init();
+}
+
+void
+rxkad_Init(void) {
+ osi_Assert(pthread_once(&rxkad_once_init, rxkad_InitPthread) == 0);
+}
+
/* rxkad_stats related stuff */
/*
(ptr)->prev->next = (ptr); \
else \
(head) = (ptr); \
- assert((head) && ((head)->prev == NULL)); \
+ osi_Assert((head) && ((head)->prev == NULL)); \
} while(0)
-void rxkad_global_stats_init() {
- assert(pthread_mutex_init(&rxkad_global_stats_lock, (const pthread_mutexattr_t *)0) == 0);
- assert(pthread_key_create(&rxkad_stats_key, NULL) == 0);
- memset(&rxkad_global_stats, 0, sizeof(rxkad_global_stats));
-}
-
-rxkad_stats_t *
-rxkad_thr_stats_init() {
+rxkad_stats_t *
+rxkad_thr_stats_init(void) {
rxkad_stats_t * rxkad_stats;
- rxkad_stats = (rxkad_stats_t *)malloc(sizeof(rxkad_stats_t));
- assert(rxkad_stats != NULL && pthread_setspecific(rxkad_stats_key,rxkad_stats) == 0);
- memset(rxkad_stats,0,sizeof(rxkad_stats_t));
+ rxkad_stats = calloc(1, sizeof(rxkad_stats_t));
+ osi_Assert(rxkad_stats != NULL && pthread_setspecific(rxkad_stats_key,rxkad_stats) == 0);
RXKAD_GLOBAL_STATS_LOCK;
DLL_INSERT_TAIL(rxkad_stats, rxkad_global_stats.first, rxkad_global_stats.last, next, prev);
RXKAD_GLOBAL_STATS_UNLOCK;
int rxkad_stats_agg(rxkad_stats_t * rxkad_stats) {
rxkad_stats_t * thr_stats;
- assert(rxkad_stats != NULL);
+ osi_Assert(rxkad_stats != NULL);
memset(rxkad_stats, 0, sizeof(rxkad_stats_t));
RXKAD_GLOBAL_STATS_LOCK;
for (thr_stats = rxkad_global_stats.first; thr_stats != NULL; thr_stats = thr_stats->next) {
rxkad_stats->des_encrypts[1] += thr_stats->des_encrypts[1];
rxkad_stats->des_key_scheds += thr_stats->des_key_scheds;
rxkad_stats->des_randoms += thr_stats->des_randoms;
+ rxkad_stats->clientObjects += thr_stats->clientObjects;
+ rxkad_stats->serverObjects += thr_stats->serverObjects;
rxkad_stats->spares[0] += thr_stats->spares[0];
rxkad_stats->spares[1] += thr_stats->spares[1];
rxkad_stats->spares[2] += thr_stats->spares[2];
rxkad_stats->spares[5] += thr_stats->spares[5];
rxkad_stats->spares[6] += thr_stats->spares[6];
rxkad_stats->spares[7] += thr_stats->spares[7];
- rxkad_stats->spares[8] += thr_stats->spares[8];
- rxkad_stats->spares[9] += thr_stats->spares[9];
}
RXKAD_GLOBAL_STATS_UNLOCK;
return 0;
}
+#else
+void
+rxkad_Init(void)
+{
+ return;
+}
#endif /* AFS_PTHREAD_ENV */
/* static prototypes */
rxkad_SetupEndpoint(struct rx_connection *aconnp,
struct rxkad_endpoint *aendpointp)
{
- register afs_int32 i;
+ afs_int32 i;
- aendpointp->cuid[0] = htonl(aconnp->epoch);
- i = aconnp->cid & RX_CIDMASK;
+ aendpointp->cuid[0] = htonl(rx_GetConnectionEpoch(aconnp));
+ i = rx_GetConnectionId(aconnp) & RX_CIDMASK;
aendpointp->cuid[1] = htonl(i);
aendpointp->cksum = 0; /* used as cksum only in chal resp. */
- aendpointp->securityIndex = htonl(aconnp->securityIndex);
+ aendpointp->securityIndex = htonl(rx_SecurityClassOf(aconnp));
return 0;
}
rxkad_SetupEndpoint(aconnp, &tendpoint);
memcpy((void *)xor, aivec, 2 * sizeof(afs_int32));
- fc_cbc_encrypt(&tendpoint, &tendpoint, sizeof(tendpoint), aschedule, xor,
+ fc_cbc_encrypt(&tendpoint, &tendpoint, sizeof(tendpoint), *aschedule, xor,
ENCRYPT);
memcpy(aresult,
((char *)&tendpoint) + sizeof(tendpoint) - ENCRYPTIONBLOCKSIZE,
rx_SetSecurityMaxTrailerSize(conn, 4);
} else if (level == rxkad_crypt) {
rx_SetSecurityHeaderSize(conn, 8);
- rx_SetSecurityMaxTrailerSize(conn, 8); /* XXX was 7, but why screw with
+ rx_SetSecurityMaxTrailerSize(conn, 8); /* XXX was 7, but why screw with
* unaligned accesses? */
}
}
afs_int32 * aivec)
{
afs_uint32 word[2];
- register afs_uint32 t;
+ afs_uint32 t;
t = apacket->header.callNumber;
word[0] = htonl(t);
word[0] ^= aivec[0];
word[1] ^= aivec[1];
/* encrypts word as if it were a character string */
- fc_ecb_encrypt(word, word, aschedule, ENCRYPT);
+ fc_ecb_encrypt(word, word, *aschedule, ENCRYPT);
t = ntohl(word[1]);
t = (t >> 16) & 0xffff;
if (t == 0)
tcp = (struct rxkad_cprivate *)aobj->privateData;
rxi_Free(aobj, sizeof(struct rx_securityClass));
if (tcp->type & rxkad_client) {
- rxi_Free(tcp, sizeof(struct rxkad_cprivate));
+ afs_int32 psize = PDATA_SIZE(tcp->ticketLen);
+ rxi_Free(tcp, psize);
} else if (tcp->type & rxkad_server) {
rxi_Free(tcp, sizeof(struct rxkad_sprivate));
} else {
rxkad_NewConnection(struct rx_securityClass *aobj,
struct rx_connection *aconn)
{
- if (aconn->securityData)
+ if (rx_GetSecurityData(aconn) != NULL)
return RXKADINCONSISTENCY; /* already allocated??? */
if (rx_IsServerConn(aconn)) {
- int size = sizeof(struct rxkad_sconn);
- aconn->securityData = (char *)rxi_Alloc(size);
- memset(aconn->securityData, 0, size); /* initialize it conveniently */
+ struct rxkad_sconn *data;
+ data = rxi_Alloc(sizeof(struct rxkad_sconn));
+ memset(data, 0, sizeof(struct rxkad_sconn));
+ rx_SetSecurityData(aconn, data);
} else { /* client */
struct rxkad_cprivate *tcp;
- struct rxkad_cconn *tccp;
- int size = sizeof(struct rxkad_cconn);
- tccp = (struct rxkad_cconn *)rxi_Alloc(size);
- aconn->securityData = (char *)tccp;
- memset(aconn->securityData, 0, size); /* initialize it conveniently */
+ struct rxkad_cconn *data;
+
+ data = rxi_Alloc(sizeof(struct rxkad_cconn));
+ memset(data, 0, sizeof(struct rxkad_cconn));
+ rx_SetSecurityData(aconn, data);
+
tcp = (struct rxkad_cprivate *)aobj->privateData;
if (!(tcp->type & rxkad_client))
return RXKADINCONSISTENCY;
rxkad_SetLevel(aconn, tcp->level); /* set header and trailer sizes */
rxkad_AllocCID(aobj, aconn); /* CHANGES cid AND epoch!!!! */
- rxkad_DeriveXORInfo(aconn, tcp->keysched, tcp->ivec, tccp->preSeq);
+ rxkad_DeriveXORInfo(aconn, (fc_KeySchedule *)tcp->keysched, (char *)tcp->ivec, (char *)data->preSeq);
INC_RXKAD_STATS(connections[rxkad_LevelIndex(tcp->level)]);
}
if (rx_IsServerConn(aconn)) {
struct rxkad_sconn *sconn;
struct rxkad_serverinfo *rock;
- sconn = (struct rxkad_sconn *)aconn->securityData;
+ sconn = rx_GetSecurityData(aconn);
if (sconn) {
- aconn->securityData = 0;
+ rx_SetSecurityData(aconn, NULL);
if (sconn->authenticated)
INC_RXKAD_STATS(destroyConn[rxkad_LevelIndex(sconn->level)]);
else
} else { /* client */
struct rxkad_cconn *cconn;
struct rxkad_cprivate *tcp;
- cconn = (struct rxkad_cconn *)aconn->securityData;
+ cconn = rx_GetSecurityData(aconn);
tcp = (struct rxkad_cprivate *)aobj->privateData;
if (!(tcp->type & rxkad_client))
return RXKADINCONSISTENCY;
if (cconn) {
- aconn->securityData = 0;
+ rx_SetSecurityData(aconn, NULL);
rxi_Free(cconn, sizeof(struct rxkad_cconn));
}
INC_RXKAD_STATS(destroyClient);
{
struct rx_connection *tconn;
rxkad_level level;
- fc_KeySchedule *schedule;
+ const fc_KeySchedule *schedule;
fc_InitializationVector *ivec;
int len;
int nlen = 0;
tconn = rx_ConnectionOf(acall);
len = rx_GetDataSize(apacket);
- checkCksum = 0; /* init */
if (rx_IsServerConn(tconn)) {
struct rxkad_sconn *sconn;
- sconn = (struct rxkad_sconn *)tconn->securityData;
+ sconn = rx_GetSecurityData(tconn);
if (rx_GetPacketCksum(apacket) != 0)
sconn->cksumSeen = 1;
checkCksum = sconn->cksumSeen;
INC_RXKAD_STATS(checkPackets[rxkad_StatIndex(rxkad_server, level)]);
sconn->stats.packetsReceived++;
sconn->stats.bytesReceived += len;
- schedule = (fc_KeySchedule *) sconn->keysched;
+ schedule = (const fc_KeySchedule *) sconn->keysched;
ivec = (fc_InitializationVector *) sconn->ivec;
} else {
INC_RXKAD_STATS(expired);
} else { /* client connection */
struct rxkad_cconn *cconn;
struct rxkad_cprivate *tcp;
- cconn = (struct rxkad_cconn *)tconn->securityData;
+ cconn = rx_GetSecurityData(tconn);
if (rx_GetPacketCksum(apacket) != 0)
cconn->cksumSeen = 1;
checkCksum = cconn->cksumSeen;
cconn->stats.packetsReceived++;
cconn->stats.bytesReceived += len;
preSeq = cconn->preSeq;
- schedule = (fc_KeySchedule *) tcp->keysched;
+ schedule = (const fc_KeySchedule *) tcp->keysched;
ivec = (fc_InitializationVector *) tcp->ivec;
}
if (checkCksum) {
- code = ComputeSum(apacket, schedule, preSeq);
+ code = ComputeSum(apacket, (fc_KeySchedule *)schedule, preSeq);
if (code != rx_GetPacketCksum(apacket))
return RXKADSEALEDINCON;
}
return 0; /* shouldn't happen */
case rxkad_auth:
rx_Pullup(apacket, 8); /* the following encrypts 8 bytes only */
- fc_ecb_encrypt(rx_DataOf(apacket), rx_DataOf(apacket), schedule,
+ fc_ecb_encrypt(rx_DataOf(apacket), rx_DataOf(apacket), *schedule,
DECRYPT);
break;
case rxkad_crypt:
- code = rxkad_DecryptPacket(tconn, schedule, ivec, len, apacket);
+ code = rxkad_DecryptPacket(tconn, schedule, (const fc_InitializationVector *)ivec, len, apacket);
if (code)
return code;
break;
return RXKADSEALEDINCON;
nlen = word & 0xffff; /* get real user data length */
- /* The sealed length should be no larger than the initial length, since the
+ /* The sealed length should be no larger than the initial length, since the
* reverse (round-up) occurs in ...PreparePacket */
if (nlen > len)
return RXKADDATALEN;
len = rx_GetDataSize(apacket);
if (rx_IsServerConn(tconn)) {
struct rxkad_sconn *sconn;
- sconn = (struct rxkad_sconn *)tconn->securityData;
+ sconn = rx_GetSecurityData(tconn);
if (sconn && sconn->authenticated
&& (osi_Time() < sconn->expirationTime)) {
level = sconn->level;
} else { /* client connection */
struct rxkad_cconn *cconn;
struct rxkad_cprivate *tcp;
- cconn = (struct rxkad_cconn *)tconn->securityData;
+ cconn = rx_GetSecurityData(tconn);
tcp = (struct rxkad_cprivate *)aobj->privateData;
if (!(tcp->type & rxkad_client))
return RXKADINCONSISTENCY;
nlen - (len + rx_GetSecurityHeaderSize(tconn)));
}
rx_Pullup(apacket, 8); /* the following encrypts 8 bytes only */
- fc_ecb_encrypt(rx_DataOf(apacket), rx_DataOf(apacket), schedule,
+ fc_ecb_encrypt(rx_DataOf(apacket), rx_DataOf(apacket), *schedule,
ENCRYPT);
break;
case rxkad_crypt:
rxi_RoundUpPacket(apacket,
nlen - (len + rx_GetSecurityHeaderSize(tconn)));
}
- code = rxkad_EncryptPacket(tconn, schedule, ivec, nlen, apacket);
+ code = rxkad_EncryptPacket(tconn, (const fc_KeySchedule *)schedule, (const fc_InitializationVector *)ivec, nlen, apacket);
if (code)
return code;
break;
rxkad_GetStats(struct rx_securityClass *aobj, struct rx_connection *aconn,
struct rx_securityObjectStats *astats)
{
+ void *securityData;
+
astats->type = 3;
astats->level = ((struct rxkad_cprivate *)aobj->privateData)->level;
- if (!aconn->securityData) {
+
+ securityData = rx_GetSecurityData(aconn);
+
+ if (!securityData) {
astats->flags |= 1;
return 0;
}
if (rx_IsServerConn(aconn)) {
- struct rxkad_sconn *sconn;
- sconn = (struct rxkad_sconn *)aconn->securityData;
+ struct rxkad_sconn *sconn = securityData;
+
astats->level = sconn->level;
if (sconn->authenticated)
astats->flags |= 2;
astats->bytesSent = sconn->stats.bytesSent;
astats->packetsSent = sconn->stats.packetsSent;
} else { /* client connection */
- struct rxkad_cconn *cconn;
- cconn = (struct rxkad_cconn *)aconn->securityData;
+ struct rxkad_cconn *cconn = securityData;
+
if (cconn->cksumSeen)
astats->flags |= 8;
astats->bytesReceived = cconn->stats.bytesReceived;