/*
  auth_gss.c

  RPCSEC_GSS client routines.

  Copyright (c) 2000 The Regents of the University of Michigan.
  All rights reserved.

  Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
  All rights reserved, all wrongs reversed.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

  1. Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
  2. 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.
  3. Neither the name of the University 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 ``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 REGENTS 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.

*/

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <rpc/types.h>
#include <rpc/xdr_inline.h>
#include <rpc/auth_inline.h>
#include <rpc/rpc.h>
#include <rpc/auth.h>
#include <rpc/auth_gss.h>
#include <rpc/clnt.h>
#include <netinet/in.h>
#include <gssapi/gssapi.h>

static void authgss_nextverf(AUTH *auth);
static bool authgss_marshal(AUTH *auth, XDR *xdrs);
static bool authgss_refresh(AUTH *auth, void *arg);
static bool authgss_validate(AUTH *auth, struct opaque_auth *verf);
static void authgss_destroy(AUTH *auth);
static void authgss_destroy_context(AUTH *auth);
static bool authgss_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func,
			 caddr_t xdr_ptr);
static bool authgss_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func,
			   caddr_t xdr_ptr);

/*
 * from mit-krb5-1.2.1 mechglue/mglueP.h:
 * Array of context IDs typed by mechanism OID
 */
typedef struct gss_union_ctx_id_t {
	gss_OID mech_type;
	gss_ctx_id_t internal_ctx_id;
} gss_union_ctx_id_desc, *gss_union_ctx_id_t;

static struct auth_ops authgss_ops = {
	authgss_nextverf,
	authgss_marshal,
	authgss_validate,
	authgss_refresh,
	authgss_destroy,
	authgss_wrap,
	authgss_unwrap
};

#ifdef DEBUG

/* useful as i add more mechanisms */
void
print_rpc_gss_sec(struct rpc_gss_sec *ptr)
{
	int i;
	char *p;

	log_debug("rpc_gss_sec:");
	if (ptr->mech == NULL)
		log_debug("NULL gss_OID mech");
	else {
		__warnx(TIRPC_DEBUG_FLAG_AUTH, "     mechanism_OID: {");
		p = (char *)ptr->mech->elements;
		for (i = 0; i < ptr->mech->length; i++)
			/* First byte of OIDs encoded to save a byte */
			if (i == 0) {
				int first, second;
				if (*p < 40) {
					first = 0;
					second = *p;
				} else if (40 <= *p && *p < 80) {
					first = 1;
					second = *p - 40;
				} else if (80 <= *p && *p < 127) {
					first = 2;
					second = *p - 80;
				} else {
					/* Invalid value! */
					first = -1;
					second = -1;
				}
				__warnx(TIRPC_DEBUG_FLAG_AUTH, " %u %u", first,
					second);
				p++;
			} else {
				__warnx(TIRPC_DEBUG_FLAG_AUTH, " %u",
					(unsigned char)*p++);
			}
		__warnx(" }\n");
	}
	__warnx(TIRPC_DEBUG_FLAG_AUTH, "     qop: %d\n", ptr->qop);
	__warnx(TIRPC_DEBUG_FLAG_AUTH, "     service: %d\n", ptr->svc);
	__warnx(TIRPC_DEBUG_FLAG_AUTH, "     cred: %p\n", ptr->cred);
}
#endif /*DEBUG*/
struct rpc_gss_data {
	mutex_t lock;
	bool established;	/* context established */
	gss_buffer_desc gc_wire_verf;	/* save GSS_S_COMPLETE NULL RPC verfier
					 * to process at end of context
					 * negotiation*/
	CLIENT *clnt;		/* client handle */
	gss_name_t name;	/* service name */
	struct rpc_gss_sec sec;	/* security tuple */
	gss_ctx_id_t ctx;	/* context id */
	struct rpc_gss_cred gc;	/* client credentials */
	u_int win;		/* sequence window */
};

#define AUTH_PRIVATE(auth) ((struct rpc_gss_data *)auth->ah_private)

static struct timeval AUTH_TIMEOUT = { 25, 0 };

