2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <afs/pthread_glock.h>
17 #include <sys/types.h>
23 #include <netinet/in.h>
29 #include <des_prototypes.h>
32 #include "cellconfig.h"
37 /* return a null security object if nothing else can be done */
39 QuickAuth(struct rx_securityClass **astr, afs_int32 *aindex)
41 struct rx_securityClass *tc;
42 tc = rxnull_NewClientSecurityObject();
44 *aindex = RX_SECIDX_NULL;
49 /* Return an appropriate security class and index */
51 afsconf_ServerAuth(void *arock,
52 struct rx_securityClass **astr,
55 struct afsconf_dir *adir = (struct afsconf_dir *) arock;
56 struct rx_securityClass *tclass;
59 tclass = (struct rx_securityClass *)
60 rxkad_NewServerSecurityObject(0, adir, afsconf_GetKey, NULL);
63 *aindex = RX_SECIDX_KAD;
71 #endif /* !defined(UKERNEL) */
74 GenericAuth(struct afsconf_dir *adir,
75 struct rx_securityClass **astr,
80 struct ktc_encryptionKey key, session;
81 struct rx_securityClass *tclass;
86 /* first, find the right key and kvno to use */
87 code = afsconf_GetLatestKey(adir, &kvno, &key);
89 return QuickAuth(astr, aindex);
92 /* next create random session key, using key for seed to good random */
93 des_init_random_number_generator(ktc_to_cblock(&key));
94 code = des_random_key(ktc_to_cblock(&session));
96 return QuickAuth(astr, aindex);
99 /* now create the actual ticket */
100 ticketLen = sizeof(tbuffer);
101 memset(tbuffer, '\0', sizeof(tbuffer));
103 tkt_MakeTicket(tbuffer, &ticketLen, &key, AUTH_SUPERUSER, "", "", 0,
104 0xffffffff, &session, 0, "afs", "");
105 /* parms were buffer, ticketlen, key to seal ticket with, principal
106 * name, instance and cell, start time, end time, session key to seal
107 * in ticket, inet host, server name and server instance */
109 return QuickAuth(astr, aindex);
112 /* Next, we have ticket, kvno and session key, authenticate the connection.
113 * We use a magic # instead of a constant because of basic compilation
114 * order when compiling the system from scratch (rx/rxkad.h isn't installed
116 tclass = (struct rx_securityClass *)
117 rxkad_NewClientSecurityObject(enclevel, &session, kvno, ticketLen,
120 *aindex = RX_SECIDX_KAD;
124 /* build a fake ticket for 'afs' using keys from adir, returning an
125 * appropriate security class and index
128 afsconf_ClientAuth(void *arock, struct rx_securityClass ** astr,
131 struct afsconf_dir * adir = (struct afsconf_dir *) arock;
135 rc = GenericAuth(adir, astr, aindex, rxkad_clear);
140 /* build a fake ticket for 'afs' using keys from adir, returning an
141 * appropriate security class and index. This one, unlike the above,
142 * tells rxkad to encrypt the data, too.
145 afsconf_ClientAuthSecure(void *arock,
146 struct rx_securityClass **astr,
149 struct afsconf_dir *adir = (struct afsconf_dir *) arock;
153 rc = GenericAuth(adir, astr, aindex, rxkad_crypt);
159 * Build a security class from the user's current tokens
161 * This function constructs an RX security class from a user's current
164 * @param[in] info The cell information structure
165 * @param[in] flags Security flags describing the desired mechanism
166 * @param[out] sc The selected security class
167 * @param[out] scIndex The index of the selected class
168 * @parma[out] expires The expiry time of the tokens used to build the class
170 * Only the AFSCONF_SECOPTS_ALWAYSENCRYPT flag will modify the behaviour of
171 * this function - it determines whether a cleartext, or encrypting, security
175 * 0 on success, non-zero on failure. An error code of
176 * AFSCONF_NO_SECURITY_CLASS indicates that were were unable to build a
177 * security class using the selected tokens.
181 afsconf_ClientAuthToken(struct afsconf_cell *info,
182 afsconf_secflags flags,
183 struct rx_securityClass **sc,
187 struct ktc_setTokenData *tokenSet = NULL;
188 struct ktc_token ttoken;
193 *scIndex = RX_SECIDX_NULL;
195 code = ktc_GetTokenEx(info->name, &tokenSet);
199 code = token_extractRxkad(tokenSet, &ttoken, NULL, NULL);
201 /* XXX - We should think about how to handle this */
202 if (ttoken.kvno < 0 || ttoken.kvno > 256) {
204 "funny kvno (%d) in ticket, proceeding\n",
207 if (flags & AFSCONF_SECOPTS_ALWAYSENCRYPT)
208 encryptLevel = rxkad_crypt;
210 encryptLevel = rxkad_clear;
211 *sc = rxkad_NewClientSecurityObject(encryptLevel,
216 *scIndex = RX_SECIDX_KAD;
218 *expires = ttoken.endTime;
222 token_FreeSet(&tokenSet);
225 return AFSCONF_NO_SECURITY_CLASS;
231 * Build a set of security classes suitable for a server accepting
232 * incoming connections
234 #if !defined(UKERNEL)
236 afsconf_BuildServerSecurityObjects(struct afsconf_dir *dir,
238 struct rx_securityClass ***classes,
239 afs_int32 *numClasses)
241 if (flags & AFSCONF_SEC_OBJS_RXKAD_CRYPT)
246 *classes = calloc(*numClasses, sizeof(**classes));
248 (*classes)[0] = rxnull_NewServerSecurityObject();
249 (*classes)[1] = NULL;
250 (*classes)[2] = rxkad_NewServerSecurityObject(0, dir,
251 afsconf_GetKey, NULL);
252 if (flags & AFSCONF_SEC_OBJS_RXKAD_CRYPT)
253 (*classes)[3] = rxkad_NewServerSecurityObject(rxkad_crypt, dir,
254 afsconf_GetKey, NULL);
259 * Pick a security class to use for an outgoing connection
261 * This function selects an RX security class to use for an outgoing
262 * connection, based on the set of security flags provided.
265 * The configuration directory structure for this cell. If NULL,
266 * no classes requiring local configuration will be returned.
268 * A set of flags to determine the properties of the security class which
270 * - AFSCONF_SECOPTS_NOAUTH - return an anonymous secirty class
271 * - AFSCONF_SECOPTS_LOCALAUTH - use classes which have local key
272 * material available.
273 * - AFSCONF_SECOPTS_ALWAYSENCRYPT - use classes in encrypting, rather
274 * than authentication or integrity modes.
275 * - AFSCONF_SECOPTS_FALLBACK_NULL - if no suitable class can be found,
276 * then fallback to the rxnull security class.
278 * The cell information structure for the current cell. If this is NULL,
279 * then use a version locally obtained using the cellName.
280 * @param[in] cellName
281 * The cellName to use when obtaining cell information (may be NULL if
284 * The selected security class
285 * @param[out] scIndex
286 * The index of the selected security class
287 * @param[out] expires
288 * The expiry time of the tokens used to construct the class. Will be
289 * NEVER_DATE if the class has an unlimited lifetime. If NULL, the
290 * function won't store the expiry date.
293 * Returns 0 on success, or a com_err error code on failure.
296 afsconf_PickClientSecObj(struct afsconf_dir *dir, afsconf_secflags flags,
297 struct afsconf_cell *info,
298 char *cellName, struct rx_securityClass **sc,
299 afs_int32 *scIndex, time_t *expires) {
300 struct afsconf_cell localInfo;
304 *scIndex = RX_SECIDX_NULL;
308 if ( !(flags & AFSCONF_SECOPTS_NOAUTH) ) {
310 return AFSCONF_NOCELLDB;
312 if (flags & AFSCONF_SECOPTS_LOCALAUTH) {
313 code = afsconf_GetLatestKey(dir, 0, 0);
317 if (flags & AFSCONF_SECOPTS_ALWAYSENCRYPT)
318 code = afsconf_ClientAuthSecure(dir, sc, scIndex);
320 code = afsconf_ClientAuth(dir, sc, scIndex);
326 *expires = NEVERDATE;
329 code = afsconf_GetCellInfo(dir, cellName, NULL, &localInfo);
335 code = afsconf_ClientAuthToken(info, flags, sc, scIndex, expires);
336 if (code && !(flags & AFSCONF_SECOPTS_FALLBACK_NULL))
339 /* If we didn't get a token, we'll just run anonymously */
344 *sc = rxnull_NewClientSecurityObject();
345 *scIndex = RX_SECIDX_NULL;
347 *expires = NEVERDATE;