/*
 * 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.
 *
 * svcauth_des.c, server-side des authentication
 *
 * We insure for the service the following:
 * (1) The timestamp microseconds do not exceed 1 million.
 * (2) The timestamp plus the window is less than the current time.
 * (3) The timestamp is not less than the one previously
 *     seen in the current session.
 *
 * It is up to the server to determine if the window size is
 * too small .
 *
 */

#include <limits.h>
#include <string.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_des.h>
#include <rpc/svc_auth.h>
#include <rpc/svc.h>
#include <rpc/des_crypt.h>

#define debug(msg)		/*printf("svcauth_des: %s\n", msg) */

#define USEC_PER_SEC ((uint32_t) 1000000L)
#define BEFORE(t1, t2) timercmp(t1, t2, <)

/*
 * LRU cache of conversation keys and some other useful items.
 */
#define AUTHDES_CACHESZ 64
struct cache_entry
  {
    des_block key;		/* conversation key */
    char *rname;		/* client's name */
    u_int window;		/* credential lifetime window */
    struct rpc_timeval laststamp;	/* detect replays of creds */
    char *localcred;		/* generic local credential */
  };
#ifdef _RPC_THREAD_SAFE_
#define authdes_cache RPC_THREAD_VARIABLE(authdes_cache_s)
#define authdes_lru RPC_THREAD_VARIABLE(authdes_lru_s)
#else
static struct cache_entry *authdes_cache;
static int *authdes_lru;
#endif

static void cache_init (void) internal_function; /* initialize the cache */
static short cache_spot (des_block *, char *, struct rpc_timeval *)
     internal_function;		/* find an entry in the cache */
static void cache_ref (uint32_t sid) internal_function;
				/* note that sid was ref'd */

static void invalidate (char *cred) internal_function;
				/* invalidate entry in cache */

/*
 * cache statistics
 */
struct
  {
    u_long ncachehits;		/* times cache hit, and is not replay */
    u_long ncachereplays;	/* times cache hit, and is replay */
    u_long ncachemisses;	/* times cache missed */
  }
svcauthdes_stats;

/*
 * Service side authenticator for AUTH_DES
 */