AUTH *
authgss_ncreate(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec)
{
	AUTH *auth;
	struct rpc_gss_data *gd;
	OM_uint32 min_stat = 0;

	log_debug("in authgss_ncreate()");

	memset(&rpc_createerr, 0, sizeof(rpc_createerr));
	auth = mem_alloc(sizeof(*auth));
	if (auth == NULL) {
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = ENOMEM;
		return (NULL);
	}
	/* XXX move to ctor */
	gd = mem_alloc(sizeof(*gd));
	if (gd == NULL) {
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = ENOMEM;
		mem_free(auth, 0);
		return (NULL);
	}
	mutex_init(&gd->lock, NULL);
#ifdef DEBUG
	__warnx(TIRPC_DEBUG_FLAG_AUTH, "authgss_ncreate: name is %p\n", name);
#endif
	if (name != GSS_C_NO_NAME) {
		if (gss_duplicate_name(&min_stat, name, &gd->name)
		    != GSS_S_COMPLETE) {
			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
			rpc_createerr.cf_error.re_errno = ENOMEM;
			mem_free(gd, 0);
			mem_free(auth, 0);
			return (NULL);
		}
	} else
		gd->name = name;

#ifdef DEBUG
	__warnx(TIRPC_DEBUG_FLAG_AUTH, "authgss_ncreate: gd->name is %p\n",
		gd->name);
#endif
	gd->clnt = clnt;
	gd->ctx = GSS_C_NO_CONTEXT;
	gd->sec = *sec;

	gd->gc.gc_v = RPCSEC_GSS_VERSION;
	gd->gc.gc_proc = RPCSEC_GSS_INIT;
	gd->gc.gc_svc = gd->sec.svc;

	auth->ah_ops = &authgss_ops;
	auth->ah_private = (caddr_t) gd;

	if (!authgss_refresh(auth, NULL))
		auth = NULL;
	else
		auth_get(auth);	/* Reference for caller */

	return (auth);
}

AUTH *
authgss_ncreate_default(CLIENT *clnt, char *service,
			      struct rpc_gss_sec *sec)
{
	AUTH *auth;
	OM_uint32 maj_stat = 0, min_stat = 0;
	gss_buffer_desc sname;
	gss_name_t name = GSS_C_NO_NAME;

	log_debug("in authgss_ncreate_default()");

	sname.value = service;
	sname.length = strlen(service);

