X-Git-Url: http://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2Fauth%2Fauthcon.c;h=aa29f79f90de6efe5dd2c6b30523dc8968b3d18d;hp=574c4d0be602ff88a00c352d59a30b958134832d;hb=d0a2889098526aa148d99e042aa8c3f7855565f7;hpb=97c317c2ccb80b1d183275258999adecb66fe5d2 diff --git a/src/auth/authcon.c b/src/auth/authcon.c index 574c4d0..aa29f79 100644 --- a/src/auth/authcon.c +++ b/src/auth/authcon.c @@ -9,24 +9,23 @@ #include #include - #include -#include -#include -#ifdef AFS_NT40_ENV -#include -#else -#include -#include -#include -#include + +#include + +#ifdef IGNORE_SOME_GCC_WARNINGS +# pragma GCC diagnostic warning "-Wdeprecated-declarations" #endif -#include -#include -#include -#include + +#define HC_DEPRECATED +#include +#include + #include #include + +#include + #include "cellconfig.h" #include "keys.h" #include "ktc.h" @@ -43,7 +42,31 @@ QuickAuth(struct rx_securityClass **astr, afs_int32 *aindex) return 0; } -#if !defined(UKERNEL) +static int _afsconf_GetRxkadKrb5Key(void *arock, int kvno, int enctype, void *outkey, + size_t *keylen) +{ + struct afsconf_dir *adir = arock; + struct afsconf_typedKey *kobj; + struct rx_opaque *keymat; + afsconf_keyType tktype; + int tkvno, tenctype; + int code; + + code = afsconf_GetKeyByTypes(adir, afsconf_rxkad_krb5, kvno, enctype, &kobj); + if (code != 0) + return code; + afsconf_typedKey_values(kobj, &tktype, &tkvno, &tenctype, &keymat); + if (*keylen < keymat->len) { + afsconf_typedKey_put(&kobj); + return AFSCONF_BADKEY; + } + memcpy(outkey, keymat->val, keymat->len); + *keylen = keymat->len; + afsconf_typedKey_put(&kobj); + return 0; +} + + /* Return an appropriate security class and index */ afs_int32 afsconf_ServerAuth(void *arock, @@ -55,7 +78,8 @@ afsconf_ServerAuth(void *arock, LOCK_GLOBAL_MUTEX; tclass = (struct rx_securityClass *) - rxkad_NewServerSecurityObject(0, adir, afsconf_GetKey, NULL); + rxkad_NewKrb5ServerSecurityObject(0, adir, afsconf_GetKey, + _afsconf_GetRxkadKrb5Key, NULL); if (tclass) { *astr = tclass; *aindex = RX_SECIDX_KAD; @@ -66,7 +90,6 @@ afsconf_ServerAuth(void *arock, return 2; } } -#endif /* !defined(UKERNEL) */ static afs_int32 GenericAuth(struct afsconf_dir *adir, @@ -74,43 +97,74 @@ GenericAuth(struct afsconf_dir *adir, afs_int32 *aindex, rxkad_level enclevel) { - char tbuffer[256]; + int enctype_preflist[]={18, 17, 23, 16, 0}; + char tbuffer[512]; struct ktc_encryptionKey key, session; struct rx_securityClass *tclass; afs_int32 kvno; afs_int32 ticketLen; afs_int32 code; + int use_krb5=0; + struct afsconf_typedKey *kobj; + struct rx_opaque *keymat; + int *et; /* first, find the right key and kvno to use */ - code = afsconf_GetLatestKey(adir, &kvno, &key); - if (code) { - return QuickAuth(astr, aindex); + + et = enctype_preflist; + while(*et != 0) { + code = afsconf_GetLatestKeyByTypes(adir, afsconf_rxkad_krb5, *et, + &kobj); + if (code == 0) { + afsconf_keyType tktype; + int tenctype; + afsconf_typedKey_values(kobj, &tktype, &kvno, &tenctype, &keymat); + RAND_add(keymat->val, keymat->len, 0.0); + use_krb5 = 1; + break; + } + et++; } - /* next create random session key, using key for seed to good random */ - des_init_random_number_generator(ktc_to_cblock(&key)); - code = des_random_key(ktc_to_cblock(&session)); + if (use_krb5 == 0) { + code = afsconf_GetLatestKey(adir, &kvno, &key); + if (code) { + return QuickAuth(astr, aindex); + } + /* next create random session key, using key for seed to good random */ + DES_init_random_number_generator((DES_cblock *) &key); + } + code = DES_new_random_key((DES_cblock *) &session); if (code) { + if (use_krb5) + afsconf_typedKey_put(&kobj); return QuickAuth(astr, aindex); } - /* now create the actual ticket */ - ticketLen = sizeof(tbuffer); - memset(tbuffer, '\0', sizeof(tbuffer)); - code = - tkt_MakeTicket(tbuffer, &ticketLen, &key, AUTH_SUPERUSER, "", "", 0, - 0xffffffff, &session, 0, "afs", ""); - /* parms were buffer, ticketlen, key to seal ticket with, principal - * name, instance and cell, start time, end time, session key to seal - * in ticket, inet host, server name and server instance */ + if (use_krb5) { + ticketLen = sizeof(tbuffer); + memset(tbuffer, '\0', sizeof(tbuffer)); + code = + tkt_MakeTicket5(tbuffer, &ticketLen, *et, &kvno, keymat->val, + keymat->len, AUTH_SUPERUSER, "", "", 0, 0x7fffffff, + &session, "afs", ""); + afsconf_typedKey_put(&kobj); + } else { + /* now create the actual ticket */ + ticketLen = sizeof(tbuffer); + memset(tbuffer, '\0', sizeof(tbuffer)); + code = + tkt_MakeTicket(tbuffer, &ticketLen, &key, AUTH_SUPERUSER, "", "", 0, + 0xffffffff, &session, 0, "afs", ""); + /* parms were buffer, ticketlen, key to seal ticket with, principal + * name, instance and cell, start time, end time, session key to seal + * in ticket, inet host, server name and server instance */ + } if (code) { return QuickAuth(astr, aindex); } - /* Next, we have ticket, kvno and session key, authenticate the connection. - * We use a magic # instead of a constant because of basic compilation - * order when compiling the system from scratch (rx/rxkad.h isn't installed - * yet). */ + /* Next, we have ticket, kvno and session key, authenticate the connection.*/ tclass = (struct rx_securityClass *) rxkad_NewClientSecurityObject(enclevel, &session, kvno, ticketLen, tbuffer); @@ -226,32 +280,44 @@ out: } /*! + * Set the security flags to be used for a particular configuration + */ +void +afsconf_SetSecurityFlags(struct afsconf_dir *dir, + afsconf_secflags flags) +{ + dir->securityFlags = flags; +} + +/*! * Build a set of security classes suitable for a server accepting * incoming connections */ -#if !defined(UKERNEL) void -afsconf_BuildServerSecurityObjects(struct afsconf_dir *dir, - afs_uint32 flags, +afsconf_BuildServerSecurityObjects(void *rock, struct rx_securityClass ***classes, afs_int32 *numClasses) { - if (flags & AFSCONF_SEC_OBJS_RXKAD_CRYPT) + struct afsconf_dir *dir = rock; + + if (dir->securityFlags & AFSCONF_SECOPTS_ALWAYSENCRYPT) *numClasses = 4; else *numClasses = 3; *classes = calloc(*numClasses, sizeof(**classes)); - (*classes)[0] = rxnull_NewServerSecurityObject(); - (*classes)[1] = NULL; - (*classes)[2] = rxkad_NewServerSecurityObject(0, dir, - afsconf_GetKey, NULL); - if (flags & AFSCONF_SEC_OBJS_RXKAD_CRYPT) - (*classes)[3] = rxkad_NewServerSecurityObject(rxkad_crypt, dir, - afsconf_GetKey, NULL); + (*classes)[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject(); + (*classes)[RX_SECIDX_VAB] = NULL; + (*classes)[RX_SECIDX_KAD] = + rxkad_NewKrb5ServerSecurityObject(0, dir, afsconf_GetKey, + _afsconf_GetRxkadKrb5Key, NULL); + + if (dir->securityFlags & AFSCONF_SECOPTS_ALWAYSENCRYPT) + (*classes)[RX_SECIDX_KAE] = + rxkad_NewKrb5ServerSecurityObject(rxkad_crypt, dir, afsconf_GetKey, + _afsconf_GetRxkadKrb5Key, NULL); } -#endif /*! * Pick a security class to use for an outgoing connection @@ -301,17 +367,13 @@ afsconf_PickClientSecObj(struct afsconf_dir *dir, afsconf_secflags flags, *sc = NULL; *scIndex = RX_SECIDX_NULL; if (expires) - expires = 0; + *expires = 0; if ( !(flags & AFSCONF_SECOPTS_NOAUTH) ) { if (!dir) return AFSCONF_NOCELLDB; if (flags & AFSCONF_SECOPTS_LOCALAUTH) { - code = afsconf_GetLatestKey(dir, 0, 0); - if (code) - goto out; - if (flags & AFSCONF_SECOPTS_ALWAYSENCRYPT) code = afsconf_ClientAuthSecure(dir, sc, scIndex); else @@ -320,6 +382,18 @@ afsconf_PickClientSecObj(struct afsconf_dir *dir, afsconf_secflags flags, if (code) goto out; + /* The afsconf_ClientAuth functions will fall back to giving + * a rxnull object, which we don't want if localauth has been + * explicitly requested. Check for this, and bail out if we + * get one. Note that this leaks a security object at present + */ + if (!(flags & AFSCONF_SECOPTS_FALLBACK_NULL) && + *scIndex == RX_SECIDX_NULL) { + sc = NULL; + code = AFSCONF_NOTFOUND; + goto out; + } + if (expires) *expires = NEVERDATE; } else {