svcauth_des.c (7c478bd9) svcauth_des.c (61961e0f)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *

--- 4 unchanged lines hidden (view full) ---

13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *

--- 4 unchanged lines hidden (view full) ---

13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 *
22 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
21 */
22
23/*
24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26/* All Rights Reserved */
27/*
28 * Portions of this source code were derived from Berkeley
29 * 4.3 BSD under license from the Regents of the University of
30 * California.

--- 16 unchanged lines hidden (view full) ---

47 */
48
49#include "mt.h"
50#include "rpc_mt.h"
51#include <assert.h>
52#include <rpc/des_crypt.h>
53#include <rpc/rpc.h>
54#include <sys/types.h>
25 * Use is subject to license terms.
26 */
27/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28/* All Rights Reserved */
29/*
30 * Portions of this source code were derived from Berkeley
31 * 4.3 BSD under license from the Regents of the University of
32 * California.

--- 16 unchanged lines hidden (view full) ---

49 */
50
51#include "mt.h"
52#include "rpc_mt.h"
53#include <assert.h>
54#include <rpc/des_crypt.h>
55#include <rpc/rpc.h>
56#include <sys/types.h>
55#include <rpc/trace.h>
56#include <stdlib.h>
57#include <unistd.h>
58#include <string.h>
57#include <stdlib.h>
58#include <unistd.h>
59#include <string.h>
60#include <strings.h>
59
61
60#ifdef KERNEL
61#include <sys/kernel.h>
62#define gettimeofday(tvp, tzp) (*(tvp) = time)
63#else
64#include <syslog.h>
62#include <syslog.h>
65#endif
66
67extern int key_decryptsession_pk(const char *, netobj *, des_block *);
68
69#ifndef NGROUPS
70#define NGROUPS 16
71#endif
72
73#define USEC_PER_SEC ((ulong_t)1000000L)

--- 48 unchanged lines hidden (view full) ---

