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, NULL } 122 }; 123 124 125 static int krb5_fini_code = EBUSY; 126 127 int 128 _init() 129 { 130 int retval; 131 gss_mechanism mech, tmp; 132 133 if ((retval = mod_install(&modlinkage)) != 0) 134 return (retval); 135 136 mech = gss_mech_initialize(); 137 138 mutex_enter(&__kgss_mech_lock); 139 tmp = __kgss_get_mechanism(&mech->mech_type); 140 if (tmp != NULL) { 141 142 KRB5_LOG0(KRB5_INFO, 143 "KRB5 GSS mechanism: mechanism already in table.\n"); 144 145 if (tmp->uses_kmod == TRUE) { 146 KRB5_LOG0(KRB5_INFO, "KRB5 GSS mechanism: mechanism " 147 "table supports kernel operations!\n"); 148 } 149 /* 150 * keep us loaded, but let us be unloadable. This 151 * will give the developer time to trouble shoot 152 */ 153 krb5_fini_code = 0; 154 } else { 155 __kgss_add_mechanism(mech); 156 ASSERT(__kgss_get_mechanism(&mech->mech_type) == mech); 157 } 158 mutex_exit(&__kgss_mech_lock); 159 160 return (0); 161 } 162 163 int 164 _fini() 165 { 166 int ret = krb5_fini_code; 167 168 if (ret == 0) { 169 ret = (mod_remove(&modlinkage)); 170 } 171 return (ret); 172 } 173 174 int 175 _info(struct modinfo *modinfop) 176 { 177 return (mod_info(&modlinkage, modinfop)); 178 } 179 180 /* ARGSUSED */ 181 static OM_uint32 182 k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token, 183 gssd_ctx_verifier) 184 void *ctx; 185 OM_uint32 *minor_status; 186 gss_ctx_id_t *context_handle; 187 gss_buffer_t output_token; 188 OM_uint32 gssd_ctx_verifier; 189 { 190 return (krb5_gss_delete_sec_context(minor_status, 191 context_handle, output_token, 192 gssd_ctx_verifier)); 193 } 194 195 /* V2 */ 196 /* ARGSUSED */ 197 static OM_uint32 198 k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle) 199 void *ctx; 200 OM_uint32 *minor_status; 201 gss_buffer_t interprocess_token; 202 gss_ctx_id_t *context_handle; 203 { 204 return (krb5_gss_import_sec_context(minor_status, 205 interprocess_token, 206 context_handle)); 207 } 208 209 /* V1 only */ 210 /* ARGSUSED */ 211 static OM_uint32 212 k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req, 213 input_message_buffer, conf_state, output_message_buffer, 214 gssd_ctx_verifier) 215 void *ctx; 216 OM_uint32 *minor_status; 217 gss_ctx_id_t context_handle; 218 int conf_req_flag; 219 int qop_req; 220 gss_buffer_t input_message_buffer; 221 int *conf_state; 222 gss_buffer_t output_message_buffer; 223 OM_uint32 gssd_ctx_verifier; 224 { 225 return (krb5_gss_seal(minor_status, context_handle, 226 conf_req_flag, qop_req, input_message_buffer, 227 conf_state, output_message_buffer, gssd_ctx_verifier)); 228 } 229 230 /* ARGSUSED */ 231 static OM_uint32 232 k5glue_sign(ctx, minor_status, context_handle, 233 qop_req, message_buffer, 234 message_token, gssd_ctx_verifier) 235 void *ctx; 236 OM_uint32 *minor_status; 237 gss_ctx_id_t context_handle; 238 int qop_req; 239 gss_buffer_t message_buffer; 240 gss_buffer_t message_token; 241 OM_uint32 gssd_ctx_verifier; 242 { 243 return (krb5_gss_sign(minor_status, context_handle, 244 qop_req, message_buffer, message_token, gssd_ctx_verifier)); 245 } 246 247 /* ARGSUSED */ 248 static OM_uint32 249 k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer, 250 output_message_buffer, conf_state, qop_state, gssd_ctx_verifier) 251 void *ctx; 252 OM_uint32 *minor_status; 253 gss_ctx_id_t context_handle; 254 gss_buffer_t input_message_buffer; 255 gss_buffer_t output_message_buffer; 256 int *conf_state; 257 int *qop_state; 258 OM_uint32 gssd_ctx_verifier; 259 { 260 return (krb5_gss_unseal(minor_status, context_handle, 261 input_message_buffer, output_message_buffer, 262 conf_state, qop_state, gssd_ctx_verifier)); 263 } 264 265 /* V1 only */ 266 /* ARGSUSED */ 267 static OM_uint32 268 k5glue_verify(ctx, minor_status, context_handle, message_buffer, 269 token_buffer, qop_state, gssd_ctx_verifier) 270 void *ctx; 271 OM_uint32 *minor_status; 272 gss_ctx_id_t context_handle; 273 gss_buffer_t message_buffer; 274 gss_buffer_t token_buffer; 275 int *qop_state; 276 OM_uint32 gssd_ctx_verifier; 277 { 278 return (krb5_gss_verify(minor_status, 279 context_handle, 280 message_buffer, 281 token_buffer, 282 qop_state, gssd_ctx_verifier)); 283 }