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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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