1261046Smav/*- 2261046Smav * Copyright (c) 2009, Sun Microsystems, Inc. 3261046Smav * All rights reserved. 4261046Smav * 5261046Smav * Redistribution and use in source and binary forms, with or without 6261046Smav * modification, are permitted provided that the following conditions are met: 7261046Smav * - Redistributions of source code must retain the above copyright notice, 8261046Smav * this list of conditions and the following disclaimer. 9261046Smav * - Redistributions in binary form must reproduce the above copyright notice, 10261046Smav * this list of conditions and the following disclaimer in the documentation 11261046Smav * and/or other materials provided with the distribution. 12261046Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 13261046Smav * contributors may be used to endorse or promote products derived 14261046Smav * from this software without specific prior written permission. 1526219Swpaul * 16261046Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17261046Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18261046Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19261046Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20261046Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21261046Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22261046Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23261046Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24261046Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25261046Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26261046Smav * POSSIBILITY OF SUCH DAMAGE. 2726219Swpaul */ 2826219Swpaul/* 2926219Swpaul * Copyright (c) 1988 by Sun Microsystems, Inc. 3026219Swpaul */ 3126219Swpaul/* 3226219Swpaul * auth_des.c, client-side implementation of DES authentication 3326219Swpaul */ 3492990Sobrien 3575094Siedowse#include "namespace.h" 3674462Salfred#include "reentrant.h" 3774462Salfred#include <err.h> 3874462Salfred#include <errno.h> 3926219Swpaul#include <string.h> 4026219Swpaul#include <stdlib.h> 4126219Swpaul#include <unistd.h> 4226219Swpaul#include <sys/cdefs.h> 4326219Swpaul#include <rpc/des_crypt.h> 4474462Salfred#include <syslog.h> 4526219Swpaul#include <rpc/types.h> 4626219Swpaul#include <rpc/auth.h> 4726219Swpaul#include <rpc/auth_des.h> 4874462Salfred#include <rpc/clnt.h> 4974462Salfred#include <rpc/xdr.h> 5026219Swpaul#include <sys/socket.h> 5126219Swpaul#undef NIS 5226219Swpaul#include <rpcsvc/nis.h> 5374462Salfred#include "un-namespace.h" 54156090Sdeischen#include "mt_misc.h" 5526219Swpaul 5626219Swpaul#if defined(LIBC_SCCS) && !defined(lint) 57136581Sobrienstatic char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; 5826219Swpaul#endif 5992990Sobrien#include <sys/cdefs.h> 6092990Sobrien__FBSDID("$FreeBSD: releng/10.2/lib/libc/rpc/auth_des.c 261046 2014-01-22 23:45:27Z mav $"); 6126219Swpaul 6274462Salfred#define USEC_PER_SEC 1000000 6374462Salfred#define RTIME_TIMEOUT 5 /* seconds to wait for sync */ 6426219Swpaul 6526219Swpaul#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private 6626219Swpaul#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type)) 6726219Swpaul#define FREE(ptr, size) mem_free((char *)(ptr), (int) size) 6826219Swpaul#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) 6926219Swpaul 7074462Salfredextern bool_t xdr_authdes_cred( XDR *, struct authdes_cred *); 7174462Salfredextern bool_t xdr_authdes_verf( XDR *, struct authdes_verf *); 7274462Salfredextern int key_encryptsession_pk(); 7326219Swpaul 7474462Salfredextern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *, 7574462Salfred char **, char **); 7674462Salfred 7726219Swpaul/* 7826219Swpaul * DES authenticator operations vector 7926219Swpaul */ 8074462Salfredstatic void authdes_nextverf(AUTH *); 8174462Salfredstatic bool_t authdes_marshal(AUTH *, XDR *); 8274462Salfredstatic bool_t authdes_validate(AUTH *, struct opaque_auth *); 8374462Salfredstatic bool_t authdes_refresh(AUTH *, void *); 8474462Salfredstatic void authdes_destroy(AUTH *); 8574462Salfred 8674462Salfredstatic struct auth_ops *authdes_ops(void); 8774462Salfred 8826219Swpaul/* 8926219Swpaul * This struct is pointed to by the ah_private field of an "AUTH *" 9026219Swpaul */ 9126219Swpaulstruct ad_private { 9226219Swpaul char *ad_fullname; /* client's full name */ 9326219Swpaul u_int ad_fullnamelen; /* length of name, rounded up */ 9426219Swpaul char *ad_servername; /* server's full name */ 9526219Swpaul u_int ad_servernamelen; /* length of name, rounded up */ 9626219Swpaul u_int ad_window; /* client specified window */ 9726219Swpaul bool_t ad_dosync; /* synchronize? */ 9874462Salfred struct netbuf ad_syncaddr; /* remote host to synch with */ 9926219Swpaul char *ad_timehost; /* remote host to synch with */ 10026219Swpaul struct timeval ad_timediff; /* server's time - client's time */ 10174462Salfred u_int ad_nickname; /* server's nickname for client */ 10226219Swpaul struct authdes_cred ad_cred; /* storage for credential */ 10326219Swpaul struct authdes_verf ad_verf; /* storage for verifier */ 10426219Swpaul struct timeval ad_timestamp; /* timestamp sent */ 10526219Swpaul des_block ad_xkey; /* encrypted conversation key */ 10626219Swpaul u_char ad_pkey[1024]; /* Server's actual public key */ 10726219Swpaul char *ad_netid; /* Timehost netid */ 10826219Swpaul char *ad_uaddr; /* Timehost uaddr */ 10926219Swpaul nis_server *ad_nis_srvr; /* NIS+ server struct */ 11026219Swpaul}; 11174462Salfred 11274462SalfredAUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *, 11374462Salfred const des_block *, nis_server *); 11426219Swpaul 11574462Salfred/* 11674462Salfred * documented version of authdes_seccreate 11774462Salfred */ 11874462Salfred/* 11974462Salfred servername: network name of server 12074462Salfred win: time to live 12174462Salfred timehost: optional hostname to sync with 12274462Salfred ckey: optional conversation key to use 12374462Salfred*/ 12426219Swpaul 12526219SwpaulAUTH * 12674462Salfredauthdes_seccreate(const char *servername, const u_int win, 12774462Salfred const char *timehost, const des_block *ckey) 12826219Swpaul{ 12974462Salfred u_char pkey_data[1024]; 13074462Salfred netobj pkey; 13174462Salfred AUTH *dummy; 13226219Swpaul 13374462Salfred if (! getpublickey(servername, (char *) pkey_data)) { 13474462Salfred syslog(LOG_ERR, 13574462Salfred "authdes_seccreate: no public key found for %s", 13674462Salfred servername); 13774462Salfred return (NULL); 13826219Swpaul } 13926219Swpaul 14074462Salfred pkey.n_bytes = (char *) pkey_data; 14174462Salfred pkey.n_len = (u_int)strlen((char *)pkey_data) + 1; 14274462Salfred dummy = authdes_pk_seccreate(servername, &pkey, win, timehost, 14374462Salfred ckey, NULL); 14474462Salfred return (dummy); 14526219Swpaul} 14626219Swpaul 14726219Swpaul/* 14874462Salfred * Slightly modified version of authdessec_create which takes the public key 14926219Swpaul * of the server principal as an argument. This spares us a call to 15026219Swpaul * getpublickey() which in the nameserver context can cause a deadlock. 15126219Swpaul */ 15226219SwpaulAUTH * 15374462Salfredauthdes_pk_seccreate(const char *servername, netobj *pkey, u_int window, 15474462Salfred const char *timehost, const des_block *ckey, nis_server *srvr) 15526219Swpaul{ 15626219Swpaul AUTH *auth; 15726219Swpaul struct ad_private *ad; 15826219Swpaul char namebuf[MAXNETNAMELEN+1]; 15926219Swpaul 16026219Swpaul /* 16126219Swpaul * Allocate everything now 16226219Swpaul */ 16326219Swpaul auth = ALLOC(AUTH); 16426219Swpaul if (auth == NULL) { 16574462Salfred syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); 16626219Swpaul return (NULL); 16726219Swpaul } 16826219Swpaul ad = ALLOC(struct ad_private); 16926219Swpaul if (ad == NULL) { 17074462Salfred syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); 17126219Swpaul goto failed; 17226219Swpaul } 17326219Swpaul ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */ 17426219Swpaul ad->ad_timehost = NULL; 17526219Swpaul ad->ad_netid = NULL; 17626219Swpaul ad->ad_uaddr = NULL; 17726219Swpaul ad->ad_nis_srvr = NULL; 17826219Swpaul ad->ad_timediff.tv_sec = 0; 17926219Swpaul ad->ad_timediff.tv_usec = 0; 18026219Swpaul memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len); 18126219Swpaul if (!getnetname(namebuf)) 18226219Swpaul goto failed; 18326219Swpaul ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf)); 18426219Swpaul ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); 18526219Swpaul ad->ad_servernamelen = strlen(servername); 18626219Swpaul ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); 18726219Swpaul 18826219Swpaul if (ad->ad_fullname == NULL || ad->ad_servername == NULL) { 18974462Salfred syslog(LOG_ERR, "authdes_seccreate: out of memory"); 19026219Swpaul goto failed; 19126219Swpaul } 19226219Swpaul if (timehost != NULL) { 19326219Swpaul ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); 19426219Swpaul if (ad->ad_timehost == NULL) { 19574462Salfred syslog(LOG_ERR, "authdes_seccreate: out of memory"); 19626219Swpaul goto failed; 19726219Swpaul } 19826219Swpaul memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1); 19926219Swpaul ad->ad_dosync = TRUE; 20026219Swpaul } else if (srvr != NULL) { 20126219Swpaul ad->ad_nis_srvr = srvr; /* transient */ 20226219Swpaul ad->ad_dosync = TRUE; 20326219Swpaul } else { 20426219Swpaul ad->ad_dosync = FALSE; 20526219Swpaul } 20626219Swpaul memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1); 20726219Swpaul memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1); 20826219Swpaul ad->ad_window = window; 20926219Swpaul if (ckey == NULL) { 21026219Swpaul if (key_gendes(&auth->ah_key) < 0) { 21174462Salfred syslog(LOG_ERR, 21274462Salfred "authdes_seccreate: keyserv(1m) is unable to generate session key"); 21326219Swpaul goto failed; 21426219Swpaul } 21526219Swpaul } else { 21626219Swpaul auth->ah_key = *ckey; 21726219Swpaul } 21826219Swpaul 21926219Swpaul /* 22026219Swpaul * Set up auth handle 22126219Swpaul */ 22226219Swpaul auth->ah_cred.oa_flavor = AUTH_DES; 22326219Swpaul auth->ah_verf.oa_flavor = AUTH_DES; 22474462Salfred auth->ah_ops = authdes_ops(); 22526219Swpaul auth->ah_private = (caddr_t)ad; 22626219Swpaul 22774462Salfred if (!authdes_refresh(auth, NULL)) { 22826219Swpaul goto failed; 22926219Swpaul } 23026219Swpaul ad->ad_nis_srvr = NULL; /* not needed any longer */ 23126219Swpaul return (auth); 23226219Swpaul 23326219Swpaulfailed: 23426219Swpaul if (auth) 23526219Swpaul FREE(auth, sizeof (AUTH)); 23626219Swpaul if (ad) { 23726219Swpaul if (ad->ad_fullname) 23826219Swpaul FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); 23926219Swpaul if (ad->ad_servername) 24026219Swpaul FREE(ad->ad_servername, ad->ad_servernamelen + 1); 24126219Swpaul if (ad->ad_timehost) 24226219Swpaul FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); 24326219Swpaul if (ad->ad_netid) 24474462Salfred FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); 24526219Swpaul if (ad->ad_uaddr) 24674462Salfred FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); 24726219Swpaul FREE(ad, sizeof (struct ad_private)); 24826219Swpaul } 24926219Swpaul return (NULL); 25026219Swpaul} 25174462Salfred 25226219Swpaul/* 25326219Swpaul * Implement the five authentication operations 25426219Swpaul */ 25526219Swpaul 25626219Swpaul 25726219Swpaul/* 25826219Swpaul * 1. Next Verifier 25926219Swpaul */ 26026219Swpaul/*ARGSUSED*/ 26126219Swpaulstatic void 26274462Salfredauthdes_nextverf(AUTH *auth) 26326219Swpaul{ 26426219Swpaul /* what the heck am I supposed to do??? */ 26526219Swpaul} 26626219Swpaul 26726219Swpaul 26826219Swpaul/* 26926219Swpaul * 2. Marshal 27026219Swpaul */ 27126219Swpaulstatic bool_t 27274462Salfredauthdes_marshal(AUTH *auth, XDR *xdrs) 27326219Swpaul{ 27474462Salfred/* LINTED pointer alignment */ 27526219Swpaul struct ad_private *ad = AUTH_PRIVATE(auth); 27626219Swpaul struct authdes_cred *cred = &ad->ad_cred; 27726219Swpaul struct authdes_verf *verf = &ad->ad_verf; 27826219Swpaul des_block cryptbuf[2]; 27926219Swpaul des_block ivec; 28026219Swpaul int status; 28174462Salfred int len; 28292889Sobrien rpc_inline_t *ixdr; 28326219Swpaul 28426219Swpaul /* 28526219Swpaul * Figure out the "time", accounting for any time difference 28626219Swpaul * with the server if necessary. 28726219Swpaul */ 288239991Sed (void)gettimeofday(&ad->ad_timestamp, NULL); 28926219Swpaul ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec; 29026219Swpaul ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec; 29174462Salfred while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) { 29274462Salfred ad->ad_timestamp.tv_usec -= USEC_PER_SEC; 29374462Salfred ad->ad_timestamp.tv_sec++; 29426219Swpaul } 29526219Swpaul 29626219Swpaul /* 29726219Swpaul * XDR the timestamp and possibly some other things, then 29826219Swpaul * encrypt them. 29926219Swpaul */ 30074462Salfred ixdr = (rpc_inline_t *)cryptbuf; 30174462Salfred IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec); 30274462Salfred IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec); 30326219Swpaul if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { 30474462Salfred IXDR_PUT_U_INT32(ixdr, ad->ad_window); 30574462Salfred IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1); 30626219Swpaul ivec.key.high = ivec.key.low = 0; 30726219Swpaul status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf, 30874462Salfred (u_int) 2 * sizeof (des_block), 30974462Salfred DES_ENCRYPT | DES_HW, (char *)&ivec); 31026219Swpaul } else { 31126219Swpaul status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf, 31274462Salfred (u_int) sizeof (des_block), 31374462Salfred DES_ENCRYPT | DES_HW); 31426219Swpaul } 31526219Swpaul if (DES_FAILED(status)) { 31674462Salfred syslog(LOG_ERR, "authdes_marshal: DES encryption failure"); 31726219Swpaul return (FALSE); 31826219Swpaul } 31926219Swpaul ad->ad_verf.adv_xtimestamp = cryptbuf[0]; 32026219Swpaul if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { 32126219Swpaul ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high; 32226219Swpaul ad->ad_verf.adv_winverf = cryptbuf[1].key.low; 32326219Swpaul } else { 32426219Swpaul ad->ad_cred.adc_nickname = ad->ad_nickname; 32526219Swpaul ad->ad_verf.adv_winverf = 0; 32626219Swpaul } 32726219Swpaul 32826219Swpaul /* 32926219Swpaul * Serialize the credential and verifier into opaque 33026219Swpaul * authentication data. 33126219Swpaul */ 33226219Swpaul if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { 33326219Swpaul len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen); 33426219Swpaul } else { 33526219Swpaul len = (1 + 1)*BYTES_PER_XDR_UNIT; 33626219Swpaul } 33726219Swpaul 33826219Swpaul if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { 33974462Salfred IXDR_PUT_INT32(ixdr, AUTH_DES); 34074462Salfred IXDR_PUT_INT32(ixdr, len); 34126219Swpaul } else { 34274462Salfred ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor)); 34374462Salfred ATTEMPT(xdr_putint32(xdrs, &len)); 34426219Swpaul } 34526219Swpaul ATTEMPT(xdr_authdes_cred(xdrs, cred)); 34626219Swpaul 34726219Swpaul len = (2 + 1)*BYTES_PER_XDR_UNIT; 34826219Swpaul if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { 34974462Salfred IXDR_PUT_INT32(ixdr, AUTH_DES); 35074462Salfred IXDR_PUT_INT32(ixdr, len); 35126219Swpaul } else { 35274462Salfred ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor)); 35374462Salfred ATTEMPT(xdr_putint32(xdrs, &len)); 35426219Swpaul } 35526219Swpaul ATTEMPT(xdr_authdes_verf(xdrs, verf)); 35626219Swpaul return (TRUE); 35726219Swpaul} 35826219Swpaul 35926219Swpaul 36026219Swpaul/* 36126219Swpaul * 3. Validate 36226219Swpaul */ 36326219Swpaulstatic bool_t 36474462Salfredauthdes_validate(AUTH *auth, struct opaque_auth *rverf) 36526219Swpaul{ 36674462Salfred/* LINTED pointer alignment */ 36726219Swpaul struct ad_private *ad = AUTH_PRIVATE(auth); 36826219Swpaul struct authdes_verf verf; 36926219Swpaul int status; 37092889Sobrien uint32_t *ixdr; 37174462Salfred des_block buf; 37226219Swpaul 37326219Swpaul if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) { 37426219Swpaul return (FALSE); 37526219Swpaul } 37674462Salfred/* LINTED pointer alignment */ 37774462Salfred ixdr = (uint32_t *)rverf->oa_base; 37874462Salfred buf.key.high = (uint32_t)*ixdr++; 37974462Salfred buf.key.low = (uint32_t)*ixdr++; 38074462Salfred verf.adv_int_u = (uint32_t)*ixdr++; 38126219Swpaul 38226219Swpaul /* 38326219Swpaul * Decrypt the timestamp 38426219Swpaul */ 38574462Salfred status = ecb_crypt((char *)&auth->ah_key, (char *)&buf, 38674462Salfred (u_int)sizeof (des_block), DES_DECRYPT | DES_HW); 38726219Swpaul 38826219Swpaul if (DES_FAILED(status)) { 38974462Salfred syslog(LOG_ERR, "authdes_validate: DES decryption failure"); 39026219Swpaul return (FALSE); 39126219Swpaul } 39226219Swpaul 39326219Swpaul /* 39474462Salfred * xdr the decrypted timestamp 39526219Swpaul */ 39674462Salfred/* LINTED pointer alignment */ 39774462Salfred ixdr = (uint32_t *)buf.c; 39874462Salfred verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1; 39974462Salfred verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr); 40026219Swpaul 40126219Swpaul /* 40226219Swpaul * validate 40326219Swpaul */ 40426219Swpaul if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, 40526219Swpaul sizeof(struct timeval)) != 0) { 40674462Salfred syslog(LOG_DEBUG, "authdes_validate: verifier mismatch"); 40726219Swpaul return (FALSE); 40826219Swpaul } 40926219Swpaul 41026219Swpaul /* 41126219Swpaul * We have a nickname now, let's use it 41226219Swpaul */ 41374462Salfred ad->ad_nickname = verf.adv_nickname; 41474462Salfred ad->ad_cred.adc_namekind = ADN_NICKNAME; 41574462Salfred return (TRUE); 41626219Swpaul} 41726219Swpaul 41826219Swpaul/* 41926219Swpaul * 4. Refresh 42026219Swpaul */ 42174462Salfred/*ARGSUSED*/ 42226219Swpaulstatic bool_t 42374462Salfredauthdes_refresh(AUTH *auth, void *dummy) 42426219Swpaul{ 42574462Salfred/* LINTED pointer alignment */ 42626219Swpaul struct ad_private *ad = AUTH_PRIVATE(auth); 42726219Swpaul struct authdes_cred *cred = &ad->ad_cred; 42874462Salfred int ok; 42926219Swpaul netobj pkey; 43026219Swpaul 43174462Salfred if (ad->ad_dosync) { 43274462Salfred ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr, 43374462Salfred ad->ad_timehost, &(ad->ad_uaddr), 43474462Salfred &(ad->ad_netid)); 43574462Salfred if (! ok) { 43674462Salfred /* 43774462Salfred * Hope the clocks are synced! 43874462Salfred */ 43974462Salfred ad->ad_dosync = 0; 44074462Salfred syslog(LOG_DEBUG, 44174462Salfred "authdes_refresh: unable to synchronize clock"); 44274462Salfred } 44326219Swpaul } 44426219Swpaul ad->ad_xkey = auth->ah_key; 44526219Swpaul pkey.n_bytes = (char *)(ad->ad_pkey); 44674462Salfred pkey.n_len = (u_int)strlen((char *)ad->ad_pkey) + 1; 44726219Swpaul if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) { 44874462Salfred syslog(LOG_INFO, 44974462Salfred "authdes_refresh: keyserv(1m) is unable to encrypt session key"); 45026219Swpaul return (FALSE); 45126219Swpaul } 45226219Swpaul cred->adc_fullname.key = ad->ad_xkey; 45326219Swpaul cred->adc_namekind = ADN_FULLNAME; 45426219Swpaul cred->adc_fullname.name = ad->ad_fullname; 45526219Swpaul return (TRUE); 45626219Swpaul} 45726219Swpaul 45826219Swpaul 45926219Swpaul/* 46026219Swpaul * 5. Destroy 46126219Swpaul */ 46226219Swpaulstatic void 46374462Salfredauthdes_destroy(AUTH *auth) 46426219Swpaul{ 46574462Salfred/* LINTED pointer alignment */ 46626219Swpaul struct ad_private *ad = AUTH_PRIVATE(auth); 46726219Swpaul 46826219Swpaul FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); 46926219Swpaul FREE(ad->ad_servername, ad->ad_servernamelen + 1); 47074462Salfred if (ad->ad_timehost) 47174462Salfred FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); 47274462Salfred if (ad->ad_netid) 47374462Salfred FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); 47474462Salfred if (ad->ad_uaddr) 47574462Salfred FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); 47674462Salfred FREE(ad, sizeof (struct ad_private)); 47726219Swpaul FREE(auth, sizeof(AUTH)); 47826219Swpaul} 47926219Swpaul 48074462Salfredstatic struct auth_ops * 48174462Salfredauthdes_ops(void) 48226219Swpaul{ 48374462Salfred static struct auth_ops ops; 48426219Swpaul 48574462Salfred /* VARIABLES PROTECTED BY ops_lock: ops */ 48674462Salfred 48774462Salfred mutex_lock(&authdes_ops_lock); 48874462Salfred if (ops.ah_nextverf == NULL) { 48974462Salfred ops.ah_nextverf = authdes_nextverf; 49074462Salfred ops.ah_marshal = authdes_marshal; 49174462Salfred ops.ah_validate = authdes_validate; 49274462Salfred ops.ah_refresh = authdes_refresh; 49374462Salfred ops.ah_destroy = authdes_destroy; 49474462Salfred } 49574462Salfred mutex_unlock(&authdes_ops_lock); 49674462Salfred return (&ops); 49726219Swpaul} 498