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 ×tamp); 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 ×tamp); 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(×tamp, 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(×tamp, 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(¤t, (struct timezone *)NULL); | 374 (void) gettimeofday(¤t, NULL); |
398 current.tv_sec -= window; /* allow for expiration */ 399 if (!BEFORE(¤t, ×tamp)) { 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(¤t, ×tamp)) { 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} |