X-Git-Url: http://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2Fauth%2Fauthcon.c;h=5f415a676f869ddbaf1f7507e707ed5e09d34c62;hp=c57abeec35e6d7e15f423dff8a6fce88e84b8fb3;hb=d008089a79ef268bbca91d660a840f32cb416865;hpb=7d05bd439e144aa3bc5fd68908d1a359182897b0 diff --git a/src/auth/authcon.c b/src/auth/authcon.c index c57abee..5f415a6 100644 --- a/src/auth/authcon.c +++ b/src/auth/authcon.c @@ -14,21 +14,20 @@ #include #endif -RCSID - ("$Header$"); #if defined(UKERNEL) #include "afs/sysincludes.h" #include "afsincludes.h" #include "afs/stds.h" #include "afs/pthread_glock.h" -#include "des/des.h" #include "rx/rxkad.h" #include "rx/rx.h" #include "afs/cellconfig.h" #include "afs/keys.h" #include "afs/auth.h" #include "afs/pthread_glock.h" +#include "des.h" +#include "des_prototypes.h" #else /* defined(UKERNEL) */ #include #include @@ -42,7 +41,9 @@ RCSID #include #endif #include +#include #include +#include #include #include #include "cellconfig.h" @@ -52,9 +53,7 @@ RCSID /* return a null security object if nothing else can be done */ static afs_int32 -QuickAuth(astr, aindex) - struct rx_securityClass **astr; - afs_int32 *aindex; +QuickAuth(struct rx_securityClass **astr, afs_int32 *aindex) { register struct rx_securityClass *tc; tc = rxnull_NewClientSecurityObject(); @@ -66,11 +65,11 @@ QuickAuth(astr, aindex) #if !defined(UKERNEL) /* Return an appropriate security class and index */ afs_int32 -afsconf_ServerAuth(adir, astr, aindex) - register struct afsconf_dir *adir; - struct rx_securityClass **astr; - afs_int32 *aindex; +afsconf_ServerAuth(void *arock, + struct rx_securityClass **astr, + afs_int32 *aindex) { + struct afsconf_dir *adir = (struct afsconf_dir *) arock; register struct rx_securityClass *tclass; LOCK_GLOBAL_MUTEX; @@ -89,11 +88,10 @@ afsconf_ServerAuth(adir, astr, aindex) #endif /* !defined(UKERNEL) */ static afs_int32 -GenericAuth(adir, astr, aindex, enclevel) - struct afsconf_dir *adir; - struct rx_securityClass **astr; - afs_int32 *aindex; - rxkad_level enclevel; +GenericAuth(struct afsconf_dir *adir, + struct rx_securityClass **astr, + afs_int32 *aindex, + rxkad_level enclevel) { char tbuffer[256]; struct ktc_encryptionKey key, session; @@ -109,8 +107,8 @@ GenericAuth(adir, astr, aindex, enclevel) } /* next create random session key, using key for seed to good random */ - des_init_random_number_generator(&key); - code = des_random_key(&session); + des_init_random_number_generator(ktc_to_cblock(&key)); + code = des_random_key(ktc_to_cblock(&session)); if (code) { return QuickAuth(astr, aindex); } @@ -144,9 +142,10 @@ GenericAuth(adir, astr, aindex, enclevel) * appropriate security class and index */ afs_int32 -afsconf_ClientAuth(struct afsconf_dir * adir, struct rx_securityClass ** astr, +afsconf_ClientAuth(void *arock, struct rx_securityClass ** astr, afs_int32 * aindex) { + struct afsconf_dir * adir = (struct afsconf_dir *) arock; afs_int32 rc; LOCK_GLOBAL_MUTEX; @@ -160,11 +159,11 @@ afsconf_ClientAuth(struct afsconf_dir * adir, struct rx_securityClass ** astr, * tells rxkad to encrypt the data, too. */ afs_int32 -afsconf_ClientAuthSecure(adir, astr, aindex) - struct afsconf_dir *adir; - struct rx_securityClass **astr; - afs_int32 *aindex; +afsconf_ClientAuthSecure(void *arock, + struct rx_securityClass **astr, + afs_int32 *aindex) { + struct afsconf_dir *adir = (struct afsconf_dir *) arock; afs_int32 rc; LOCK_GLOBAL_MUTEX; @@ -172,3 +171,195 @@ afsconf_ClientAuthSecure(adir, astr, aindex) UNLOCK_GLOBAL_MUTEX; return rc; } + +/*! + * Build a security class from the user's current tokens + * + * This function constructs an RX security class from a user's current + * tokens. + * + * @param[in] info The cell information structure + * @param[in] flags Security flags describing the desired mechanism + * @param[out] sc The selected security class + * @param[out] scIndex The index of the selected class + * @parma[out] expires The expiry time of the tokens used to build the class + * + * Only the AFSCONF_SECOPTS_ALWAYSENCRYPT flag will modify the behaviour of + * this function - it determines whether a cleartext, or encrypting, security + * class is provided. + * + * @return + * 0 on success, non-zero on failure. An error code of + * AFSCONF_NO_SECURITY_CLASS indicates that were were unable to build a + * security class using the selected tokens. + */ + +afs_int32 +afsconf_ClientAuthToken(struct afsconf_cell *info, + afsconf_secflags flags, + struct rx_securityClass **sc, + afs_int32 *scIndex, + time_t *expires) +{ + struct ktc_principal sname; + struct ktc_token ttoken; + int encryptLevel; + afs_int32 code; + + *sc = NULL; + *scIndex = 0; + + strcpy(sname.cell, info->name); + sname.instance[0] = 0; + strcpy(sname.name, "afs"); + code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); + + if (code == 0) { + /* XXX - We should think about how to handle this */ + if (ttoken.kvno < 0 || ttoken.kvno > 256) { + fprintf(stderr, + "funny kvno (%d) in ticket, proceeding\n", + ttoken.kvno); + } + if (flags & AFSCONF_SECOPTS_ALWAYSENCRYPT) + encryptLevel = rxkad_crypt; + else + encryptLevel = rxkad_clear; + *sc = rxkad_NewClientSecurityObject(encryptLevel, + &ttoken.sessionKey, + ttoken.kvno, + ttoken.ticketLen, + ttoken.ticket); + *scIndex = 2; + if (expires) + *expires = ttoken.endTime; + } + if (*sc == NULL) + return AFSCONF_NO_SECURITY_CLASS; + + return code; +} + +/*! + * 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, + struct rx_securityClass ***classes, + afs_int32 *numClasses) +{ + if (flags & AFSCONF_SEC_OBJS_RXKAD_CRYPT) + *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); +} +#endif + +/*! + * Pick a security class to use for an outgoing connection + * + * This function selects an RX security class to use for an outgoing + * connection, based on the set of security flags provided. + * + * @param[in] dir + * The configuration directory structure for this cell. If NULL, + * no classes requiring local configuration will be returned. + * @param[in] flags + * A set of flags to determine the properties of the security class which + * is selected + * - AFSCONF_SECOPTS_NOAUTH - return an anonymous secirty class + * - AFSCONF_SECOPTS_LOCALAUTH - use classes which have local key + * material available. + * - AFSCONF_SECOPTS_ALWAYSENCRYPT - use classes in encrypting, rather + * than authentication or integrity modes. + * - AFSCONF_SECOPTS_FALLBACK_NULL - if no suitable class can be found, + * then fallback to the rxnull security class. + * @param[in] info + * The cell information structure for the current cell. If this is NULL, + * then use a version locally obtained using the cellName. + * @param[in] cellName + * The cellName to use when obtaining cell information (may be NULL if + * info is specified) + * @param[out] sc + * The selected security class + * @param[out] scIndex + * The index of the selected security class + * @param[out] expires + * The expiry time of the tokens used to construct the class. Will be + * NEVER_DATE if the class has an unlimited lifetime. If NULL, the + * function won't store the expiry date. + * + * @return + * Returns 0 on success, or a com_err error code on failure. + */ +afs_int32 +afsconf_PickClientSecObj(struct afsconf_dir *dir, afsconf_secflags flags, + struct afsconf_cell *info, + char *cellName, struct rx_securityClass **sc, + afs_int32 *scIndex, time_t *expires) { + struct afsconf_cell localInfo; + afs_int32 code = 0; + + *sc = NULL; + *scIndex = 0; + if (expires) + 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 + code = afsconf_ClientAuth(dir, sc, scIndex); + + if (code) + goto out; + + if (expires) + *expires = NEVERDATE; + } else { + if (info == NULL) { + code = afsconf_GetCellInfo(dir, cellName, NULL, &localInfo); + if (code) + goto out; + info = &localInfo; + } + + code = afsconf_ClientAuthToken(info, flags, sc, scIndex, expires); + if (code && !(flags & AFSCONF_SECOPTS_FALLBACK_NULL)) + goto out; + + /* If we didn't get a token, we'll just run anonymously */ + code = 0; + } + } + if (*sc == NULL) { + *sc = rxnull_NewClientSecurityObject(); + *scIndex = 0; + if (expires) + *expires = NEVERDATE; + } + +out: + return code; +}