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>
14 #include <afs/pthread_glock.h>
15 #include <sys/types.h>
21 #include <netinet/in.h>
27 #include <des_prototypes.h>
30 #include "cellconfig.h"
34 /* return a null security object if nothing else can be done */
36 QuickAuth(struct rx_securityClass **astr, afs_int32 *aindex)
38 struct rx_securityClass *tc;
39 tc = rxnull_NewClientSecurityObject();
41 *aindex = RX_SECIDX_NULL;
46 /* Return an appropriate security class and index */
48 afsconf_ServerAuth(void *arock,
49 struct rx_securityClass **astr,
52 struct afsconf_dir *adir = (struct afsconf_dir *) arock;
53 struct rx_securityClass *tclass;
56 tclass = (struct rx_securityClass *)
57 rxkad_NewServerSecurityObject(0, adir, afsconf_GetKey, NULL);
60 *aindex = RX_SECIDX_KAD;
68 #endif /* !defined(UKERNEL) */
71 GenericAuth(struct afsconf_dir *adir,
72 struct rx_securityClass **astr,
77 struct ktc_encryptionKey key, session;
78 struct rx_securityClass *tclass;
83 /* first, find the right key and kvno to use */
84 code = afsconf_GetLatestKey(adir, &kvno, &key);
86 return QuickAuth(astr, aindex);
89 /* next create random session key, using key for seed to good random */
90 des_init_random_number_generator(ktc_to_cblock(&key));
91 code = des_random_key(ktc_to_cblock(&session));
93 return QuickAuth(astr, aindex);
96 /* now create the actual ticket */
97 ticketLen = sizeof(tbuffer);
98 memset(tbuffer, '\0', sizeof(tbuffer));
100 tkt_MakeTicket(tbuffer, &ticketLen, &key, AUTH_SUPERUSER, "", "", 0,
101 0xffffffff, &session, 0, "afs", "");
102 /* parms were buffer, ticketlen, key to seal ticket with, principal
103 * name, instance and cell, start time, end time, session key to seal
104 * in ticket, inet host, server name and server instance */
106 return QuickAuth(astr, aindex);
109 /* Next, we have ticket, kvno and session key, authenticate the connection.
110 * We use a magic # instead of a constant because of basic compilation
111 * order when compiling the system from scratch (rx/rxkad.h isn't installed
113 tclass = (struct rx_securityClass *)
114 rxkad_NewClientSecurityObject(enclevel, &session, kvno, ticketLen,
117 *aindex = RX_SECIDX_KAD;
121 /* build a fake ticket for 'afs' using keys from adir, returning an
122 * appropriate security class and index
125 afsconf_ClientAuth(void *arock, struct rx_securityClass ** astr,
128 struct afsconf_dir * adir = (struct afsconf_dir *) arock;
132 rc = GenericAuth(adir, astr, aindex, rxkad_clear);
137 /* build a fake ticket for 'afs' using keys from adir, returning an
138 * appropriate security class and index. This one, unlike the above,
139 * tells rxkad to encrypt the data, too.
142 afsconf_ClientAuthSecure(void *arock,
143 struct rx_securityClass **astr,
146 struct afsconf_dir *adir = (struct afsconf_dir *) arock;
150 rc = GenericAuth(adir, astr, aindex, rxkad_crypt);
156 * Build a security class from the user's current tokens
158 * This function constructs an RX security class from a user's current
161 * @param[in] info The cell information structure
162 * @param[in] flags Security flags describing the desired mechanism
163 * @param[out] sc The selected security class
164 * @param[out] scIndex The index of the selected class
165 * @parma[out] expires The expiry time of the tokens used to build the class
167 * Only the AFSCONF_SECOPTS_ALWAYSENCRYPT flag will modify the behaviour of
168 * this function - it determines whether a cleartext, or encrypting, security
172 * 0 on success, non-zero on failure. An error code of
173 * AFSCONF_NO_SECURITY_CLASS indicates that were were unable to build a
174 * security class using the selected tokens.
178 afsconf_ClientAuthToken(struct afsconf_cell *info,
179 afsconf_secflags flags,
180 struct rx_securityClass **sc,
184 struct ktc_principal sname;
185 struct ktc_token ttoken;
190 *scIndex = RX_SECIDX_NULL;
192 strcpy(sname.cell, info->name);
193 sname.instance[0] = 0;
194 strcpy(sname.name, "afs");
195 code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
198 /* XXX - We should think about how to handle this */
199 if (ttoken.kvno < 0 || ttoken.kvno > 256) {
201 "funny kvno (%d) in ticket, proceeding\n",
204 if (flags & AFSCONF_SECOPTS_ALWAYSENCRYPT)
205 encryptLevel = rxkad_crypt;
207 encryptLevel = rxkad_clear;
208 *sc = rxkad_NewClientSecurityObject(encryptLevel,
213 *scIndex = RX_SECIDX_KAD;
215 *expires = ttoken.endTime;
218 return AFSCONF_NO_SECURITY_CLASS;
224 * Build a set of security classes suitable for a server accepting
225 * incoming connections
227 #if !defined(UKERNEL)
229 afsconf_BuildServerSecurityObjects(struct afsconf_dir *dir,
231 struct rx_securityClass ***classes,
232 afs_int32 *numClasses)
234 if (flags & AFSCONF_SEC_OBJS_RXKAD_CRYPT)
239 *classes = calloc(*numClasses, sizeof(**classes));
241 (*classes)[0] = rxnull_NewServerSecurityObject();
242 (*classes)[1] = NULL;
243 (*classes)[2] = rxkad_NewServerSecurityObject(0, dir,
244 afsconf_GetKey, NULL);
245 if (flags & AFSCONF_SEC_OBJS_RXKAD_CRYPT)
246 (*classes)[3] = rxkad_NewServerSecurityObject(rxkad_crypt, dir,
247 afsconf_GetKey, NULL);
252 * Pick a security class to use for an outgoing connection
254 * This function selects an RX security class to use for an outgoing
255 * connection, based on the set of security flags provided.
258 * The configuration directory structure for this cell. If NULL,
259 * no classes requiring local configuration will be returned.
261 * A set of flags to determine the properties of the security class which
263 * - AFSCONF_SECOPTS_NOAUTH - return an anonymous secirty class
264 * - AFSCONF_SECOPTS_LOCALAUTH - use classes which have local key
265 * material available.
266 * - AFSCONF_SECOPTS_ALWAYSENCRYPT - use classes in encrypting, rather
267 * than authentication or integrity modes.
268 * - AFSCONF_SECOPTS_FALLBACK_NULL - if no suitable class can be found,
269 * then fallback to the rxnull security class.
271 * The cell information structure for the current cell. If this is NULL,
272 * then use a version locally obtained using the cellName.
273 * @param[in] cellName
274 * The cellName to use when obtaining cell information (may be NULL if
277 * The selected security class
278 * @param[out] scIndex
279 * The index of the selected security class
280 * @param[out] expires
281 * The expiry time of the tokens used to construct the class. Will be
282 * NEVER_DATE if the class has an unlimited lifetime. If NULL, the
283 * function won't store the expiry date.
286 * Returns 0 on success, or a com_err error code on failure.
289 afsconf_PickClientSecObj(struct afsconf_dir *dir, afsconf_secflags flags,
290 struct afsconf_cell *info,
291 char *cellName, struct rx_securityClass **sc,
292 afs_int32 *scIndex, time_t *expires) {
293 struct afsconf_cell localInfo;
297 *scIndex = RX_SECIDX_NULL;
301 if ( !(flags & AFSCONF_SECOPTS_NOAUTH) ) {
303 return AFSCONF_NOCELLDB;
305 if (flags & AFSCONF_SECOPTS_LOCALAUTH) {
306 code = afsconf_GetLatestKey(dir, 0, 0);
310 if (flags & AFSCONF_SECOPTS_ALWAYSENCRYPT)
311 code = afsconf_ClientAuthSecure(dir, sc, scIndex);
313 code = afsconf_ClientAuth(dir, sc, scIndex);
319 *expires = NEVERDATE;
322 code = afsconf_GetCellInfo(dir, cellName, NULL, &localInfo);
328 code = afsconf_ClientAuthToken(info, flags, sc, scIndex, expires);
329 if (code && !(flags & AFSCONF_SECOPTS_FALLBACK_NULL))
332 /* If we didn't get a token, we'll just run anonymously */
337 *sc = rxnull_NewClientSecurityObject();
338 *scIndex = RX_SECIDX_NULL;
340 *expires = NEVERDATE;