1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* -*- mode: c; indent-tabs-mode: nil -*- */ 6 /* 7 * Copyright 1993 by OpenVision Technologies, Inc. 8 * 9 * Permission to use, copy, modify, distribute, and sell this software 10 * and its documentation for any purpose is hereby granted without fee, 11 * provided that the above copyright notice appears in all copies and 12 * that both that copyright notice and this permission notice appear in 13 * supporting documentation, and that the name of OpenVision not be used 14 * in advertising or publicity pertaining to distribution of the software 15 * without specific, written prior permission. OpenVision makes no 16 * representations about the suitability of this software for any 17 * purpose. It is provided "as is" without express or implied warranty. 18 * 19 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 21 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 23 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 24 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 25 * PERFORMANCE OF THIS SOFTWARE. 26 */ 27 /* 28 * Copyright (c) 2006-2008, Novell, Inc. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions are met: 33 * 34 * * Redistributions of source code must retain the above copyright notice, 35 * this list of conditions and the following disclaimer. 36 * * Redistributions in binary form must reproduce the above copyright 37 * notice, this list of conditions and the following disclaimer in the 38 * documentation and/or other materials provided with the distribution. 39 * * The copyright holder's name is not used to endorse or promote products 40 * derived from this software without specific prior written permission. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 43 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 46 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 47 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 48 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 49 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 50 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 52 * POSSIBILITY OF SUCH DAMAGE. 53 */ 54 /* 55 * Copyright (c) 2006-2008, Novell, Inc. 56 * All rights reserved. 57 * 58 * Redistribution and use in source and binary forms, with or without 59 * modification, are permitted provided that the following conditions are met: 60 * 61 * * Redistributions of source code must retain the above copyright notice, 62 * this list of conditions and the following disclaimer. 63 * * Redistributions in binary form must reproduce the above copyright 64 * notice, this list of conditions and the following disclaimer in the 65 * documentation and/or other materials provided with the distribution. 66 * * The copyright holder's name is not used to endorse or promote products 67 * derived from this software without specific prior written permission. 68 * 69 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 70 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 71 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 72 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 73 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 74 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 75 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 76 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 77 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 78 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 79 * POSSIBILITY OF SUCH DAMAGE. 80 */ 81 82 #include "gssapiP_krb5.h" 83 #include "mechglueP.h" /* SUNW17PACresync */ 84 85 OM_uint32 86 krb5_gss_inquire_context(minor_status, context_handle, initiator_name, 87 acceptor_name, lifetime_rec, mech_type, ret_flags, 88 locally_initiated, opened) 89 OM_uint32 *minor_status; 90 gss_ctx_id_t context_handle; 91 gss_name_t *initiator_name; 92 gss_name_t *acceptor_name; 93 OM_uint32 *lifetime_rec; 94 gss_OID *mech_type; 95 OM_uint32 *ret_flags; 96 int *locally_initiated; 97 int *opened; 98 { 99 krb5_context context; 100 krb5_error_code code; 101 krb5_gss_ctx_id_rec *ctx; 102 krb5_principal initiator, acceptor; 103 krb5_timestamp now; 104 krb5_deltat lifetime; 105 106 if (initiator_name) 107 *initiator_name = (gss_name_t) NULL; 108 if (acceptor_name) 109 *acceptor_name = (gss_name_t) NULL; 110 111 /* validate the context handle */ 112 if (! kg_validate_ctx_id(context_handle)) { 113 *minor_status = (OM_uint32) G_VALIDATE_FAILED; 114 return(GSS_S_NO_CONTEXT); 115 } 116 117 ctx = (krb5_gss_ctx_id_rec *) context_handle; 118 119 if (! ctx->established) { 120 *minor_status = KG_CTX_INCOMPLETE; 121 return(GSS_S_NO_CONTEXT); 122 } 123 124 initiator = NULL; 125 acceptor = NULL; 126 context = ctx->k5_context; 127 128 if ((code = krb5_timeofday(context, &now))) { 129 *minor_status = code; 130 save_error_info(*minor_status, context); 131 return(GSS_S_FAILURE); 132 } 133 134 135 /* SUNW17PACresync - should be krb_times.endtime (revisit) */ 136 if ((lifetime = ctx->endtime - now) < 0) 137 lifetime = 0; 138 139 if (initiator_name) { 140 if ((code = krb5_copy_principal(context, 141 ctx->initiate?ctx->here:ctx->there, 142 &initiator))) { 143 *minor_status = code; 144 save_error_info(*minor_status, context); 145 return(GSS_S_FAILURE); 146 } 147 if (! kg_save_name((gss_name_t) initiator)) { 148 krb5_free_principal(context, initiator); 149 *minor_status = (OM_uint32) G_VALIDATE_FAILED; 150 return(GSS_S_FAILURE); 151 } 152 } 153 154 if (acceptor_name) { 155 if ((code = krb5_copy_principal(context, 156 ctx->initiate?ctx->there:ctx->here, 157 &acceptor))) { 158 if (initiator) krb5_free_principal(context, initiator); 159 *minor_status = code; 160 save_error_info(*minor_status, context); 161 return(GSS_S_FAILURE); 162 } 163 if (! kg_save_name((gss_name_t) acceptor)) { 164 krb5_free_principal(context, acceptor); 165 if (initiator) { 166 kg_delete_name((gss_name_t) initiator); 167 krb5_free_principal(context, initiator); 168 } 169 *minor_status = (OM_uint32) G_VALIDATE_FAILED; 170 return(GSS_S_FAILURE); 171 } 172 } 173 174 if (initiator_name) 175 *initiator_name = (gss_name_t) initiator; 176 177 if (acceptor_name) 178 *acceptor_name = (gss_name_t) acceptor; 179 180 if (lifetime_rec) 181 *lifetime_rec = lifetime; 182 183 if (mech_type) 184 *mech_type = (gss_OID) ctx->mech_used; 185 186 if (ret_flags) 187 *ret_flags = ctx->gss_flags; 188 189 if (locally_initiated) 190 *locally_initiated = ctx->initiate; 191 192 if (opened) 193 *opened = ctx->established; 194 195 *minor_status = 0; 196 197 return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); 198 } 199 200 OM_uint32 201 gss_krb5int_inq_session_key( 202 OM_uint32 *minor_status, 203 const gss_ctx_id_t context_handle, 204 const gss_OID desired_object, 205 gss_buffer_set_t *data_set) 206 { 207 krb5_gss_ctx_id_rec *ctx; 208 krb5_keyblock *key; 209 gss_buffer_desc keyvalue, keyinfo; 210 OM_uint32 major_status, minor; 211 unsigned char oid_buf[GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH + 6]; 212 gss_OID_desc oid; 213 214 ctx = (krb5_gss_ctx_id_rec *) context_handle; 215 key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey; 216 217 keyvalue.value = key->contents; 218 keyvalue.length = key->length; 219 220 major_status = generic_gss_add_buffer_set_member(minor_status, &keyvalue, data_set); 221 if (GSS_ERROR(major_status)) 222 goto cleanup; 223 224 oid.elements = oid_buf; 225 oid.length = sizeof(oid_buf); 226 227 major_status = generic_gss_oid_compose(minor_status, 228 GSS_KRB5_SESSION_KEY_ENCTYPE_OID, 229 GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH, 230 key->enctype, 231 &oid); 232 if (GSS_ERROR(major_status)) 233 goto cleanup; 234 235 keyinfo.value = oid.elements; 236 keyinfo.length = oid.length; 237 238 major_status = generic_gss_add_buffer_set_member(minor_status, &keyinfo, data_set); 239 if (GSS_ERROR(major_status)) 240 goto cleanup; 241 242 return GSS_S_COMPLETE; 243 244 cleanup: 245 if (*data_set != GSS_C_NO_BUFFER_SET) { 246 if ((*data_set)->count != 0) 247 memset((*data_set)->elements[0].value, 0, (*data_set)->elements[0].length); 248 gss_release_buffer_set(&minor, data_set); 249 } 250 251 return major_status; 252 } 253 254 OM_uint32 255 gss_krb5int_extract_authz_data_from_sec_context( 256 OM_uint32 *minor_status, 257 const gss_ctx_id_t context_handle, 258 const gss_OID desired_object, 259 gss_buffer_set_t *data_set) 260 { 261 OM_uint32 major_status; 262 krb5_gss_ctx_id_rec *ctx; 263 int ad_type = 0; 264 size_t i; 265 266 *data_set = GSS_C_NO_BUFFER_SET; 267 268 ctx = (krb5_gss_ctx_id_rec *) context_handle; 269 270 major_status = generic_gss_oid_decompose(minor_status, 271 GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID, 272 GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH, 273 desired_object, 274 &ad_type); 275 if (major_status != GSS_S_COMPLETE || ad_type == 0) { 276 *minor_status = ENOENT; 277 return major_status; /* SUNW17PACresync */ 278 } 279 280 if (ctx->authdata != NULL) { 281 for (i = 0; ctx->authdata[i] != NULL; i++) { 282 if (ctx->authdata[i]->ad_type == ad_type) { 283 gss_buffer_desc ad_data; 284 285 ad_data.length = ctx->authdata[i]->length; 286 ad_data.value = ctx->authdata[i]->contents; 287 288 major_status = generic_gss_add_buffer_set_member(minor_status, 289 &ad_data, data_set); 290 if (GSS_ERROR(major_status)) 291 break; 292 } 293 } 294 } 295 296 if (GSS_ERROR(major_status)) { 297 OM_uint32 tmp; 298 299 generic_gss_release_buffer_set(&tmp, data_set); 300 } 301 302 return major_status; 303 } 304 305 OM_uint32 306 gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status, 307 const gss_ctx_id_t context_handle, 308 const gss_OID desired_oid, 309 gss_buffer_set_t *data_set) 310 { 311 krb5_gss_ctx_id_rec *ctx; 312 gss_buffer_desc rep; 313 314 ctx = (krb5_gss_ctx_id_rec *) context_handle; 315 316 rep.value = &ctx->krb_times.authtime; 317 rep.length = sizeof(ctx->krb_times.authtime); 318 319 return generic_gss_add_buffer_set_member(minor_status, &rep, data_set); 320 } 321 322