	maj_stat =
	    gss_import_name(&min_stat, &sname,
			    (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &name);

	if (maj_stat != GSS_S_COMPLETE) {
		log_status("gss_import_name", maj_stat, min_stat);
		rpc_createerr.cf_stat = RPC_AUTHERROR;
		return (NULL);
	}

	auth = authgss_ncreate(clnt, name, sec);

	if (name != GSS_C_NO_NAME) {
#ifdef DEBUG
		__warnx(TIRPC_DEBUG_FLAG_AUTH,
			"authgss_ncreate_default: freeing name %p\n", name);
#endif
		gss_release_name(&min_stat, &name);
	}

	return (auth);
}

bool
authgss_get_private_data(AUTH *auth, struct authgss_private_data *pd)
{
	struct rpc_gss_data *gd;

	log_debug("in authgss_get_private_data()");

	if (!auth || !pd)
		return (false);

	gd = AUTH_PRIVATE(auth);

	if (!gd || !gd->established)
		return (false);

	pd->pd_ctx = gd->ctx;
	pd->pd_ctx_hndl = gd->gc.gc_ctx;
	pd->pd_seq_win = gd->win;

	return (true);
}

static void
authgss_nextverf(AUTH *auth)
{
	log_debug("in authgss_nextverf()");
	/* no action necessary */
}

static bool
authgss_marshal(AUTH *auth, XDR *xdrs)
{
	XDR tmpxdrs;
	char tmp[MAX_AUTH_BYTES];
	struct rpc_gss_data *gd;
	gss_buffer_desc rpcbuf, checksum;
	OM_uint32 maj_stat, min_stat;
	bool xdr_stat;

	log_debug("in authgss_marshal()");

	gd = AUTH_PRIVATE(auth);

	if (gd->established) {
		/* XXX */
		mutex_lock(&gd->lock);
		gd->gc.gc_seq++;
		mutex_unlock(&gd->lock);
	}

	xdrmem_create(&tmpxdrs, tmp, sizeof(tmp), XDR_ENCODE);

	if (!xdr_rpc_gss_cred(&tmpxdrs, &gd->gc)) {
		XDR_DESTROY(&tmpxdrs);
		return (false);
	}
	auth->ah_cred.oa_flavor = RPCSEC_GSS;
	auth->ah_cred.oa_base = tmp;
	auth->ah_cred.oa_length = XDR_GETPOS(&tmpxdrs);

	XDR_DESTROY(&tmpxdrs);

	if (!inline_xdr_opaque_auth(xdrs, &auth->ah_cred))
		return (false);

	if (gd->gc.gc_proc == RPCSEC_GSS_INIT
	    || gd->gc.gc_proc == RPCSEC_GSS_CONTINUE_INIT) {
		return (inline_xdr_opaque_auth(xdrs, &_null_auth));
	}
	/* Checksum serialized RPC header, up to and including credential. */
	rpcbuf.length = XDR_GETPOS(xdrs);
	XDR_SETPOS(xdrs, 0);
	rpcbuf.value = XDR_INLINE(xdrs, rpcbuf.length);

	maj_stat =
	    gss_get_mic(&min_stat, gd->ctx, gd->sec.qop, &rpcbuf, &checksum);

	if (maj_stat != GSS_S_COMPLETE) {
		log_status("gss_get_mic", maj_stat, min_stat);
		if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
			gd->established = false;
			authgss_destroy_context(auth);
		}
		return (false);
	}
	auth->ah_verf.oa_flavor = RPCSEC_GSS;
	auth->ah_verf.oa_base = checksum.value;
	auth->ah_verf.oa_length = checksum.length;

	xdr_stat = xdr_opaque_auth(xdrs, &auth->ah_verf);
	gss_release_buffer(&min_stat, &checksum);

	return (xdr_stat);
}

static bool
authgss_validate(AUTH *auth, struct opaque_auth *verf)
{
	struct rpc_gss_data *gd;
	u_int num, qop_state;
	gss_buffer_desc signbuf, checksum;
	OM_uint32 maj_stat, min_stat;

	log_debug("in authgss_validate()");

	gd = AUTH_PRIVATE(auth);

	if (gd->established == false) {
		/* would like to do this only on NULL rpc --
		 * gc->established is good enough.
		 * save the on the wire verifier to validate last
		 * INIT phase packet after decode if the major
		 * status is GSS_S_COMPLETE
		 */
		gd->gc_wire_verf.value = mem_alloc(verf->oa_length);
		if (gd->gc_wire_verf.value == NULL) {
			__warnx(TIRPC_DEBUG_FLAG_AUTH,
				"gss_validate: out of memory\n");
			return (false);
		}
		memcpy(gd->gc_wire_verf.value, verf->oa_base, verf->oa_length);
		gd->gc_wire_verf.length = verf->oa_length;
		return (true);
	}

	if (gd->gc.gc_proc == RPCSEC_GSS_INIT
	    || gd->gc.gc_proc == RPCSEC_GSS_CONTINUE_INIT) {
		num = htonl(gd->win);
	} else
		num = htonl(gd->gc.gc_seq);

	signbuf.value = &num;
	signbuf.length = sizeof(num);

	checksum.value = verf->oa_base;
	checksum.length = verf->oa_length;

	maj_stat =
	    gss_verify_mic(&min_stat, gd->ctx, &signbuf, &checksum, &qop_state);
	if (maj_stat != GSS_S_COMPLETE || qop_state != gd->sec.qop) {
		log_status("gss_verify_mic", maj_stat, min_stat);
		if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
			gd->established = false;
			authgss_destroy_context(auth);
		}
		return (false);
	}
	return (true);
}

#define authgss_refresh_return(code) \
	do { \
		if (gd_locked) \
			mutex_unlock(&gd->lock); \
		return (code); \
	} while (0)

