/*
 * Copyright (c) 2010, Oracle America, Inc.
 *
 * 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 the "Oracle America, 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.
 */
/*
 * The original source is from the RPCSRC 4.0 package from Sun Microsystems.
 * The Interface to keyserver protocoll 2, RPC over AF_UNIX and Linux/doors
 * was added by Thorsten Kukuk <kukuk@suse.de>
 * Since the Linux/doors project was stopped, I doubt that this code will
 * ever be useful <kukuk@suse.de>.
 */

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/auth.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <rpc/key_prot.h>
#include <bits/libc-lock.h>

#define KEY_TIMEOUT	5	/* per-try timeout in seconds */
#define KEY_NRETRY	12	/* number of retries */

#define debug(msg)		/* turn off debugging */

#ifndef SO_PASSCRED
extern int _openchild (const char *command, FILE **fto, FILE **ffrom);
#endif

static int key_call (u_long, xdrproc_t xdr_arg, char *,
		     xdrproc_t xdr_rslt, char *) internal_function;

static const struct timeval trytimeout = {KEY_TIMEOUT, 0};
static const struct timeval tottimeout = {KEY_TIMEOUT *KEY_NRETRY, 0};

int
key_setsecret (char *secretkey)
{
  keystatus status;

  if (!key_call ((u_long) KEY_SET, (xdrproc_t) xdr_keybuf, secretkey,
		 (xdrproc_t) xdr_keystatus, (char *) &status))
    return -1;
  if (status != KEY_SUCCESS)
    {
      debug ("set status is nonzero");
      return -1;
    }
  return 0;
}
libc_hidden_nolink_sunrpc (key_setsecret, GLIBC_2_1)

/* key_secretkey_is_set() returns 1 if the keyserver has a secret key
 * stored for the caller's effective uid; it returns 0 otherwise
 *
 * N.B.:  The KEY_NET_GET key call is undocumented.  Applications shouldn't
 * be using it, because it allows them to get the user's secret key.
 */
