1c19800e8SDoug Rabson /*
2c19800e8SDoug Rabson * Copyright (c) 2004, PADL Software Pty Ltd.
3c19800e8SDoug Rabson * All rights reserved.
4c19800e8SDoug Rabson *
5c19800e8SDoug Rabson * Redistribution and use in source and binary forms, with or without
6c19800e8SDoug Rabson * modification, are permitted provided that the following conditions
7c19800e8SDoug Rabson * are met:
8c19800e8SDoug Rabson *
9c19800e8SDoug Rabson * 1. Redistributions of source code must retain the above copyright
10c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer.
11c19800e8SDoug Rabson *
12c19800e8SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright
13c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer in the
14c19800e8SDoug Rabson * documentation and/or other materials provided with the distribution.
15c19800e8SDoug Rabson *
16c19800e8SDoug Rabson * 3. Neither the name of PADL Software nor the names of its contributors
17c19800e8SDoug Rabson * may be used to endorse or promote products derived from this software
18c19800e8SDoug Rabson * without specific prior written permission.
19c19800e8SDoug Rabson *
20c19800e8SDoug Rabson * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21c19800e8SDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c19800e8SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c19800e8SDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24c19800e8SDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c19800e8SDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c19800e8SDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c19800e8SDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c19800e8SDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c19800e8SDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c19800e8SDoug Rabson * SUCH DAMAGE.
31c19800e8SDoug Rabson */
32c19800e8SDoug Rabson
33*ae771770SStanislav Sedov #include "spnego_locl.h"
34c19800e8SDoug Rabson
35*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
_gss_spnego_release_cred(OM_uint32 * minor_status,gss_cred_id_t * cred_handle)36c19800e8SDoug Rabson _gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
37c19800e8SDoug Rabson {
38c19800e8SDoug Rabson OM_uint32 ret;
39c19800e8SDoug Rabson
40c19800e8SDoug Rabson *minor_status = 0;
41c19800e8SDoug Rabson
42*ae771770SStanislav Sedov if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL)
43c19800e8SDoug Rabson return GSS_S_COMPLETE;
44c19800e8SDoug Rabson
45*ae771770SStanislav Sedov ret = gss_release_cred(minor_status, cred_handle);
46c19800e8SDoug Rabson
47c19800e8SDoug Rabson *cred_handle = GSS_C_NO_CREDENTIAL;
48c19800e8SDoug Rabson
49c19800e8SDoug Rabson return ret;
50c19800e8SDoug Rabson }
51c19800e8SDoug Rabson
52c19800e8SDoug Rabson /*
53c19800e8SDoug Rabson * For now, just a simple wrapper that avoids recursion. When
54c19800e8SDoug Rabson * we support gss_{get,set}_neg_mechs() we will need to expose
55c19800e8SDoug Rabson * more functionality.
56c19800e8SDoug Rabson */
_gss_spnego_acquire_cred(OM_uint32 * minor_status,const gss_name_t desired_name,OM_uint32 time_req,const gss_OID_set desired_mechs,gss_cred_usage_t cred_usage,gss_cred_id_t * output_cred_handle,gss_OID_set * actual_mechs,OM_uint32 * time_rec)57*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_acquire_cred
58c19800e8SDoug Rabson (OM_uint32 *minor_status,
59c19800e8SDoug Rabson const gss_name_t desired_name,
60c19800e8SDoug Rabson OM_uint32 time_req,
61c19800e8SDoug Rabson const gss_OID_set desired_mechs,
62c19800e8SDoug Rabson gss_cred_usage_t cred_usage,
63c19800e8SDoug Rabson gss_cred_id_t * output_cred_handle,
64c19800e8SDoug Rabson gss_OID_set * actual_mechs,
65c19800e8SDoug Rabson OM_uint32 * time_rec
66c19800e8SDoug Rabson )
67c19800e8SDoug Rabson {
68c19800e8SDoug Rabson const spnego_name dname = (const spnego_name)desired_name;
69c19800e8SDoug Rabson gss_name_t name = GSS_C_NO_NAME;
70c19800e8SDoug Rabson OM_uint32 ret, tmp;
71c19800e8SDoug Rabson gss_OID_set_desc actual_desired_mechs;
72c19800e8SDoug Rabson gss_OID_set mechs;
73*ae771770SStanislav Sedov size_t i, j;
74c19800e8SDoug Rabson
75c19800e8SDoug Rabson *output_cred_handle = GSS_C_NO_CREDENTIAL;
76c19800e8SDoug Rabson
77c19800e8SDoug Rabson if (dname) {
78c19800e8SDoug Rabson ret = gss_import_name(minor_status, &dname->value, &dname->type, &name);
79c19800e8SDoug Rabson if (ret) {
80c19800e8SDoug Rabson return ret;
81c19800e8SDoug Rabson }
82c19800e8SDoug Rabson }
83c19800e8SDoug Rabson
84c19800e8SDoug Rabson ret = gss_indicate_mechs(minor_status, &mechs);
85c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE) {
86c19800e8SDoug Rabson gss_release_name(minor_status, &name);
87c19800e8SDoug Rabson return ret;
88c19800e8SDoug Rabson }
89c19800e8SDoug Rabson
90c19800e8SDoug Rabson /* Remove ourselves from this list */
91c19800e8SDoug Rabson actual_desired_mechs.count = mechs->count;
92c19800e8SDoug Rabson actual_desired_mechs.elements = malloc(actual_desired_mechs.count *
93c19800e8SDoug Rabson sizeof(gss_OID_desc));
94c19800e8SDoug Rabson if (actual_desired_mechs.elements == NULL) {
95c19800e8SDoug Rabson *minor_status = ENOMEM;
96c19800e8SDoug Rabson ret = GSS_S_FAILURE;
97c19800e8SDoug Rabson goto out;
98c19800e8SDoug Rabson }
99c19800e8SDoug Rabson
100c19800e8SDoug Rabson for (i = 0, j = 0; i < mechs->count; i++) {
101c19800e8SDoug Rabson if (gss_oid_equal(&mechs->elements[i], GSS_SPNEGO_MECHANISM))
102c19800e8SDoug Rabson continue;
103c19800e8SDoug Rabson
104c19800e8SDoug Rabson actual_desired_mechs.elements[j] = mechs->elements[i];
105c19800e8SDoug Rabson j++;
106c19800e8SDoug Rabson }
107c19800e8SDoug Rabson actual_desired_mechs.count = j;
108c19800e8SDoug Rabson
109c19800e8SDoug Rabson ret = gss_acquire_cred(minor_status, name,
110c19800e8SDoug Rabson time_req, &actual_desired_mechs,
111c19800e8SDoug Rabson cred_usage,
112*ae771770SStanislav Sedov output_cred_handle,
113c19800e8SDoug Rabson actual_mechs, time_rec);
114c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE)
115c19800e8SDoug Rabson goto out;
116c19800e8SDoug Rabson
117c19800e8SDoug Rabson out:
118c19800e8SDoug Rabson gss_release_name(minor_status, &name);
119c19800e8SDoug Rabson gss_release_oid_set(&tmp, &mechs);
120c19800e8SDoug Rabson if (actual_desired_mechs.elements != NULL) {
121c19800e8SDoug Rabson free(actual_desired_mechs.elements);
122c19800e8SDoug Rabson }
123c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE) {
124*ae771770SStanislav Sedov _gss_spnego_release_cred(&tmp, output_cred_handle);
125c19800e8SDoug Rabson }
126c19800e8SDoug Rabson
127c19800e8SDoug Rabson return ret;
128c19800e8SDoug Rabson }
129c19800e8SDoug Rabson
_gss_spnego_inquire_cred(OM_uint32 * minor_status,const gss_cred_id_t cred_handle,gss_name_t * name,OM_uint32 * lifetime,gss_cred_usage_t * cred_usage,gss_OID_set * mechanisms)130*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred
131c19800e8SDoug Rabson (OM_uint32 * minor_status,
132c19800e8SDoug Rabson const gss_cred_id_t cred_handle,
133c19800e8SDoug Rabson gss_name_t * name,
134c19800e8SDoug Rabson OM_uint32 * lifetime,
135c19800e8SDoug Rabson gss_cred_usage_t * cred_usage,
136c19800e8SDoug Rabson gss_OID_set * mechanisms
137c19800e8SDoug Rabson )
138c19800e8SDoug Rabson {
139c19800e8SDoug Rabson spnego_name sname = NULL;
140c19800e8SDoug Rabson OM_uint32 ret;
141c19800e8SDoug Rabson
142c19800e8SDoug Rabson if (cred_handle == GSS_C_NO_CREDENTIAL) {
143c19800e8SDoug Rabson *minor_status = 0;
144c19800e8SDoug Rabson return GSS_S_NO_CRED;
145c19800e8SDoug Rabson }
146c19800e8SDoug Rabson
147c19800e8SDoug Rabson if (name) {
148c19800e8SDoug Rabson sname = calloc(1, sizeof(*sname));
149c19800e8SDoug Rabson if (sname == NULL) {
150c19800e8SDoug Rabson *minor_status = ENOMEM;
151c19800e8SDoug Rabson return GSS_S_FAILURE;
152c19800e8SDoug Rabson }
153c19800e8SDoug Rabson }
154c19800e8SDoug Rabson
155c19800e8SDoug Rabson ret = gss_inquire_cred(minor_status,
156*ae771770SStanislav Sedov cred_handle,
157c19800e8SDoug Rabson sname ? &sname->mech : NULL,
158c19800e8SDoug Rabson lifetime,
159c19800e8SDoug Rabson cred_usage,
160c19800e8SDoug Rabson mechanisms);
161c19800e8SDoug Rabson if (ret) {
162c19800e8SDoug Rabson if (sname)
163c19800e8SDoug Rabson free(sname);
164c19800e8SDoug Rabson return ret;
165c19800e8SDoug Rabson }
166c19800e8SDoug Rabson if (name)
167c19800e8SDoug Rabson *name = (gss_name_t)sname;
168c19800e8SDoug Rabson
169c19800e8SDoug Rabson return ret;
170c19800e8SDoug Rabson }
171c19800e8SDoug Rabson
_gss_spnego_inquire_cred_by_mech(OM_uint32 * minor_status,const gss_cred_id_t cred_handle,const gss_OID mech_type,gss_name_t * name,OM_uint32 * initiator_lifetime,OM_uint32 * acceptor_lifetime,gss_cred_usage_t * cred_usage)172*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred_by_mech (
173c19800e8SDoug Rabson OM_uint32 * minor_status,
174c19800e8SDoug Rabson const gss_cred_id_t cred_handle,
175c19800e8SDoug Rabson const gss_OID mech_type,
176c19800e8SDoug Rabson gss_name_t * name,
177c19800e8SDoug Rabson OM_uint32 * initiator_lifetime,
178c19800e8SDoug Rabson OM_uint32 * acceptor_lifetime,
179c19800e8SDoug Rabson gss_cred_usage_t * cred_usage
180c19800e8SDoug Rabson )
181c19800e8SDoug Rabson {
182c19800e8SDoug Rabson spnego_name sname = NULL;
183c19800e8SDoug Rabson OM_uint32 ret;
184c19800e8SDoug Rabson
185c19800e8SDoug Rabson if (cred_handle == GSS_C_NO_CREDENTIAL) {
186c19800e8SDoug Rabson *minor_status = 0;
187c19800e8SDoug Rabson return GSS_S_NO_CRED;
188c19800e8SDoug Rabson }
189c19800e8SDoug Rabson
190c19800e8SDoug Rabson if (name) {
191c19800e8SDoug Rabson sname = calloc(1, sizeof(*sname));
192c19800e8SDoug Rabson if (sname == NULL) {
193c19800e8SDoug Rabson *minor_status = ENOMEM;
194c19800e8SDoug Rabson return GSS_S_FAILURE;
195c19800e8SDoug Rabson }
196c19800e8SDoug Rabson }
197c19800e8SDoug Rabson
198c19800e8SDoug Rabson ret = gss_inquire_cred_by_mech(minor_status,
199*ae771770SStanislav Sedov cred_handle,
200c19800e8SDoug Rabson mech_type,
201c19800e8SDoug Rabson sname ? &sname->mech : NULL,
202c19800e8SDoug Rabson initiator_lifetime,
203c19800e8SDoug Rabson acceptor_lifetime,
204c19800e8SDoug Rabson cred_usage);
205c19800e8SDoug Rabson
206c19800e8SDoug Rabson if (ret) {
207c19800e8SDoug Rabson if (sname)
208c19800e8SDoug Rabson free(sname);
209c19800e8SDoug Rabson return ret;
210c19800e8SDoug Rabson }
211c19800e8SDoug Rabson if (name)
212c19800e8SDoug Rabson *name = (gss_name_t)sname;
213c19800e8SDoug Rabson
214c19800e8SDoug Rabson return GSS_S_COMPLETE;
215c19800e8SDoug Rabson }
216c19800e8SDoug Rabson
_gss_spnego_inquire_cred_by_oid(OM_uint32 * minor_status,const gss_cred_id_t cred_handle,const gss_OID desired_object,gss_buffer_set_t * data_set)217*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred_by_oid
218c19800e8SDoug Rabson (OM_uint32 * minor_status,
219c19800e8SDoug Rabson const gss_cred_id_t cred_handle,
220c19800e8SDoug Rabson const gss_OID desired_object,
221c19800e8SDoug Rabson gss_buffer_set_t *data_set)
222c19800e8SDoug Rabson {
223c19800e8SDoug Rabson OM_uint32 ret;
224c19800e8SDoug Rabson
225c19800e8SDoug Rabson if (cred_handle == GSS_C_NO_CREDENTIAL) {
226c19800e8SDoug Rabson *minor_status = 0;
227c19800e8SDoug Rabson return GSS_S_NO_CRED;
228c19800e8SDoug Rabson }
229c19800e8SDoug Rabson
230c19800e8SDoug Rabson ret = gss_inquire_cred_by_oid(minor_status,
231*ae771770SStanislav Sedov cred_handle,
232c19800e8SDoug Rabson desired_object,
233c19800e8SDoug Rabson data_set);
234c19800e8SDoug Rabson
235c19800e8SDoug Rabson return ret;
236c19800e8SDoug Rabson }
237c19800e8SDoug Rabson
238*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
_gss_spnego_set_cred_option(OM_uint32 * minor_status,gss_cred_id_t * cred_handle,const gss_OID object,const gss_buffer_t value)239*ae771770SStanislav Sedov _gss_spnego_set_cred_option (OM_uint32 *minor_status,
240*ae771770SStanislav Sedov gss_cred_id_t *cred_handle,
241*ae771770SStanislav Sedov const gss_OID object,
242*ae771770SStanislav Sedov const gss_buffer_t value)
243*ae771770SStanislav Sedov {
244*ae771770SStanislav Sedov if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
245*ae771770SStanislav Sedov *minor_status = 0;
246*ae771770SStanislav Sedov return GSS_S_NO_CRED;
247*ae771770SStanislav Sedov }
248*ae771770SStanislav Sedov
249*ae771770SStanislav Sedov return gss_set_cred_option(minor_status,
250*ae771770SStanislav Sedov cred_handle,
251*ae771770SStanislav Sedov object,
252*ae771770SStanislav Sedov value);
253*ae771770SStanislav Sedov }
254*ae771770SStanislav Sedov
255*ae771770SStanislav Sedov #if 0
256*ae771770SStanislav Sedov
257*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
258*ae771770SStanislav Sedov _gss_spnego_export_cred (OM_uint32 *minor_status,
259*ae771770SStanislav Sedov gss_cred_id_t cred_handle,
260*ae771770SStanislav Sedov gss_buffer_t value)
261*ae771770SStanislav Sedov {
262*ae771770SStanislav Sedov return gss_export_cred(minor_status, cred_handle, value);
263*ae771770SStanislav Sedov }
264*ae771770SStanislav Sedov
265*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
266*ae771770SStanislav Sedov _gss_spnego_import_cred (OM_uint32 *minor_status,
267*ae771770SStanislav Sedov gss_buffer_t value,
268*ae771770SStanislav Sedov gss_cred_id_t *cred_handle)
269*ae771770SStanislav Sedov {
270*ae771770SStanislav Sedov return gss_import_cred(minor_status, value, cred_handle);
271*ae771770SStanislav Sedov }
272*ae771770SStanislav Sedov
273*ae771770SStanislav Sedov #endif
274