122} svcauthdes_stats;
123
124/*
125 * Service side authenticator for AUTH_DES
126 */
127enum auth_stat
128__svcauth_des(struct svc_req *rqst, struct rpc_msg *msg)
129{
63
64extern int key_decryptsession_pk(const char *, netobj *, des_block *);
65
66#ifndef NGROUPS
67#define NGROUPS 16
68#endif
69
70#define USEC_PER_SEC ((ulong_t)1000000L)

--- 48 unchanged lines hidden (view full) ---

119} svcauthdes_stats;
120
121/*
122 * Service side authenticator for AUTH_DES
123 */
124enum auth_stat
125__svcauth_des(struct svc_req *rqst, struct rpc_msg *msg)
126{
130
131 int32_t *ixdr;
132 des_block cryptbuf[2];
133 struct authdes_cred *cred;
134 struct authdes_verf verf;
135 int status;
136 struct cache_entry *entry;
137 uint32_t sid;
138 int cache_spot_id;

--- 4 unchanged lines hidden (view full) ---

143 uint32_t namelen;
144 struct area {
145 struct authdes_cred area_cred;
146 char area_netname[MAXNETNAMELEN+1];
147 } *area;
148 int fullname_rcvd = 0;
149 int from_cache = 0;
150
127 int32_t *ixdr;
128 des_block cryptbuf[2];
129 struct authdes_cred *cred;
130 struct authdes_verf verf;
131 int status;
132 struct cache_entry *entry;
133 uint32_t sid;
134 int cache_spot_id;

--- 4 unchanged lines hidden (view full) ---

139 uint32_t namelen;
140 struct area {
141 struct authdes_cred area_cred;
142 char area_netname[MAXNETNAMELEN+1];
143 } *area;
144 int fullname_rcvd = 0;
145 int from_cache = 0;
146
151 trace1(TR___svcauth_des, 0);
152 mutex_lock(&authdes_lock);
147 (void) mutex_lock(&authdes_lock);
153 if (_rpc_authdes_cache == NULL) {
154 int ret = cache_init();
155 if (ret == -1) {
148 if (_rpc_authdes_cache == NULL) {
149 int ret = cache_init();
150 if (ret == -1) {
156 mutex_unlock(&authdes_lock);
157 trace1(TR___svcauth_des, 1);
151 (void) mutex_unlock(&authdes_lock);
158 return (AUTH_FAILED);
159 }
160 }
152 return (AUTH_FAILED);
153 }
154 }
161 mutex_unlock(&authdes_lock);
155 (void) mutex_unlock(&authdes_lock);
162
156
157 /* LINTED pointer cast */
163 area = (struct area *)rqst->rq_clntcred;
164 cred = (struct authdes_cred *)&area->area_cred;
165
158 area = (struct area *)rqst->rq_clntcred;
159 cred = (struct authdes_cred *)&area->area_cred;
160
166 if ((uint_t)msg->rm_call.cb_cred.oa_length == 0) {
167 trace1(TR___svcauth_des, 1);
161 if ((uint_t)msg->rm_call.cb_cred.oa_length == 0)
168 return (AUTH_BADCRED);
162 return (AUTH_BADCRED);
169 }
170 /*
171 * Get the credential
172 */
163 /*
164 * Get the credential
165 */
166 /* LINTED pointer cast */
173 ixdr = (int32_t *)msg->rm_call.cb_cred.oa_base;
174 cred->adc_namekind = IXDR_GET_ENUM(ixdr, enum authdes_namekind);
175 switch (cred->adc_namekind) {
176 case ADN_FULLNAME:
177 namelen = IXDR_GET_U_INT32(ixdr);
167 ixdr = (int32_t *)msg->rm_call.cb_cred.oa_base;
168 cred->adc_namekind = IXDR_GET_ENUM(ixdr, enum authdes_namekind);
169 switch (cred->adc_namekind) {
170 case ADN_FULLNAME:
171 namelen = IXDR_GET_U_INT32(ixdr);
178 if (namelen > MAXNETNAMELEN) {
179 trace1(TR___svcauth_des, 1);
172 if (namelen > MAXNETNAMELEN)
180 return (AUTH_BADCRED);
173 return (AUTH_BADCRED);
181 }
182 cred->adc_fullname.name = area->area_netname;
174 cred->adc_fullname.name = area->area_netname;
183 memcpy(cred->adc_fullname.name, (char *)ixdr, (uint_t)namelen);
175 (void) memcpy(cred->adc_fullname.name, ixdr, (uint_t)namelen);
184 cred->adc_fullname.name[namelen] = 0;
185 ixdr += (RNDUP(namelen) / BYTES_PER_XDR_UNIT);
186 cred->adc_fullname.key.key.high = (uint32_t)*ixdr++;
187 cred->adc_fullname.key.key.low = (uint32_t)*ixdr++;
188 cred->adc_fullname.window = (uint32_t)*ixdr++;
189 fullname_rcvd++;
190 break;
191 case ADN_NICKNAME:
192 cred->adc_nickname = (uint32_t)*ixdr++;
193 break;
194 default:
176 cred->adc_fullname.name[namelen] = 0;
177 ixdr += (RNDUP(namelen) / BYTES_PER_XDR_UNIT);
178 cred->adc_fullname.key.key.high = (uint32_t)*ixdr++;
179 cred->adc_fullname.key.key.low = (uint32_t)*ixdr++;
180 cred->adc_fullname.window = (uint32_t)*ixdr++;
181 fullname_rcvd++;
182 break;
183 case ADN_NICKNAME:
184 cred->adc_nickname = (uint32_t)*ixdr++;
185 break;
186 default:
195 trace1(TR___svcauth_des, 1);
196 return (AUTH_BADCRED);
197 }
198
187 return (AUTH_BADCRED);
188 }
189
199 if ((uint_t)msg->rm_call.cb_verf.oa_length == 0) {
200 trace1(TR___svcauth_des, 1);
190 if ((uint_t)msg->rm_call.cb_verf.oa_length == 0)
201 return (AUTH_BADVERF);
191 return (AUTH_BADVERF);
202 }
203 /*
204 * Get the verifier
205 */
192 /*
193 * Get the verifier
194 */
195 /* LINTED pointer cast */
206 ixdr = (int32_t *)msg->rm_call.cb_verf.oa_base;
207 verf.adv_xtimestamp.key.high = (uint32_t)*ixdr++;
208 verf.adv_xtimestamp.key.low = (uint32_t)*ixdr++;
209 verf.adv_int_u = (uint32_t)*ixdr++;
210
196 ixdr = (int32_t *)msg->rm_call.cb_verf.oa_base;
197 verf.adv_xtimestamp.key.high = (uint32_t)*ixdr++;
198 verf.adv_xtimestamp.key.low = (uint32_t)*ixdr++;
199 verf.adv_int_u = (uint32_t)*ixdr++;
200
211 mutex_lock(&authdes_lock);
201 (void) mutex_lock(&authdes_lock);
212
213 /*
214 * Get the conversation key
215 */
216 if (fullname_rcvd) { /* ADN_FULLNAME */
217 netobj pkey;
218 char pkey_data[1024];
219
220again:
221 init_sessionkey = cred->adc_fullname.key;
222 sessionkey = &init_sessionkey;
223
202
203 /*
204 * Get the conversation key
205 */
206 if (fullname_rcvd) { /* ADN_FULLNAME */
207 netobj pkey;
208 char pkey_data[1024];
209
210again:
211 init_sessionkey = cred->adc_fullname.key;
212 sessionkey = &init_sessionkey;
213
224 if (! __getpublickey_cached(cred->adc_fullname.name,
214 if (!__getpublickey_cached(cred->adc_fullname.name,
225 pkey_data, &from_cache)) {
215 pkey_data, &from_cache)) {
226
227 /*
228 * if the user has no public key, treat him as the
229 * unauthenticated identity - nobody. If this
230 * works, it means the client didn't find the
231 * user's keys and used nobody's secret key
232 * as a backup.
233 */
216 /*
217 * if the user has no public key, treat him as the
218 * unauthenticated identity - nobody. If this
219 * works, it means the client didn't find the
220 * user's keys and used nobody's secret key
221 * as a backup.
222 */
234
235 if (! __getpublickey_cached("nobody",
223 if (!__getpublickey_cached("nobody",
236 pkey_data, &from_cache)) {
237 __msgout(LOG_INFO,
238 "_svcauth_des: no public key for nobody or ",
239 cred->adc_fullname.name);
224 pkey_data, &from_cache)) {
225 __msgout(LOG_INFO,
226 "_svcauth_des: no public key for nobody or ",
227 cred->adc_fullname.name);
240 mutex_unlock(&authdes_lock);
241 trace1(TR___svcauth_des, 1);
228 (void) mutex_unlock(&authdes_lock);
242 return (AUTH_BADCRED); /* no key */
229 return (AUTH_BADCRED); /* no key */
243 } else {
244
245 /*
246 * found a public key for nobody. change
247 * the fullname id to nobody, so the caller
248 * thinks the client specified nobody
249 * as the user identity.
250 */
251
252 strcpy(cred->adc_fullname.name, "nobody");
253 }
230 }
231
232 /*
233 * found a public key for nobody. change
234 * the fullname id to nobody, so the caller
235 * thinks the client specified nobody
236 * as the user identity.
237 */
238 (void) strcpy(cred->adc_fullname.name, "nobody");
254 }
255 pkey.n_bytes = pkey_data;
256 pkey.n_len = strlen(pkey_data) + 1;
257 if (key_decryptsession_pk(cred->adc_fullname.name, &pkey,
258 sessionkey) < 0) {
259 if (from_cache) {
260 __getpublickey_flush(cred->adc_fullname.name);
261 goto again;
262 }
239 }
240 pkey.n_bytes = pkey_data;
241 pkey.n_len = strlen(pkey_data) + 1;
242 if (key_decryptsession_pk(cred->adc_fullname.name, &pkey,
243 sessionkey) < 0) {
244 if (from_cache) {
245 __getpublickey_flush(cred->adc_fullname.name);
246 goto again;
247 }
263 __msgout(LOG_INFO,
264 "_svcauth_des: key_decryptsessionkey failed for",
265 cred->adc_fullname.name);
266 mutex_unlock(&authdes_lock);
267 trace1(TR___svcauth_des, 1);
248 __msgout(LOG_INFO,
249 "_svcauth_des: key_decryptsessionkey failed for",
250 cred->adc_fullname.name);
251 (void) mutex_unlock(&authdes_lock);
268 return (AUTH_BADCRED); /* key not found */
269 }
270 } else { /* ADN_NICKNAME */
271 sid = cred->adc_nickname;
272 if (sid >= authdes_cachesz) {
273 __msgout(LOG_INFO, "_svcauth_des:", "bad nickname");
252 return (AUTH_BADCRED); /* key not found */
253 }
254 } else { /* ADN_NICKNAME */
255 sid = cred->adc_nickname;
256 if (sid >= authdes_cachesz) {
257 __msgout(LOG_INFO, "_svcauth_des:", "bad nickname");
274 mutex_unlock(&authdes_lock);
275 trace1(TR___svcauth_des, 1);
258 (void) mutex_unlock(&authdes_lock);
276 return (AUTH_BADCRED); /* garbled credential */
277 }
278 /* actually check that the entry is not null */
279 entry = &_rpc_authdes_cache[sid];
280 if (entry->rname == NULL) {
259 return (AUTH_BADCRED); /* garbled credential */
260 }
261 /* actually check that the entry is not null */
262 entry = &_rpc_authdes_cache[sid];
263 if (entry->rname == NULL) {
281 mutex_unlock(&authdes_lock);
282 trace1(TR___svcauth_des, 1);
264 (void) mutex_unlock(&authdes_lock);
283 return (AUTH_BADCRED); /* cached out */
284 }
285 sessionkey = &_rpc_authdes_cache[sid].key;
286 }
287
288 /*
289 * Decrypt the timestamp
290 */

--- 12 unchanged lines hidden (view full) ---

303 if (DES_FAILED(status)) {
304 if (fullname_rcvd && from_cache) {
305 __getpublickey_flush(cred->adc_fullname.name);
306 goto again;
307 }
308 __msgout(LOG_ERR, "_svcauth_des: DES decryption failure for",
309 fullname_rcvd ? cred->adc_fullname.name :
310 _rpc_authdes_cache[sid].rname);
265 return (AUTH_BADCRED); /* cached out */
266 }
267 sessionkey = &_rpc_authdes_cache[sid].key;
268 }
269
270 /*
271 * Decrypt the timestamp
272 */

--- 12 unchanged lines hidden (view full) ---

285 if (DES_FAILED(status)) {
286 if (fullname_rcvd && from_cache) {
287 __getpublickey_flush(cred->adc_fullname.name);
288 goto again;
289 }
290 __msgout(LOG_ERR, "_svcauth_des: DES decryption failure for",
291 fullname_rcvd ? cred->adc_fullname.name :
292 _rpc_authdes_cache[sid].rname);
311 mutex_unlock(&authdes_lock);
312 trace1(TR___svcauth_des, 1);
293 (void) mutex_unlock(&authdes_lock);
313 return (AUTH_FAILED); /* system error */
314 }
315
316 /*
317 * XDR the decrypted timestamp
318 */
319 ixdr = (int32_t *)cryptbuf;
320 timestamp.tv_sec = IXDR_GET_INT32(ixdr);

--- 17 unchanged lines hidden (view full) ---

338 if (from_cache) {
339 __getpublickey_flush(
340 cred->adc_fullname.name);
341 goto again;
342 }
343 __msgout(LOG_INFO,
344 "_svcauth_des: corrupted window from",
345 cred->adc_fullname.name);
294 return (AUTH_FAILED); /* system error */
295 }
296
297 /*
298 * XDR the decrypted timestamp
299 */
300 ixdr = (int32_t *)cryptbuf;
301 timestamp.tv_sec = IXDR_GET_INT32(ixdr);

--- 17 unchanged lines hidden (view full) ---

319 if (from_cache) {
320 __getpublickey_flush(
321 cred->adc_fullname.name);
322 goto again;
323 }
324 __msgout(LOG_INFO,
325 "_svcauth_des: corrupted window from",
326 cred->adc_fullname.name);
346 mutex_unlock(&authdes_lock);
347 trace1(TR___svcauth_des, 1);
327 (void) mutex_unlock(&authdes_lock);
348 /* garbled credential or invalid secret key */
349 return (AUTH_BADCRED);
350 }
351 cache_spot_id = cache_spot(sessionkey,
352 cred->adc_fullname.name,
353
354 &timestamp);
355 if (cache_spot_id < 0) {
356 __msgout(LOG_INFO,
357 "_svcauth_des: replayed credential from",
358 cred->adc_fullname.name);
328 /* garbled credential or invalid secret key */
329 return (AUTH_BADCRED);
330 }
331 cache_spot_id = cache_spot(sessionkey,
332 cred->adc_fullname.name,
333
334 &timestamp);
335 if (cache_spot_id < 0) {
336 __msgout(LOG_INFO,
337 "_svcauth_des: replayed credential from",
338 cred->adc_fullname.name);
359 mutex_unlock(&authdes_lock);
360 trace1(TR___svcauth_des, 1);
339 (void) mutex_unlock(&authdes_lock);
361 return (AUTH_REJECTEDCRED); /* replay */
362 } else sid = cache_spot_id;
363 nick = 0;
364 } else { /* ADN_NICKNAME */
365 window = _rpc_authdes_cache[sid].window;
366 nick = 1;
367 }
368
369 if ((ulong_t)timestamp.tv_usec >= USEC_PER_SEC) {
370 if (fullname_rcvd && from_cache) {
371 __getpublickey_flush(cred->adc_fullname.name);
372 goto again;
373 }
374 __msgout(LOG_INFO,
375 "_svcauth_des: invalid timestamp received from",
376 fullname_rcvd ? cred->adc_fullname.name :
377 _rpc_authdes_cache[sid].rname);
378 /* cached out (bad key), or garbled verifier */
340 return (AUTH_REJECTEDCRED); /* replay */
341 } else sid = cache_spot_id;
342 nick = 0;
343 } else { /* ADN_NICKNAME */
344 window = _rpc_authdes_cache[sid].window;
345 nick = 1;
346 }
347
348 if ((ulong_t)timestamp.tv_usec >= USEC_PER_SEC) {
349 if (fullname_rcvd && from_cache) {
350 __getpublickey_flush(cred->adc_fullname.name);
351 goto again;
352 }
353 __msgout(LOG_INFO,
354 "_svcauth_des: invalid timestamp received from",
355 fullname_rcvd ? cred->adc_fullname.name :
356 _rpc_authdes_cache[sid].rname);
357 /* cached out (bad key), or garbled verifier */
379 mutex_unlock(&authdes_lock);
380 trace1(TR___svcauth_des, 1);
358 (void) mutex_unlock(&authdes_lock);
381 return (nick ? AUTH_REJECTEDVERF : AUTH_BADVERF);
382 }
383 if (nick && BEFORE(&timestamp,
384 &_rpc_authdes_cache[sid].laststamp)) {
385 if (fullname_rcvd && from_cache) {
386 __getpublickey_flush(cred->adc_fullname.name);
387 goto again;
388 }
389 __msgout(LOG_INFO,
390 "_svcauth_des: timestamp is earlier than the one previously seen from",
391 fullname_rcvd ? cred->adc_fullname.name :
392 _rpc_authdes_cache[sid].rname);
359 return (nick ? AUTH_REJECTEDVERF : AUTH_BADVERF);
360 }
361 if (nick && BEFORE(&timestamp,
362 &_rpc_authdes_cache[sid].laststamp)) {
363 if (fullname_rcvd && from_cache) {
364 __getpublickey_flush(cred->adc_fullname.name);
365 goto again;
366 }
367 __msgout(LOG_INFO,
368 "_svcauth_des: timestamp is earlier than the one previously seen from",
369 fullname_rcvd ? cred->adc_fullname.name :
370 _rpc_authdes_cache[sid].rname);
393 mutex_unlock(&authdes_lock);
394 trace1(TR___svcauth_des, 1);
371 (void) mutex_unlock(&authdes_lock);
395 return (AUTH_REJECTEDVERF); /* replay */
396 }
372 return (AUTH_REJECTEDVERF); /* replay */
373 }
397 (void) gettimeofday(&current, (struct timezone *)NULL);
374 (void) gettimeofday(&current, NULL);
398 current.tv_sec -= window; /* allow for expiration */
399 if (!BEFORE(&current, &timestamp)) {
400 if (fullname_rcvd && from_cache) {
401 __getpublickey_flush(cred->adc_fullname.name);
402 goto again;
403 }
404 __msgout(LOG_INFO,
405 "_svcauth_des: timestamp expired for",
406 fullname_rcvd ? cred->adc_fullname.name :
407 _rpc_authdes_cache[sid].rname);
408 /* replay, or garbled credential */
375 current.tv_sec -= window; /* allow for expiration */
376 if (!BEFORE(&current, &timestamp)) {
377 if (fullname_rcvd && from_cache) {
378 __getpublickey_flush(cred->adc_fullname.name);
379 goto again;
380 }
381 __msgout(LOG_INFO,
382 "_svcauth_des: timestamp expired for",
383 fullname_rcvd ? cred->adc_fullname.name :
384 _rpc_authdes_cache[sid].rname);
385 /* replay, or garbled credential */
409 mutex_unlock(&authdes_lock);
410 trace1(TR___svcauth_des, 1);
386 (void) mutex_unlock(&authdes_lock);
411 return (nick ? AUTH_REJECTEDVERF : AUTH_BADCRED);
412 }
413 }
414
415 /*
416 * Set up the reply verifier
417 */
418 verf.adv_nickname = sid;

