/*
 * Copyright (c) 2009, Sun Microsystems, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name of Sun Microsystems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Copyright (c) 1988 by Sun Microsystems, Inc.
 */
/*
 * auth_des.c, client-side implementation of DES authentication
 */

#ifndef __APPLE__

#include <config.h>
#include <pthread.h>
#include <reentrant.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/cdefs.h>
#include <rpc/des_crypt.h>
#include <rpc/types.h>
#include <rpc/auth.h>
#include <rpc/auth_des.h>
#include <rpc/clnt.h>
#include <rpc/xdr.h>
#include <sys/socket.h>
#undef NIS
#include <rpcsvc/nis.h>

#if defined(LIBC_SCCS) && !defined(lint)
#endif
#include <sys/cdefs.h>

#define USEC_PER_SEC  1000000
#define RTIME_TIMEOUT  5	/* seconds to wait for sync */

#define AUTH_PRIVATE(auth) ((struct ad_private *) (auth)->ah_private)
#define ALLOC(object_type) ((object_type *) mem_alloc(sizeof(object_type)))
#define FREE(ptr, size)  mem_free((char *)(ptr), (int) size)
#define ATTEMPT(xdr_op)  if (!(xdr_op)) return (false)

bool xdr_authdes_cred(XDR *, struct authdes_cred *);
bool xdr_authdes_verf(XDR *, struct authdes_verf *);

bool __rpc_get_time_offset(struct timeval *, nis_server *, char *,
			   char **, char **);

/*
 * DES authenticator operations vector
 */
static void authdes_nextverf(AUTH *);
static bool authdes_marshal(AUTH *, XDR *);
static bool authdes_validate(AUTH *, struct opaque_auth *);
static bool authdes_refresh(AUTH *, void *);
static void authdes_destroy(AUTH *);

static struct auth_ops *authdes_ops(void);

/*
 * This struct is pointed to by the ah_private field of an "AUTH *"
 */
struct ad_private {
	char *ad_fullname;	/* client's full name */
	u_int ad_fullnamelen;	/* length of name, rounded up */
	char *ad_servername;	/* server's full name */
	u_int ad_servernamelen;	/* length of name, rounded up */
	u_int ad_window;	/* client specified window */
	bool ad_dosync;		/* synchronize? */
	struct netbuf ad_syncaddr;	/* remote host to synch with */
	char *ad_timehost;	/* remote host to synch with */
	struct timeval ad_timediff;	/* server's time - client's time */
	u_int ad_nickname;	/* server's nickname for client */
	struct authdes_cred ad_cred;	/* storage for credential */
	struct authdes_verf ad_verf;	/* storage for verifier */
	struct timeval ad_timestamp;	/* timestamp sent */
	des_block ad_xkey;	/* encrypted conversation key */
	u_char ad_pkey[1024];	/* Server's actual public key */
	char *ad_netid;		/* Timehost netid */
	char *ad_uaddr;		/* Timehost uaddr */
	nis_server *ad_nis_srvr;	/* NIS+ server struct */
};

AUTH *
authdes_pk_nseccreate(const char *, netobj *, u_int, const char *,
		      const des_block *, nis_server *);

/*
 * documented version of authdes_nseccreate
 */
/*
  servername: network name of server
  win:  time to live
  timehost: optional hostname to sync with
  ckey:  optional conversation key to use
*/

AUTH *
authdes_nseccreate(const char *servername, const u_int win,
		   const char *timehost, const des_block *ckey)
{
	u_char pkey_data[1024];
	netobj pkey;
	AUTH *dummy;

	if (!getpublickey(servername, (char *)pkey_data)) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authdes_nseccreate: no public key found for %s",
			servername);
		return (NULL);
	}

	pkey.n_bytes = (char *)pkey_data;
	pkey.n_len = (u_int) strlen((char *)pkey_data) + 1;
	dummy =
	    authdes_pk_nseccreate(servername, &pkey, win, timehost, ckey, NULL);
	return (dummy);
}

/*
 * Slightly modified version of authdessec_create which takes the public key
 * of the server principal as an argument. This spares us a call to
 * getpublickey() which in the nameserver context can cause a deadlock.
 */
