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 }