struct afs_osi_WaitHandle AFS_WaitHandler, AFS_CSWaitHandler;
static int afs_brs_count = 0; /* request counter, to service reqs in order */
-static int rxepoch_checked = 0;
-#define afs_CheckRXEpoch() {if (rxepoch_checked == 0 && rxkad_EpochWasSet) { \
- rxepoch_checked = 1; afs_GCUserData(/* force flag */ 1); } }
-
/* PAG garbage collection */
/* We induce a compile error if param.h does not define AFS_GCPAGS */
afs_int32 afs_gcpags = AFS_GCPAGS;
#if 0
afs_StoreDirtyVcaches();
#endif
- afs_CheckRXEpoch();
last1MinCheck = now;
}
AFS_STATCNT(shutdown_daemons);
if (afs_cold_shutdown) {
afs_brsDaemons = brsInit = 0;
- rxepoch_checked = afs_nbrs = 0;
+ afs_nbrs = 0;
memset(afs_brs, 0, sizeof(afs_brs));
memset(&afs_xbrs, 0, sizeof(afs_lock_t));
afs_brsWaiters = 0;
${TOP_LIBDIR}/libafsint.a \
${TOP_LIBDIR}/libcmd.a \
${TOP_LIBDIR}/librx.a \
+ ${TOP_LIBDIR}/libafshcrypto_lwp.a \
${TOP_LIBDIR}/liblwp.a \
${TOP_LIBDIR}/libsys.a \
$(TOP_LIBDIR)/libopr.a \
$(DESTDIR)\lib\afs\afsutil.lib \
$(DESTDIR)\lib\afs\afsauth.lib \
$(DESTDIR)\lib\afsrx.lib \
+ $(DESTDIR)\lib\afshcrypto.lib \
$(DESTDIR)\lib\afslwp.lib \
$(DESTDIR)\lib\afs\afsreg.lib \
$(DESTDIR)\lib\afs\afspioctl.lib \
$(DESTDIR)\afsubik.lib \
$(DESTDIR)\afs\afsprot.lib \
$(DESTDIR)\afsrx.lib \
+ $(DESTDIR)\lib\afshcrypto.lib \
$(DESTDIR)\afs\afscom_err.lib \
$(DESTDIR)\afs\afskauth.lib \
$(DESTDIR)\lib\afsrfc3961.lib
#endif /* KERNEL */
#include <opr/queue.h>
+#include <hcrypto/rand.h>
#include "rx.h"
#include "rx_clock.h"
static void rxi_CancelKeepAliveEvent(struct rx_call *call);
static void rxi_CancelDelayedAbortEvent(struct rx_call *call);
static void rxi_CancelGrowMTUEvent(struct rx_call *call);
+static void update_nextCid(void);
#ifdef RX_ENABLE_LOCKS
struct rx_tq_debug {
* tiers:
*
* rx_connHashTable_lock - synchronizes conn creation, rx_connHashTable access
+ * also protects updates to rx_nextCid
* conn_call_lock - used to synchonize rx_EndCall and rx_NewCall
* call->lock - locks call data fields.
* These are independent of each other:
/* ------------Exported Interfaces------------- */
-/* This function allows rxkad to set the epoch to a suitably random number
- * which rx_NewConnection will use in the future. The principle purpose is to
- * get rxnull connections to use the same epoch as the rxkad connections do, at
- * least once the first rxkad connection is established. This is important now
- * that the host/port addresses aren't used in FindConnection: the uniqueness
- * of epoch/cid matters and the start time won't do. */
-
#ifdef AFS_PTHREAD_ENV
/*
* This mutex protects the following global variables:
#endif
}
rx_stats.minRtt.sec = 9999999;
-#ifdef KERNEL
- rx_SetEpoch(tv.tv_sec | 0x80000000);
-#else
- rx_SetEpoch(tv.tv_sec); /* Start time of this package, rxkad
- * will provide a randomer value. */
-#endif
+ if (RAND_bytes(&rx_epoch, sizeof(rx_epoch)) != 1)
+ return -1;
+ rx_epoch = (rx_epoch & ~0x40000000) | 0x80000000;
+ if (RAND_bytes(&rx_nextCid, sizeof(rx_nextCid)) != 1)
+ return -1;
+ rx_nextCid &= RX_CIDMASK;
MUTEX_ENTER(&rx_quota_mutex);
rxi_dataQuota += rx_extraQuota; /* + extra pkts caller asked to rsrv */
MUTEX_EXIT(&rx_quota_mutex);
int serviceSecurityIndex)
{
int hashindex, i;
- afs_int32 cid;
struct rx_connection *conn;
SPLVAR;
#endif
NETPRI;
MUTEX_ENTER(&rx_connHashTable_lock);
- cid = (rx_nextCid += RX_MAXCALLS);
conn->type = RX_CLIENT_CONNECTION;
- conn->cid = cid;
conn->epoch = rx_epoch;
+ conn->cid = rx_nextCid;
+ update_nextCid();
conn->peer = rxi_FindPeer(shost, sport, 1);
conn->serviceId = sservice;
conn->securityObject = securityObject;
}
}
+/*
+ * Increment the counter for the next connection ID, handling overflow.
+ */
+static void
+update_nextCid(void)
+{
+ /* Overflow is technically undefined behavior; avoid it. */
+ if (rx_nextCid > MAX_AFS_INT32 - (1 << RX_CIDSHIFT))
+ rx_nextCid = -1 * ((MAX_AFS_INT32 / RX_CIDSHIFT) * RX_CIDSHIFT);
+ else
+ rx_nextCid += 1 << RX_CIDSHIFT;
+}
+
static void
rxi_KeepAliveOn(struct rx_call *call)
{
/* all one string */
"LIBS = $(DESTDIR)/lib/afsrxkad.lib \\\n"
"\t$(DESTDIR)/lib/afsdes.lib \\\n" "\t$(DESTDIR)/lib/afsrx.lib \\\n"
+ "\t$(DESTDIR)/lib/afshcrypto.lib \\\n"
"\t$(DESTDIR)/lib/afslwp.lib \\\n"
"\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
"\t$(DESTDIR)/lib/afs/afsafs_com_err.lib \\\n"
LIBS=${TOP_LIBDIR}/librx.a \
+ ${TOP_LIBDIR}/libafshcrypto_lwp.a \
${TOP_LIBDIR}/liblwp.a \
${TOP_LIBDIR}/libcmd.a \
${TOP_LIBDIR}/libsys.a \
LIBDIR = $(DESTDIR)\lib
RXDLIBS = $(LIBDIR)\afs\afscmd.lib \
$(LIBDIR)\afsrx.lib \
+ $(LIBDIR)\afshcrypto.lib \
$(LIBDIR)\afslwp.lib \
$(LIBDIR)\afs\afsutil.lib \
$(LIBDIR)\afs\afsreg.lib \
afs_int32 securityIndex; /* security index */
};
-/* structure used for generating connection IDs; must be encrypted in network
- * byte order. Also must be a multiple of 8 bytes for encryption to work
- * properly.
- */
-struct rxkad_cidgen {
- struct clock time; /* time now */
- afs_int32 random1; /* some implementation-specific random info */
- afs_int32 random2; /* more random info */
- afs_int32 counter; /* a counter */
- afs_int32 ipAddr; /* or an approximation to it */
-};
-
#define PDATA_SIZE(l) (sizeof(struct rxkad_cprivate) - MAXKTCTICKETLEN + (l))
/* private data in client-side security object */
((((type) == 1) || ((type) == 2)) ? ((type)-1) : 0)
-extern int rxkad_EpochWasSet; /* TRUE => we called rx_SetEpoch */
/* Get key by enctype. Takes a rock (path to conf dir), kvno and enctype as
* input and returns the key and key length. On input, the keylength parameter
* must be set to the length of storage allocated by the caller. */
0,
};
-/* To minimize changes to epoch, we set this Cuid once, and everyone (including
- * rxnull) uses it after that. This means that the Ksession of the first
- * authencticated connection should be a good one. */
-
-#ifdef AFS_PTHREAD_ENV
-/*
- * This mutex protects the following global variables:
- * Cuid
- * counter
- * rxkad_EpochWasSet
- */
-pthread_mutex_t rxkad_client_uid_mutex;
-#define LOCK_CUID osi_Assert(pthread_mutex_lock(&rxkad_client_uid_mutex)==0)
-#define UNLOCK_CUID osi_Assert(pthread_mutex_unlock(&rxkad_client_uid_mutex)==0)
-#else
-#define LOCK_CUID
-#define UNLOCK_CUID
-#endif /* AFS_PTHREAD_ENV */
-
-static afs_int32 Cuid[2]; /* set once and shared by all */
-int rxkad_EpochWasSet = 0; /* TRUE => we called rx_SetEpoch */
-
-/* allocate a new connetion ID in place */
-int
-rxkad_AllocCID(struct rx_securityClass *aobj, struct rx_connection *aconn)
-{
- struct rxkad_cprivate *tcp;
- struct rxkad_cidgen tgen;
- static afs_int32 counter = 0; /* not used anymore */
-
- LOCK_CUID;
- if (Cuid[0] == 0) {
- afs_uint32 xor[2];
- tgen.ipAddr = rxi_getaddr(); /* comes back in net order */
- clock_GetTime(&tgen.time); /* changes time1 and time2 */
- tgen.time.sec = htonl(tgen.time.sec);
- tgen.time.usec = htonl(tgen.time.usec);
- tgen.counter = htonl(counter);
- counter++;
-#ifdef KERNEL
- tgen.random1 = afs_random() & 0x7fffffff; /* was "80000" */
- tgen.random2 = afs_random() & 0x7fffffff; /* was "htonl(100)" */
-#else
- tgen.random1 = htonl(getpid());
- tgen.random2 = htonl(100);
-#endif
- if (aobj) {
- /* block is ready for encryption with session key, let's go for it. */
- tcp = (struct rxkad_cprivate *)aobj->privateData;
- memcpy((void *)xor, (void *)tcp->ivec, 2 * sizeof(afs_int32));
- fc_cbc_encrypt((char *)&tgen, (char *)&tgen, sizeof(tgen),
- tcp->keysched, xor, ENCRYPT);
- } else {
- /* Create a session key so that we can encrypt it */
-
- }
- memcpy((void *)Cuid,
- ((char *)&tgen) + sizeof(tgen) - ENCRYPTIONBLOCKSIZE,
- ENCRYPTIONBLOCKSIZE);
- Cuid[0] = (Cuid[0] & ~0x40000000) | 0x80000000;
- Cuid[1] &= RX_CIDMASK;
- rx_SetEpoch(Cuid[0]); /* for future rxnull connections */
- rxkad_EpochWasSet++;
- }
-
- if (!aconn) {
- UNLOCK_CUID;
- return 0;
- }
- rx_SetConnectionEpoch(aconn, Cuid[0]);
- rx_SetConnectionId(aconn, Cuid[1]);
- Cuid[1] += 1 << RX_CIDSHIFT;
- UNLOCK_CUID;
- return 0;
-}
-
/* Allocate a new client security object. Called with the encryption level,
* the session key and the ticket for the other side obtained from the
* AuthServer. Refers to export control to determine level. */
rx_SetDataSize(apacket, responseSize + tcp->ticketLen);
return 0;
}
-
-void
-rxkad_ResetState(void)
-{
- LOCK_CUID;
- Cuid[0] = 0;
- rxkad_EpochWasSet = 0;
- UNLOCK_CUID;
-}
#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
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();
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, (fc_KeySchedule *)tcp->keysched, (char *)tcp->ivec, (char *)data->preSeq);
INC_RXKAD_STATS(connections[rxkad_LevelIndex(tcp->level)]);
}
EXELIBS =\
$(DESTDIR)\lib\afsrxkad.lib \
$(DESTDIR)\lib\afsrx.lib \
+ $(DESTDIR)\lib\afshcrypto.lib \
$(DESTDIR)\lib\afsdes.lib \
$(DESTDIR)\lib\afslwp.lib \
$(DESTDIR)\lib\afs\afscmd.lib \
${TOP_LIBDIR}/librxkad.a \
${TOP_LIBDIR}/libsys.a \
${TOP_LIBDIR}/librx.a \
+ ${TOP_LIBDIR}/libafshcrypto_lwp.a \
${TOP_LIBDIR}/liblwp.a \
${TOP_LIBDIR}/util.a \
$(TOP_LIBDIR)/libopr.a \
${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/xdr.h \
${TOP_INCDIR}/lock.h ubik.h ubik_int.h
-LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libauth.a \
+LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/libafshcrypto_lwp.a \
+ ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libauth.a \
${TOP_LIBDIR}/libafscom_err.a ${TOP_LIBDIR}/libcmd.a \
${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libauth.a \
${TOP_LIBDIR}/libafsutil.a ${TOP_LIBDIR}/libopr.a \
UDBG_EXELIBS =\
$(DESTDIR)\lib\afsubik.lib \
$(DESTDIR)\lib\afsrx.lib \
+ $(DESTDIR)\lib\afshcrypto.lib \
$(DESTDIR)\lib\afs\afsreg.lib \
$(DESTDIR)\lib\afslwp.lib \
$(DESTDIR)\lib\afs\afscom_err.lib \
${TOP_LIBDIR}/libafscom_err.a \
${TOP_LIBDIR}/libcmd.a \
${TOP_LIBDIR}/librx.a \
+ ${TOP_LIBDIR}/libafshcrypto_lwp.a \
${TOP_LIBDIR}/libsys.a \
${TOP_LIBDIR}/liblwp.a \
$(TOP_LIBDIR)/libopr.a \
LIBS=${TOP_LIBDIR}/libcmd.a vlib.a ${TOP_LIBDIR}/util.a \
${TOP_LIBDIR}/libdir.a ${TOP_LIBDIR}/librx.a \
+ ${TOP_LIBDIR}/libafshcrypto_lwp.a \
${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libsys.a \
${TOP_LIBDIR}/libacl.a ${TOP_LIBDIR}/libopr.a
${TOP_LIBDIR}/libafscom_err.a \
${TOP_LIBDIR}/libdir.a \
${TOP_LIBDIR}/librx.a \
+ ${TOP_LIBDIR}/libafshcrypto_lwp.a \
${TOP_LIBDIR}/liblwp.a \
${TOP_LIBDIR}/libsys.a \
${TOP_LIBDIR}/libacl.a \
LIBS=${TOP_LIBDIR}/libafsint.a \
${TOP_LIBDIR}/libcmd.a \
${TOP_LIBDIR}/librx.a \
+ ${TOP_LIBDIR}/libafshcrypto_lwp.a \
${TOP_LIBDIR}/liblwp.a \
${TOP_LIBDIR}/libsys.a \
${TOP_LIBDIR}/libopr.a \
$(LIBDIR)\afs\afsint.lib \
$(LIBDIR)\afs\afscmd.lib \
$(LIBDIR)\afsrx.lib \
+ $(LIBDIR)\afshcrypto.lib \
$(LIBDIR)\afslwp.lib \
$(LIBDIR)\afs\afspioctl.lib \
$(LIBDIR)\afs\afsutil.lib \