2 * Copyright (c) 2010 Your Filesystem Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 #include <afsconfig.h>
26 #include "afs/param.h"
27 #include "afs/sysincludes.h"
28 #include "afsincludes.h"
30 /* A jar for storing tokens in */
33 * Return a token of the specified type from the selected tokenjar.
36 * The tokenjar in which to search
38 * The type of token to return
41 * A tokenUnion structure, from which the desired token can be
42 * accessed using the appropriate element of the union.
45 afs_FindToken(struct tokenJar *tokens, rx_securityIndex type) {
46 while (tokens != NULL) {
47 if (tokens->type == type) {
50 tokens = tokens->next;
58 * This will free the given token. No attempt is made to unlink
59 * the token from its container, and it is an error to attempt to
60 * free a token which is still linked.
62 * This performs a secure free, setting all token information to 0
63 * before returning allocated data blocks to the kernel.
65 * Intended primarily for internal use.
72 afs_FreeOneToken(struct tokenJar *token) {
73 if (token->next != NULL)
74 osi_Panic("Freeing linked token");
76 switch (token->type) {
78 if (token->u.rxkad.ticket != NULL) {
79 memset(token->u.rxkad.ticket, 0, token->u.rxkad.ticketLen);
80 afs_osi_Free(token->u.rxkad.ticket,
81 token->u.rxkad.ticketLen);
87 memset(token, 0, sizeof(struct tokenJar));
88 afs_osi_Free(token, sizeof(struct tokenJar));
94 * Free all of the tokens in a given token jar. This will also set the
95 * pointer to the jar to NULL, to indicate that it has been freed.
98 * A pointer to the address of the tokenjar to free.
101 afs_FreeTokens(struct tokenJar **tokenPtr) {
102 struct tokenJar *next, *tokens;
106 while(tokens != NULL) {
108 tokens->next = NULL; /* Unlink from chain */
109 afs_FreeOneToken(tokens);
115 * Add a token to a token jar
117 * Add a new token to a token jar. If the jar already exists,
118 * then this token becomes the first in the jar. If it doesn't
119 * exist, then a new jar is created. The contents of the new
120 * token are initialised to 0 upon creation.
123 * A pointer to the address of the token jar to populate
125 * The type of token to create
128 * A pointer to the tokenUnion of the newly created token,
129 * which may then be used to populate the token.
132 afs_AddToken(struct tokenJar **tokens, rx_securityIndex type) {
133 struct tokenJar *newToken;
135 newToken = afs_osi_Alloc(sizeof(struct tokenJar));
136 memset(newToken, 0, sizeof(*newToken));
138 newToken->type = type;
139 newToken->next = *tokens;
146 * Indicate if a single token is expired
151 * The time to check against for expiry (typically the results of
152 * calling osi_Time())
155 * True if the token has expired, false otherwise
158 afs_IsTokenExpired(struct tokenJar *token, afs_int32 now) {
159 switch (token->type) {
161 if (token->u.rxkad.clearToken.EndTimestamp < now - NOTOKTIMEOUT)
167 return 0; /* not reached, but keep gcc happy */
171 * Indicate if a token is usable by the kernel module
173 * This determines whether a token is usable. A usable token is one that
174 * has not expired, and which is otherwise suitable for use.
179 * The time to use for the expiry check
182 * True if the token is usable, false otherwise
185 afs_IsTokenUsable(struct tokenJar *token, afs_int32 now) {
187 if (afs_IsTokenExpired(token, now))
190 switch (token->type) {
192 /* We assume that all non-expired rxkad tokens are usable by us */
200 * Discard all expired tokens from a token jar
202 * This permanently removes all tokens which have expired from the token
203 * jar. Note that tokens which are not usable, but which have not expired,
204 * will not be deleted.
206 * @param[in] tokenPtr
207 * A pointer to the address of the token jar to check
209 * The time to use for the expiry check
213 afs_DiscardExpiredTokens(struct tokenJar **tokenPtr, afs_int32 now) {
214 struct tokenJar *next;
216 while (*tokenPtr != NULL) {
217 if (afs_IsTokenExpired(*tokenPtr, now)) {
218 next = (*tokenPtr)->next;
219 (*tokenPtr)->next = NULL;
220 afs_FreeOneToken(*tokenPtr);
223 tokenPtr = &(*tokenPtr)->next;
229 * Indicate whether a token jar contains one, or more usable tokens
232 * The token jar to check
234 * The cime to use for the expiry check
237 * True if the jar contains usable tokens, otherwise false
240 afs_HasUsableTokens(struct tokenJar *token, afs_int32 now) {
241 while (token != NULL) {
242 if (afs_IsTokenUsable(token, now))
250 * Add an rxkad token to the token jar
253 * A pointer to the address of the jar to add the token to
255 * A data block containing the token's opaque ticket
256 * @param[in] ticketLen
257 * The length of the ticket data block
258 * @param[in] clearToken
259 * The cleartext token information
262 afs_AddRxkadToken(struct tokenJar **tokens, char *ticket, int ticketLen,
263 struct ClearToken *clearToken) {
264 union tokenUnion *tokenU;
265 struct rxkadToken *rxkad;
267 tokenU = afs_AddToken(tokens, RX_SECIDX_KAD);
268 rxkad = &tokenU->rxkad;
270 rxkad->ticket = afs_osi_Alloc(ticketLen);
271 rxkad->ticketLen = ticketLen;
272 memcpy(rxkad->ticket, ticket, ticketLen);
273 rxkad->clearToken = *clearToken;