enum auth_stat
_svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg)
{
  register uint32_t *ixdr;
  des_block cryptbuf[2];
  register struct authdes_cred *cred;
  struct authdes_verf verf;
  int status;
  register struct cache_entry *entry;
  uint32_t sid = 0;
  des_block *sessionkey;
  des_block ivec;
  u_int window;
  struct rpc_timeval timestamp;
  uint32_t namelen;
  struct area
    {
      struct authdes_cred area_cred;
      char area_netname[MAXNETNAMELEN + 1];
    }
   *area;

  if (authdes_cache == NULL)
    cache_init ();
  if (authdes_cache == NULL) /* No free memory */
    return AUTH_FAILED;

  area = (struct area *) rqst->rq_clntcred;
  cred = (struct authdes_cred *) &area->area_cred;

  /*
   * Get the credential
   */
  if (msg->rm_call.cb_cred.oa_length <= 0 ||
      msg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES)
    return AUTH_BADCRED;

  ixdr = (uint32_t *) msg->rm_call.cb_cred.oa_base;
  cred->adc_namekind = IXDR_GET_ENUM (ixdr, enum authdes_namekind);
  switch (cred->adc_namekind)
    {
    case ADN_FULLNAME:
      namelen = IXDR_GET_U_INT32 (ixdr);
      if (namelen > MAXNETNAMELEN)
	{
	  return AUTH_BADCRED;
	}
      cred->adc_fullname.name = area->area_netname;
      memcpy (cred->adc_fullname.name, (char *) ixdr, namelen);
      cred->adc_fullname.name[namelen] = 0;
      ixdr += (RNDUP (namelen) / BYTES_PER_XDR_UNIT);
      cred->adc_fullname.key.key.high = *ixdr++;
      cred->adc_fullname.key.key.low = *ixdr++;
      cred->adc_fullname.window = *ixdr++;
      break;
    case ADN_NICKNAME:
      cred->adc_nickname = *ixdr++;
      break;
    default:
      return AUTH_BADCRED;
    }

  /*
   * Get the verifier
   */
  if (msg->rm_call.cb_verf.oa_length <= 0 ||
      msg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES)
    return AUTH_BADCRED;

  ixdr = (uint32_t *) msg->rm_call.cb_verf.oa_base;
  verf.adv_xtimestamp.key.high = *ixdr++;
  verf.adv_xtimestamp.key.low = *ixdr++;
  verf.adv_int_u = *ixdr++;

  /*
   * Get the conversation key
   */
  if (cred->adc_namekind == ADN_FULLNAME)
    {
      netobj pkey;
      char pkey_data[1024];

      sessionkey = &cred->adc_fullname.key;
      if (!getpublickey (cred->adc_fullname.name, pkey_data))
	{
	  debug("getpublickey");
	  return AUTH_BADCRED;
	}
      pkey.n_bytes = pkey_data;
      pkey.n_len = strlen (pkey_data) + 1;
      if (key_decryptsession_pk (cred->adc_fullname.name, &pkey,
				 sessionkey) < 0)
	{
	  debug ("decryptsessionkey");
	  return AUTH_BADCRED;	/* key not found */
	}
    }
  else
    {				/* ADN_NICKNAME */
      if (cred->adc_nickname >= AUTHDES_CACHESZ)
	{
	  debug ("bad nickname");
	  return AUTH_BADCRED;	/* garbled credential */
	}
      else
	sid = cred->adc_nickname;

      /* XXX This could be wrong, but else we have a
	 security problem */
      if (authdes_cache[sid].rname == NULL)
	return AUTH_BADCRED;
      sessionkey = &authdes_cache[sid].key;
    }


  /*
   * Decrypt the timestamp
   */
  cryptbuf[0] = verf.adv_xtimestamp;
  if (cred->adc_namekind == ADN_FULLNAME)
    {
      cryptbuf[1].key.high = cred->adc_fullname.window;
      cryptbuf[1].key.low = verf.adv_winverf;
      ivec.key.high = ivec.key.low = 0;
      status = cbc_crypt ((char *) sessionkey, (char *) cryptbuf,
			  2 * sizeof (des_block), DES_DECRYPT | DES_HW,
			  (char *) &ivec);
    }
  else
    status = ecb_crypt ((char *) sessionkey, (char *) cryptbuf,
			sizeof (des_block), DES_DECRYPT | DES_HW);

  if (DES_FAILED (status))
    {
      debug ("decryption failure");
      return AUTH_FAILED;	/* system error */
    }

  /*
   * XDR the decrypted timestamp
   */
  ixdr = (uint32_t *) cryptbuf;
  timestamp.tv_sec = IXDR_GET_INT32 (ixdr);
  timestamp.tv_usec = IXDR_GET_INT32 (ixdr);

  /*
   * Check for valid credentials and verifiers.
   * They could be invalid because the key was flushed
   * out of the cache, and so a new session should begin.
   * Be sure and send AUTH_REJECTED{CRED, VERF} if this is the case.
   */
  {
    struct timeval current;
    int nick;
    u_int winverf;

    if (cred->adc_namekind == ADN_FULLNAME)
      {
	short tmp_spot;

	window = IXDR_GET_U_INT32 (ixdr);
	winverf = IXDR_GET_U_INT32 (ixdr);
	if (winverf != window - 1)
	  {
	    debug ("window verifier mismatch");
	    return AUTH_BADCRED;	/* garbled credential */
	  }
	tmp_spot = cache_spot (sessionkey, cred->adc_fullname.name,
			       &timestamp);
	if (tmp_spot < 0 || tmp_spot > AUTHDES_CACHESZ)
	  {
	    debug ("replayed credential");
	    return AUTH_REJECTEDCRED;		/* replay */
	  }
	sid = tmp_spot;
	nick = 0;
      }
    else
      {				/* ADN_NICKNAME */
	window = authdes_cache[sid].window;
	nick = 1;
      }

    if (timestamp.tv_usec >= USEC_PER_SEC)
      {
	debug ("invalid usecs");
	/* cached out (bad key), or garbled verifier */
	return nick ? AUTH_REJECTEDVERF : AUTH_BADVERF;
      }
    if (nick && BEFORE (&timestamp, &authdes_cache[sid].laststamp))
      {
	debug ("timestamp before last seen");
	return AUTH_REJECTEDVERF;	/* replay */
      }
    __gettimeofday (&current, (struct timezone *) NULL);
    current.tv_sec -= window;	/* allow for expiration */
    if (!BEFORE (&current, &timestamp))
      {
	debug ("timestamp expired");
	/* replay, or garbled credential */
	return nick ? AUTH_REJECTEDVERF : AUTH_BADCRED;
      }
  }

  /*
   * Set up the reply verifier
   */
  verf.adv_nickname = sid;

  /*
   * xdr the timestamp before encrypting
   */
  ixdr = (uint32_t *) cryptbuf;
  IXDR_PUT_INT32 (ixdr, timestamp.tv_sec - 1);
  IXDR_PUT_INT32 (ixdr, timestamp.tv_usec);

  /*
   * encrypt the timestamp
   */
  status = ecb_crypt ((char *) sessionkey, (char *) cryptbuf,
		      sizeof (des_block), DES_ENCRYPT | DES_HW);
  if (DES_FAILED (status))
    {
      debug ("encryption failure");
      return AUTH_FAILED;	/* system error */
    }
  verf.adv_xtimestamp = cryptbuf[0];

  /*
   * Serialize the reply verifier, and update rqst
   */
  ixdr = (uint32_t *) msg->rm_call.cb_verf.oa_base;
  *ixdr++ = verf.adv_xtimestamp.key.high;
  *ixdr++ = verf.adv_xtimestamp.key.low;
  *ixdr++ = verf.adv_int_u;

  rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES;
  rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
  rqst->rq_xprt->xp_verf.oa_length =
    (char *) ixdr - msg->rm_call.cb_verf.oa_base;

  /*
   * We succeeded, commit the data to the cache now and
   * finish cooking the credential.
   */
  entry = &authdes_cache[sid];
  entry->laststamp = timestamp;
  cache_ref (sid);
  if (cred->adc_namekind == ADN_FULLNAME)
    {
      size_t full_len;

      cred->adc_fullname.window = window;
      cred->adc_nickname = sid;	/* save nickname */
      if (entry->rname != NULL)
	mem_free (entry->rname, strlen (entry->rname) + 1);
      full_len = strlen (cred->adc_fullname.name) + 1;
      entry->rname = mem_alloc ((u_int) full_len);
      if (entry->rname != NULL)
	memcpy (entry->rname, cred->adc_fullname.name, full_len);
      else
	{
	  debug ("out of memory");
	  return AUTH_FAILED; /* out of memory is bad */
	}
      entry->key = *sessionkey;
      entry->window = window;
      invalidate (entry->localcred);	/* mark any cached cred invalid */
    }
  else
    {				/* ADN_NICKNAME */
      /*
       * nicknames are cooked into fullnames
       */
      cred->adc_namekind = ADN_FULLNAME;
      cred->adc_fullname.name = entry->rname;
      cred->adc_fullname.key = entry->key;
      cred->adc_fullname.window = entry->window;
    }
  return AUTH_OK;		/* we made it! */
}


