Esempio n. 1
0
bool_t
xdr_rpc_gss_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
		 gss_ctx_id_t ctx, gss_qop_t qop,
		 rpc_gss_svc_t svc, u_int seq)
{
	switch (xdrs->x_op) {

	case XDR_ENCODE:
		return (xdr_rpc_gss_wrap_data(xdrs, xdr_func, xdr_ptr,
					      ctx, qop, svc, seq));
	case XDR_DECODE:
		return (xdr_rpc_gss_unwrap_data(xdrs, xdr_func, xdr_ptr,
						ctx, qop,svc, seq));
	case XDR_FREE:
		return (TRUE);
	}
	return (FALSE);
}
Esempio n. 2
0
bool_t
__rpc_gss_wrap(AUTH *auth, void *header, size_t headerlen,
    XDR* xdrs, xdrproc_t xdr_args, void *args_ptr)
{
	XDR			 tmpxdrs;
	char			 credbuf[MAX_AUTH_BYTES];
	char			 tmpheader[MAX_AUTH_BYTES];
	struct opaque_auth	 creds, verf;
	struct rpc_gss_data	*gd;
	gss_buffer_desc		 rpcbuf, checksum;
	OM_uint32		 maj_stat, min_stat;
	bool_t			 xdr_stat;
	
	log_debug("in rpc_gss_wrap()");
	
	gd = AUTH_PRIVATE(auth);

	if (gd->gd_state == RPCSEC_GSS_ESTABLISHED)
		gd->gd_cred.gc_seq++;
	
	/*
	 * We need to encode our creds and then put the header and
	 * creds together in a buffer so that we can create a checksum
	 * for the verf.
	 */
	xdrmem_create(&tmpxdrs, credbuf, sizeof(credbuf), XDR_ENCODE);
	if (!xdr_rpc_gss_cred(&tmpxdrs, &gd->gd_cred)) {
		XDR_DESTROY(&tmpxdrs);
		_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
		return (FALSE);
	}
	creds.oa_flavor = RPCSEC_GSS;
	creds.oa_base = credbuf;
	creds.oa_length = XDR_GETPOS(&tmpxdrs);
	XDR_DESTROY(&tmpxdrs);
	
	xdrmem_create(&tmpxdrs, tmpheader, sizeof(tmpheader), XDR_ENCODE);
	if (!XDR_PUTBYTES(&tmpxdrs, header, headerlen) ||
	    !xdr_opaque_auth(&tmpxdrs, &creds)) {
		XDR_DESTROY(&tmpxdrs);
		_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
		return (FALSE);
	}
	headerlen = XDR_GETPOS(&tmpxdrs);
	XDR_DESTROY(&tmpxdrs);
		
	if (!XDR_PUTBYTES(xdrs, tmpheader, headerlen)) {
		_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
		return (FALSE);
	}
	
	if (gd->gd_cred.gc_proc == RPCSEC_GSS_INIT ||
	    gd->gd_cred.gc_proc == RPCSEC_GSS_CONTINUE_INIT) {
		if (!xdr_opaque_auth(xdrs, &_null_auth)) {
			_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
			return (FALSE);
		}
	} else {
		/*
		 * Checksum serialized RPC header, up to and including
		 * credential.
		 */
		rpcbuf.length = headerlen;
		rpcbuf.value = tmpheader;
	
		maj_stat = gss_get_mic(&min_stat, gd->gd_ctx, gd->gd_qop,
		    &rpcbuf, &checksum);

		if (maj_stat != GSS_S_COMPLETE) {
			log_status("gss_get_mic", gd->gd_mech,
			    maj_stat, min_stat);
			if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
				rpc_gss_destroy_context(auth, TRUE);
			}
			_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, EPERM);
			return (FALSE);
		}

		verf.oa_flavor = RPCSEC_GSS;
		verf.oa_base = checksum.value;
		verf.oa_length = checksum.length;

		xdr_stat = xdr_opaque_auth(xdrs, &verf);
		gss_release_buffer(&min_stat, &checksum);
		if (!xdr_stat) {
			_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
			return (FALSE);
		}
	}
	
	if (gd->gd_state != RPCSEC_GSS_ESTABLISHED ||
	    gd->gd_cred.gc_svc == rpc_gss_svc_none) {
		return (xdr_args(xdrs, args_ptr));
	}
	return (xdr_rpc_gss_wrap_data(xdrs, xdr_args, args_ptr,
		gd->gd_ctx, gd->gd_qop, gd->gd_cred.gc_svc,
		gd->gd_cred.gc_seq));
}