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
krb5_gss_inquire_context(minor_status,context_handle,initiator_name,acceptor_name,lifetime_rec,mech_type,ret_flags,locally_initiated,opened)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
gss_krb5int_inq_session_key(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_OID desired_object,gss_buffer_set_t * data_set)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
gss_krb5int_extract_authz_data_from_sec_context(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_OID desired_object,gss_buffer_set_t * data_set)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
gss_krb5int_extract_authtime_from_sec_context(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_OID desired_oid,gss_buffer_set_t * data_set)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