xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c (revision 694c35faa87b858ecdadfe4fc592615f4eefbb07)
17c478bd9Sstevel@tonic-gate /*
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  */
21ad19d054Sgtb /*
22919de62bSmp153739  * 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 */
417c478bd9Sstevel@tonic-gate 
42ab9b2e15Sgtb static OM_uint32 k5glue_delete_sec_context
43ab9b2e15Sgtb 	(void *, OM_uint32 *,	/* minor_status */
44ab9b2e15Sgtb 	gss_ctx_id_t *,	/* context_handle */
45ab9b2e15Sgtb 	gss_buffer_t,	/* output_token */
46ab9b2e15Sgtb 	OM_uint32);
477c478bd9Sstevel@tonic-gate 
48ab9b2e15Sgtb static OM_uint32 k5glue_sign
49ab9b2e15Sgtb 	(void *, OM_uint32 *,	/* minor_status */
50ab9b2e15Sgtb 	gss_ctx_id_t,	/* context_handle */
51ab9b2e15Sgtb 	int,		/* qop_req */
52ab9b2e15Sgtb 	gss_buffer_t,	/* message_buffer */
53ab9b2e15Sgtb 	gss_buffer_t,	/* message_token */
54ab9b2e15Sgtb 	OM_uint32);
55ab9b2e15Sgtb 
56ab9b2e15Sgtb static OM_uint32 k5glue_verify
57ab9b2e15Sgtb 	(void *, OM_uint32 *,	/* minor_status */
58ab9b2e15Sgtb 	gss_ctx_id_t,	/* context_handle */
59ab9b2e15Sgtb 	gss_buffer_t,	/* message_buffer */
60ab9b2e15Sgtb 	gss_buffer_t,	/* token_buffer */
61ab9b2e15Sgtb 	int *,	/* qop_state */
62ab9b2e15Sgtb 	OM_uint32);
63ab9b2e15Sgtb 
64ab9b2e15Sgtb static OM_uint32 k5glue_seal
65ab9b2e15Sgtb 	(void *, OM_uint32 *,	/* minor_status */
66ab9b2e15Sgtb 	gss_ctx_id_t,		/* context_handle */
67ab9b2e15Sgtb 	int,			/* conf_req_flag */
68ab9b2e15Sgtb 	int,			/* qop_req */
69ab9b2e15Sgtb 	gss_buffer_t,		/* input_message_buffer */
70ab9b2e15Sgtb 	int *,			/* conf_state */
71ab9b2e15Sgtb 	gss_buffer_t,		/* output_message_buffer */
72ab9b2e15Sgtb 	OM_uint32);
73ab9b2e15Sgtb 
74ab9b2e15Sgtb static OM_uint32 k5glue_unseal
75ab9b2e15Sgtb 	(void *, OM_uint32 *,	/* minor_status */
76ab9b2e15Sgtb 	gss_ctx_id_t,		/* context_handle */
77ab9b2e15Sgtb 	gss_buffer_t,		/* input_message_buffer */
78ab9b2e15Sgtb 	gss_buffer_t,		/* output_message_buffer */
79ab9b2e15Sgtb 	int *,			/* conf_state */
80ab9b2e15Sgtb 	int *,			/* qop_state */
81ab9b2e15Sgtb 	OM_uint32);
82ab9b2e15Sgtb 
83ab9b2e15Sgtb static OM_uint32 k5glue_import_sec_context
84ab9b2e15Sgtb 	(void *, OM_uint32 *,		/* minor_status */
85ab9b2e15Sgtb 	gss_buffer_t,			/* interprocess_token */
86ab9b2e15Sgtb 	gss_ctx_id_t *);		/* context_handle */
87ab9b2e15Sgtb 
88ab9b2e15Sgtb 
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,
1017c478bd9Sstevel@tonic-gate 	};
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,
1447c478bd9Sstevel@tonic-gate 		    "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 "
1487c478bd9Sstevel@tonic-gate 			    "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)
185ab9b2e15Sgtb 	void *ctx;
186ab9b2e15Sgtb 	OM_uint32 *minor_status;
187ab9b2e15Sgtb 	gss_ctx_id_t *context_handle;
188ab9b2e15Sgtb 	gss_buffer_t output_token;
189ab9b2e15Sgtb 	OM_uint32 gssd_ctx_verifier;
1907c478bd9Sstevel@tonic-gate {
191ab9b2e15Sgtb 	return (krb5_gss_delete_sec_context(minor_status,
192ab9b2e15Sgtb 				    context_handle, output_token,
193ab9b2e15Sgtb 				    gssd_ctx_verifier));
1947c478bd9Sstevel@tonic-gate }
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)
200ab9b2e15Sgtb 	void *ctx;
201ab9b2e15Sgtb 	OM_uint32 *minor_status;
202ab9b2e15Sgtb 	gss_buffer_t	interprocess_token;
203ab9b2e15Sgtb 	gss_ctx_id_t	 *context_handle;
2047c478bd9Sstevel@tonic-gate {
205ab9b2e15Sgtb 	return (krb5_gss_import_sec_context(minor_status,
206ab9b2e15Sgtb 			interprocess_token,
207ab9b2e15Sgtb 			context_handle));
2087c478bd9Sstevel@tonic-gate }
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)
216ab9b2e15Sgtb 	void *ctx;
217ab9b2e15Sgtb 	OM_uint32 *minor_status;
218ab9b2e15Sgtb 	gss_ctx_id_t context_handle;
219ab9b2e15Sgtb 	int conf_req_flag;
220ab9b2e15Sgtb 	int qop_req;
221ab9b2e15Sgtb 	gss_buffer_t input_message_buffer;
222ab9b2e15Sgtb 	int *conf_state;
223ab9b2e15Sgtb 	gss_buffer_t output_message_buffer;
224ab9b2e15Sgtb 	OM_uint32 gssd_ctx_verifier;
225ab9b2e15Sgtb {
226ab9b2e15Sgtb 	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,
234ab9b2e15Sgtb 		qop_req, message_buffer,
235ab9b2e15Sgtb 		message_token, gssd_ctx_verifier)
236ab9b2e15Sgtb 	void *ctx;
237ab9b2e15Sgtb 	OM_uint32 *minor_status;
238ab9b2e15Sgtb 	gss_ctx_id_t context_handle;
239ab9b2e15Sgtb 	int qop_req;
240ab9b2e15Sgtb 	gss_buffer_t message_buffer;
241ab9b2e15Sgtb 	gss_buffer_t message_token;
242ab9b2e15Sgtb 	OM_uint32 gssd_ctx_verifier;
243ab9b2e15Sgtb {
244ab9b2e15Sgtb 	return (krb5_gss_sign(minor_status, context_handle,
245ab9b2e15Sgtb 		qop_req, message_buffer, message_token, gssd_ctx_verifier));
246ab9b2e15Sgtb }
247ab9b2e15Sgtb 
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)
252ab9b2e15Sgtb 	void *ctx;
253ab9b2e15Sgtb 	OM_uint32 *minor_status;
254ab9b2e15Sgtb 	gss_ctx_id_t context_handle;
255ab9b2e15Sgtb 	gss_buffer_t input_message_buffer;
256ab9b2e15Sgtb 	gss_buffer_t output_message_buffer;
257ab9b2e15Sgtb 	int *conf_state;
258ab9b2e15Sgtb 	int *qop_state;
259ab9b2e15Sgtb 	OM_uint32 gssd_ctx_verifier;
260ab9b2e15Sgtb {
261ab9b2e15Sgtb 	return (krb5_gss_unseal(minor_status, context_handle,
262ab9b2e15Sgtb 				input_message_buffer, output_message_buffer,
263ab9b2e15Sgtb 				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)
271ab9b2e15Sgtb 	void *ctx;
272ab9b2e15Sgtb 	OM_uint32 *minor_status;
273ab9b2e15Sgtb 	gss_ctx_id_t context_handle;
274ab9b2e15Sgtb 	gss_buffer_t message_buffer;
275ab9b2e15Sgtb 	gss_buffer_t token_buffer;
276ab9b2e15Sgtb 	int *qop_state;
277ab9b2e15Sgtb 	OM_uint32 gssd_ctx_verifier;
278ab9b2e15Sgtb {
279ab9b2e15Sgtb 	return (krb5_gss_verify(minor_status,
280ab9b2e15Sgtb 				context_handle,
281ab9b2e15Sgtb 				message_buffer,
282ab9b2e15Sgtb 				token_buffer,
283ab9b2e15Sgtb 				qop_state, gssd_ctx_verifier));
2847c478bd9Sstevel@tonic-gate }
285