X-Git-Url: http://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2Fauth%2Fauthcon.c;h=5f415a676f869ddbaf1f7507e707ed5e09d34c62;hp=006fd232569b892516060a28a26b34dceb8e6f1e;hb=d008089a79ef268bbca91d660a840f32cb416865;hpb=d302f1e193f631abb1c17253e8e3558f9c4a528c diff --git a/src/auth/authcon.c b/src/auth/authcon.c index 006fd23..5f415a6 100644 --- a/src/auth/authcon.c +++ b/src/auth/authcon.c @@ -173,6 +173,74 @@ afsconf_ClientAuthSecure(void *arock, } /*! + * 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 */ @@ -199,3 +267,99 @@ afsconf_BuildServerSecurityObjects(struct afsconf_dir *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; +}