static bool
authgss_refresh(AUTH *auth, void *arg)
{
	struct rpc_gss_data *gd;
	struct rpc_gss_init_res gr;
	gss_buffer_desc *recv_tokenp, send_token;
	OM_uint32 maj_stat, min_stat, call_stat, ret_flags;
	bool gd_locked = false;

	log_debug("in authgss_refresh()");

	gd = AUTH_PRIVATE(auth);

	/* Serialize context. */
	mutex_lock(&gd->lock);
	gd_locked = true;

	if (gd->established)
		authgss_refresh_return(true);

	/* GSS context establishment loop. */
	memset(&gr, 0, sizeof(gr));
	recv_tokenp = GSS_C_NO_BUFFER;

#ifdef DEBUG
	print_rpc_gss_sec(&gd->sec);
#endif	 /*DEBUG*/
	    for (;;) {
#ifdef DEBUG
		/* print the token we just received */
		if (recv_tokenp != GSS_C_NO_BUFFER) {
			log_debug("The token we just received (length %d):",
				  recv_tokenp->length);
			gss_log_hexdump(recv_tokenp->value, recv_tokenp->length,
					0);
		}
#endif
		maj_stat = gss_init_sec_context(&min_stat,
						gd->sec.cred,
						&gd->ctx,
						gd->name,
						gd->sec.mech,
						gd->sec.req_flags,
						0,	/* time req */
						NULL,	/* channel */
						recv_tokenp,
						NULL,	/* used mech */
						&send_token,
						&ret_flags,
						NULL);	/* time rec */

		if (recv_tokenp != GSS_C_NO_BUFFER) {
			gss_release_buffer(&min_stat, &gr.gr_token);
			recv_tokenp = GSS_C_NO_BUFFER;
		}
		if (maj_stat != GSS_S_COMPLETE
		    && maj_stat != GSS_S_CONTINUE_NEEDED) {
			log_status("gss_init_sec_context", maj_stat, min_stat);
			break;
		}
		if (send_token.length != 0) {
			memset(&gr, 0, sizeof(gr));

#ifdef DEBUG
			/* print the token we are about to send */
			log_debug("The token being sent (length %d):",
				  send_token.length);
			gss_log_hexdump(send_token.value, send_token.length, 0);
#endif

			call_stat =
			    clnt_call(gd->clnt, auth, NULLPROC,
				      (xdrproc_t) xdr_rpc_gss_init_args,
				      &send_token,
				      (xdrproc_t) xdr_rpc_gss_init_res,
				      (caddr_t) &gr, AUTH_TIMEOUT);

			gss_release_buffer(&min_stat, &send_token);

			if (call_stat != RPC_SUCCESS
			    || (gr.gr_major != GSS_S_COMPLETE
				&& gr.gr_major != GSS_S_CONTINUE_NEEDED))
				authgss_refresh_return(false);

			if (gr.gr_ctx.length != 0) {
				if (gd->gc.gc_ctx.value)
					gss_release_buffer(&min_stat,
							   &gd->gc.gc_ctx);
				gd->gc.gc_ctx = gr.gr_ctx;
			}
			if (gr.gr_token.length != 0) {
				if (maj_stat != GSS_S_CONTINUE_NEEDED)
					break;
				recv_tokenp = &gr.gr_token;
			}
			gd->gc.gc_proc = RPCSEC_GSS_CONTINUE_INIT;
		}

		/* GSS_S_COMPLETE => check gss header verifier,
		 * usually checked in gss_validate
		 */
		if (maj_stat == GSS_S_COMPLETE) {
			gss_buffer_desc bufin;
			gss_buffer_desc bufout;
			u_int seq, qop_state = 0;

			seq = htonl(gr.gr_win);
			bufin.value = (unsigned char *)&seq;
			bufin.length = sizeof(seq);
			bufout.value = (unsigned char *)gd->gc_wire_verf.value;
			bufout.length = gd->gc_wire_verf.length;

			maj_stat =
			    gss_verify_mic(&min_stat, gd->ctx, &bufin, &bufout,
					   &qop_state);

			if (maj_stat != GSS_S_COMPLETE
			    || qop_state != gd->sec.qop) {
				log_status("gss_verify_mic", maj_stat,
					   min_stat);
				if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
					gd->established = false;
					authgss_destroy_context(auth);
				}
				authgss_refresh_return (false);
			}
			gd->established = true;
			gd->gc.gc_proc = RPCSEC_GSS_DATA;
			gd->gc.gc_seq = 0;
			gd->win = gr.gr_win;
			break;
		}
	}
	/* End context negotiation loop. */
	if (gd->gc.gc_proc != RPCSEC_GSS_DATA) {
		if (gr.gr_token.length != 0)
			gss_release_buffer(&min_stat, &gr.gr_token);

		authgss_destroy(auth);
		auth = NULL;
		rpc_createerr.cf_stat = RPC_AUTHERROR;

		authgss_refresh_return(false);
	}
	authgss_refresh_return(true);
}