AUTH *
authdes_pk_nseccreate(const char *servername, netobj *pkey, u_int window,
		      const char *timehost, const des_block *ckey,
		      nis_server *srvr)
{
	AUTH *auth;
	struct ad_private *ad;
	char namebuf[MAXNETNAMELEN + 1];

	/*
	 * Allocate everything now
	 */
	auth = ALLOC(AUTH);
	if (auth == NULL) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authdes_pk_nseccreate: out of memory");
		return (NULL);
	}
	ad = ALLOC(struct ad_private);
	if (ad == NULL) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authdes_pk_nseccreate: out of memory");
		goto failed;
	}
	ad->ad_fullname = ad->ad_servername = NULL;	/* Sanity reasons */
	ad->ad_timehost = NULL;
	ad->ad_netid = NULL;
	ad->ad_uaddr = NULL;
	ad->ad_nis_srvr = NULL;
	ad->ad_timediff.tv_sec = 0;
	ad->ad_timediff.tv_usec = 0;
	memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len);
	if (!getnetname(namebuf))
		goto failed;
	ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf));
	ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
	ad->ad_servernamelen = strlen(servername);
	ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);

	if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authdes_nseccreate: out of memory");
		goto failed;
	}
	if (timehost != NULL) {
		ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1);
		if (ad->ad_timehost == NULL) {
			__warnx(TIRPC_DEBUG_FLAG_AUTH,
				"authdes_nseccreate: out of memory");
			goto failed;
		}
		memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
		ad->ad_dosync = true;
	} else if (srvr != NULL) {
		ad->ad_nis_srvr = srvr;	/* transient */
		ad->ad_dosync = true;
	} else {
		ad->ad_dosync = false;
	}
	memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
	memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1);
	ad->ad_window = window;
	if (ckey == NULL) {
		if (key_gendes(&auth->ah_key) < 0) {
			__warnx(TIRPC_DEBUG_FLAG_AUTH,
				"authdes_nseccreate: keyserv(1m) is unable to generate "
				"session key");
			goto failed;
		}
	} else {
		auth->ah_key = *ckey;
	}

	/*
	 * Set up auth handle
	 */
	auth->ah_cred.oa_flavor = AUTH_DES;
	auth->ah_verf.oa_flavor = AUTH_DES;
	auth->ah_ops = authdes_ops();
	auth->ah_private = (caddr_t) ad;

	if (!authdes_refresh(auth, NULL))
		goto failed;

	ad->ad_nis_srvr = NULL;	/* not needed any longer */
	auth_get(auth);		/* Reference for caller */
	return (auth);

 failed:
	if (auth)
		FREE(auth, sizeof(AUTH));
	if (ad) {
		if (ad->ad_fullname)
			FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
		if (ad->ad_servername)
			FREE(ad->ad_servername, ad->ad_servernamelen + 1);
		if (ad->ad_timehost)
			FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
		if (ad->ad_netid)
			FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
		if (ad->ad_uaddr)
			FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
		FREE(ad, sizeof(struct ad_private));
	}
	return (NULL);
}

/*
 * Implement the five authentication operations
 */

/*
 * 1. Next Verifier
 */
static void authdes_nextverf(AUTH *auth)
{
	/* what the heck am I supposed to do??? */
}

/*
 * 2. Marshal
 */
static bool
authdes_marshal(AUTH *auth, XDR *xdrs)
{
	/* LINTED pointer alignment */
	struct ad_private *ad = AUTH_PRIVATE(auth);
	struct authdes_cred *cred = &ad->ad_cred;
	struct authdes_verf *verf = &ad->ad_verf;
	des_block cryptbuf[2];
	des_block ivec;
	int status;
	int len;
	rpc_inline_t *ixdr;

	/*
	 * Figure out the "time", accounting for any time difference
	 * with the server if necessary.
	 */
	(void)gettimeofday(&ad->ad_timestamp, (struct timezone *)NULL);
	ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
	ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
	while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) {
		ad->ad_timestamp.tv_usec -= USEC_PER_SEC;
		ad->ad_timestamp.tv_sec++;
	}

	/*
	 * XDR the timestamp and possibly some other things, then
	 * encrypt them.
	 */
	ixdr = (rpc_inline_t *) cryptbuf;
	IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec);
	IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec);
	if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
		IXDR_PUT_U_INT32(ixdr, ad->ad_window);
		IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1);
		ivec.key.high = ivec.key.low = 0;
		status =
		    cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf,
			      (u_int) 2 * sizeof(des_block),
			      DES_ENCRYPT | DES_HW, (char *)&ivec);
	} else {
		status =
		    ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf,
			      (u_int) sizeof(des_block), DES_ENCRYPT | DES_HW);
	}
	if (DES_FAILED(status)) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authdes_marshal: DES encryption failure");
		return (false);
	}
	ad->ad_verf.adv_xtimestamp = cryptbuf[0];
	if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
		ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high;
		ad->ad_verf.adv_winverf = cryptbuf[1].key.low;
	} else {
		ad->ad_cred.adc_nickname = ad->ad_nickname;
		ad->ad_verf.adv_winverf = 0;
	}

	/*
	 * Serialize the credential and verifier into opaque
	 * authentication data.
	 */
	if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
		len =
		    ((1 + 1 + 2 + 1) * BYTES_PER_XDR_UNIT + ad->ad_fullnamelen);
	} else {
		len = (1 + 1) * BYTES_PER_XDR_UNIT;
	}

	ixdr = xdr_inline(xdrs, 2 * BYTES_PER_XDR_UNIT);
	if (ixdr) {
		IXDR_PUT_INT32(ixdr, AUTH_DES);
		IXDR_PUT_INT32(ixdr, len);
	} else {
		ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor));
		ATTEMPT(xdr_putint32(xdrs, &len));
	}
	ATTEMPT(xdr_authdes_cred(xdrs, cred));

	len = (2 + 1) * BYTES_PER_XDR_UNIT;
	ixdr = xdr_inline(xdrs, 2 * BYTES_PER_XDR_UNIT);
	if (ixdr) {
		IXDR_PUT_INT32(ixdr, AUTH_DES);
		IXDR_PUT_INT32(ixdr, len);
	} else {
		ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor));
		ATTEMPT(xdr_putint32(xdrs, &len));
	}
	ATTEMPT(xdr_authdes_verf(xdrs, verf));
	return (true);
}

