10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
21*132Srobinson */
22*132Srobinson
23*132Srobinson /*
24*132Srobinson * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
250Sstevel@tonic-gate * Use is subject to license terms.
260Sstevel@tonic-gate */
270Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
280Sstevel@tonic-gate /* All Rights Reserved */
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate * Portions of this source code were derived from Berkeley
310Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of
320Sstevel@tonic-gate * California.
330Sstevel@tonic-gate */
340Sstevel@tonic-gate
350Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
360Sstevel@tonic-gate
370Sstevel@tonic-gate /*
380Sstevel@tonic-gate * auth_des.c, client-side implementation of DES authentication
390Sstevel@tonic-gate *
400Sstevel@tonic-gate */
410Sstevel@tonic-gate
420Sstevel@tonic-gate #include "mt.h"
430Sstevel@tonic-gate #include "rpc_mt.h"
440Sstevel@tonic-gate #include <rpc/rpc.h>
450Sstevel@tonic-gate #include <rpc/des_crypt.h>
460Sstevel@tonic-gate #include <syslog.h>
470Sstevel@tonic-gate #include <stdlib.h>
480Sstevel@tonic-gate #include <string.h>
490Sstevel@tonic-gate #include <synch.h>
500Sstevel@tonic-gate #undef NIS
510Sstevel@tonic-gate #include <rpcsvc/nis.h>
520Sstevel@tonic-gate
530Sstevel@tonic-gate #define USEC_PER_SEC 1000000
540Sstevel@tonic-gate #define RTIME_TIMEOUT 5 /* seconds to wait for sync */
550Sstevel@tonic-gate
560Sstevel@tonic-gate extern bool_t xdr_authdes_cred(XDR *, struct authdes_cred *);
570Sstevel@tonic-gate extern bool_t xdr_authdes_verf(XDR *, struct authdes_verf *);
58*132Srobinson extern int key_encryptsession_pk(const char *, netobj *, des_block *);
590Sstevel@tonic-gate
600Sstevel@tonic-gate extern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *,
610Sstevel@tonic-gate char **, char **);
62*132Srobinson static struct auth_ops *authdes_ops(void);
63*132Srobinson static bool_t authdes_refresh(AUTH *, void *);
640Sstevel@tonic-gate
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate * This struct is pointed to by the ah_private field of an "AUTH *"
670Sstevel@tonic-gate */
680Sstevel@tonic-gate struct ad_private {
690Sstevel@tonic-gate char *ad_fullname; /* client's full name */
700Sstevel@tonic-gate uint_t ad_fullnamelen; /* length of name, rounded up */
710Sstevel@tonic-gate char *ad_servername; /* server's full name */
720Sstevel@tonic-gate size_t ad_servernamelen; /* length of name, rounded up */
730Sstevel@tonic-gate uint_t ad_window; /* client specified window */
740Sstevel@tonic-gate bool_t ad_dosync; /* synchronize? */
750Sstevel@tonic-gate char *ad_timehost; /* remote host to sync with */
760Sstevel@tonic-gate struct timeval ad_timediff; /* server's time - client's time */
770Sstevel@tonic-gate uint_t ad_nickname; /* server's nickname for client */
780Sstevel@tonic-gate struct authdes_cred ad_cred; /* storage for credential */
790Sstevel@tonic-gate struct authdes_verf ad_verf; /* storage for verifier */
800Sstevel@tonic-gate struct timeval ad_timestamp; /* timestamp sent */
810Sstevel@tonic-gate des_block ad_xkey; /* encrypted conversation key */
820Sstevel@tonic-gate uchar_t ad_pkey[1024]; /* Servers actual public key */
830Sstevel@tonic-gate char *ad_netid; /* Timehost netid */
840Sstevel@tonic-gate char *ad_uaddr; /* Timehost uaddr */
850Sstevel@tonic-gate nis_server *ad_nis_srvr; /* NIS+ server struct */
860Sstevel@tonic-gate };
870Sstevel@tonic-gate
88*132Srobinson extern AUTH *authdes_pk_seccreate(const char *, netobj *, uint_t, const char *,
890Sstevel@tonic-gate const des_block *, nis_server *);
900Sstevel@tonic-gate
910Sstevel@tonic-gate /*
920Sstevel@tonic-gate * documented version of authdes_seccreate
930Sstevel@tonic-gate */
940Sstevel@tonic-gate /*
950Sstevel@tonic-gate * servername: network name of server
960Sstevel@tonic-gate * win: time to live
970Sstevel@tonic-gate * timehost: optional hostname to sync with
980Sstevel@tonic-gate * ckey: optional conversation key to use
990Sstevel@tonic-gate */
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate AUTH *
authdes_seccreate(const char * servername,const uint_t win,const char * timehost,const des_block * ckey)1020Sstevel@tonic-gate authdes_seccreate(const char *servername, const uint_t win,
1030Sstevel@tonic-gate const char *timehost, const des_block *ckey)
1040Sstevel@tonic-gate {
1050Sstevel@tonic-gate uchar_t pkey_data[1024];
1060Sstevel@tonic-gate netobj pkey;
1070Sstevel@tonic-gate
108*132Srobinson if (!getpublickey(servername, (char *)pkey_data)) {
1090Sstevel@tonic-gate syslog(LOG_ERR,
1100Sstevel@tonic-gate "authdes_seccreate: no public key found for %s",
1110Sstevel@tonic-gate servername);
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate return (NULL);
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate pkey.n_bytes = (char *)pkey_data;
1170Sstevel@tonic-gate pkey.n_len = (uint_t)strlen((char *)pkey_data) + 1;
118*132Srobinson return (authdes_pk_seccreate(servername, &pkey, win, timehost,
119*132Srobinson ckey, NULL));
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate /*
1230Sstevel@tonic-gate * Slightly modified version of authdes_seccreate which takes the public key
1240Sstevel@tonic-gate * of the server principal as an argument. This spares us a call to
1250Sstevel@tonic-gate * getpublickey() which in the nameserver context can cause a deadlock.
1260Sstevel@tonic-gate */
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate AUTH *
authdes_pk_seccreate(const char * servername,netobj * pkey,uint_t window,const char * timehost,const des_block * ckey,nis_server * srvr)1290Sstevel@tonic-gate authdes_pk_seccreate(const char *servername, netobj *pkey, uint_t window,
1300Sstevel@tonic-gate const char *timehost, const des_block *ckey, nis_server *srvr)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate AUTH *auth;
1330Sstevel@tonic-gate struct ad_private *ad;
1340Sstevel@tonic-gate char namebuf[MAXNETNAMELEN+1];
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate /*
1370Sstevel@tonic-gate * Allocate everything now
1380Sstevel@tonic-gate */
139*132Srobinson auth = malloc(sizeof (AUTH));
1400Sstevel@tonic-gate if (auth == NULL) {
1410Sstevel@tonic-gate syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
1420Sstevel@tonic-gate return (NULL);
1430Sstevel@tonic-gate }
144*132Srobinson ad = malloc(sizeof (struct ad_private));
1450Sstevel@tonic-gate if (ad == NULL) {
1460Sstevel@tonic-gate syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
1470Sstevel@tonic-gate goto failed;
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */
1500Sstevel@tonic-gate ad->ad_timehost = NULL;
1510Sstevel@tonic-gate ad->ad_netid = NULL;
1520Sstevel@tonic-gate ad->ad_uaddr = NULL;
1530Sstevel@tonic-gate ad->ad_nis_srvr = NULL;
1540Sstevel@tonic-gate ad->ad_timediff.tv_sec = 0;
1550Sstevel@tonic-gate ad->ad_timediff.tv_usec = 0;
156*132Srobinson (void) memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len);
1570Sstevel@tonic-gate if (!getnetname(namebuf))
1580Sstevel@tonic-gate goto failed;
1590Sstevel@tonic-gate ad->ad_fullnamelen = RNDUP((uint_t)strlen(namebuf));
160*132Srobinson ad->ad_fullname = malloc(ad->ad_fullnamelen + 1);
1610Sstevel@tonic-gate ad->ad_servernamelen = strlen(servername);
162*132Srobinson ad->ad_servername = malloc(ad->ad_servernamelen + 1);
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
1650Sstevel@tonic-gate syslog(LOG_ERR, "authdes_seccreate: out of memory");
1660Sstevel@tonic-gate goto failed;
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate if (timehost != NULL) {
169*132Srobinson ad->ad_timehost = malloc(strlen(timehost) + 1);
1700Sstevel@tonic-gate if (ad->ad_timehost == NULL) {
1710Sstevel@tonic-gate syslog(LOG_ERR, "authdes_seccreate: out of memory");
1720Sstevel@tonic-gate goto failed;
1730Sstevel@tonic-gate }
174*132Srobinson (void) memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
1750Sstevel@tonic-gate ad->ad_dosync = TRUE;
1760Sstevel@tonic-gate } else if (srvr != NULL) {
1770Sstevel@tonic-gate ad->ad_nis_srvr = srvr; /* transient */
1780Sstevel@tonic-gate ad->ad_dosync = TRUE;
1790Sstevel@tonic-gate } else {
1800Sstevel@tonic-gate ad->ad_dosync = FALSE;
1810Sstevel@tonic-gate }
182*132Srobinson (void) memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
183*132Srobinson (void) memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1);
1840Sstevel@tonic-gate ad->ad_window = window;
1850Sstevel@tonic-gate if (ckey == NULL) {
1860Sstevel@tonic-gate if (key_gendes(&auth->ah_key) < 0) {
1870Sstevel@tonic-gate syslog(LOG_ERR,
1880Sstevel@tonic-gate "authdes_seccreate: keyserv(1m) is unable to generate session key");
1890Sstevel@tonic-gate goto failed;
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate } else
1920Sstevel@tonic-gate auth->ah_key = *ckey;
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate /*
1950Sstevel@tonic-gate * Set up auth handle
1960Sstevel@tonic-gate */
1970Sstevel@tonic-gate auth->ah_cred.oa_flavor = AUTH_DES;
1980Sstevel@tonic-gate auth->ah_verf.oa_flavor = AUTH_DES;
1990Sstevel@tonic-gate auth->ah_ops = authdes_ops();
2000Sstevel@tonic-gate auth->ah_private = (caddr_t)ad;
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate if (!authdes_refresh(auth, NULL)) {
2030Sstevel@tonic-gate goto failed;
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate ad->ad_nis_srvr = NULL; /* not needed any longer */
2060Sstevel@tonic-gate return (auth);
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate failed:
2090Sstevel@tonic-gate if (auth)
210*132Srobinson free(auth);
2110Sstevel@tonic-gate if (ad) {
2120Sstevel@tonic-gate if (ad->ad_fullname)
213*132Srobinson free(ad->ad_fullname);
2140Sstevel@tonic-gate if (ad->ad_servername)
215*132Srobinson free(ad->ad_servername);
2160Sstevel@tonic-gate if (ad->ad_timehost)
217*132Srobinson free(ad->ad_timehost);
2180Sstevel@tonic-gate if (ad->ad_netid)
219*132Srobinson free(ad->ad_netid);
2200Sstevel@tonic-gate if (ad->ad_uaddr)
221*132Srobinson free(ad->ad_uaddr);
222*132Srobinson free(ad);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate return (NULL);
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate /*
2280Sstevel@tonic-gate * Implement the five authentication operations
2290Sstevel@tonic-gate */
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate /*
2320Sstevel@tonic-gate * 1. Next Verifier
2330Sstevel@tonic-gate */
2340Sstevel@tonic-gate /*ARGSUSED*/
2350Sstevel@tonic-gate static void
authdes_nextverf(AUTH * auth)2360Sstevel@tonic-gate authdes_nextverf(AUTH *auth)
2370Sstevel@tonic-gate {
2380Sstevel@tonic-gate /* what the heck am I supposed to do??? */
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate /*
2430Sstevel@tonic-gate * 2. Marshal
2440Sstevel@tonic-gate */
2450Sstevel@tonic-gate static bool_t
authdes_marshal(AUTH * auth,XDR * xdrs)2460Sstevel@tonic-gate authdes_marshal(AUTH *auth, XDR *xdrs)
2470Sstevel@tonic-gate {
2480Sstevel@tonic-gate /* LINTED pointer alignment */
249*132Srobinson struct ad_private *ad = (struct ad_private *)auth->ah_private;
2500Sstevel@tonic-gate struct authdes_cred *cred = &ad->ad_cred;
2510Sstevel@tonic-gate struct authdes_verf *verf = &ad->ad_verf;
2520Sstevel@tonic-gate des_block cryptbuf[2];
2530Sstevel@tonic-gate des_block ivec;
2540Sstevel@tonic-gate int status;
2550Sstevel@tonic-gate int len;
2560Sstevel@tonic-gate rpc_inline_t *ixdr;
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate /*
2590Sstevel@tonic-gate * Figure out the "time", accounting for any time difference
2600Sstevel@tonic-gate * with the server if necessary.
2610Sstevel@tonic-gate */
262*132Srobinson (void) gettimeofday(&ad->ad_timestamp, NULL);
2630Sstevel@tonic-gate ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
2640Sstevel@tonic-gate ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
2650Sstevel@tonic-gate while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) {
2660Sstevel@tonic-gate ad->ad_timestamp.tv_usec -= USEC_PER_SEC;
2670Sstevel@tonic-gate ad->ad_timestamp.tv_sec++;
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate /*
2710Sstevel@tonic-gate * XDR the timestamp and possibly some other things, then
2720Sstevel@tonic-gate * encrypt them.
2730Sstevel@tonic-gate */
2740Sstevel@tonic-gate ixdr = (rpc_inline_t *)cryptbuf;
2750Sstevel@tonic-gate IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec);
2760Sstevel@tonic-gate IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec);
2770Sstevel@tonic-gate if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
2780Sstevel@tonic-gate IXDR_PUT_U_INT32(ixdr, ad->ad_window);
2790Sstevel@tonic-gate IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1);
2800Sstevel@tonic-gate ivec.key.high = ivec.key.low = 0;
2810Sstevel@tonic-gate status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf,
2820Sstevel@tonic-gate 2 * sizeof (des_block),
2830Sstevel@tonic-gate DES_ENCRYPT | DES_HW, (char *)&ivec);
2840Sstevel@tonic-gate } else {
2850Sstevel@tonic-gate status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf,
2860Sstevel@tonic-gate sizeof (des_block),
2870Sstevel@tonic-gate DES_ENCRYPT | DES_HW);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate if (DES_FAILED(status)) {
2900Sstevel@tonic-gate syslog(LOG_ERR, "authdes_marshal: DES encryption failure");
2910Sstevel@tonic-gate return (FALSE);
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate ad->ad_verf.adv_xtimestamp = cryptbuf[0];
2940Sstevel@tonic-gate if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
2950Sstevel@tonic-gate ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high;
2960Sstevel@tonic-gate ad->ad_verf.adv_winverf = cryptbuf[1].key.low;
2970Sstevel@tonic-gate } else {
2980Sstevel@tonic-gate ad->ad_cred.adc_nickname = ad->ad_nickname;
2990Sstevel@tonic-gate ad->ad_verf.adv_winverf = 0;
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate /*
3030Sstevel@tonic-gate * Serialize the credential and verifier into opaque
3040Sstevel@tonic-gate * authentication data.
3050Sstevel@tonic-gate */
3060Sstevel@tonic-gate if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
3070Sstevel@tonic-gate len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen);
3080Sstevel@tonic-gate } else {
3090Sstevel@tonic-gate len = (1 + 1)*BYTES_PER_XDR_UNIT;
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate
3120Sstevel@tonic-gate if (ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT)) {
3130Sstevel@tonic-gate IXDR_PUT_INT32(ixdr, AUTH_DES);
3140Sstevel@tonic-gate IXDR_PUT_INT32(ixdr, len);
3150Sstevel@tonic-gate } else {
316*132Srobinson if (!xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor))
317*132Srobinson return (FALSE);
318*132Srobinson if (!xdr_putint32(xdrs, &len))
319*132Srobinson return (FALSE);
3200Sstevel@tonic-gate }
321*132Srobinson if (!xdr_authdes_cred(xdrs, cred))
322*132Srobinson return (FALSE);
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate len = (2 + 1)*BYTES_PER_XDR_UNIT;
3250Sstevel@tonic-gate if (ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT)) {
3260Sstevel@tonic-gate IXDR_PUT_INT32(ixdr, AUTH_DES);
3270Sstevel@tonic-gate IXDR_PUT_INT32(ixdr, len);
3280Sstevel@tonic-gate } else {
329*132Srobinson if (!xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor))
330*132Srobinson return (FALSE);
331*132Srobinson if (!xdr_putint32(xdrs, &len))
332*132Srobinson return (FALSE);
3330Sstevel@tonic-gate }
334*132Srobinson return (xdr_authdes_verf(xdrs, verf));
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate /*
3390Sstevel@tonic-gate * 3. Validate
3400Sstevel@tonic-gate */
3410Sstevel@tonic-gate static bool_t
authdes_validate(AUTH * auth,struct opaque_auth * rverf)3420Sstevel@tonic-gate authdes_validate(AUTH *auth, struct opaque_auth *rverf)
3430Sstevel@tonic-gate {
3440Sstevel@tonic-gate /* LINTED pointer alignment */
345*132Srobinson struct ad_private *ad = (struct ad_private *)auth->ah_private;
3460Sstevel@tonic-gate struct authdes_verf verf;
3470Sstevel@tonic-gate int status;
3480Sstevel@tonic-gate uint32_t *ixdr;
3490Sstevel@tonic-gate des_block buf;
3500Sstevel@tonic-gate
351*132Srobinson if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT)
3520Sstevel@tonic-gate return (FALSE);
3530Sstevel@tonic-gate /* LINTED pointer alignment */
3540Sstevel@tonic-gate ixdr = (uint32_t *)rverf->oa_base;
3550Sstevel@tonic-gate buf.key.high = (uint32_t)*ixdr++;
3560Sstevel@tonic-gate buf.key.low = (uint32_t)*ixdr++;
3570Sstevel@tonic-gate verf.adv_int_u = (uint32_t)*ixdr++;
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate /*
3600Sstevel@tonic-gate * Decrypt the timestamp
3610Sstevel@tonic-gate */
3620Sstevel@tonic-gate status = ecb_crypt((char *)&auth->ah_key, (char *)&buf,
3630Sstevel@tonic-gate sizeof (des_block), DES_DECRYPT | DES_HW);
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate if (DES_FAILED(status)) {
3660Sstevel@tonic-gate syslog(LOG_ERR, "authdes_validate: DES decryption failure");
3670Sstevel@tonic-gate return (FALSE);
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate /*
3710Sstevel@tonic-gate * xdr the decrypted timestamp
3720Sstevel@tonic-gate */
3730Sstevel@tonic-gate /* LINTED pointer alignment */
3740Sstevel@tonic-gate ixdr = (uint32_t *)buf.c;
3750Sstevel@tonic-gate verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1;
3760Sstevel@tonic-gate verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr);
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate /*
3790Sstevel@tonic-gate * validate
3800Sstevel@tonic-gate */
381*132Srobinson if (memcmp(&ad->ad_timestamp, &verf.adv_timestamp,
3820Sstevel@tonic-gate sizeof (struct timeval)) != 0) {
3830Sstevel@tonic-gate syslog(LOG_DEBUG, "authdes_validate: verifier mismatch");
3840Sstevel@tonic-gate return (FALSE);
3850Sstevel@tonic-gate }
3860Sstevel@tonic-gate
3870Sstevel@tonic-gate /*
3880Sstevel@tonic-gate * We have a nickname now, let's use it
3890Sstevel@tonic-gate */
3900Sstevel@tonic-gate ad->ad_nickname = verf.adv_nickname;
3910Sstevel@tonic-gate ad->ad_cred.adc_namekind = ADN_NICKNAME;
3920Sstevel@tonic-gate return (TRUE);
3930Sstevel@tonic-gate }
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate /*
3960Sstevel@tonic-gate * 4. Refresh
3970Sstevel@tonic-gate */
3980Sstevel@tonic-gate /*ARGSUSED*/
3990Sstevel@tonic-gate static bool_t
authdes_refresh(AUTH * auth,void * dummy)4000Sstevel@tonic-gate authdes_refresh(AUTH *auth, void *dummy)
4010Sstevel@tonic-gate {
4020Sstevel@tonic-gate /* LINTED pointer alignment */
403*132Srobinson struct ad_private *ad = (struct ad_private *)auth->ah_private;
4040Sstevel@tonic-gate struct authdes_cred *cred = &ad->ad_cred;
4050Sstevel@tonic-gate int ok;
4060Sstevel@tonic-gate netobj pkey;
4070Sstevel@tonic-gate
4080Sstevel@tonic-gate if (ad->ad_dosync) {
4090Sstevel@tonic-gate ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr,
4100Sstevel@tonic-gate ad->ad_timehost, &(ad->ad_uaddr),
4110Sstevel@tonic-gate &(ad->ad_netid));
412*132Srobinson if (!ok) {
4130Sstevel@tonic-gate /*
4140Sstevel@tonic-gate * Hope the clocks are synced!
4150Sstevel@tonic-gate */
4160Sstevel@tonic-gate ad->ad_dosync = 0;
4170Sstevel@tonic-gate syslog(LOG_DEBUG,
4180Sstevel@tonic-gate "authdes_refresh: unable to synchronize clock");
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate ad->ad_xkey = auth->ah_key;
4220Sstevel@tonic-gate pkey.n_bytes = (char *)(ad->ad_pkey);
4230Sstevel@tonic-gate pkey.n_len = (uint_t)strlen((char *)ad->ad_pkey) + 1;
4240Sstevel@tonic-gate if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) {
4250Sstevel@tonic-gate syslog(LOG_INFO,
4260Sstevel@tonic-gate "authdes_refresh: keyserv(1m) is unable to encrypt session key");
4270Sstevel@tonic-gate return (FALSE);
4280Sstevel@tonic-gate }
4290Sstevel@tonic-gate cred->adc_fullname.key = ad->ad_xkey;
4300Sstevel@tonic-gate cred->adc_namekind = ADN_FULLNAME;
4310Sstevel@tonic-gate cred->adc_fullname.name = ad->ad_fullname;
4320Sstevel@tonic-gate return (TRUE);
4330Sstevel@tonic-gate }
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate
4360Sstevel@tonic-gate /*
4370Sstevel@tonic-gate * 5. Destroy
4380Sstevel@tonic-gate */
4390Sstevel@tonic-gate static void
authdes_destroy(AUTH * auth)4400Sstevel@tonic-gate authdes_destroy(AUTH *auth)
4410Sstevel@tonic-gate {
4420Sstevel@tonic-gate /* LINTED pointer alignment */
443*132Srobinson struct ad_private *ad = (struct ad_private *)auth->ah_private;
4440Sstevel@tonic-gate
445*132Srobinson free(ad->ad_fullname);
446*132Srobinson free(ad->ad_servername);
4470Sstevel@tonic-gate if (ad->ad_timehost)
448*132Srobinson free(ad->ad_timehost);
4490Sstevel@tonic-gate if (ad->ad_netid)
450*132Srobinson free(ad->ad_netid);
4510Sstevel@tonic-gate if (ad->ad_uaddr)
452*132Srobinson free(ad->ad_uaddr);
453*132Srobinson free(ad);
454*132Srobinson free(auth);
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate static struct auth_ops *
authdes_ops(void)4580Sstevel@tonic-gate authdes_ops(void)
4590Sstevel@tonic-gate {
4600Sstevel@tonic-gate static struct auth_ops ops;
4610Sstevel@tonic-gate extern mutex_t ops_lock;
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate /* VARIABLES PROTECTED BY ops_lock: ops */
4640Sstevel@tonic-gate
465*132Srobinson (void) mutex_lock(&ops_lock);
4660Sstevel@tonic-gate if (ops.ah_nextverf == NULL) {
4670Sstevel@tonic-gate ops.ah_nextverf = authdes_nextverf;
4680Sstevel@tonic-gate ops.ah_marshal = authdes_marshal;
4690Sstevel@tonic-gate ops.ah_validate = authdes_validate;
4700Sstevel@tonic-gate ops.ah_refresh = authdes_refresh;
4710Sstevel@tonic-gate ops.ah_destroy = authdes_destroy;
4720Sstevel@tonic-gate }
473*132Srobinson (void) mutex_unlock(&ops_lock);
4740Sstevel@tonic-gate return (&ops);
4750Sstevel@tonic-gate }
476