bool
authgss_service(AUTH *auth, int svc)
{
	struct rpc_gss_data *gd;

	log_debug("in authgss_service()");

	if (!auth)
		return (false);
	gd = AUTH_PRIVATE(auth);
	if (!gd || !gd->established)
		return (false);
	gd->sec.svc = svc;
	gd->gc.gc_svc = svc;
	return (true);
}

static void
authgss_destroy_context(AUTH *auth)
{
	struct rpc_gss_data *gd;
	OM_uint32 min_stat;

	log_debug("in authgss_destroy_context()");

	gd = AUTH_PRIVATE(auth);

	if (gd->gc.gc_ctx.length != 0) {
		if (gd->established) {
			gd->gc.gc_proc = RPCSEC_GSS_DESTROY;
			clnt_call(gd->clnt, auth, NULLPROC,
				  (xdrproc_t) xdr_void, NULL,
				  (xdrproc_t) xdr_void, NULL, AUTH_TIMEOUT);
		}
		gss_release_buffer(&min_stat, &gd->gc.gc_ctx);
		/* XXX ANDROS check size of context  - should be 8 */
		memset(&gd->gc.gc_ctx, 0, sizeof(gd->gc.gc_ctx));
	}
	if (gd->ctx != GSS_C_NO_CONTEXT) {
		gss_delete_sec_context(&min_stat, &gd->ctx, NULL);
		gd->ctx = GSS_C_NO_CONTEXT;
	}

	/* free saved wire verifier (if any) */
	mem_free(gd->gc_wire_verf.value, gd->gc_wire_verf.length);
	gd->gc_wire_verf.value = NULL;
	gd->gc_wire_verf.length = 0;

	gd->established = false;
}

static void
authgss_destroy(AUTH *auth)
{
	struct rpc_gss_data *gd;
	OM_uint32 min_stat;

	log_debug("in authgss_destroy()");

	gd = AUTH_PRIVATE(auth);

	authgss_destroy_context(auth);

#ifdef DEBUG
	__warnx(TIRPC_DEBUG_FLAG_AUTH, "authgss_destroy: freeing name %p\n",
		gd->name);
#endif
	if (gd->name != GSS_C_NO_NAME)
		gss_release_name(&min_stat, &gd->name);

	mem_free(gd, 0);
	mem_free(auth, 0);
}

bool
authgss_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr)
{
	struct rpc_gss_data *gd;

	log_debug("in authgss_wrap()");

	gd = AUTH_PRIVATE(auth);

	if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE)
		return ((*xdr_func) (xdrs, xdr_ptr));

	return (xdr_rpc_gss_data
		(xdrs, xdr_func, xdr_ptr, gd->ctx, gd->sec.qop, gd->sec.svc,
		 gd->gc.gc_seq));
}

bool
authgss_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func,
	       caddr_t xdr_ptr)
{
	struct rpc_gss_data *gd;

	log_debug("in authgss_unwrap()");

	gd = AUTH_PRIVATE(auth);

	if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE)
		return ((*xdr_func) (xdrs, xdr_ptr));

	return (xdr_rpc_gss_data
		(xdrs, xdr_func, xdr_ptr, gd->ctx, gd->sec.qop, gd->sec.svc,
		 gd->gc.gc_seq));
}
