1ad19d054Sgtb /*
2ad19d054Sgtb  * CDDL HEADER START
3ad19d054Sgtb  *
4ad19d054Sgtb  * The contents of this file are subject to the terms of the
5ad19d054Sgtb  * Common Development and Distribution License (the "License").
6ad19d054Sgtb  * You may not use this file except in compliance with the License.
7ad19d054Sgtb  *
8ad19d054Sgtb  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9ad19d054Sgtb  * or http://www.opensolaris.org/os/licensing.
10ad19d054Sgtb  * See the License for the specific language governing permissions
11ad19d054Sgtb  * and limitations under the License.
12ad19d054Sgtb  *
13ad19d054Sgtb  * When distributing Covered Code, include this CDDL HEADER in each
14ad19d054Sgtb  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15ad19d054Sgtb  * If applicable, add the following below this CDDL HEADER, with the
16ad19d054Sgtb  * fields enclosed by brackets "[]" replaced with your own identifying
17ad19d054Sgtb  * information: Portions Copyright [yyyy] [name of copyright owner]
18ad19d054Sgtb  *
19ad19d054Sgtb  * CDDL HEADER END
20ad19d054Sgtb  */
217c478bd9Sstevel@tonic-gate /*
22919de62bSmp  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*89b43686SBayard Bell  * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
257c478bd9Sstevel@tonic-gate  *
267c478bd9Sstevel@tonic-gate  * A module for Kerberos V5  security mechanism.
277c478bd9Sstevel@tonic-gate  *
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
327c478bd9Sstevel@tonic-gate #include <sys/errno.h>
337c478bd9Sstevel@tonic-gate #include <mechglueP.h>
347c478bd9Sstevel@tonic-gate #include <gssapiP_krb5.h>
357c478bd9Sstevel@tonic-gate #include <gssapi_err_generic.h>
367c478bd9Sstevel@tonic-gate #include <gssapi/kgssapi_defs.h>
377c478bd9Sstevel@tonic-gate #include <sys/debug.h>
387c478bd9Sstevel@tonic-gate #include <k5-int.h>
397c478bd9Sstevel@tonic-gate 
40ad19d054Sgtb /* mechglue wrappers */
41ab9b2e15Sgtb 
42ab9b2e15Sgtb static OM_uint32 k5glue_delete_sec_context
43ad19d054Sgtb 	(void *, OM_uint32 *,	/* minor_status */
44ad19d054Sgtb 	gss_ctx_id_t *,	/* context_handle */
45ad19d054Sgtb 	gss_buffer_t,	/* output_token */
46ad19d054Sgtb 	OM_uint32);
47ab9b2e15Sgtb 
48ab9b2e15Sgtb static OM_uint32 k5glue_sign
49ad19d054Sgtb 	(void *, OM_uint32 *,	/* minor_status */
50ad19d054Sgtb 	gss_ctx_id_t,	/* context_handle */
51ad19d054Sgtb 	int,		/* qop_req */
52ad19d054Sgtb 	gss_buffer_t,	/* message_buffer */
53ad19d054Sgtb 	gss_buffer_t,	/* message_token */
54ad19d054Sgtb 	OM_uint32);
55ab9b2e15Sgtb 
56ab9b2e15Sgtb static OM_uint32 k5glue_verify
57ad19d054Sgtb 	(void *, OM_uint32 *,	/* minor_status */
58ad19d054Sgtb 	gss_ctx_id_t,	/* context_handle */
59ad19d054Sgtb 	gss_buffer_t,	/* message_buffer */
60ad19d054Sgtb 	gss_buffer_t,	/* token_buffer */
61ad19d054Sgtb 	int *,	/* qop_state */
62ad19d054Sgtb 	OM_uint32);
63ab9b2e15Sgtb 
64ab9b2e15Sgtb static OM_uint32 k5glue_seal
65ad19d054Sgtb 	(void *, OM_uint32 *,	/* minor_status */
66ad19d054Sgtb 	gss_ctx_id_t,		/* context_handle */
67ad19d054Sgtb 	int,			/* conf_req_flag */
68ad19d054Sgtb 	int,			/* qop_req */
69ad19d054Sgtb 	gss_buffer_t,		/* input_message_buffer */
70ad19d054Sgtb 	int *,			/* conf_state */
71ad19d054Sgtb 	gss_buffer_t,		/* output_message_buffer */
72ad19d054Sgtb 	OM_uint32);
73ab9b2e15Sgtb 
74ab9b2e15Sgtb static OM_uint32 k5glue_unseal
75ad19d054Sgtb 	(void *, OM_uint32 *,	/* minor_status */
76ad19d054Sgtb 	gss_ctx_id_t,		/* context_handle */
77ad19d054Sgtb 	gss_buffer_t,		/* input_message_buffer */
78ad19d054Sgtb 	gss_buffer_t,		/* output_message_buffer */
79ad19d054Sgtb 	int *,			/* conf_state */
80ad19d054Sgtb 	int *,			/* qop_state */
81ad19d054Sgtb 	OM_uint32);
82ab9b2e15Sgtb 
83ab9b2e15Sgtb static OM_uint32 k5glue_import_sec_context
84ad19d054Sgtb 	(void *, OM_uint32 *,		/* minor_status */
85ad19d054Sgtb 	gss_buffer_t,			/* interprocess_token */
86ad19d054Sgtb 	gss_ctx_id_t *);		/* context_handle */
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate static	struct	gss_config krb5_mechanism =
917c478bd9Sstevel@tonic-gate 	{{9, "\052\206\110\206\367\022\001\002\002"},
927c478bd9Sstevel@tonic-gate 	NULL,	/* context */
937c478bd9Sstevel@tonic-gate 	NULL,	/* next */
947c478bd9Sstevel@tonic-gate 	TRUE,	/* uses_kmod */
95ab9b2e15Sgtb 	k5glue_unseal,
96ab9b2e15Sgtb 	k5glue_delete_sec_context,
97ab9b2e15Sgtb 	k5glue_seal,
98ab9b2e15Sgtb 	k5glue_import_sec_context,
99ab9b2e15Sgtb 	k5glue_sign,
100ab9b2e15Sgtb 	k5glue_verify,
101ab9b2e15Sgtb 	};
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate static gss_mechanism
gss_mech_initialize()1047c478bd9Sstevel@tonic-gate 	gss_mech_initialize()
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	return (&krb5_mechanism);
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate /*
1117c478bd9Sstevel@tonic-gate  * Module linkage information for the kernel.
1127c478bd9Sstevel@tonic-gate  */
1137c478bd9Sstevel@tonic-gate extern struct mod_ops mod_miscops;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate static struct modlmisc modlmisc = {
1167c478bd9Sstevel@tonic-gate 	&mod_miscops, "Krb5 GSS mechanism"
1177c478bd9Sstevel@tonic-gate };
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
1207c478bd9Sstevel@tonic-gate 	MODREV_1,
1217c478bd9Sstevel@tonic-gate 	(void *)&modlmisc,
1227c478bd9Sstevel@tonic-gate 	NULL
1237c478bd9Sstevel@tonic-gate };
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate static int krb5_fini_code = EBUSY;
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate int
_init()1297c478bd9Sstevel@tonic-gate _init()
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 	int retval;
1327c478bd9Sstevel@tonic-gate 	gss_mechanism mech, tmp;
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	if ((retval = mod_install(&modlinkage)) != 0)
1357c478bd9Sstevel@tonic-gate 		return (retval);
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	mech = gss_mech_initialize();
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	mutex_enter(&__kgss_mech_lock);
1407c478bd9Sstevel@tonic-gate 	tmp = __kgss_get_mechanism(&mech->mech_type);
1417c478bd9Sstevel@tonic-gate 	if (tmp != NULL) {
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 		KRB5_LOG0(KRB5_INFO,
144ad19d054Sgtb 		    "KRB5 GSS mechanism: mechanism already in table.\n");
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 		if (tmp->uses_kmod == TRUE) {
1477c478bd9Sstevel@tonic-gate 			KRB5_LOG0(KRB5_INFO, "KRB5 GSS mechanism: mechanism "
148ad19d054Sgtb 			    "table supports kernel operations!\n");
1497c478bd9Sstevel@tonic-gate 		}
1507c478bd9Sstevel@tonic-gate 		/*
1517c478bd9Sstevel@tonic-gate 		 * keep us loaded, but let us be unloadable. This
1527c478bd9Sstevel@tonic-gate 		 * will give the developer time to trouble shoot
1537c478bd9Sstevel@tonic-gate 		 */
1547c478bd9Sstevel@tonic-gate 		krb5_fini_code = 0;
1557c478bd9Sstevel@tonic-gate 	} else {
1567c478bd9Sstevel@tonic-gate 		__kgss_add_mechanism(mech);
1577c478bd9Sstevel@tonic-gate 		ASSERT(__kgss_get_mechanism(&mech->mech_type) == mech);
1587c478bd9Sstevel@tonic-gate 	}
1597c478bd9Sstevel@tonic-gate 	mutex_exit(&__kgss_mech_lock);
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	return (0);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate int
_fini()1657c478bd9Sstevel@tonic-gate _fini()
1667c478bd9Sstevel@tonic-gate {
1677c478bd9Sstevel@tonic-gate 	int ret = krb5_fini_code;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	if (ret == 0) {
1707c478bd9Sstevel@tonic-gate 		ret = (mod_remove(&modlinkage));
1717c478bd9Sstevel@tonic-gate 	}
1727c478bd9Sstevel@tonic-gate 	return (ret);
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate int
_info(struct modinfo * modinfop)1767c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop)
1777c478bd9Sstevel@tonic-gate {
1787c478bd9Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate 
181ab9b2e15Sgtb /* ARGSUSED */
182ab9b2e15Sgtb static OM_uint32
k5glue_delete_sec_context(ctx,minor_status,context_handle,output_token,gssd_ctx_verifier)183ab9b2e15Sgtb k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token,
184ab9b2e15Sgtb 	gssd_ctx_verifier)
185ad19d054Sgtb 	void *ctx;
186ad19d054Sgtb 	OM_uint32 *minor_status;
187ad19d054Sgtb 	gss_ctx_id_t *context_handle;
188ad19d054Sgtb 	gss_buffer_t output_token;
189ad19d054Sgtb 	OM_uint32 gssd_ctx_verifier;
1907c478bd9Sstevel@tonic-gate {
191ad19d054Sgtb 	return (krb5_gss_delete_sec_context(minor_status,
192ab9b2e15Sgtb 				    context_handle, output_token,
193ab9b2e15Sgtb 				    gssd_ctx_verifier));
194ab9b2e15Sgtb }
1957c478bd9Sstevel@tonic-gate 
196ab9b2e15Sgtb /* V2 */
197ab9b2e15Sgtb /* ARGSUSED */
198ab9b2e15Sgtb static OM_uint32
k5glue_import_sec_context(ctx,minor_status,interprocess_token,context_handle)199ab9b2e15Sgtb k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle)
200ad19d054Sgtb 	void *ctx;
201ad19d054Sgtb 	OM_uint32 *minor_status;
202ad19d054Sgtb 	gss_buffer_t	interprocess_token;
203ad19d054Sgtb 	gss_ctx_id_t	 *context_handle;
204ab9b2e15Sgtb {
205ad19d054Sgtb 	return (krb5_gss_import_sec_context(minor_status,
206ad19d054Sgtb 			interprocess_token,
207ad19d054Sgtb 			context_handle));
208ab9b2e15Sgtb }
2097c478bd9Sstevel@tonic-gate 
210ab9b2e15Sgtb /* V1 only */
211ab9b2e15Sgtb /* ARGSUSED */
212ab9b2e15Sgtb static OM_uint32
k5glue_seal(ctx,minor_status,context_handle,conf_req_flag,qop_req,input_message_buffer,conf_state,output_message_buffer,gssd_ctx_verifier)213ab9b2e15Sgtb k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req,
214ad19d054Sgtb 	    input_message_buffer, conf_state, output_message_buffer,
215ad19d054Sgtb 	    gssd_ctx_verifier)
216ad19d054Sgtb 	void *ctx;
217ad19d054Sgtb 	OM_uint32 *minor_status;
218ad19d054Sgtb 	gss_ctx_id_t context_handle;
219ad19d054Sgtb 	int conf_req_flag;
220ad19d054Sgtb 	int qop_req;
221ad19d054Sgtb 	gss_buffer_t input_message_buffer;
222ad19d054Sgtb 	int *conf_state;
223ad19d054Sgtb 	gss_buffer_t output_message_buffer;
224ad19d054Sgtb 	OM_uint32 gssd_ctx_verifier;
225ab9b2e15Sgtb {
226ad19d054Sgtb 	return (krb5_gss_seal(minor_status, context_handle,
227ab9b2e15Sgtb 			conf_req_flag, qop_req, input_message_buffer,
228ab9b2e15Sgtb 			conf_state, output_message_buffer, gssd_ctx_verifier));
229ab9b2e15Sgtb }
230ab9b2e15Sgtb 
231ab9b2e15Sgtb /* ARGSUSED */
232ab9b2e15Sgtb static OM_uint32
k5glue_sign(ctx,minor_status,context_handle,qop_req,message_buffer,message_token,gssd_ctx_verifier)233ab9b2e15Sgtb k5glue_sign(ctx, minor_status, context_handle,
234ad19d054Sgtb 		qop_req, message_buffer,
235ad19d054Sgtb 		message_token, gssd_ctx_verifier)
236ad19d054Sgtb 	void *ctx;
237ad19d054Sgtb 	OM_uint32 *minor_status;
238ad19d054Sgtb 	gss_ctx_id_t context_handle;
239ad19d054Sgtb 	int qop_req;
240ad19d054Sgtb 	gss_buffer_t message_buffer;
241ad19d054Sgtb 	gss_buffer_t message_token;
242ad19d054Sgtb 	OM_uint32 gssd_ctx_verifier;
243ab9b2e15Sgtb {
244ad19d054Sgtb 	return (krb5_gss_sign(minor_status, context_handle,
245ad19d054Sgtb 		qop_req, message_buffer, message_token, gssd_ctx_verifier));
246ab9b2e15Sgtb }
2477c478bd9Sstevel@tonic-gate 
248ab9b2e15Sgtb /* ARGSUSED */
249ab9b2e15Sgtb static OM_uint32
k5glue_unseal(ctx,minor_status,context_handle,input_message_buffer,output_message_buffer,conf_state,qop_state,gssd_ctx_verifier)250ab9b2e15Sgtb k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer,
251ab9b2e15Sgtb 	    output_message_buffer, conf_state, qop_state, gssd_ctx_verifier)
252ad19d054Sgtb 	void *ctx;
253ad19d054Sgtb 	OM_uint32 *minor_status;
254ad19d054Sgtb 	gss_ctx_id_t context_handle;
255ad19d054Sgtb 	gss_buffer_t input_message_buffer;
256ad19d054Sgtb 	gss_buffer_t output_message_buffer;
257ad19d054Sgtb 	int *conf_state;
258ad19d054Sgtb 	int *qop_state;
259ad19d054Sgtb 	OM_uint32 gssd_ctx_verifier;
260ab9b2e15Sgtb {
261ad19d054Sgtb 	return (krb5_gss_unseal(minor_status, context_handle,
262ad19d054Sgtb 				input_message_buffer, output_message_buffer,
263ad19d054Sgtb 				conf_state, qop_state, gssd_ctx_verifier));
264ab9b2e15Sgtb }
265ab9b2e15Sgtb 
266ab9b2e15Sgtb /* V1 only */
267ab9b2e15Sgtb /* ARGSUSED */
268ab9b2e15Sgtb static OM_uint32
k5glue_verify(ctx,minor_status,context_handle,message_buffer,token_buffer,qop_state,gssd_ctx_verifier)269ab9b2e15Sgtb k5glue_verify(ctx, minor_status, context_handle, message_buffer,
270ab9b2e15Sgtb 	    token_buffer, qop_state, gssd_ctx_verifier)
271ad19d054Sgtb 	void *ctx;
272ad19d054Sgtb 	OM_uint32 *minor_status;
273ad19d054Sgtb 	gss_ctx_id_t context_handle;
274ad19d054Sgtb 	gss_buffer_t message_buffer;
275ad19d054Sgtb 	gss_buffer_t token_buffer;
276ad19d054Sgtb 	int *qop_state;
277ad19d054Sgtb 	OM_uint32 gssd_ctx_verifier;
278ab9b2e15Sgtb {
279ad19d054Sgtb 	return (krb5_gss_verify(minor_status,
280ad19d054Sgtb 				context_handle,
281ad19d054Sgtb 				message_buffer,
282ad19d054Sgtb 				token_buffer,
283ad19d054Sgtb 				qop_state, gssd_ctx_verifier));
2847c478bd9Sstevel@tonic-gate }
285