int
key_secretkey_is_set (void)
{
  struct key_netstres kres;

  memset (&kres, 0, sizeof (kres));
  if (key_call ((u_long) KEY_NET_GET, (xdrproc_t) xdr_void,
		(char *) NULL, (xdrproc_t) xdr_key_netstres,
		(char *) &kres) &&
      (kres.status == KEY_SUCCESS) &&
      (kres.key_netstres_u.knet.st_priv_key[0] != 0))
    {
      /* avoid leaving secret key in memory */
      memset (kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
      return 1;
    }
  return 0;
}
#ifdef EXPORT_RPC_SYMBOLS
libc_hidden_def (key_secretkey_is_set)
#else
libc_hidden_nolink_sunrpc (key_secretkey_is_set, GLIBC_2_1)
#endif

int
key_encryptsession (char *remotename, des_block *deskey)
{
  cryptkeyarg arg;
  cryptkeyres res;

  arg.remotename = remotename;
  arg.deskey = *deskey;
  if (!key_call ((u_long) KEY_ENCRYPT, (xdrproc_t) xdr_cryptkeyarg,
		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
		 (char *) &res))
    return -1;

  if (res.status != KEY_SUCCESS)
    {
      debug ("encrypt status is nonzero");
      return -1;
    }
  *deskey = res.cryptkeyres_u.deskey;
  return 0;
}
libc_hidden_nolink_sunrpc (key_encryptsession, GLIBC_2_1)

int
key_decryptsession (char *remotename, des_block *deskey)
{
  cryptkeyarg arg;
  cryptkeyres res;

  arg.remotename = remotename;
  arg.deskey = *deskey;
  if (!key_call ((u_long) KEY_DECRYPT, (xdrproc_t) xdr_cryptkeyarg,
		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
		 (char *) &res))
    return -1;
  if (res.status != KEY_SUCCESS)
    {
      debug ("decrypt status is nonzero");
      return -1;
    }
  *deskey = res.cryptkeyres_u.deskey;
  return 0;
}
libc_hidden_nolink_sunrpc (key_decryptsession, GLIBC_2_1)

int
key_encryptsession_pk (char *remotename, netobj *remotekey,
		       des_block *deskey)
{
  cryptkeyarg2 arg;
  cryptkeyres res;

  arg.remotename = remotename;
  arg.remotekey = *remotekey;
  arg.deskey = *deskey;
  if (!key_call ((u_long) KEY_ENCRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
		 (char *) &res))
    return -1;

  if (res.status != KEY_SUCCESS)
    {
      debug ("encrypt status is nonzero");
      return -1;
    }
  *deskey = res.cryptkeyres_u.deskey;
  return 0;
}
libc_hidden_nolink_sunrpc (key_encryptsession_pk, GLIBC_2_1)

int
key_decryptsession_pk (char *remotename, netobj *remotekey,
		       des_block *deskey)
{
  cryptkeyarg2 arg;
  cryptkeyres res;

  arg.remotename = remotename;
  arg.remotekey = *remotekey;
  arg.deskey = *deskey;
  if (!key_call ((u_long) KEY_DECRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
		 (char *) &res))
    return -1;

  if (res.status != KEY_SUCCESS)
    {
      debug ("decrypt status is nonzero");
      return -1;
    }
  *deskey = res.cryptkeyres_u.deskey;
  return 0;
}
libc_hidden_nolink_sunrpc (key_decryptsession_pk, GLIBC_2_1)

int
key_gendes (des_block *key)
{
  struct sockaddr_in sin;
  CLIENT *client;
  int socket;
  enum clnt_stat stat;

  sin.sin_family = AF_INET;
  sin.sin_port = 0;
  sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
  __bzero (sin.sin_zero, sizeof (sin.sin_zero));
  socket = RPC_ANYSOCK;
  client = clntudp_bufcreate (&sin, (u_long) KEY_PROG, (u_long) KEY_VERS,
			      trytimeout, &socket, RPCSMALLMSGSIZE,
			      RPCSMALLMSGSIZE);
  if (client == NULL)
    return -1;

  stat = clnt_call (client, KEY_GEN, (xdrproc_t) xdr_void, NULL,
		    (xdrproc_t) xdr_des_block, (caddr_t) key,
		    tottimeout);
  clnt_destroy (client);
  __close (socket);
  if (stat != RPC_SUCCESS)
    return -1;

  return 0;
}
#ifdef EXPORT_RPC_SYMBOLS
libc_hidden_def (key_gendes)
#else
libc_hidden_nolink_sunrpc (key_gendes, GLIBC_2_1)
#endif

int
key_setnet (struct key_netstarg *arg)
{
  keystatus status;

  if (!key_call ((u_long) KEY_NET_PUT, (xdrproc_t) xdr_key_netstarg,
		 (char *) arg,(xdrproc_t) xdr_keystatus,
		 (char *) &status))
    return -1;

  if (status != KEY_SUCCESS)
    {
      debug ("key_setnet status is nonzero");
      return -1;
    }
  return 1;
}
libc_hidden_nolink_sunrpc (key_setnet, GLIBC_2_1)

int
key_get_conv (char *pkey, des_block *deskey)
{
  cryptkeyres res;

  if (!key_call ((u_long) KEY_GET_CONV, (xdrproc_t) xdr_keybuf, pkey,
		 (xdrproc_t) xdr_cryptkeyres, (char *) &res))
    return -1;

  if (res.status != KEY_SUCCESS)
    {
      debug ("get_conv status is nonzero");
      return -1;
    }
  *deskey = res.cryptkeyres_u.deskey;
  return 0;
}
libc_hidden_nolink_sunrpc (key_get_conv, GLIBC_2_1)

/*
 * Hack to allow the keyserver to use AUTH_DES (for authenticated
 * NIS+ calls, for example).  The only functions that get called
 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
 *
 * The approach is to have the keyserver fill in pointers to local
 * implementations of these functions, and to call those in key_call().
 */

cryptkeyres *(*__key_encryptsession_pk_LOCAL) (uid_t, char *);
cryptkeyres *(*__key_decryptsession_pk_LOCAL) (uid_t, char *);
des_block *(*__key_gendes_LOCAL) (uid_t, char *);

#ifndef SO_PASSCRED
static int
internal_function
key_call_keyenvoy (u_long proc, xdrproc_t xdr_arg, char *arg,
		   xdrproc_t xdr_rslt, char *rslt)
{
  XDR xdrargs;
  XDR xdrrslt;
  FILE *fargs;
  FILE *frslt;
  sigset_t oldmask, mask;
  union wait status;
  int pid;
  int success;
  uid_t ruid;
  uid_t euid;
  static const char MESSENGER[] = "/usr/etc/keyenvoy";

  success = 1;
  sigemptyset (&mask);
  sigaddset (&mask, SIGCHLD);
  __sigprocmask (SIG_BLOCK, &mask, &oldmask);

  /*
   * We are going to exec a set-uid program which makes our effective uid
   * zero, and authenticates us with our real uid. We need to make the
   * effective uid be the real uid for the setuid program, and
   * the real uid be the effective uid so that we can change things back.
   */
  euid = __geteuid ();
  ruid = __getuid ();
  __setreuid (euid, ruid);
  pid = _openchild (MESSENGER, &fargs, &frslt);
  __setreuid (ruid, euid);
  if (pid < 0)
    {
      debug ("open_streams");
      __sigprocmask (SIG_SETMASK, &oldmask, NULL);
      return (0);
    }
  xdrstdio_create (&xdrargs, fargs, XDR_ENCODE);
  xdrstdio_create (&xdrrslt, frslt, XDR_DECODE);

  if (!xdr_u_long (&xdrargs, &proc) || !(*xdr_arg) (&xdrargs, arg))
    {
      debug ("xdr args");
      success = 0;
    }
  fclose (fargs);

  if (success && !(*xdr_rslt) (&xdrrslt, rslt))
    {
      debug ("xdr rslt");
      success = 0;
    }
  fclose(frslt);

 wait_again:
  if (__wait4 (pid, &status, 0, NULL) < 0)
    {
      if (errno == EINTR)
	goto wait_again;
      debug ("wait4");
      if (errno == ECHILD || errno == ESRCH)
	perror ("wait");
      else
	success = 0;
    }
  else
    if (status.w_retcode)
      {
	debug ("wait4 1");
	success = 0;
      }
  __sigprocmask (SIG_SETMASK, &oldmask, NULL);

  return success;
}
#endif

struct  key_call_private {
  CLIENT  *client;        /* Client handle */
  pid_t   pid;            /* process-id at moment of creation */
  uid_t   uid;            /* user-id at last authorization */
};
#ifdef _RPC_THREAD_SAFE_
#define key_call_private_main RPC_THREAD_VARIABLE(key_call_private_s)
#else
static struct key_call_private *key_call_private_main;
#endif
__libc_lock_define_initialized (static, keycall_lock)

/*
 * Keep the handle cached.  This call may be made quite often.
 */
static CLIENT *
getkeyserv_handle (int vers)
{
  struct key_call_private *kcp = key_call_private_main;
  struct timeval wait_time;
  int fd;
  struct sockaddr_un name;
  socklen_t namelen = sizeof(struct sockaddr_un);

#define TOTAL_TIMEOUT   30      /* total timeout talking to keyserver */
#define TOTAL_TRIES     5       /* Number of tries */

  if (kcp == (struct key_call_private *)NULL)
    {
      kcp = (struct key_call_private *)malloc (sizeof (*kcp));
      if (kcp == (struct key_call_private *)NULL)
	return (CLIENT *) NULL;

      key_call_private_main = kcp;
      kcp->client = NULL;
    }

  /* if pid has changed, destroy client and rebuild */
  if (kcp->client != NULL && kcp->pid != __getpid ())
    {
      auth_destroy (kcp->client->cl_auth);
      clnt_destroy (kcp->client);
      kcp->client = NULL;
    }

  if (kcp->client != NULL)
    {
      /* if other side closed socket, build handle again */
      clnt_control (kcp->client, CLGET_FD, (char *)&fd);
      if (__getpeername (fd,(struct sockaddr *)&name,&namelen) == -1)
	{
	  auth_destroy (kcp->client->cl_auth);
	  clnt_destroy (kcp->client);
	  kcp->client = NULL;
	}
    }

  if (kcp->client != NULL)
    {
      /* if uid has changed, build client handle again */
      if (kcp->uid != __geteuid ())
	{
	kcp->uid = __geteuid ();
	auth_destroy (kcp->client->cl_auth);
	kcp->client->cl_auth =
	  authunix_create ((char *)"", kcp->uid, 0, 0, NULL);
	if (kcp->client->cl_auth == NULL)
	  {
	    clnt_destroy (kcp->client);
	    kcp->client = NULL;
	    return ((CLIENT *) NULL);
	  }
	}
      /* Change the version number to the new one */
      clnt_control (kcp->client, CLSET_VERS, (void *)&vers);
      return kcp->client;
    }

  if ((kcp->client == (CLIENT *) NULL))
    /* Use the AF_UNIX transport */
    kcp->client = clnt_create ("/var/run/keyservsock", KEY_PROG, vers, "unix");

  if (kcp->client == (CLIENT *) NULL)
    return (CLIENT *) NULL;

  kcp->uid = __geteuid ();
  kcp->pid = __getpid ();
  kcp->client->cl_auth = authunix_create ((char *)"", kcp->uid, 0, 0, NULL);
  if (kcp->client->cl_auth == NULL)
    {
      clnt_destroy (kcp->client);
      kcp->client = NULL;
      return (CLIENT *) NULL;
    }

  wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
  wait_time.tv_usec = 0;
  clnt_control (kcp->client, CLSET_RETRY_TIMEOUT,
		(char *)&wait_time);
  if (clnt_control (kcp->client, CLGET_FD, (char *)&fd))
    __fcntl (fd, F_SETFD, FD_CLOEXEC);  /* make it "close on exec" */

  return kcp->client;
}

/* returns  0 on failure, 1 on success */
static int
internal_function
key_call_socket (u_long proc, xdrproc_t xdr_arg, char *arg,
	       xdrproc_t xdr_rslt, char *rslt)
{
  CLIENT *clnt;
  struct timeval wait_time;
  int result = 0;

  __libc_lock_lock (keycall_lock);
  if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
      (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
      (proc == KEY_GET_CONV))
    clnt = getkeyserv_handle(2); /* talk to version 2 */
  else
    clnt = getkeyserv_handle(1); /* talk to version 1 */

  if (clnt != NULL)
    {
      wait_time.tv_sec = TOTAL_TIMEOUT;
      wait_time.tv_usec = 0;

      if (clnt_call (clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
		     wait_time) == RPC_SUCCESS)
	result = 1;
    }

  __libc_lock_unlock (keycall_lock);

  return result;
}


/* returns 0 on failure, 1 on success */
static int
internal_function
key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
	  xdrproc_t xdr_rslt, char *rslt)
{
#ifndef SO_PASSCRED
  static int use_keyenvoy;
#endif

  if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL)
    {
      cryptkeyres *res;
      res = (*__key_encryptsession_pk_LOCAL) (__geteuid (), arg);
      *(cryptkeyres *) rslt = *res;
      return 1;
    }
  else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL)
    {
      cryptkeyres *res;
      res = (*__key_decryptsession_pk_LOCAL) (__geteuid (), arg);
      *(cryptkeyres *) rslt = *res;
      return 1;
    }
  else if (proc == KEY_GEN && __key_gendes_LOCAL)
    {
      des_block *res;
      res = (*__key_gendes_LOCAL) (__geteuid (), 0);
      *(des_block *) rslt = *res;
      return 1;
    }

#ifdef SO_PASSCRED
  return key_call_socket (proc, xdr_arg, arg, xdr_rslt, rslt);
#else
  if (!use_keyenvoy)
    {
      if (key_call_socket (proc, xdr_arg, arg, xdr_rslt, rslt))
	return 1;
      use_keyenvoy = 1;
    }
  return key_call_keyenvoy (proc, xdr_arg, arg, xdr_rslt, rslt);
#endif
}

#ifdef _RPC_THREAD_SAFE_
void
__rpc_thread_key_cleanup (void)
{
	struct key_call_private *kcp = RPC_THREAD_VARIABLE(key_call_private_s);

	if (kcp) {
		if (kcp->client) {
			if (kcp->client->cl_auth)
				auth_destroy (kcp->client->cl_auth);
			clnt_destroy(kcp->client);
		}
		free (kcp);
	}
}
#endif /* _RPC_THREAD_SAFE_ */