/*
 * Initialize the cache
 */
static void
internal_function
cache_init (void)
{
  register int i;

  authdes_cache = (struct cache_entry *)
    calloc (sizeof (struct cache_entry) * AUTHDES_CACHESZ, 1);
  if (authdes_cache == NULL)
    return;

  authdes_lru = (int *) mem_alloc (sizeof (int) * AUTHDES_CACHESZ);
  /*
   * Initialize the lru list
   */
  for (i = 0; i < AUTHDES_CACHESZ; ++i)
    authdes_lru[i] = i;
}


/*
 * Find the lru victim
 */
static short
cache_victim (void)
{
  return authdes_lru[AUTHDES_CACHESZ - 1];
}

/*
 * Note that sid was referenced
 */
static void
internal_function
cache_ref (register uint32_t sid)
{
  register int i;
  register int curr;
  register int prev;

  prev = authdes_lru[0];
  authdes_lru[0] = sid;
  for (i = 1; prev != sid; ++i)
    {
      curr = authdes_lru[i];
      authdes_lru[i] = prev;
      prev = curr;
    }
}

/*
 * Find a spot in the cache for a credential containing
 * the items given.  Return -1 if a replay is detected, otherwise
 * return the spot in the cache.
 */
static short
internal_function
cache_spot (register des_block *key, char *name,
	    struct rpc_timeval *timestamp)
{
  register struct cache_entry *cp;
  register int i;
  register uint32_t hi;

