17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*89b43686SBayard Bell  * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * A module that implements a dummy security mechanism.
307c478bd9Sstevel@tonic-gate  * It's mainly used to test GSS-API application. Multiple tokens
317c478bd9Sstevel@tonic-gate  * exchanged during security context establishment can be
327c478bd9Sstevel@tonic-gate  * specified through dummy_mech.conf located in /etc.
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #include <sys/types.h>
367c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
377c478bd9Sstevel@tonic-gate #include <sys/errno.h>
387c478bd9Sstevel@tonic-gate #include <gssapiP_dummy.h>
397c478bd9Sstevel@tonic-gate #include <gssapi_err_generic.h>
407c478bd9Sstevel@tonic-gate #include <mechglueP.h>
417c478bd9Sstevel@tonic-gate #include <gssapi/kgssapi_defs.h>
427c478bd9Sstevel@tonic-gate #include <sys/debug.h>
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #ifdef DUMMY_MECH_DEBUG
457c478bd9Sstevel@tonic-gate /*
467c478bd9Sstevel@tonic-gate  * Kernel kgssd module debugging aid. The global variable "dummy_mech_log"
477c478bd9Sstevel@tonic-gate  * is a bit mask which allows various types of debugging messages
487c478bd9Sstevel@tonic-gate  * to be printed out.
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  *       dummy_mech_log & 1  will cause actual failures to be printed.
517c478bd9Sstevel@tonic-gate  *       dummy_mech_log & 2  will cause informational messages to be
527c478bd9Sstevel@tonic-gate  *                       printed on the client side of kgssd.
537c478bd9Sstevel@tonic-gate  *       dummy_mech_log & 4  will cause informational messages to be
547c478bd9Sstevel@tonic-gate  *                       printed on the server side of kgssd.
557c478bd9Sstevel@tonic-gate  *       dummy_mech_log & 8  will cause informational messages to be
567c478bd9Sstevel@tonic-gate  *                       printed on both client and server side of kgssd.
577c478bd9Sstevel@tonic-gate  */
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate uint_t dummy_mech_log = 1;
607c478bd9Sstevel@tonic-gate #endif
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate /* Local defines */
637c478bd9Sstevel@tonic-gate #define	MAGIC_TOKEN_NUMBER 12345
647c478bd9Sstevel@tonic-gate /* private routines for dummy_mechanism */
657c478bd9Sstevel@tonic-gate static gss_buffer_desc make_dummy_token_msg(void *data, int datalen);
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate static int der_length_size(int);
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate static void der_write_length(unsigned char **, int);
707c478bd9Sstevel@tonic-gate static int der_read_length(unsigned char **, int *);
717c478bd9Sstevel@tonic-gate static int g_token_size(gss_OID mech, unsigned int body_size);
727c478bd9Sstevel@tonic-gate static void g_make_token_header(gss_OID mech, int body_size,
737c478bd9Sstevel@tonic-gate 				unsigned char **buf, int tok_type);
747c478bd9Sstevel@tonic-gate static int g_verify_token_header(gss_OID mech, int *body_size,
757c478bd9Sstevel@tonic-gate 				unsigned char **buf_in, int tok_type,
767c478bd9Sstevel@tonic-gate 				int toksize);
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate /* private global variables */
797c478bd9Sstevel@tonic-gate static int dummy_token_nums;
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate /*
827c478bd9Sstevel@tonic-gate  * This OID:
837c478bd9Sstevel@tonic-gate  * { iso(1) org(3) internet(6) dod(1) private(4) enterprises(1) sun(42)
847c478bd9Sstevel@tonic-gate  * products(2) gssapi(26) mechtypes(1) dummy(2) }
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate static struct gss_config dummy_mechanism =
887c478bd9Sstevel@tonic-gate 	{{10, "\053\006\001\004\001\052\002\032\001\002"},
897c478bd9Sstevel@tonic-gate 	NULL,	/* context */
907c478bd9Sstevel@tonic-gate 	NULL,	/* next */
917c478bd9Sstevel@tonic-gate 	TRUE,	/* uses_kmod */
927c478bd9Sstevel@tonic-gate 	dummy_gss_unseal,
937c478bd9Sstevel@tonic-gate 	dummy_gss_delete_sec_context,
947c478bd9Sstevel@tonic-gate 	dummy_gss_seal,
957c478bd9Sstevel@tonic-gate 	dummy_gss_import_sec_context,
967c478bd9Sstevel@tonic-gate 	dummy_gss_sign,
977c478bd9Sstevel@tonic-gate 	dummy_gss_verify
987c478bd9Sstevel@tonic-gate };
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate static gss_mechanism
gss_mech_initialize()1017c478bd9Sstevel@tonic-gate gss_mech_initialize()
1027c478bd9Sstevel@tonic-gate {
1037c478bd9Sstevel@tonic-gate 	dprintf("Entering gss_mech_initialize\n");
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	if (dummy_token_nums == 0)
1067c478bd9Sstevel@tonic-gate 		dummy_token_nums = 1;
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 	dprintf("Leaving gss_mech_initialize\n");
1097c478bd9Sstevel@tonic-gate 	return (&dummy_mechanism);
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate /*
1137c478bd9Sstevel@tonic-gate  * Clean up after a failed mod_install()
1147c478bd9Sstevel@tonic-gate  */
1157c478bd9Sstevel@tonic-gate static void
gss_mech_fini()1167c478bd9Sstevel@tonic-gate gss_mech_fini()
1177c478bd9Sstevel@tonic-gate {
1187c478bd9Sstevel@tonic-gate 	/* Nothing to do */
1197c478bd9Sstevel@tonic-gate }
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate /*
1237c478bd9Sstevel@tonic-gate  * Module linkage information for the kernel.
1247c478bd9Sstevel@tonic-gate  */
1257c478bd9Sstevel@tonic-gate extern struct mod_ops mod_miscops;
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate static struct modlmisc modlmisc = {
1287c478bd9Sstevel@tonic-gate 	&mod_miscops, "in-kernel dummy GSS mechanism"
1297c478bd9Sstevel@tonic-gate };
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
1327c478bd9Sstevel@tonic-gate 	MODREV_1,
1337c478bd9Sstevel@tonic-gate 	(void *)&modlmisc,
1347c478bd9Sstevel@tonic-gate 	NULL
1357c478bd9Sstevel@tonic-gate };
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate static int dummy_fini_code = EBUSY;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate int
_init()1407c478bd9Sstevel@tonic-gate _init()
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate 	int retval;
1437c478bd9Sstevel@tonic-gate 	gss_mechanism mech, tmp;
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	mech = gss_mech_initialize();
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	mutex_enter(&__kgss_mech_lock);
1487c478bd9Sstevel@tonic-gate 	tmp = __kgss_get_mechanism(&mech->mech_type);
1497c478bd9Sstevel@tonic-gate 	if (tmp != NULL) {
1507c478bd9Sstevel@tonic-gate 		DUMMY_MECH_LOG0(8,
1517c478bd9Sstevel@tonic-gate 			"dummy GSS mechanism: mechanism already in table.\n");
1527c478bd9Sstevel@tonic-gate 		if (tmp->uses_kmod == TRUE) {
1537c478bd9Sstevel@tonic-gate 			DUMMY_MECH_LOG0(8, "dummy GSS mechanism: mechanism "
1547c478bd9Sstevel@tonic-gate 				"table supports kernel operations!\n");
1557c478bd9Sstevel@tonic-gate 		}
1567c478bd9Sstevel@tonic-gate 		/*
1577c478bd9Sstevel@tonic-gate 		 * keep us loaded, but let us be unloadable. This
1587c478bd9Sstevel@tonic-gate 		 * will give the developer time to trouble shoot
1597c478bd9Sstevel@tonic-gate 		 */
1607c478bd9Sstevel@tonic-gate 		dummy_fini_code = 0;
1617c478bd9Sstevel@tonic-gate 	} else {
1627c478bd9Sstevel@tonic-gate 		__kgss_add_mechanism(mech);
1637c478bd9Sstevel@tonic-gate 		ASSERT(__kgss_get_mechanism(&mech->mech_type) == mech);
1647c478bd9Sstevel@tonic-gate 	}
1657c478bd9Sstevel@tonic-gate 	mutex_exit(&__kgss_mech_lock);
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	if ((retval = mod_install(&modlinkage)) != 0)
1687c478bd9Sstevel@tonic-gate 		gss_mech_fini();	/* clean up */
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 	return (retval);
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate int
_fini()1747c478bd9Sstevel@tonic-gate _fini()
1757c478bd9Sstevel@tonic-gate {
1767c478bd9Sstevel@tonic-gate 	int ret = dummy_fini_code;
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	if (ret == 0) {
1797c478bd9Sstevel@tonic-gate 		ret = (mod_remove(&modlinkage));
1807c478bd9Sstevel@tonic-gate 	}
1817c478bd9Sstevel@tonic-gate 	return (ret);
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate int
_info(struct modinfo * modinfop)1857c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop)
1867c478bd9Sstevel@tonic-gate {
1877c478bd9Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1927c478bd9Sstevel@tonic-gate static OM_uint32
dummy_gss_sign(context,minor_status,context_handle,qop_req,message_buffer,message_token,gssd_ctx_verifier)1937c478bd9Sstevel@tonic-gate dummy_gss_sign(context, minor_status, context_handle,
1947c478bd9Sstevel@tonic-gate 		qop_req, message_buffer, message_token,
1957c478bd9Sstevel@tonic-gate 		gssd_ctx_verifier)
1967c478bd9Sstevel@tonic-gate 	void *context;
1977c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
1987c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
1997c478bd9Sstevel@tonic-gate 	int qop_req;
2007c478bd9Sstevel@tonic-gate 	gss_buffer_t message_buffer;
2017c478bd9Sstevel@tonic-gate 	gss_buffer_t message_token;
2027c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_ctx_verifier;
2037c478bd9Sstevel@tonic-gate {
2047c478bd9Sstevel@tonic-gate 	dummy_gss_ctx_id_rec	*ctx;
2057c478bd9Sstevel@tonic-gate 	char token_string[] = "dummy_gss_sign";
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	dprintf("Entering gss_sign\n");
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	if (context_handle == GSS_C_NO_CONTEXT)
2107c478bd9Sstevel@tonic-gate 		return (GSS_S_NO_CONTEXT);
2117c478bd9Sstevel@tonic-gate 	ctx = (dummy_gss_ctx_id_rec *) context_handle;
2127c478bd9Sstevel@tonic-gate 	ASSERT(ctx->established == 1);
2137c478bd9Sstevel@tonic-gate 	ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	*message_token = make_dummy_token_msg(
2167c478bd9Sstevel@tonic-gate 				token_string, strlen(token_string));
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	dprintf("Leaving gss_sign\n");
2197c478bd9Sstevel@tonic-gate 	return (GSS_S_COMPLETE);
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2237c478bd9Sstevel@tonic-gate static OM_uint32
dummy_gss_verify(context,minor_status,context_handle,message_buffer,token_buffer,qop_state,gssd_ctx_verifier)2247c478bd9Sstevel@tonic-gate 	dummy_gss_verify(context, minor_status, context_handle,
2257c478bd9Sstevel@tonic-gate 		message_buffer, token_buffer, qop_state,
2267c478bd9Sstevel@tonic-gate 		gssd_ctx_verifier)
2277c478bd9Sstevel@tonic-gate 	void *context;
2287c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
2297c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
2307c478bd9Sstevel@tonic-gate 	gss_buffer_t message_buffer;
2317c478bd9Sstevel@tonic-gate 	gss_buffer_t token_buffer;
2327c478bd9Sstevel@tonic-gate 	int *qop_state;
2337c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_ctx_verifier;
2347c478bd9Sstevel@tonic-gate {
2357c478bd9Sstevel@tonic-gate 	unsigned char *ptr;
2367c478bd9Sstevel@tonic-gate 	int bodysize;
2377c478bd9Sstevel@tonic-gate 	int err;
2387c478bd9Sstevel@tonic-gate 	dummy_gss_ctx_id_rec	*ctx;
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	dprintf("Entering gss_verify\n");
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	if (context_handle == GSS_C_NO_CONTEXT)
2437c478bd9Sstevel@tonic-gate 		return (GSS_S_NO_CONTEXT);
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	ctx = (dummy_gss_ctx_id_rec *) context_handle;
2467c478bd9Sstevel@tonic-gate 	ASSERT(ctx->established == 1);
2477c478bd9Sstevel@tonic-gate 	ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
2487c478bd9Sstevel@tonic-gate 	/* Check for defective input token. */
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	ptr = (unsigned char *) token_buffer->value;
2517c478bd9Sstevel@tonic-gate 	if (err = g_verify_token_header((gss_OID)gss_mech_dummy, &bodysize,
2527c478bd9Sstevel@tonic-gate 					&ptr, 0,
2537c478bd9Sstevel@tonic-gate 					token_buffer->length)) {
2547c478bd9Sstevel@tonic-gate 		*minor_status = err;
2557c478bd9Sstevel@tonic-gate 		return (GSS_S_DEFECTIVE_TOKEN);
2567c478bd9Sstevel@tonic-gate 	}
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	*qop_state = GSS_C_QOP_DEFAULT;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 	dprintf("Leaving gss_verify\n");
2617c478bd9Sstevel@tonic-gate 	return (GSS_S_COMPLETE);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2657c478bd9Sstevel@tonic-gate static OM_uint32
dummy_gss_seal(context,minor_status,context_handle,conf_req_flag,qop_req,input_message_buffer,conf_state,output_message_buffer,gssd_ctx_verifier)2667c478bd9Sstevel@tonic-gate dummy_gss_seal(context, minor_status, context_handle, conf_req_flag,
2677c478bd9Sstevel@tonic-gate 		qop_req, input_message_buffer, conf_state,
2687c478bd9Sstevel@tonic-gate 		output_message_buffer, gssd_ctx_verifier)
2697c478bd9Sstevel@tonic-gate 	void *context;
2707c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
2717c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
2727c478bd9Sstevel@tonic-gate 	int conf_req_flag;
2737c478bd9Sstevel@tonic-gate 	int qop_req;
2747c478bd9Sstevel@tonic-gate 	gss_buffer_t input_message_buffer;
2757c478bd9Sstevel@tonic-gate 	int *conf_state;
2767c478bd9Sstevel@tonic-gate 	gss_buffer_t output_message_buffer;
2777c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_ctx_verifier;
2787c478bd9Sstevel@tonic-gate {
2797c478bd9Sstevel@tonic-gate 	gss_buffer_desc	output;
2807c478bd9Sstevel@tonic-gate 	dummy_gss_ctx_id_rec	*ctx;
2817c478bd9Sstevel@tonic-gate 	dprintf("Entering gss_seal\n");
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 	if (context_handle == GSS_C_NO_CONTEXT)
2847c478bd9Sstevel@tonic-gate 		return (GSS_S_NO_CONTEXT);
2857c478bd9Sstevel@tonic-gate 	ctx = (dummy_gss_ctx_id_rec *) context_handle;
2867c478bd9Sstevel@tonic-gate 	ASSERT(ctx->established == 1);
2877c478bd9Sstevel@tonic-gate 	ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
2887c478bd9Sstevel@tonic-gate 	/* Copy the input message to output message */
2897c478bd9Sstevel@tonic-gate 	output = make_dummy_token_msg(
2907c478bd9Sstevel@tonic-gate 		input_message_buffer->value, input_message_buffer->length);
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	if (conf_state)
2937c478bd9Sstevel@tonic-gate 		*conf_state = 1;
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	*output_message_buffer = output;
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	dprintf("Leaving gss_seal\n");
2987c478bd9Sstevel@tonic-gate 	return (GSS_S_COMPLETE);
2997c478bd9Sstevel@tonic-gate }
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3027c478bd9Sstevel@tonic-gate static OM_uint32
dummy_gss_unseal(context,minor_status,context_handle,input_message_buffer,output_message_buffer,conf_state,qop_state,gssd_ctx_verifier)3037c478bd9Sstevel@tonic-gate dummy_gss_unseal(context, minor_status, context_handle,
3047c478bd9Sstevel@tonic-gate 		input_message_buffer, output_message_buffer,
3057c478bd9Sstevel@tonic-gate 		conf_state, qop_state, gssd_ctx_verifier)
3067c478bd9Sstevel@tonic-gate 	void *context;
3077c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
3087c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
3097c478bd9Sstevel@tonic-gate 	gss_buffer_t input_message_buffer;
3107c478bd9Sstevel@tonic-gate 	gss_buffer_t output_message_buffer;
3117c478bd9Sstevel@tonic-gate 	int *conf_state;
3127c478bd9Sstevel@tonic-gate 	int *qop_state;
3137c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_ctx_verifier;
3147c478bd9Sstevel@tonic-gate {
3157c478bd9Sstevel@tonic-gate 	gss_buffer_desc output;
3167c478bd9Sstevel@tonic-gate 	dummy_gss_ctx_id_rec	*ctx;
3177c478bd9Sstevel@tonic-gate 	unsigned char *ptr;
3187c478bd9Sstevel@tonic-gate 	int bodysize;
3197c478bd9Sstevel@tonic-gate 	int err;
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	dprintf("Entering gss_unseal\n");
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	if (context_handle == GSS_C_NO_CONTEXT)
3247c478bd9Sstevel@tonic-gate 		return (GSS_S_NO_CONTEXT);
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 	ctx = (dummy_gss_ctx_id_rec *) context_handle;
3277c478bd9Sstevel@tonic-gate 	ASSERT(ctx->established == 1);
3287c478bd9Sstevel@tonic-gate 	ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	ptr = (unsigned char *) input_message_buffer->value;
3317c478bd9Sstevel@tonic-gate 	if (err = g_verify_token_header((gss_OID)gss_mech_dummy, &bodysize,
3327c478bd9Sstevel@tonic-gate 					&ptr, 0,
3337c478bd9Sstevel@tonic-gate 					input_message_buffer->length)) {
3347c478bd9Sstevel@tonic-gate 		*minor_status = err;
3357c478bd9Sstevel@tonic-gate 		return (GSS_S_DEFECTIVE_TOKEN);
3367c478bd9Sstevel@tonic-gate 	}
3377c478bd9Sstevel@tonic-gate 	output.length = bodysize;
3387c478bd9Sstevel@tonic-gate 	output.value = (void *)MALLOC(output.length);
3397c478bd9Sstevel@tonic-gate 	(void) memcpy(output.value, ptr, output.length);
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 	*output_message_buffer = output;
3427c478bd9Sstevel@tonic-gate 	*qop_state = GSS_C_QOP_DEFAULT;
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	if (conf_state)
3457c478bd9Sstevel@tonic-gate 		*conf_state = 1;
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 	dprintf("Leaving gss_unseal\n");
3487c478bd9Sstevel@tonic-gate 	return (GSS_S_COMPLETE);
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3527c478bd9Sstevel@tonic-gate OM_uint32
dummy_gss_import_sec_context(ct,minor_status,interprocess_token,context_handle)3537c478bd9Sstevel@tonic-gate 	dummy_gss_import_sec_context(ct, minor_status, interprocess_token,
3547c478bd9Sstevel@tonic-gate 					context_handle)
3557c478bd9Sstevel@tonic-gate void *ct;
3567c478bd9Sstevel@tonic-gate OM_uint32 *minor_status;
3577c478bd9Sstevel@tonic-gate gss_buffer_t interprocess_token;
3587c478bd9Sstevel@tonic-gate gss_ctx_id_t *context_handle;
3597c478bd9Sstevel@tonic-gate {
3607c478bd9Sstevel@tonic-gate 	unsigned char *ptr;
3617c478bd9Sstevel@tonic-gate 	int bodysize;
3627c478bd9Sstevel@tonic-gate 	int err;
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	/* Assume that we got ctx from the interprocess token. */
3657c478bd9Sstevel@tonic-gate 	dummy_gss_ctx_id_t ctx;
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	dprintf("Entering import_sec_context\n");
3687c478bd9Sstevel@tonic-gate 	ptr = (unsigned char *) interprocess_token->value;
3697c478bd9Sstevel@tonic-gate 	if (err = g_verify_token_header((gss_OID)gss_mech_dummy, &bodysize,
3707c478bd9Sstevel@tonic-gate 					&ptr, 0,
3717c478bd9Sstevel@tonic-gate 					interprocess_token->length)) {
3727c478bd9Sstevel@tonic-gate 		*minor_status = err;
3737c478bd9Sstevel@tonic-gate 		return (GSS_S_DEFECTIVE_TOKEN);
3747c478bd9Sstevel@tonic-gate 	}
3757c478bd9Sstevel@tonic-gate 	ctx = (dummy_gss_ctx_id_t)MALLOC(sizeof (dummy_gss_ctx_id_rec));
3767c478bd9Sstevel@tonic-gate 	ctx->token_number = MAGIC_TOKEN_NUMBER;
3777c478bd9Sstevel@tonic-gate 	ctx->established = 1;
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate 	*context_handle = (gss_ctx_id_t)ctx;
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 	dprintf("Leaving import_sec_context\n");
3827c478bd9Sstevel@tonic-gate 	return (GSS_S_COMPLETE);
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3867c478bd9Sstevel@tonic-gate static OM_uint32
dummy_gss_delete_sec_context(ct,minor_status,context_handle,output_token,gssd_ctx_verifier)3877c478bd9Sstevel@tonic-gate dummy_gss_delete_sec_context(ct, minor_status,
3887c478bd9Sstevel@tonic-gate 			context_handle, output_token,
3897c478bd9Sstevel@tonic-gate 			gssd_ctx_verifier)
3907c478bd9Sstevel@tonic-gate void *ct;
3917c478bd9Sstevel@tonic-gate OM_uint32 *minor_status;
3927c478bd9Sstevel@tonic-gate gss_ctx_id_t *context_handle;
3937c478bd9Sstevel@tonic-gate gss_buffer_t output_token;
3947c478bd9Sstevel@tonic-gate OM_uint32 gssd_ctx_verifier;
3957c478bd9Sstevel@tonic-gate {
3967c478bd9Sstevel@tonic-gate 	dummy_gss_ctx_id_t ctx;
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 	dprintf("Entering delete_sec_context\n");
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	/* Make the length to 0, so the output token is not sent to peer */
4017c478bd9Sstevel@tonic-gate 	if (output_token) {
4027c478bd9Sstevel@tonic-gate 		output_token->length = 0;
4037c478bd9Sstevel@tonic-gate 		output_token->value = NULL;
4047c478bd9Sstevel@tonic-gate 	}
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 	if (*context_handle == GSS_C_NO_CONTEXT) {
4077c478bd9Sstevel@tonic-gate 		*minor_status = 0;
4087c478bd9Sstevel@tonic-gate 		return (GSS_S_COMPLETE);
4097c478bd9Sstevel@tonic-gate 	}
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	ctx = (dummy_gss_ctx_id_rec *) *context_handle;
4127c478bd9Sstevel@tonic-gate 	ASSERT(ctx->established == 1);
4137c478bd9Sstevel@tonic-gate 	ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate 	FREE(ctx, sizeof (dummy_gss_ctx_id_rec));
4167c478bd9Sstevel@tonic-gate 	*context_handle = GSS_C_NO_CONTEXT;
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	dprintf("Leaving delete_sec_context\n");
4197c478bd9Sstevel@tonic-gate 	return (GSS_S_COMPLETE);
4207c478bd9Sstevel@tonic-gate }
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate static int
der_length_size(int length)4237c478bd9Sstevel@tonic-gate der_length_size(int length)
4247c478bd9Sstevel@tonic-gate {
4257c478bd9Sstevel@tonic-gate 	if (length < (1<<7))
4267c478bd9Sstevel@tonic-gate 		return (1);
4277c478bd9Sstevel@tonic-gate 	else if (length < (1<<8))
4287c478bd9Sstevel@tonic-gate 		return (2);
4297c478bd9Sstevel@tonic-gate 	else if (length < (1<<16))
4307c478bd9Sstevel@tonic-gate 		return (3);
4317c478bd9Sstevel@tonic-gate 	else if (length < (1<<24))
4327c478bd9Sstevel@tonic-gate 		return (4);
4337c478bd9Sstevel@tonic-gate 	else
4347c478bd9Sstevel@tonic-gate 		return (5);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate static void
der_write_length(unsigned char ** buf,int length)4387c478bd9Sstevel@tonic-gate der_write_length(unsigned char ** buf, int length)
4397c478bd9Sstevel@tonic-gate {
4407c478bd9Sstevel@tonic-gate 	if (length < (1<<7)) {
4417c478bd9Sstevel@tonic-gate 		*(*buf)++ = (unsigned char) length;
4427c478bd9Sstevel@tonic-gate 	} else {
4437c478bd9Sstevel@tonic-gate 		*(*buf)++ = (unsigned char) (der_length_size(length)+127);
4447c478bd9Sstevel@tonic-gate 		if (length >= (1<<24))
4457c478bd9Sstevel@tonic-gate 			*(*buf)++ = (unsigned char) (length>>24);
4467c478bd9Sstevel@tonic-gate 		if (length >= (1<<16))
4477c478bd9Sstevel@tonic-gate 			*(*buf)++ = (unsigned char) ((length>>16)&0xff);
4487c478bd9Sstevel@tonic-gate 		if (length >= (1<<8))
4497c478bd9Sstevel@tonic-gate 			*(*buf)++ = (unsigned char) ((length>>8)&0xff);
4507c478bd9Sstevel@tonic-gate 		*(*buf)++ = (unsigned char) (length&0xff);
4517c478bd9Sstevel@tonic-gate 	}
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate static int
der_read_length(buf,bufsize)4557c478bd9Sstevel@tonic-gate der_read_length(buf, bufsize)
4567c478bd9Sstevel@tonic-gate unsigned char **buf;
4577c478bd9Sstevel@tonic-gate int *bufsize;
4587c478bd9Sstevel@tonic-gate {
4597c478bd9Sstevel@tonic-gate 	unsigned char sf;
4607c478bd9Sstevel@tonic-gate 	int ret;
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 	if (*bufsize < 1)
4637c478bd9Sstevel@tonic-gate 		return (-1);
4647c478bd9Sstevel@tonic-gate 	sf = *(*buf)++;
4657c478bd9Sstevel@tonic-gate 	(*bufsize)--;
4667c478bd9Sstevel@tonic-gate 	if (sf & 0x80) {
4677c478bd9Sstevel@tonic-gate 		if ((sf &= 0x7f) > ((*bufsize)-1))
4687c478bd9Sstevel@tonic-gate 			return (-1);
4697c478bd9Sstevel@tonic-gate 		if (sf > DUMMY_SIZE_OF_INT)
4707c478bd9Sstevel@tonic-gate 			return (-1);
4717c478bd9Sstevel@tonic-gate 		ret = 0;
4727c478bd9Sstevel@tonic-gate 		for (; sf; sf--) {
4737c478bd9Sstevel@tonic-gate 			ret = (ret<<8) + (*(*buf)++);
4747c478bd9Sstevel@tonic-gate 			(*bufsize)--;
4757c478bd9Sstevel@tonic-gate 		}
4767c478bd9Sstevel@tonic-gate 	} else {
4777c478bd9Sstevel@tonic-gate 		ret = sf;
4787c478bd9Sstevel@tonic-gate 	}
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	return (ret);
4817c478bd9Sstevel@tonic-gate }
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate static int
g_token_size(mech,body_size)4847c478bd9Sstevel@tonic-gate g_token_size(mech, body_size)
4857c478bd9Sstevel@tonic-gate 	gss_OID mech;
4867c478bd9Sstevel@tonic-gate 	unsigned int body_size;
4877c478bd9Sstevel@tonic-gate {
4887c478bd9Sstevel@tonic-gate 	/* set body_size to sequence contents size */
4897c478bd9Sstevel@tonic-gate 	body_size += 4 + (int)mech->length;	/* NEED overflow check */
4907c478bd9Sstevel@tonic-gate 	return (1 + der_length_size(body_size) + body_size);
4917c478bd9Sstevel@tonic-gate }
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate static void
g_make_token_header(mech,body_size,buf,tok_type)4947c478bd9Sstevel@tonic-gate g_make_token_header(mech, body_size, buf, tok_type)
4957c478bd9Sstevel@tonic-gate 	gss_OID mech;
4967c478bd9Sstevel@tonic-gate 	int body_size;
4977c478bd9Sstevel@tonic-gate 	unsigned char **buf;
4987c478bd9Sstevel@tonic-gate 	int tok_type;
4997c478bd9Sstevel@tonic-gate {
5007c478bd9Sstevel@tonic-gate 	*(*buf)++ = 0x60;
5017c478bd9Sstevel@tonic-gate 	der_write_length(buf, 4 + mech->length + body_size);
5027c478bd9Sstevel@tonic-gate 	*(*buf)++ = 0x06;
5037c478bd9Sstevel@tonic-gate 	*(*buf)++ = (unsigned char) mech->length;
5047c478bd9Sstevel@tonic-gate 	TWRITE_STR(*buf, mech->elements, ((int)mech->length));
5057c478bd9Sstevel@tonic-gate 	*(*buf)++ = (unsigned char) ((tok_type>>8)&0xff);
5067c478bd9Sstevel@tonic-gate 	*(*buf)++ = (unsigned char) (tok_type&0xff);
5077c478bd9Sstevel@tonic-gate }
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate static int
g_verify_token_header(mech,body_size,buf_in,tok_type,toksize)5107c478bd9Sstevel@tonic-gate g_verify_token_header(mech, body_size, buf_in, tok_type, toksize)
5117c478bd9Sstevel@tonic-gate 	gss_OID mech;
5127c478bd9Sstevel@tonic-gate 	int *body_size;
5137c478bd9Sstevel@tonic-gate 	unsigned char **buf_in;
5147c478bd9Sstevel@tonic-gate 	int tok_type;
5157c478bd9Sstevel@tonic-gate 	int toksize;
5167c478bd9Sstevel@tonic-gate {
5177c478bd9Sstevel@tonic-gate 	unsigned char *buf = *buf_in;
5187c478bd9Sstevel@tonic-gate 	int seqsize;
5197c478bd9Sstevel@tonic-gate 	gss_OID_desc toid;
5207c478bd9Sstevel@tonic-gate 	int ret = 0;
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 	if ((toksize -= 1) < 0)
5237c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5247c478bd9Sstevel@tonic-gate 	if (*buf++ != 0x60)
5257c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 	if ((seqsize = der_read_length(&buf, &toksize)) < 0)
5287c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	if (seqsize != toksize)
5317c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 	if ((toksize -= 1) < 0)
5347c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5357c478bd9Sstevel@tonic-gate 	if (*buf++ != 0x06)
5367c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 	if ((toksize -= 1) < 0)
5397c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5407c478bd9Sstevel@tonic-gate 	toid.length = *buf++;
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate 	if ((toksize -= toid.length) < 0)
5437c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5447c478bd9Sstevel@tonic-gate 	toid.elements = buf;
5457c478bd9Sstevel@tonic-gate 	buf += toid.length;
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	if (! g_OID_equal(&toid, mech))
5487c478bd9Sstevel@tonic-gate 		ret = G_WRONG_MECH;
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	/*
5517c478bd9Sstevel@tonic-gate 	 * G_WRONG_MECH is not returned immediately because it's more important
5527c478bd9Sstevel@tonic-gate 	 * to return G_BAD_TOK_HEADER if the token header is in fact bad
5537c478bd9Sstevel@tonic-gate 	 */
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	if ((toksize -= 2) < 0)
5567c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate 	if ((*buf++ != ((tok_type>>8)&0xff)) ||
5597c478bd9Sstevel@tonic-gate 	    (*buf++ != (tok_type&0xff)))
5607c478bd9Sstevel@tonic-gate 		return (G_BAD_TOK_HEADER);
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	if (!ret) {
5637c478bd9Sstevel@tonic-gate 		*buf_in = buf;
5647c478bd9Sstevel@tonic-gate 		*body_size = toksize;
5657c478bd9Sstevel@tonic-gate 	}
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	return (ret);
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate static gss_buffer_desc
make_dummy_token_msg(void * data,int dataLen)5717c478bd9Sstevel@tonic-gate make_dummy_token_msg(void *data, int dataLen)
5727c478bd9Sstevel@tonic-gate {
5737c478bd9Sstevel@tonic-gate 	gss_buffer_desc buffer;
5747c478bd9Sstevel@tonic-gate 	int tlen;
5757c478bd9Sstevel@tonic-gate 	unsigned char *t;
5767c478bd9Sstevel@tonic-gate 	unsigned char *ptr;
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate 	if (data == NULL) {
5797c478bd9Sstevel@tonic-gate 		buffer.length = 0;
5807c478bd9Sstevel@tonic-gate 		buffer.value = NULL;
5817c478bd9Sstevel@tonic-gate 		return (buffer);
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate 	tlen = g_token_size((gss_OID)gss_mech_dummy, dataLen);
5857c478bd9Sstevel@tonic-gate 	t = (unsigned char *) MALLOC(tlen);
5867c478bd9Sstevel@tonic-gate 	ptr = t;
5877c478bd9Sstevel@tonic-gate 
5887c478bd9Sstevel@tonic-gate 	g_make_token_header((gss_OID)gss_mech_dummy, dataLen, &ptr, 0);
5897c478bd9Sstevel@tonic-gate 	(void) memcpy(ptr, data, dataLen);
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	buffer.length = tlen;
5927c478bd9Sstevel@tonic-gate 	buffer.value = (void *) t;
5937c478bd9Sstevel@tonic-gate 	return (buffer);
5947c478bd9Sstevel@tonic-gate }
595