1 | /* |
---|
2 | * Sun RPC is a product of Sun Microsystems, Inc. and is provided for |
---|
3 | * unrestricted use provided that this legend is included on all tape |
---|
4 | * media and as a part of the software program in whole or part. Users |
---|
5 | * may copy or modify Sun RPC without charge, but are not authorized |
---|
6 | * to license or distribute it to anyone else except as part of a product or |
---|
7 | * program developed by the user. |
---|
8 | * |
---|
9 | * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE |
---|
10 | * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR |
---|
11 | * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. |
---|
12 | * |
---|
13 | * Sun RPC is provided with no support and without any obligation on the |
---|
14 | * part of Sun Microsystems, Inc. to assist in its use, correction, |
---|
15 | * modification or enhancement. |
---|
16 | * |
---|
17 | * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE |
---|
18 | * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC |
---|
19 | * OR ANY PART THEREOF. |
---|
20 | * |
---|
21 | * In no event will Sun Microsystems, Inc. be liable for any lost revenue |
---|
22 | * or profits or other special, indirect and consequential damages, even if |
---|
23 | * Sun has been advised of the possibility of such damages. |
---|
24 | * |
---|
25 | * Sun Microsystems, Inc. |
---|
26 | * 2550 Garcia Avenue |
---|
27 | * Mountain View, California 94043 |
---|
28 | */ |
---|
29 | /* |
---|
30 | * Copyright (c) 1988 by Sun Microsystems, Inc. |
---|
31 | */ |
---|
32 | /* |
---|
33 | * auth_des.c, client-side implementation of DES authentication |
---|
34 | */ |
---|
35 | #include <string.h> |
---|
36 | #include <stdlib.h> |
---|
37 | #include <unistd.h> |
---|
38 | #include <sys/cdefs.h> |
---|
39 | #include <rpc/des_crypt.h> |
---|
40 | #include <rpc/types.h> |
---|
41 | #include <rpc/xdr.h> |
---|
42 | #include <rpc/auth.h> |
---|
43 | #include <rpc/auth_des.h> |
---|
44 | #include <netinet/in.h> /* XXX: just to get htonl() and ntohl() */ |
---|
45 | #include <sys/socket.h> |
---|
46 | #undef NIS |
---|
47 | #include <rpcsvc/nis.h> |
---|
48 | |
---|
49 | #if defined(LIBC_SCCS) && !defined(lint) |
---|
50 | /* from: static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; */ |
---|
51 | static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/auth_des.c,v 1.3 1999/08/28 00:00:32 peter Exp $"; |
---|
52 | #endif |
---|
53 | |
---|
54 | extern bool_t __rpc_get_time_offset __P(( struct timeval *, nis_server *, |
---|
55 | char *, char **, struct sockaddr_in * )); |
---|
56 | extern int rtime __P(( struct sockaddr_in *, struct timeval *, struct timeval *)); |
---|
57 | extern bool_t xdr_authdes_cred __P(( XDR *, struct authdes_cred * )); |
---|
58 | extern bool_t xdr_authdes_verf __P(( XDR *, struct authdes_verf * )); |
---|
59 | |
---|
60 | #define MILLION 1000000L |
---|
61 | #define RTIME_TIMEOUT 5 /* seconds to wait for sync */ |
---|
62 | |
---|
63 | #define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private |
---|
64 | #define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type)) |
---|
65 | #define FREE(ptr, size) mem_free((char *)(ptr), (int) size) |
---|
66 | #define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) |
---|
67 | |
---|
68 | #define debug(msg) /*printf("%s\n", msg) */ |
---|
69 | |
---|
70 | /* |
---|
71 | * DES authenticator operations vector |
---|
72 | */ |
---|
73 | static void authdes_nextverf(); |
---|
74 | static bool_t authdes_marshal(); |
---|
75 | static bool_t authdes_validate(); |
---|
76 | static bool_t authdes_refresh(); |
---|
77 | static void authdes_destroy(); |
---|
78 | static struct auth_ops authdes_ops = { |
---|
79 | authdes_nextverf, |
---|
80 | authdes_marshal, |
---|
81 | authdes_validate, |
---|
82 | authdes_refresh, |
---|
83 | authdes_destroy |
---|
84 | }; |
---|
85 | #ifdef foo |
---|
86 | static bool_t synchronize __P(( struct sockaddr *, struct timeval *)); |
---|
87 | #endif |
---|
88 | /* |
---|
89 | * This struct is pointed to by the ah_private field of an "AUTH *" |
---|
90 | */ |
---|
91 | struct ad_private { |
---|
92 | char *ad_fullname; /* client's full name */ |
---|
93 | u_int ad_fullnamelen; /* length of name, rounded up */ |
---|
94 | char *ad_servername; /* server's full name */ |
---|
95 | u_int ad_servernamelen; /* length of name, rounded up */ |
---|
96 | u_int ad_window; /* client specified window */ |
---|
97 | bool_t ad_dosync; /* synchronize? */ |
---|
98 | struct sockaddr ad_syncaddr; /* remote host to synch with */ |
---|
99 | char *ad_timehost; /* remote host to synch with */ |
---|
100 | struct timeval ad_timediff; /* server's time - client's time */ |
---|
101 | u_long ad_nickname; /* server's nickname for client */ |
---|
102 | struct authdes_cred ad_cred; /* storage for credential */ |
---|
103 | struct authdes_verf ad_verf; /* storage for verifier */ |
---|
104 | struct timeval ad_timestamp; /* timestamp sent */ |
---|
105 | des_block ad_xkey; /* encrypted conversation key */ |
---|
106 | u_char ad_pkey[1024]; /* Server's actual public key */ |
---|
107 | char *ad_netid; /* Timehost netid */ |
---|
108 | char *ad_uaddr; /* Timehost uaddr */ |
---|
109 | nis_server *ad_nis_srvr; /* NIS+ server struct */ |
---|
110 | }; |
---|
111 | |
---|
112 | |
---|
113 | /* |
---|
114 | * Create the client des authentication object |
---|
115 | */ |
---|
116 | AUTH * |
---|
117 | authdes_create(servername, window, syncaddr, ckey) |
---|
118 | char *servername; /* network name of server */ |
---|
119 | u_int window; /* time to live */ |
---|
120 | struct sockaddr *syncaddr; /* optional addr of host to sync with */ |
---|
121 | des_block *ckey; /* optional conversation key to use*/ |
---|
122 | { |
---|
123 | |
---|
124 | AUTH *auth; |
---|
125 | struct ad_private *ad; |
---|
126 | char namebuf[MAXNETNAMELEN+1]; |
---|
127 | u_char pkey_data[1024]; |
---|
128 | |
---|
129 | if (!getpublickey(servername, pkey_data)) |
---|
130 | return(NULL); |
---|
131 | |
---|
132 | /* |
---|
133 | * Allocate everything now |
---|
134 | */ |
---|
135 | auth = ALLOC(AUTH); |
---|
136 | ad = ALLOC(struct ad_private); |
---|
137 | (void) getnetname(namebuf); |
---|
138 | |
---|
139 | ad->ad_fullnamelen = RNDUP(strlen(namebuf)); |
---|
140 | ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); |
---|
141 | |
---|
142 | ad->ad_servernamelen = strlen(servername); |
---|
143 | ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); |
---|
144 | |
---|
145 | if (auth == NULL || ad == NULL || ad->ad_fullname == NULL || |
---|
146 | ad->ad_servername == NULL) { |
---|
147 | debug("authdes_create: out of memory"); |
---|
148 | goto failed; |
---|
149 | } |
---|
150 | |
---|
151 | /* |
---|
152 | * Set up private data |
---|
153 | */ |
---|
154 | bcopy(namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1); |
---|
155 | bcopy(servername, ad->ad_servername, ad->ad_servernamelen + 1); |
---|
156 | bcopy(pkey_data, ad->ad_pkey, strlen(pkey_data) + 1); |
---|
157 | if (syncaddr != NULL) { |
---|
158 | ad->ad_syncaddr = *syncaddr; |
---|
159 | ad->ad_dosync = TRUE; |
---|
160 | } else { |
---|
161 | ad->ad_dosync = FALSE; |
---|
162 | } |
---|
163 | ad->ad_window = window; |
---|
164 | if (ckey == NULL) { |
---|
165 | if (key_gendes(&auth->ah_key) < 0) { |
---|
166 | debug("authdes_create: unable to gen conversation key"); |
---|
167 | return (NULL); |
---|
168 | } |
---|
169 | } else { |
---|
170 | auth->ah_key = *ckey; |
---|
171 | } |
---|
172 | |
---|
173 | /* |
---|
174 | * Set up auth handle |
---|
175 | */ |
---|
176 | auth->ah_cred.oa_flavor = AUTH_DES; |
---|
177 | auth->ah_verf.oa_flavor = AUTH_DES; |
---|
178 | auth->ah_ops = &authdes_ops; |
---|
179 | auth->ah_private = (caddr_t)ad; |
---|
180 | |
---|
181 | if (!authdes_refresh(auth)) { |
---|
182 | goto failed; |
---|
183 | } |
---|
184 | return (auth); |
---|
185 | |
---|
186 | failed: |
---|
187 | if (auth != NULL) |
---|
188 | FREE(auth, sizeof(AUTH)); |
---|
189 | if (ad != NULL) |
---|
190 | FREE(ad, sizeof(struct ad_private)); |
---|
191 | if (ad->ad_fullname != NULL) |
---|
192 | FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); |
---|
193 | if (ad->ad_servername != NULL) |
---|
194 | FREE(ad->ad_servername, ad->ad_servernamelen + 1); |
---|
195 | return (NULL); |
---|
196 | } |
---|
197 | |
---|
198 | /* |
---|
199 | * Slightly modified version of authdes_create which takes the public key |
---|
200 | * of the server principal as an argument. This spares us a call to |
---|
201 | * getpublickey() which in the nameserver context can cause a deadlock. |
---|
202 | */ |
---|
203 | AUTH * |
---|
204 | authdes_pk_create(servername, pkey, window, timehost, ckey, srvr) |
---|
205 | char *servername; /* network name of server */ |
---|
206 | netobj *pkey; /* public key of server */ |
---|
207 | u_int window; /* time to live */ |
---|
208 | char *timehost; /* optional hostname to sync with */ |
---|
209 | des_block *ckey; /* optional conversation key to use */ |
---|
210 | nis_server *srvr; /* optional NIS+ server struct */ |
---|
211 | { |
---|
212 | AUTH *auth; |
---|
213 | struct ad_private *ad; |
---|
214 | char namebuf[MAXNETNAMELEN+1]; |
---|
215 | |
---|
216 | /* |
---|
217 | * Allocate everything now |
---|
218 | */ |
---|
219 | auth = ALLOC(AUTH); |
---|
220 | if (auth == NULL) { |
---|
221 | debug("authdes_pk_create: out of memory"); |
---|
222 | return (NULL); |
---|
223 | } |
---|
224 | ad = ALLOC(struct ad_private); |
---|
225 | if (ad == NULL) { |
---|
226 | debug("authdes_pk_create: out of memory"); |
---|
227 | goto failed; |
---|
228 | } |
---|
229 | ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */ |
---|
230 | ad->ad_timehost = NULL; |
---|
231 | ad->ad_netid = NULL; |
---|
232 | ad->ad_uaddr = NULL; |
---|
233 | ad->ad_nis_srvr = NULL; |
---|
234 | ad->ad_timediff.tv_sec = 0; |
---|
235 | ad->ad_timediff.tv_usec = 0; |
---|
236 | memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len); |
---|
237 | if (!getnetname(namebuf)) |
---|
238 | goto failed; |
---|
239 | ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf)); |
---|
240 | ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); |
---|
241 | ad->ad_servernamelen = strlen(servername); |
---|
242 | ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); |
---|
243 | |
---|
244 | if (ad->ad_fullname == NULL || ad->ad_servername == NULL) { |
---|
245 | debug("authdes_pk_create: out of memory"); |
---|
246 | goto failed; |
---|
247 | } |
---|
248 | if (timehost != NULL) { |
---|
249 | ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); |
---|
250 | if (ad->ad_timehost == NULL) { |
---|
251 | debug("authdes_pk_create: out of memory"); |
---|
252 | goto failed; |
---|
253 | } |
---|
254 | memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1); |
---|
255 | ad->ad_dosync = TRUE; |
---|
256 | } else if (srvr != NULL) { |
---|
257 | ad->ad_nis_srvr = srvr; /* transient */ |
---|
258 | ad->ad_dosync = TRUE; |
---|
259 | } else { |
---|
260 | ad->ad_dosync = FALSE; |
---|
261 | } |
---|
262 | memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1); |
---|
263 | memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1); |
---|
264 | ad->ad_window = window; |
---|
265 | if (ckey == NULL) { |
---|
266 | if (key_gendes(&auth->ah_key) < 0) { |
---|
267 | debug("authdes_pk_create: unable to gen conversation key"); |
---|
268 | goto failed; |
---|
269 | } |
---|
270 | } else { |
---|
271 | auth->ah_key = *ckey; |
---|
272 | } |
---|
273 | |
---|
274 | /* |
---|
275 | * Set up auth handle |
---|
276 | */ |
---|
277 | auth->ah_cred.oa_flavor = AUTH_DES; |
---|
278 | auth->ah_verf.oa_flavor = AUTH_DES; |
---|
279 | auth->ah_ops = &authdes_ops; |
---|
280 | auth->ah_private = (caddr_t)ad; |
---|
281 | |
---|
282 | if (!authdes_refresh(auth)) { |
---|
283 | goto failed; |
---|
284 | } |
---|
285 | ad->ad_nis_srvr = NULL; /* not needed any longer */ |
---|
286 | return (auth); |
---|
287 | |
---|
288 | failed: |
---|
289 | if (auth) |
---|
290 | FREE(auth, sizeof (AUTH)); |
---|
291 | if (ad) { |
---|
292 | if (ad->ad_fullname) |
---|
293 | FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); |
---|
294 | if (ad->ad_servername) |
---|
295 | FREE(ad->ad_servername, ad->ad_servernamelen + 1); |
---|
296 | if (ad->ad_timehost) |
---|
297 | FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); |
---|
298 | if (ad->ad_netid) |
---|
299 | free(ad->ad_netid); |
---|
300 | if (ad->ad_uaddr) |
---|
301 | free(ad->ad_uaddr); |
---|
302 | FREE(ad, sizeof (struct ad_private)); |
---|
303 | } |
---|
304 | return (NULL); |
---|
305 | } |
---|
306 | /* |
---|
307 | * Implement the five authentication operations |
---|
308 | */ |
---|
309 | |
---|
310 | |
---|
311 | /* |
---|
312 | * 1. Next Verifier |
---|
313 | */ |
---|
314 | /*ARGSUSED*/ |
---|
315 | static void |
---|
316 | authdes_nextverf(auth) |
---|
317 | AUTH *auth; |
---|
318 | { |
---|
319 | /* what the heck am I supposed to do??? */ |
---|
320 | } |
---|
321 | |
---|
322 | |
---|
323 | |
---|
324 | /* |
---|
325 | * 2. Marshal |
---|
326 | */ |
---|
327 | static bool_t |
---|
328 | authdes_marshal(auth, xdrs) |
---|
329 | AUTH *auth; |
---|
330 | XDR *xdrs; |
---|
331 | { |
---|
332 | struct ad_private *ad = AUTH_PRIVATE(auth); |
---|
333 | struct authdes_cred *cred = &ad->ad_cred; |
---|
334 | struct authdes_verf *verf = &ad->ad_verf; |
---|
335 | des_block cryptbuf[2]; |
---|
336 | des_block ivec; |
---|
337 | int status; |
---|
338 | long len; |
---|
339 | int32_t *ixdr; |
---|
340 | |
---|
341 | /* |
---|
342 | * Figure out the "time", accounting for any time difference |
---|
343 | * with the server if necessary. |
---|
344 | */ |
---|
345 | (void) gettimeofday(&ad->ad_timestamp, (struct timezone *)NULL); |
---|
346 | ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec; |
---|
347 | ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec; |
---|
348 | if (ad->ad_timestamp.tv_usec >= MILLION) { |
---|
349 | ad->ad_timestamp.tv_usec -= MILLION; |
---|
350 | ad->ad_timestamp.tv_sec += 1; |
---|
351 | } |
---|
352 | |
---|
353 | /* |
---|
354 | * XDR the timestamp and possibly some other things, then |
---|
355 | * encrypt them. |
---|
356 | */ |
---|
357 | ixdr = (int32_t *)cryptbuf; |
---|
358 | IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_sec); |
---|
359 | IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_usec); |
---|
360 | if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { |
---|
361 | IXDR_PUT_U_LONG(ixdr, ad->ad_window); |
---|
362 | IXDR_PUT_U_LONG(ixdr, ad->ad_window - 1); |
---|
363 | ivec.key.high = ivec.key.low = 0; |
---|
364 | status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf, |
---|
365 | 2*sizeof(des_block), DES_ENCRYPT | DES_HW, (char *)&ivec); |
---|
366 | } else { |
---|
367 | status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf, |
---|
368 | sizeof(des_block), DES_ENCRYPT | DES_HW); |
---|
369 | } |
---|
370 | if (DES_FAILED(status)) { |
---|
371 | debug("authdes_marshal: DES encryption failure"); |
---|
372 | return (FALSE); |
---|
373 | } |
---|
374 | ad->ad_verf.adv_xtimestamp = cryptbuf[0]; |
---|
375 | if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { |
---|
376 | ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high; |
---|
377 | ad->ad_verf.adv_winverf = cryptbuf[1].key.low; |
---|
378 | } else { |
---|
379 | ad->ad_cred.adc_nickname = ad->ad_nickname; |
---|
380 | ad->ad_verf.adv_winverf = 0; |
---|
381 | } |
---|
382 | |
---|
383 | /* |
---|
384 | * Serialize the credential and verifier into opaque |
---|
385 | * authentication data. |
---|
386 | */ |
---|
387 | if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { |
---|
388 | len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen); |
---|
389 | } else { |
---|
390 | len = (1 + 1)*BYTES_PER_XDR_UNIT; |
---|
391 | } |
---|
392 | |
---|
393 | if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { |
---|
394 | IXDR_PUT_LONG(ixdr, AUTH_DES); |
---|
395 | IXDR_PUT_LONG(ixdr, len); |
---|
396 | } else { |
---|
397 | ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_cred.oa_flavor)); |
---|
398 | ATTEMPT(xdr_putlong(xdrs, &len)); |
---|
399 | } |
---|
400 | ATTEMPT(xdr_authdes_cred(xdrs, cred)); |
---|
401 | |
---|
402 | len = (2 + 1)*BYTES_PER_XDR_UNIT; |
---|
403 | if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { |
---|
404 | IXDR_PUT_LONG(ixdr, AUTH_DES); |
---|
405 | IXDR_PUT_LONG(ixdr, len); |
---|
406 | } else { |
---|
407 | ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_verf.oa_flavor)); |
---|
408 | ATTEMPT(xdr_putlong(xdrs, &len)); |
---|
409 | } |
---|
410 | ATTEMPT(xdr_authdes_verf(xdrs, verf)); |
---|
411 | return (TRUE); |
---|
412 | } |
---|
413 | |
---|
414 | |
---|
415 | /* |
---|
416 | * 3. Validate |
---|
417 | */ |
---|
418 | static bool_t |
---|
419 | authdes_validate(auth, rverf) |
---|
420 | AUTH *auth; |
---|
421 | struct opaque_auth *rverf; |
---|
422 | { |
---|
423 | struct ad_private *ad = AUTH_PRIVATE(auth); |
---|
424 | struct authdes_verf verf; |
---|
425 | int status; |
---|
426 | register u_long *ixdr; |
---|
427 | |
---|
428 | if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) { |
---|
429 | return (FALSE); |
---|
430 | } |
---|
431 | ixdr = (u_long *)rverf->oa_base; |
---|
432 | verf.adv_xtimestamp.key.high = (u_long)*ixdr++; |
---|
433 | verf.adv_xtimestamp.key.low = (u_long)*ixdr++; |
---|
434 | verf.adv_int_u = (u_long)*ixdr++; /* nickname not XDR'd ! */ |
---|
435 | |
---|
436 | /* |
---|
437 | * Decrypt the timestamp |
---|
438 | */ |
---|
439 | status = ecb_crypt((char *)&auth->ah_key, (char *)&verf.adv_xtimestamp, |
---|
440 | sizeof(des_block), DES_DECRYPT | DES_HW); |
---|
441 | |
---|
442 | if (DES_FAILED(status)) { |
---|
443 | debug("authdes_validate: DES decryption failure"); |
---|
444 | return (FALSE); |
---|
445 | } |
---|
446 | |
---|
447 | /* |
---|
448 | * xdr the decrypted timestamp |
---|
449 | */ |
---|
450 | ixdr = (u_long *)verf.adv_xtimestamp.c; |
---|
451 | verf.adv_timestamp.tv_sec = IXDR_GET_LONG(ixdr) + 1; |
---|
452 | verf.adv_timestamp.tv_usec = IXDR_GET_LONG(ixdr); |
---|
453 | |
---|
454 | /* |
---|
455 | * validate |
---|
456 | */ |
---|
457 | if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, |
---|
458 | sizeof(struct timeval)) != 0) { |
---|
459 | debug("authdes_validate: verifier mismatch\n"); |
---|
460 | return (FALSE); |
---|
461 | } |
---|
462 | |
---|
463 | /* |
---|
464 | * We have a nickname now, let's use it |
---|
465 | */ |
---|
466 | ad->ad_nickname = verf.adv_nickname; |
---|
467 | ad->ad_cred.adc_namekind = ADN_NICKNAME; |
---|
468 | return (TRUE); |
---|
469 | } |
---|
470 | |
---|
471 | /* |
---|
472 | * 4. Refresh |
---|
473 | */ |
---|
474 | static bool_t |
---|
475 | authdes_refresh(auth) |
---|
476 | AUTH *auth; |
---|
477 | { |
---|
478 | struct ad_private *ad = AUTH_PRIVATE(auth); |
---|
479 | struct authdes_cred *cred = &ad->ad_cred; |
---|
480 | netobj pkey; |
---|
481 | |
---|
482 | if (ad->ad_dosync && |
---|
483 | #ifdef old |
---|
484 | !synchronize(&ad->ad_syncaddr, &ad->ad_timediff)) { |
---|
485 | #else |
---|
486 | !__rpc_get_time_offset(&ad->ad_timediff,ad->ad_nis_srvr, |
---|
487 | ad->ad_timehost, &(ad->ad_uaddr), |
---|
488 | (struct sockaddr_in *)&(ad->ad_syncaddr))) { |
---|
489 | #endif |
---|
490 | /* |
---|
491 | * Hope the clocks are synced! |
---|
492 | */ |
---|
493 | ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0; |
---|
494 | ad->ad_dosync = 0; |
---|
495 | debug("authdes_refresh: unable to synchronize with server"); |
---|
496 | } |
---|
497 | ad->ad_xkey = auth->ah_key; |
---|
498 | pkey.n_bytes = (char *)(ad->ad_pkey); |
---|
499 | pkey.n_len = strlen((char *)ad->ad_pkey) + 1; |
---|
500 | if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) { |
---|
501 | debug("authdes_create: unable to encrypt conversation key"); |
---|
502 | return (FALSE); |
---|
503 | } |
---|
504 | cred->adc_fullname.key = ad->ad_xkey; |
---|
505 | cred->adc_namekind = ADN_FULLNAME; |
---|
506 | cred->adc_fullname.name = ad->ad_fullname; |
---|
507 | return (TRUE); |
---|
508 | } |
---|
509 | |
---|
510 | |
---|
511 | /* |
---|
512 | * 5. Destroy |
---|
513 | */ |
---|
514 | static void |
---|
515 | authdes_destroy(auth) |
---|
516 | AUTH *auth; |
---|
517 | { |
---|
518 | struct ad_private *ad = AUTH_PRIVATE(auth); |
---|
519 | |
---|
520 | FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); |
---|
521 | FREE(ad->ad_servername, ad->ad_servernamelen + 1); |
---|
522 | FREE(ad, sizeof(struct ad_private)); |
---|
523 | FREE(auth, sizeof(AUTH)); |
---|
524 | } |
---|
525 | |
---|
526 | |
---|
527 | #ifdef old |
---|
528 | /* |
---|
529 | * Synchronize with the server at the given address, that is, |
---|
530 | * adjust timep to reflect the delta between our clocks |
---|
531 | */ |
---|
532 | static bool_t |
---|
533 | synchronize(syncaddr, timep) |
---|
534 | struct sockaddr *syncaddr; |
---|
535 | struct timeval *timep; |
---|
536 | { |
---|
537 | struct timeval mytime; |
---|
538 | struct timeval timeout; |
---|
539 | |
---|
540 | timeout.tv_sec = RTIME_TIMEOUT; |
---|
541 | timeout.tv_usec = 0; |
---|
542 | if (rtime((struct sockaddr_in *)syncaddr, timep, NULL /*&timeout*/) < 0) { |
---|
543 | return (FALSE); |
---|
544 | } |
---|
545 | (void) gettimeofday(&mytime, (struct timezone *)NULL); |
---|
546 | timep->tv_sec -= mytime.tv_sec; |
---|
547 | if (mytime.tv_usec > timep->tv_usec) { |
---|
548 | timep->tv_sec -= 1; |
---|
549 | timep->tv_usec += MILLION; |
---|
550 | } |
---|
551 | timep->tv_usec -= mytime.tv_usec; |
---|
552 | return (TRUE); |
---|
553 | } |
---|
554 | #endif |
---|