/*
 * 3. Validate
 */
static bool
authdes_validate(AUTH *auth, struct opaque_auth *rverf)
{
	/* LINTED pointer alignment */
	struct ad_private *ad = AUTH_PRIVATE(auth);
	struct authdes_verf verf;
	int status;
	uint32_t *ixdr;
	des_block buf;

	if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT)
		return (false);

	/* LINTED pointer alignment */
	ixdr = (uint32_t *) rverf->oa_base;
	buf.key.high = (uint32_t) *ixdr++;
	buf.key.low = (uint32_t) *ixdr++;
	verf.adv_int_u = (uint32_t) *ixdr++;

	/*
	 * Decrypt the timestamp
	 */
	status =
	    ecb_crypt((char *)&auth->ah_key, (char *)&buf,
		      (u_int) sizeof(des_block), DES_DECRYPT | DES_HW);

	if (DES_FAILED(status)) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authdes_validate: DES decryption failure");
		return (false);
	}

	/*
	 * xdr the decrypted timestamp
	 */
	/* LINTED pointer alignment */
	ixdr = (uint32_t *) buf.c;
	verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1;
	verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr);

	/*
	 * validate
	 */
	if (bcmp
	    ((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp,
	     sizeof(struct timeval)) != 0) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authdes_validate: verifier mismatch");
		return (false);
	}

	/*
	 * We have a nickname now, let's use it
	 */
	ad->ad_nickname = verf.adv_nickname;
	ad->ad_cred.adc_namekind = ADN_NICKNAME;
	return (true);
}

/*
 * 4. Refresh
 */
 /*ARGSUSED*/
static bool
authdes_refresh(AUTH *auth, void *dummy)
{
/* LINTED pointer alignment */
	struct ad_private *ad = AUTH_PRIVATE(auth);
	struct authdes_cred *cred = &ad->ad_cred;
	int ok;
	netobj pkey;

	if (ad->ad_dosync) {
		ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr,
					   ad->ad_timehost, &(ad->ad_uaddr),
					   &(ad->ad_netid));
		if (!ok) {
			/*
			 * Hope the clocks are synced!
			 */
			ad->ad_dosync = 0;
			__warnx(TIRPC_DEBUG_FLAG_AUTH,
				"authdes_refresh: unable to synchronize clock");
		}
	}
	ad->ad_xkey = auth->ah_key;
	pkey.n_bytes = (char *)(ad->ad_pkey);
	pkey.n_len = (u_int) strlen((char *)ad->ad_pkey) + 1;
	if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authdes_refresh: keyserv(1m) is unable to encrypt "
			"session key");
		return (false);
	}
	cred->adc_fullname.key = ad->ad_xkey;
	cred->adc_namekind = ADN_FULLNAME;
	cred->adc_fullname.name = ad->ad_fullname;
	return (true);
}

/*
 * 5. Destroy
 */
static void
authdes_destroy(AUTH *auth)
{
/* LINTED pointer alignment */
	struct ad_private *ad = AUTH_PRIVATE(auth);

	FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
	FREE(ad->ad_servername, ad->ad_servernamelen + 1);
	if (ad->ad_timehost)
		FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
	if (ad->ad_netid)
		FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
	if (ad->ad_uaddr)
		FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
	FREE(ad, sizeof(struct ad_private));
	FREE(auth, sizeof(AUTH));
}

static bool
authdes_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xfunc,
	     caddr_t xwhere)
{
	return ((*xfunc) (xdrs, xwhere));
}

static struct auth_ops *
authdes_ops(void)
{
	static struct auth_ops ops;
	extern mutex_t authdes_ops_lock;

	/* VARIABLES PROTECTED BY ops_lock: ops */

	mutex_lock(&authdes_ops_lock);
	if (ops.ah_nextverf == NULL) {
		ops.ah_nextverf = authdes_nextverf;
		ops.ah_marshal = authdes_marshal;
		ops.ah_validate = authdes_validate;
		ops.ah_refresh = authdes_refresh;
		ops.ah_destroy = authdes_destroy;
		ops.ah_wrap = authdes_wrap;
		ops.ah_unwrap = authdes_wrap;
	}
	mutex_unlock(&authdes_ops_lock);
	return (&ops);
}

#endif
