xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c (revision 694c35faa87b858ecdadfe4fc592615f4eefbb07)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
25  *
26  * A module for Kerberos V5  security mechanism.
27  *
28  */
29 
30 #include <sys/types.h>
31 #include <sys/modctl.h>
32 #include <sys/errno.h>
33 #include <mechglueP.h>
34 #include <gssapiP_krb5.h>
35 #include <gssapi_err_generic.h>
36 #include <gssapi/kgssapi_defs.h>
37 #include <sys/debug.h>
38 #include <k5-int.h>
39 
40 /* mechglue wrappers */
41 
42 static OM_uint32 k5glue_delete_sec_context
43 	(void *, OM_uint32 *,	/* minor_status */
44 	gss_ctx_id_t *,	/* context_handle */
45 	gss_buffer_t,	/* output_token */
46 	OM_uint32);
47 
48 static OM_uint32 k5glue_sign
49 	(void *, OM_uint32 *,	/* minor_status */
50 	gss_ctx_id_t,	/* context_handle */
51 	int,		/* qop_req */
52 	gss_buffer_t,	/* message_buffer */
53 	gss_buffer_t,	/* message_token */
54 	OM_uint32);
55 
56 static OM_uint32 k5glue_verify
57 	(void *, OM_uint32 *,	/* minor_status */
58 	gss_ctx_id_t,	/* context_handle */
59 	gss_buffer_t,	/* message_buffer */
60 	gss_buffer_t,	/* token_buffer */
61 	int *,	/* qop_state */
62 	OM_uint32);
63 
64 static OM_uint32 k5glue_seal
65 	(void *, OM_uint32 *,	/* minor_status */
66 	gss_ctx_id_t,		/* context_handle */
67 	int,			/* conf_req_flag */
68 	int,			/* qop_req */
69 	gss_buffer_t,		/* input_message_buffer */
70 	int *,			/* conf_state */
71 	gss_buffer_t,		/* output_message_buffer */
72 	OM_uint32);
73 
74 static OM_uint32 k5glue_unseal
75 	(void *, OM_uint32 *,	/* minor_status */
76 	gss_ctx_id_t,		/* context_handle */
77 	gss_buffer_t,		/* input_message_buffer */
78 	gss_buffer_t,		/* output_message_buffer */
79 	int *,			/* conf_state */
80 	int *,			/* qop_state */
81 	OM_uint32);
82 
83 static OM_uint32 k5glue_import_sec_context
84 	(void *, OM_uint32 *,		/* minor_status */
85 	gss_buffer_t,			/* interprocess_token */
86 	gss_ctx_id_t *);		/* context_handle */
87 
88 
89 
90 static	struct	gss_config krb5_mechanism =
91 	{{9, "\052\206\110\206\367\022\001\002\002"},
92 	NULL,	/* context */
93 	NULL,	/* next */
94 	TRUE,	/* uses_kmod */
95 	k5glue_unseal,
96 	k5glue_delete_sec_context,
97 	k5glue_seal,
98 	k5glue_import_sec_context,
99 	k5glue_sign,
100 	k5glue_verify,
101 	};
102 
103 static gss_mechanism
104 	gss_mech_initialize()
105 {
106 	return (&krb5_mechanism);
107 }
108 
109 
110 /*
111  * Module linkage information for the kernel.
112  */
113 extern struct mod_ops mod_miscops;
114 
115 static struct modlmisc modlmisc = {
116 	&mod_miscops, "Krb5 GSS mechanism"
117 };
118 
119 static struct modlinkage modlinkage = {
120 	MODREV_1,
121 	(void *)&modlmisc,
122 	NULL
123 };
124 
125 
126 static int krb5_fini_code = EBUSY;
127 
128 int
129 _init()
130 {
131 	int retval;
132 	gss_mechanism mech, tmp;
133 
134 	if ((retval = mod_install(&modlinkage)) != 0)
135 		return (retval);
136 
137 	mech = gss_mech_initialize();
138 
139 	mutex_enter(&__kgss_mech_lock);
140 	tmp = __kgss_get_mechanism(&mech->mech_type);
141 	if (tmp != NULL) {
142 
143 		KRB5_LOG0(KRB5_INFO,
144 		    "KRB5 GSS mechanism: mechanism already in table.\n");
145 
146 		if (tmp->uses_kmod == TRUE) {
147 			KRB5_LOG0(KRB5_INFO, "KRB5 GSS mechanism: mechanism "
148 			    "table supports kernel operations!\n");
149 		}
150 		/*
151 		 * keep us loaded, but let us be unloadable. This
152 		 * will give the developer time to trouble shoot
153 		 */
154 		krb5_fini_code = 0;
155 	} else {
156 		__kgss_add_mechanism(mech);
157 		ASSERT(__kgss_get_mechanism(&mech->mech_type) == mech);
158 	}
159 	mutex_exit(&__kgss_mech_lock);
160 
161 	return (0);
162 }
163 
164 int
165 _fini()
166 {
167 	int ret = krb5_fini_code;
168 
169 	if (ret == 0) {
170 		ret = (mod_remove(&modlinkage));
171 	}
172 	return (ret);
173 }
174 
175 int
176 _info(struct modinfo *modinfop)
177 {
178 	return (mod_info(&modlinkage, modinfop));
179 }
180 
181 /* ARGSUSED */
182 static OM_uint32
183 k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token,
184 	gssd_ctx_verifier)
185 	void *ctx;
186 	OM_uint32 *minor_status;
187 	gss_ctx_id_t *context_handle;
188 	gss_buffer_t output_token;
189 	OM_uint32 gssd_ctx_verifier;
190 {
191 	return (krb5_gss_delete_sec_context(minor_status,
192 				    context_handle, output_token,
193 				    gssd_ctx_verifier));
194 }
195 
196 /* V2 */
197 /* ARGSUSED */
198 static OM_uint32
199 k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle)
200 	void *ctx;
201 	OM_uint32 *minor_status;
202 	gss_buffer_t	interprocess_token;
203 	gss_ctx_id_t	 *context_handle;
204 {
205 	return (krb5_gss_import_sec_context(minor_status,
206 			interprocess_token,
207 			context_handle));
208 }
209 
210 /* V1 only */
211 /* ARGSUSED */
212 static OM_uint32
213 k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req,
214 	    input_message_buffer, conf_state, output_message_buffer,
215 	    gssd_ctx_verifier)
216 	void *ctx;
217 	OM_uint32 *minor_status;
218 	gss_ctx_id_t context_handle;
219 	int conf_req_flag;
220 	int qop_req;
221 	gss_buffer_t input_message_buffer;
222 	int *conf_state;
223 	gss_buffer_t output_message_buffer;
224 	OM_uint32 gssd_ctx_verifier;
225 {
226 	return (krb5_gss_seal(minor_status, context_handle,
227 			conf_req_flag, qop_req, input_message_buffer,
228 			conf_state, output_message_buffer, gssd_ctx_verifier));
229 }
230 
231 /* ARGSUSED */
232 static OM_uint32
233 k5glue_sign(ctx, minor_status, context_handle,
234 		qop_req, message_buffer,
235 		message_token, gssd_ctx_verifier)
236 	void *ctx;
237 	OM_uint32 *minor_status;
238 	gss_ctx_id_t context_handle;
239 	int qop_req;
240 	gss_buffer_t message_buffer;
241 	gss_buffer_t message_token;
242 	OM_uint32 gssd_ctx_verifier;
243 {
244 	return (krb5_gss_sign(minor_status, context_handle,
245 		qop_req, message_buffer, message_token, gssd_ctx_verifier));
246 }
247 
248 /* ARGSUSED */
249 static OM_uint32
250 k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer,
251 	    output_message_buffer, conf_state, qop_state, gssd_ctx_verifier)
252 	void *ctx;
253 	OM_uint32 *minor_status;
254 	gss_ctx_id_t context_handle;
255 	gss_buffer_t input_message_buffer;
256 	gss_buffer_t output_message_buffer;
257 	int *conf_state;
258 	int *qop_state;
259 	OM_uint32 gssd_ctx_verifier;
260 {
261 	return (krb5_gss_unseal(minor_status, context_handle,
262 				input_message_buffer, output_message_buffer,
263 				conf_state, qop_state, gssd_ctx_verifier));
264 }
265 
266 /* V1 only */
267 /* ARGSUSED */
268 static OM_uint32
269 k5glue_verify(ctx, minor_status, context_handle, message_buffer,
270 	    token_buffer, qop_state, gssd_ctx_verifier)
271 	void *ctx;
272 	OM_uint32 *minor_status;
273 	gss_ctx_id_t context_handle;
274 	gss_buffer_t message_buffer;
275 	gss_buffer_t token_buffer;
276 	int *qop_state;
277 	OM_uint32 gssd_ctx_verifier;
278 {
279 	return (krb5_gss_verify(minor_status,
280 				context_handle,
281 				message_buffer,
282 				token_buffer,
283 				qop_state, gssd_ctx_verifier));
284 }
285