--- 9 unchanged lines hidden (view full) ---

428 * encrypt the timestamp
429 */
430 status = ecb_crypt((char *)sessionkey, (char *)cryptbuf,
431 (int)sizeof (des_block), DES_ENCRYPT | DES_HW);
432 if (DES_FAILED(status)) {
433 __msgout(LOG_ERR, "_svcauth_des: DES encryption failure for",
434 fullname_rcvd ? cred->adc_fullname.name :
435 _rpc_authdes_cache[sid].rname);
387 return (nick ? AUTH_REJECTEDVERF : AUTH_BADCRED);
388 }
389 }
390
391 /*
392 * Set up the reply verifier
393 */
394 verf.adv_nickname = sid;

--- 9 unchanged lines hidden (view full) ---

404 * encrypt the timestamp
405 */
406 status = ecb_crypt((char *)sessionkey, (char *)cryptbuf,
407 (int)sizeof (des_block), DES_ENCRYPT | DES_HW);
408 if (DES_FAILED(status)) {
409 __msgout(LOG_ERR, "_svcauth_des: DES encryption failure for",
410 fullname_rcvd ? cred->adc_fullname.name :
411 _rpc_authdes_cache[sid].rname);
436 mutex_unlock(&authdes_lock);
437 trace1(TR___svcauth_des, 1);
412 (void) mutex_unlock(&authdes_lock);
438 return (AUTH_FAILED); /* system error */
439 }
440 verf.adv_xtimestamp = cryptbuf[0];
441
442 /*
443 * Serialize the reply verifier, and update rqst
444 */
413 return (AUTH_FAILED); /* system error */
414 }
415 verf.adv_xtimestamp = cryptbuf[0];
416
417 /*
418 * Serialize the reply verifier, and update rqst
419 */
420 /* LINTED pointer cast */
445 ixdr = (int32_t *)msg->rm_call.cb_verf.oa_base;
446 *ixdr++ = (int32_t)verf.adv_xtimestamp.key.high;
447 *ixdr++ = (int32_t)verf.adv_xtimestamp.key.low;
448 *ixdr++ = (int32_t)verf.adv_int_u;
449
450 rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES;
451 rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
452 rqst->rq_xprt->xp_verf.oa_length =
453 (char *)ixdr - msg->rm_call.cb_verf.oa_base;
454 if (rqst->rq_xprt->xp_verf.oa_length > MAX_AUTH_BYTES) {
455 __msgout(LOG_ERR,
456 "_svcauth_des: Authenticator length error",
457 fullname_rcvd ? cred->adc_fullname.name :
458 _rpc_authdes_cache[sid].rname);
421 ixdr = (int32_t *)msg->rm_call.cb_verf.oa_base;
422 *ixdr++ = (int32_t)verf.adv_xtimestamp.key.high;
423 *ixdr++ = (int32_t)verf.adv_xtimestamp.key.low;
424 *ixdr++ = (int32_t)verf.adv_int_u;
425
426 rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES;
427 rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
428 rqst->rq_xprt->xp_verf.oa_length =
429 (char *)ixdr - msg->rm_call.cb_verf.oa_base;
430 if (rqst->rq_xprt->xp_verf.oa_length > MAX_AUTH_BYTES) {
431 __msgout(LOG_ERR,
432 "_svcauth_des: Authenticator length error",
433 fullname_rcvd ? cred->adc_fullname.name :
434 _rpc_authdes_cache[sid].rname);
459 mutex_unlock(&authdes_lock);
460 trace1(TR___svcauth_des, 1);
435 (void) mutex_unlock(&authdes_lock);
461 return (AUTH_REJECTEDVERF);
462 }
463
464 /*
465 * We succeeded, commit the data to the cache now and
466 * finish cooking the credential.
467 */
468 entry = &_rpc_authdes_cache[sid];
469 entry->laststamp = timestamp;
470 cache_ref(sid);
471 if (cred->adc_namekind == ADN_FULLNAME) {
472 cred->adc_fullname.window = window;
473 cred->adc_nickname = sid; /* save nickname */
436 return (AUTH_REJECTEDVERF);
437 }
438
439 /*
440 * We succeeded, commit the data to the cache now and
441 * finish cooking the credential.
442 */
443 entry = &_rpc_authdes_cache[sid];
444 entry->laststamp = timestamp;
445 cache_ref(sid);
446 if (cred->adc_namekind == ADN_FULLNAME) {
447 cred->adc_fullname.window = window;
448 cred->adc_nickname = sid; /* save nickname */
449 if (entry->rname != NULL)
450 free(entry->rname);
451 entry->rname = malloc(strlen(cred->adc_fullname.name) + 1);
474 if (entry->rname != NULL) {
452 if (entry->rname != NULL) {
475 mem_free(entry->rname, strlen(entry->rname) + 1);
476 }
477 entry->rname =
478 (char *)mem_alloc((uint_t)strlen(cred->adc_fullname.name)
479 + 1);
480 if (entry->rname != NULL) {
481 (void) strcpy(entry->rname, cred->adc_fullname.name);
482 } else {
483 __msgout(LOG_CRIT, "_svcauth_des:", "out of memory");
453 (void) strcpy(entry->rname, cred->adc_fullname.name);
454 } else {
455 __msgout(LOG_CRIT, "_svcauth_des:", "out of memory");
484 mutex_unlock(&authdes_lock);
456 (void) mutex_unlock(&authdes_lock);
485 return (AUTH_FAILED);
486 }
487 entry->key = *sessionkey;
488 entry->window = window;
489 /* mark any cached cred invalid */
490 invalidate(entry->localcred);
491 } else { /* ADN_NICKNAME */
492 /*
493 * nicknames are cooked into fullnames
494 */
495 cred->adc_namekind = ADN_FULLNAME;
496 cred->adc_fullname.name = entry->rname;
497 cred->adc_fullname.key = entry->key;
498 cred->adc_fullname.window = entry->window;
499 }
457 return (AUTH_FAILED);
458 }
459 entry->key = *sessionkey;
460 entry->window = window;
461 /* mark any cached cred invalid */
462 invalidate(entry->localcred);
463 } else { /* ADN_NICKNAME */
464 /*
465 * nicknames are cooked into fullnames
466 */
467 cred->adc_namekind = ADN_FULLNAME;
468 cred->adc_fullname.name = entry->rname;
469 cred->adc_fullname.key = entry->key;
470 cred->adc_fullname.window = entry->window;
471 }
500 mutex_unlock(&authdes_lock);
501 trace1(TR___svcauth_des, 1);
472 (void) mutex_unlock(&authdes_lock);
502 return (AUTH_OK); /* we made it! */
503}
504
505
506/*
507 * Initialize the cache
508 */
509static int
473 return (AUTH_OK); /* we made it! */
474}
475
476
477/*
478 * Initialize the cache
479 */
480static int
510cache_init()
481cache_init(void)
511{
512 int i;
513
514/* LOCK HELD ON ENTRY: authdes_lock */
515
482{
483 int i;
484
485/* LOCK HELD ON ENTRY: authdes_lock */
486
516 trace1(TR_cache_init, 0);
517 assert(MUTEX_HELD(&authdes_lock));
487 assert(MUTEX_HELD(&authdes_lock));
518 _rpc_authdes_cache = (struct cache_entry *)
519 mem_alloc(sizeof (struct cache_entry) * authdes_cachesz);
488 _rpc_authdes_cache =
489 malloc(sizeof (struct cache_entry) * authdes_cachesz);
520 if (_rpc_authdes_cache == NULL) {
521 __msgout(LOG_CRIT, "cache_init:", "out of memory");
522 return (-1);
523 }
490 if (_rpc_authdes_cache == NULL) {
491 __msgout(LOG_CRIT, "cache_init:", "out of memory");
492 return (-1);
493 }
524 memset((char *)_rpc_authdes_cache, 0,
494 (void) memset(_rpc_authdes_cache, 0,
525 sizeof (struct cache_entry) * authdes_cachesz);
526
527 /*
528 * Initialize the lru chain (linked-list)
529 */
530 for (i = 1; i < (authdes_cachesz - 1); i++) {
531 _rpc_authdes_cache[i].index = i;
532 _rpc_authdes_cache[i].next = &_rpc_authdes_cache[i + 1];

--- 6 unchanged lines hidden (view full) ---

539 * These elements of the chain need special attention...
540 */
541 cache_head->index = 0;
542 cache_tail->index = authdes_cachesz - 1;
543 cache_head->next = &_rpc_authdes_cache[1];
544 cache_head->prev = cache_tail;
545 cache_tail->next = cache_head;
546 cache_tail->prev = &_rpc_authdes_cache[authdes_cachesz - 2];
495 sizeof (struct cache_entry) * authdes_cachesz);
496
497 /*
498 * Initialize the lru chain (linked-list)
499 */
500 for (i = 1; i < (authdes_cachesz - 1); i++) {
501 _rpc_authdes_cache[i].index = i;
502 _rpc_authdes_cache[i].next = &_rpc_authdes_cache[i + 1];

--- 6 unchanged lines hidden (view full) ---

509 * These elements of the chain need special attention...
510 */
511 cache_head->index = 0;
512 cache_tail->index = authdes_cachesz - 1;
513 cache_head->next = &_rpc_authdes_cache[1];
514 cache_head->prev = cache_tail;
515 cache_tail->next = cache_head;
516 cache_tail->prev = &_rpc_authdes_cache[authdes_cachesz - 2];
547 trace1(TR_cache_init, 1);
548 return (0);
549}
550
551
552/*
553 * Find the lru victim
554 */
555static uint32_t
517 return (0);
518}
519
520
521/*
522 * Find the lru victim
523 */
524static uint32_t
556cache_victim()
525cache_victim(void)
557{
526{
558
559/* LOCK HELD ON ENTRY: authdes_lock */
560
527/* LOCK HELD ON ENTRY: authdes_lock */
528
561 trace1(TR_cache_victim, 0);
562 assert(MUTEX_HELD(&authdes_lock));
529 assert(MUTEX_HELD(&authdes_lock));
563 trace1(TR_cache_victim, 1);
564 return (cache_head->index); /* list in lru order */
565}
566
567/*
568 * Note that sid was referenced
569 */
570static void
571cache_ref(uint32_t sid)
572{
530 return (cache_head->index); /* list in lru order */
531}
532
533/*
534 * Note that sid was referenced
535 */
536static void
537cache_ref(uint32_t sid)
538{
573 int i;
574 struct cache_entry *curr = &_rpc_authdes_cache[sid];
575
576
577/* LOCK HELD ON ENTRY: authdes_lock */
578
539 struct cache_entry *curr = &_rpc_authdes_cache[sid];
540
541
542/* LOCK HELD ON ENTRY: authdes_lock */
543
579 trace1(TR_cache_ref, 0);
580 assert(MUTEX_HELD(&authdes_lock));
581
582 /*
583 * move referenced item from its place on the LRU chain
584 * to the tail of the chain while checking for special
585 * conditions (mainly for performance).
586 */
587 if (cache_tail == curr) { /* no work to do */

--- 5 unchanged lines hidden (view full) ---

593 (curr->next)->prev = curr->prev; /* fix thy neighbor */
594 (curr->prev)->next = curr->next;
595 curr->next = cache_head; /* fix thy self... */
596 curr->prev = cache_tail;
597 cache_head->prev = curr; /* fix the head */
598 cache_tail->next = curr; /* fix the tail */
599 cache_tail = curr; /* move the tail */
600 }
544 assert(MUTEX_HELD(&authdes_lock));
545
546 /*
547 * move referenced item from its place on the LRU chain
548 * to the tail of the chain while checking for special
549 * conditions (mainly for performance).
550 */
551 if (cache_tail == curr) { /* no work to do */

--- 5 unchanged lines hidden (view full) ---

557 (curr->next)->prev = curr->prev; /* fix thy neighbor */
558 (curr->prev)->next = curr->next;
559 curr->next = cache_head; /* fix thy self... */
560 curr->prev = cache_tail;
561 cache_head->prev = curr; /* fix the head */
562 cache_tail->next = curr; /* fix the tail */
563 cache_tail = curr; /* move the tail */
564 }
601
602 trace1(TR_cache_ref, 1);
603}
604
605/*
606 * Find a spot in the cache for a credential containing
607 * the items given. Return -1 if a replay is detected, otherwise
608 * return the spot in the cache.
609 */
610static int
611cache_spot(des_block *key, char *name, struct timeval *timestamp)
612{
613 struct cache_entry *cp;
614 int i;
615 uint32_t hi;
565}
566
567/*
568 * Find a spot in the cache for a credential containing
569 * the items given. Return -1 if a replay is detected, otherwise
570 * return the spot in the cache.
571 */
572static int
573cache_spot(des_block *key, char *name, struct timeval *timestamp)
574{
575 struct cache_entry *cp;
576 int i;
577 uint32_t hi;
616 static uint32_t dummy;
617
618/* LOCK HELD ON ENTRY: authdes_lock */
619
578
579/* LOCK HELD ON ENTRY: authdes_lock */
580
620 trace1(TR_cache_spot, 0);
621 assert(MUTEX_HELD(&authdes_lock));
622 hi = key->key.high;
623 for (cp = _rpc_authdes_cache, i = 0; i < authdes_cachesz; i++, cp++) {
624 if (cp->key.key.high == hi &&
625 cp->key.key.low == key->key.low &&
626 cp->rname != NULL &&
627 memcmp(cp->rname, name, strlen(name) + 1) == 0) {
628 if (BEFORE(timestamp, &cp->laststamp)) {
629 svcauthdes_stats.ncachereplays++;
581 assert(MUTEX_HELD(&authdes_lock));
582 hi = key->key.high;
583 for (cp = _rpc_authdes_cache, i = 0; i < authdes_cachesz; i++, cp++) {
584 if (cp->key.key.high == hi &&
585 cp->key.key.low == key->key.low &&
586 cp->rname != NULL &&
587 memcmp(cp->rname, name, strlen(name) + 1) == 0) {
588 if (BEFORE(timestamp, &cp->laststamp)) {
589 svcauthdes_stats.ncachereplays++;
630 trace1(TR_cache_spot, 1);
631 return (-1); /* replay */
632 }
633 svcauthdes_stats.ncachehits++;
590 return (-1); /* replay */
591 }
592 svcauthdes_stats.ncachehits++;
634 trace1(TR_cache_spot, 1);
635 return (i);
636 /* refresh */
637 }
638 }
639 svcauthdes_stats.ncachemisses++;
593 return (i);
594 /* refresh */
595 }
596 }
597 svcauthdes_stats.ncachemisses++;
640 dummy = cache_victim();
641 trace1(TR_cache_spot, 1);
642 return (dummy); /* new credential */
598 return (cache_victim());
643}
644
645
646/*
647 * Local credential handling stuff.
648 * NOTE: bsd unix dependent.
649 * Other operating systems should put something else here.
650 */

--- 5 unchanged lines hidden (view full) ---

656 gid_t gid; /* cached gid */
657 short grouplen; /* length of cached groups */
658 short groups[NGROUPS]; /* cached groups */
659};
660
661static void
662invalidate(char *cred)
663{
599}
600
601
602/*
603 * Local credential handling stuff.
604 * NOTE: bsd unix dependent.
605 * Other operating systems should put something else here.
606 */

--- 5 unchanged lines hidden (view full) ---

612 gid_t gid; /* cached gid */
613 short grouplen; /* length of cached groups */
614 short groups[NGROUPS]; /* cached groups */
615};
616
617static void
618invalidate(char *cred)
619{
664 trace1(TR_invalidate, 0);
665 if (cred == NULL) {
666 trace1(TR_invalidate, 1);
620 if (cred == NULL)
667 return;
621 return;
668 }
622 /* LINTED pointer cast */
669 ((struct bsdcred *)cred)->grouplen = INVALID;
623 ((struct bsdcred *)cred)->grouplen = INVALID;
670 trace1(TR_invalidate, 1);
671}
672
624}
625
673
674
675/*
676 * Map a des credential into a unix cred.
677 * We cache the credential here so the application does
678 * not have to make an rpc call every time to interpret
679 * the credential.
680 */
681int
682authdes_getucred(const struct authdes_cred *adc, uid_t *uid, gid_t *gid,
683 short *grouplen, gid_t *groups)
684{
685 uint32_t sid;
686 int i;
687 uid_t i_uid;
688 gid_t i_gid;
689 int i_grouplen;
690 struct bsdcred *cred;
691
626/*
627 * Map a des credential into a unix cred.
628 * We cache the credential here so the application does
629 * not have to make an rpc call every time to interpret
630 * the credential.
631 */
632int
633authdes_getucred(const struct authdes_cred *adc, uid_t *uid, gid_t *gid,
634 short *grouplen, gid_t *groups)
635{
636 uint32_t sid;
637 int i;
638 uid_t i_uid;
639 gid_t i_gid;
640 int i_grouplen;
641 struct bsdcred *cred;
642
692 trace1(TR_authdes_getucred, 0);
693 sid = adc->adc_nickname;
694 if (sid >= authdes_cachesz) {
695 __msgout2(__getucredstr, "invalid nickname");
643 sid = adc->adc_nickname;
644 if (sid >= authdes_cachesz) {
645 __msgout2(__getucredstr, "invalid nickname");
696 trace1(TR_authdes_getucred, 1);
697 return (0);
698 }
646 return (0);
647 }
699 mutex_lock(&authdes_lock);
648 (void) mutex_lock(&authdes_lock);
649 /* LINTED pointer cast */
700 cred = (struct bsdcred *)_rpc_authdes_cache[sid].localcred;
701 if (cred == NULL) {
650 cred = (struct bsdcred *)_rpc_authdes_cache[sid].localcred;
651 if (cred == NULL) {
702 cred = (struct bsdcred *)mem_alloc(sizeof (struct bsdcred));
652 cred = malloc(sizeof (struct bsdcred));
703 if (cred == NULL) {
704 __msgout2(__getucredstr, "out of memory");
653 if (cred == NULL) {
654 __msgout2(__getucredstr, "out of memory");
705 mutex_unlock(&authdes_lock);
706 trace1(TR_authdes_getucred, 1);
655 (void) mutex_unlock(&authdes_lock);
707 return (0);
708 }
709 _rpc_authdes_cache[sid].localcred = (char *)cred;
710 cred->grouplen = INVALID;
711 }
712 if (cred->grouplen == INVALID) {
713 /*
714 * not in cache: lookup
715 */
716 if (!netname2user(adc->adc_fullname.name, (uid_t *)&i_uid,
717 (gid_t *)&i_gid, &i_grouplen, (gid_t *)groups)) {
718 __msgout2(__getucredstr, "unknown netname");
719 /* mark as lookup up, but not found */
720 cred->grouplen = UNKNOWN;
656 return (0);
657 }
658 _rpc_authdes_cache[sid].localcred = (char *)cred;
659 cred->grouplen = INVALID;
660 }
661 if (cred->grouplen == INVALID) {
662 /*
663 * not in cache: lookup
664 */
665 if (!netname2user(adc->adc_fullname.name, (uid_t *)&i_uid,
666 (gid_t *)&i_gid, &i_grouplen, (gid_t *)groups)) {
667 __msgout2(__getucredstr, "unknown netname");
668 /* mark as lookup up, but not found */
669 cred->grouplen = UNKNOWN;
721 mutex_unlock(&authdes_lock);
722 trace1(TR_authdes_getucred, 1);
670 (void) mutex_unlock(&authdes_lock);
723 return (0);
724 }
725 __msgout2(__getucredstr, "missed ucred cache");
726 *uid = cred->uid = i_uid;
727 *gid = cred->gid = i_gid;
728 *grouplen = cred->grouplen = i_grouplen;
729 for (i = i_grouplen - 1; i >= 0; i--) {
730 cred->groups[i] = groups[i]; /* int to short */
731 }
671 return (0);
672 }
673 __msgout2(__getucredstr, "missed ucred cache");
674 *uid = cred->uid = i_uid;
675 *gid = cred->gid = i_gid;
676 *grouplen = cred->grouplen = i_grouplen;
677 for (i = i_grouplen - 1; i >= 0; i--) {
678 cred->groups[i] = groups[i]; /* int to short */
679 }
732 mutex_unlock(&authdes_lock);
733 trace1(TR_authdes_getucred, 1);
680 (void) mutex_unlock(&authdes_lock);
734 return (1);
681 return (1);
735 } else if (cred->grouplen == UNKNOWN) {
682 }
683 if (cred->grouplen == UNKNOWN) {
736 /*
737 * Already lookup up, but no match found
738 */
684 /*
685 * Already lookup up, but no match found
686 */
739 mutex_unlock(&authdes_lock);
740 trace1(TR_authdes_getucred, 1);
687 (void) mutex_unlock(&authdes_lock);
741 return (0);
742 }
743
744 /*
745 * cached credentials
746 */
747 *uid = cred->uid;
748 *gid = cred->gid;
749 *grouplen = cred->grouplen;
750 for (i = cred->grouplen - 1; i >= 0; i--) {
751 groups[i] = cred->groups[i]; /* short to int */
752 }
688 return (0);
689 }
690
691 /*
692 * cached credentials
693 */
694 *uid = cred->uid;
695 *gid = cred->gid;
696 *grouplen = cred->grouplen;
697 for (i = cred->grouplen - 1; i >= 0; i--) {
698 groups[i] = cred->groups[i]; /* short to int */
699 }
753 mutex_unlock(&authdes_lock);
754 trace1(TR_authdes_getucred, 1);
700 (void) mutex_unlock(&authdes_lock);
755 return (1);
756}
757
758
759static void
760__msgout(int level, const char *str, const char *strarg)
761{
701 return (1);
702}
703
704
705static void
706__msgout(int level, const char *str, const char *strarg)
707{
762 trace1(TR___msgout, 0);
763#ifdef KERNEL
764 printf("%s %s\n", str, strarg);
765#else
766 (void) syslog(level, "%s %s", str, strarg);
767#endif
768 trace1(TR___msgout, 1);
708 (void) syslog(level, "%s %s", str, strarg);
769}
770
771
772static void
773__msgout2(const char *str, const char *str2)
774{
709}
710
711
712static void
713__msgout2(const char *str, const char *str2)
714{
775 trace1(TR___msgout, 0);
776#ifdef KERNEL
777 printf("%s %s", str, str2);
778#else
779 (void) syslog(LOG_DEBUG, "%s %s", str, str2);
780#endif
781 trace1(TR___msgout, 1);
715 (void) syslog(LOG_DEBUG, "%s %s", str, str2);
782}
716}