/*
 * rpc_prot.c
 *
 * 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.
 *
 * This set of routines implements the rpc message definition,
 * its serializer and some common rpc utility routines.
 * The routines are meant for various implementations of rpc -
 * they are NOT for the rpc client or rpc service implementations!
 * Because authentication stuff is easy and is part of rpc, the opaque
 * routines are also in this program.
 */

#include <sys/param.h>
#include <rpc/rpc.h>
#include <shlib-compat.h>

/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */

/*
 * XDR an opaque authentication struct
 * (see auth.h)
 */
bool_t
xdr_opaque_auth (XDR *xdrs, struct opaque_auth *ap)
{

  if (xdr_enum (xdrs, &(ap->oa_flavor)))
    return xdr_bytes (xdrs, &ap->oa_base,
		      &ap->oa_length, MAX_AUTH_BYTES);
  return FALSE;
}
libc_hidden_nolink_sunrpc (xdr_opaque_auth, GLIBC_2_0)

/*
 * XDR a DES block
 */
bool_t
xdr_des_block (XDR *xdrs, des_block *blkp)
{
  return xdr_opaque (xdrs, (caddr_t) blkp, sizeof (des_block));
}
libc_hidden_nolink_sunrpc (xdr_des_block, GLIBC_2_0)

/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */

/*
 * XDR the MSG_ACCEPTED part of a reply message union
 */
bool_t
xdr_accepted_reply (XDR *xdrs, struct accepted_reply *ar)
{
  /* personalized union, rather than calling xdr_union */
  if (!xdr_opaque_auth (xdrs, &(ar->ar_verf)))
    return FALSE;
  if (!xdr_enum (xdrs, (enum_t *) & (ar->ar_stat)))
    return FALSE;
  switch (ar->ar_stat)
    {
    case SUCCESS:
      return ((*(ar->ar_results.proc)) (xdrs, ar->ar_results.where));
    case PROG_MISMATCH:
      if (!xdr_u_long (xdrs, &(ar->ar_vers.low)))
	return FALSE;
      return (xdr_u_long (xdrs, &(ar->ar_vers.high)));
    default:
      return TRUE;
    }
  return TRUE;		/* TRUE => open ended set of problems */
}
libc_hidden_nolink_sunrpc (xdr_accepted_reply, GLIBC_2_0)

/*
 * XDR the MSG_DENIED part of a reply message union
 */
bool_t
xdr_rejected_reply (XDR *xdrs, struct rejected_reply *rr)
{
  /* personalized union, rather than calling xdr_union */
  if (!xdr_enum (xdrs, (enum_t *) & (rr->rj_stat)))
    return FALSE;
  switch (rr->rj_stat)
    {
    case RPC_MISMATCH:
      if (!xdr_u_long (xdrs, &(rr->rj_vers.low)))
	return FALSE;
      return xdr_u_long (xdrs, &(rr->rj_vers.high));

    case AUTH_ERROR:
      return xdr_enum (xdrs, (enum_t *) & (rr->rj_why));
    }
  return FALSE;
}
libc_hidden_nolink_sunrpc (xdr_rejected_reply, GLIBC_2_0)

static const struct xdr_discrim reply_dscrm[3] =
{
  {(int) MSG_ACCEPTED, (xdrproc_t) xdr_accepted_reply},
  {(int) MSG_DENIED, (xdrproc_t) xdr_rejected_reply},
  {__dontcare__, NULL_xdrproc_t}};

/*
 * XDR a reply message
 */
bool_t
xdr_replymsg (XDR *xdrs, struct rpc_msg *rmsg)
{
  if (xdr_u_long (xdrs, &(rmsg->rm_xid)) &&
      xdr_enum (xdrs, (enum_t *) & (rmsg->rm_direction)) &&
      (rmsg->rm_direction == REPLY))
    return xdr_union (xdrs, (enum_t *) & (rmsg->rm_reply.rp_stat),
		      (caddr_t) & (rmsg->rm_reply.ru), reply_dscrm,
		      NULL_xdrproc_t);
  return FALSE;
}
libc_hidden_nolink_sunrpc (xdr_replymsg, GLIBC_2_0)