  hi = key->key.high;
  for (cp = authdes_cache, i = 0; i < AUTHDES_CACHESZ; ++i, ++cp)
    {
      if (cp->key.key.high == hi &&
	  cp->key.key.low == key->key.low &&
	  cp->rname != NULL &&
	  memcmp (cp->rname, name, strlen (name) + 1) == 0)
	{
	  if (BEFORE (timestamp, &cp->laststamp))
	    {
	      ++svcauthdes_stats.ncachereplays;
	      return -1;	/* replay */
	    }
	  ++svcauthdes_stats.ncachehits;
	  return i;		/* refresh */
	}
    }
  ++svcauthdes_stats.ncachemisses;
  return cache_victim ();	/* new credential */
}

/*
 * Local credential handling stuff.
 * NOTE: bsd unix dependent.
 * Other operating systems should put something else here.
 */
#define UNKNOWN 	-2	/* grouplen, if cached cred is unknown user */
#define INVALID		-1	/* grouplen, if cache entry is invalid */

struct bsdcred
{
  uid_t uid;			/* cached uid */
  gid_t gid;			/* cached gid */
  int grouplen;			/* length of cached groups */
  int grouplen_max;		/* length of allocated cached groups */
  gid_t groups[0];		/* cached groups */
};

/*
 * Map a des credential into a unix cred.
 * We cache the credential here so the application does
 * not have to make an rpc call every time to interpret
 * the credential.
 */
int
authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
		  short *grouplen, gid_t * groups)
{
  unsigned sid;
  register int i;
  uid_t i_uid;
  gid_t i_gid;
  int i_grouplen;
  struct bsdcred *cred;

  sid = adc->adc_nickname;
  if (sid >= AUTHDES_CACHESZ)
    {
      debug ("invalid nickname");
      return 0;
    }
  cred = (struct bsdcred *) authdes_cache[sid].localcred;
  if (cred == NULL || cred->grouplen == INVALID)
    {
      /*
       * not in cache: lookup
       */
      if (!netname2user (adc->adc_fullname.name, &i_uid, &i_gid,
			 &i_grouplen, groups))
	{
	  debug ("unknown netname");
	  if (cred != NULL)
	    cred->grouplen = UNKNOWN;	/* mark as lookup up, but not found */
	  return 0;
	}

      if (cred != NULL && cred->grouplen_max < i_grouplen)
	{
	  /* We already have an allocated data structure.  But it is
	     too small.  */
	  free (cred);
	  authdes_cache[sid].localcred = NULL;
	  cred = NULL;
	}

      if (cred == NULL)
	{
	  /* We should allocate room for at least NGROUPS groups.  */
	  int ngroups_max = MAX (i_grouplen, NGROUPS);

	  cred = (struct bsdcred *) mem_alloc (sizeof (struct bsdcred)
					       + ngroups_max * sizeof (gid_t));
	  if (cred == NULL)
	    return 0;

	  authdes_cache[sid].localcred = (char *) cred;
	  cred->grouplen = INVALID;
	  cred->grouplen_max = ngroups_max;
	}

      debug ("missed ucred cache");
      *uid = cred->uid = i_uid;
      *gid = cred->gid = i_gid;
      cred->grouplen = i_grouplen;
      for (i = i_grouplen - 1; i >= 0; --i)
	cred->groups[i] = groups[i];
      /* Make sure no too large values are reported.  */
      *grouplen = MIN (SHRT_MAX, i_grouplen);
      return 1;
    }
  else if (cred->grouplen == UNKNOWN)
    {
      /*
       * Already lookup up, but no match found
       */
      return 0;
    }

  /*
   * cached credentials
   */
  *uid = cred->uid;
  *gid = cred->gid;

  /* Another stupidity in the interface: *grouplen is of type short.
     So we might have to cut the information passed up short.  */
  int grouplen_copy = MIN (SHRT_MAX, cred->grouplen);
  *grouplen = grouplen_copy;
  for (i = grouplen_copy - 1; i >= 0; --i)
    groups[i] = cred->groups[i];
  return 1;
}

static void
internal_function
invalidate (char *cred)
{
  if (cred == NULL)
    return;
  ((struct bsdcred *) cred)->grouplen = INVALID;
}
