diff --git a/src/rxgk/rxgk.h b/src/rxgk/rxgk.h index 679489ee5b..da5225e575 100644 --- a/src/rxgk/rxgk.h +++ b/src/rxgk/rxgk.h @@ -106,6 +106,8 @@ typedef afs_int32 (*rxgk_getkey_func)(void *rock, afs_int32 *kvno, afs_int32 *enctype, rxgk_key *key); struct rx_securityClass * rxgk_NewServerSecurityObject(void *getkey_rock, rxgk_getkey_func getkey); +struct rx_securityClass * rxgk_NewNullServerSecurityObject( + void *getkey_rock, rxgk_getkey_func getkey); /* rxgk_client.c */ struct rx_securityClass *rxgk_NewClientSecurityObject(RXGK_Level level, diff --git a/src/rxgk/rxgk_private.h b/src/rxgk/rxgk_private.h index ec301a3e81..ee55a9964b 100644 --- a/src/rxgk/rxgk_private.h +++ b/src/rxgk/rxgk_private.h @@ -84,6 +84,25 @@ struct rxgk_sconn { rxgk_key k0; }; +/* + * Security Object private data for rxnull connections serving + * RXGK_GSSNegotiate requests -- there needs to be a way to know what + * key material to use to encrypt the resulting token. + * Attempt to avoid being rxgk-specific by wrapping the struct with + * getkey pointer and rock inside another struct, which has space for + * pointers if other security classes need to hang things off an rxnull + * security object. + */ +struct rxgk_nullgetkey { + void *rock; + rxgk_getkey_func getkey; +}; +struct rxgk_nullprivate { + afs_int32 valid; + void *pad[4]; + struct rxgk_nullgetkey *rxgk; +}; + int rxgk_CheckAuthentication(struct rx_securityClass *aobj, struct rx_connection *aconn); int rxgk_CreateChallenge(struct rx_securityClass *aobj, diff --git a/src/rxgk/rxgk_server.c b/src/rxgk/rxgk_server.c index 8a936a6293..50358a508f 100644 --- a/src/rxgk/rxgk_server.c +++ b/src/rxgk/rxgk_server.c @@ -71,6 +71,9 @@ static struct rx_securityOps rxgk_server_ops = { 0, /* spare 2 */ }; +/* All zeros for rxnull */ +static struct rx_securityOps null_ops; + struct rx_securityClass * rxgk_NewServerSecurityObject(void *getkey_rock, rxgk_getkey_func getkey) { @@ -98,6 +101,41 @@ rxgk_NewServerSecurityObject(void *getkey_rock, rxgk_getkey_func getkey) return sc; } +/* + * We need a custom rxnull security object so that we can have a getkey + * function available for SRXGK_GSSNegotiate to use to get a key in which + * to encrypt the resulting token. + */ +struct rx_securityClass * +rxgk_NewNullServerSecurityObject(void *getkey_rock, rxgk_getkey_func getkey) +{ + struct rx_securityClass *sc; + struct rxgk_nullprivate *sp; + + sc = calloc(1, sizeof(*sc)); + if (sc == NULL) + return NULL; + sp = calloc(1, sizeof(*sp)); + if (sp == NULL) { + free(sc); + return NULL; + } + sp->rxgk = calloc(1, sizeof(*sp->rxgk)); + if (sp->rxgk == NULL) { + free(sc); + free(sp); + return NULL; + } + sp->rxgk->rock = getkey_rock; + sp->rxgk->getkey = getkey; + sp->valid = 1u << RX_SECIDX_GK; + sc->ops = &null_ops; + sc->refCount = 1; + sc->privateData = sp; + + return sc; +} + /* Did a connection properly authenticate? */ int rxgk_CheckAuthentication(struct rx_securityClass *aobj,