/*
 * Serializes the "static part" of a call message header.
 * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
 * The rm_xid is not really static, but the user can easily munge on the fly.
 */
bool_t
xdr_callhdr (XDR *xdrs, struct rpc_msg *cmsg)
{

  cmsg->rm_direction = CALL;
  cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
  if (
       (xdrs->x_op == XDR_ENCODE) &&
       xdr_u_long (xdrs, &(cmsg->rm_xid)) &&
       xdr_enum (xdrs, (enum_t *) & (cmsg->rm_direction)) &&
       xdr_u_long (xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
       xdr_u_long (xdrs, &(cmsg->rm_call.cb_prog)))
    return xdr_u_long (xdrs, &(cmsg->rm_call.cb_vers));
  return FALSE;
}
libc_hidden_nolink_sunrpc (xdr_callhdr, GLIBC_2_0)

/* ************************** Client utility routine ************* */

static void
accepted (enum accept_stat acpt_stat,
	  struct rpc_err *error)
{
  switch (acpt_stat)
    {

    case PROG_UNAVAIL:
      error->re_status = RPC_PROGUNAVAIL;
      return;

    case PROG_MISMATCH:
      error->re_status = RPC_PROGVERSMISMATCH;
      return;

    case PROC_UNAVAIL:
      error->re_status = RPC_PROCUNAVAIL;
      return;

    case GARBAGE_ARGS:
      error->re_status = RPC_CANTDECODEARGS;
      return;

    case SYSTEM_ERR:
      error->re_status = RPC_SYSTEMERROR;
      return;

    case SUCCESS:
      error->re_status = RPC_SUCCESS;
      return;
    }
  /* something's wrong, but we don't know what ... */
  error->re_status = RPC_FAILED;
  error->re_lb.s1 = (long) MSG_ACCEPTED;
  error->re_lb.s2 = (long) acpt_stat;
}

static void
rejected (enum reject_stat rjct_stat,
	  struct rpc_err *error)
{
  switch (rjct_stat)
    {
    case RPC_MISMATCH:
      error->re_status = RPC_VERSMISMATCH;
      return;
    case AUTH_ERROR:
      error->re_status = RPC_AUTHERROR;
      return;
    default:
      /* something's wrong, but we don't know what ... */
      error->re_status = RPC_FAILED;
      error->re_lb.s1 = (long) MSG_DENIED;
      error->re_lb.s2 = (long) rjct_stat;
      return;
    }
}

/*
 * given a reply message, fills in the error
 */
void
_seterr_reply (struct rpc_msg *msg,
	       struct rpc_err *error)
{
  /* optimized for normal, SUCCESSful case */
  switch (msg->rm_reply.rp_stat)
    {
    case MSG_ACCEPTED:
      if (msg->acpted_rply.ar_stat == SUCCESS)
	{
	  error->re_status = RPC_SUCCESS;
	  return;
	};
      accepted (msg->acpted_rply.ar_stat, error);
      break;

    case MSG_DENIED:
      rejected (msg->rjcted_rply.rj_stat, error);
      break;

    default:
      error->re_status = RPC_FAILED;
      error->re_lb.s1 = (long) (msg->rm_reply.rp_stat);
      break;
    }
  switch (error->re_status)
    {

    case RPC_VERSMISMATCH:
      error->re_vers.low = msg->rjcted_rply.rj_vers.low;
      error->re_vers.high = msg->rjcted_rply.rj_vers.high;
      break;

    case RPC_AUTHERROR:
      error->re_why = msg->rjcted_rply.rj_why;
      break;

    case RPC_PROGVERSMISMATCH:
      error->re_vers.low = msg->acpted_rply.ar_vers.low;
      error->re_vers.high = msg->acpted_rply.ar_vers.high;
      break;
    default:
      break;
    }
}
libc_hidden_nolink_sunrpc (_seterr_reply, GLIBC_2_0)
