Line data Source code
1 : /*-
2 : * Copyright (c) 2005 Doug Rabson
3 : * All rights reserved.
4 : *
5 : * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : *
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 : * SUCH DAMAGE.
27 : *
28 : * $FreeBSD: src/lib/libgssapi/gss_names.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
29 : */
30 :
31 : #include "mech_locl.h"
32 :
33 : gss_name_t
34 0 : _gss_mg_get_underlying_mech_name(gss_name_t name,
35 : gss_const_OID mech)
36 : {
37 0 : struct _gss_name *n = (struct _gss_name *)name;
38 0 : struct _gss_mechanism_name *mn;
39 :
40 0 : HEIM_TAILQ_FOREACH(mn, &n->gn_mn, gmn_link) {
41 0 : if (gss_oid_equal(mech, mn->gmn_mech_oid))
42 0 : return mn->gmn_name;
43 : }
44 0 : return GSS_C_NO_NAME;
45 : }
46 :
47 : OM_uint32
48 47850 : _gss_find_mn(OM_uint32 *minor_status,
49 : struct _gss_name *name,
50 : gss_const_OID mech,
51 : struct _gss_mechanism_name ** output_mn)
52 : {
53 1915 : OM_uint32 major_status;
54 1915 : gssapi_mech_interface m;
55 1915 : struct _gss_mechanism_name *mn;
56 :
57 47850 : *output_mn = NULL;
58 :
59 : /* null names are ok, some mechs might not have names */
60 47850 : if (name == NULL)
61 0 : return GSS_S_COMPLETE;
62 :
63 47850 : HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) {
64 47850 : if (gss_oid_equal(mech, mn->gmn_mech_oid))
65 45935 : break;
66 : }
67 :
68 47850 : if (!mn) {
69 : /*
70 : * If this name is canonical (i.e. there is only an
71 : * MN but it is from a different mech), give up now.
72 : */
73 0 : if (!name->gn_value.value)
74 0 : return GSS_S_BAD_NAME;
75 :
76 0 : m = __gss_get_mechanism(mech);
77 0 : if (!m || !m->gm_import_name)
78 0 : return (GSS_S_BAD_MECH);
79 :
80 0 : mn = malloc(sizeof(struct _gss_mechanism_name));
81 0 : if (!mn)
82 0 : return GSS_S_FAILURE;
83 :
84 0 : major_status = m->gm_import_name(minor_status,
85 0 : &name->gn_value,
86 : name->gn_type,
87 : &mn->gmn_name);
88 0 : if (major_status != GSS_S_COMPLETE) {
89 0 : _gss_mg_error(m, *minor_status);
90 0 : free(mn);
91 0 : return major_status;
92 : }
93 :
94 0 : mn->gmn_mech = m;
95 0 : mn->gmn_mech_oid = &m->gm_mech_oid;
96 0 : HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link);
97 : }
98 47850 : *output_mn = mn;
99 47850 : return 0;
100 : }
101 :
102 :
103 : /*
104 : * Make a name from an MN.
105 : */
106 : struct _gss_name *
107 108424 : _gss_create_name(gss_name_t new_mn,
108 : struct gssapi_mech_interface_desc *m)
109 : {
110 2012 : struct _gss_name *name;
111 2012 : struct _gss_mechanism_name *mn;
112 :
113 108424 : name = calloc(1, sizeof(struct _gss_name));
114 108424 : if (!name)
115 0 : return (0);
116 :
117 108424 : HEIM_TAILQ_INIT(&name->gn_mn);
118 :
119 108424 : if (new_mn) {
120 84187 : mn = malloc(sizeof(struct _gss_mechanism_name));
121 84187 : if (!mn) {
122 0 : free(name);
123 0 : return (0);
124 : }
125 :
126 84187 : mn->gmn_mech = m;
127 84187 : mn->gmn_mech_oid = &m->gm_mech_oid;
128 84187 : mn->gmn_name = new_mn;
129 84187 : HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link);
130 : }
131 :
132 106412 : return (name);
133 : }
134 :
135 : /*
136 : *
137 : */
138 :
139 : void
140 76416 : _gss_mg_release_name(struct _gss_name *name)
141 : {
142 1911 : OM_uint32 junk;
143 1911 : struct _gss_mechanism_name *mn, *next;
144 :
145 76416 : gss_release_oid(&junk, &name->gn_type);
146 :
147 152832 : HEIM_TAILQ_FOREACH_SAFE(mn, &name->gn_mn, gmn_link, next) {
148 76416 : HEIM_TAILQ_REMOVE(&name->gn_mn, mn, gmn_link);
149 76416 : mn->gmn_mech->gm_release_name(&junk, &mn->gmn_name);
150 76416 : free(mn);
151 : }
152 76416 : gss_release_buffer(&junk, &name->gn_value);
153 76416 : free(name);
154 76416 : }
155 :
156 : void
157 47850 : _gss_mg_check_name(gss_const_name_t name)
158 : {
159 47850 : if (name == NULL) return;
160 : }
161 :
162 : /*
163 : *
164 : */
165 :
166 : OM_uint32
167 0 : _gss_mech_import_name(OM_uint32 * minor_status,
168 : gss_const_OID mech,
169 : struct _gss_name_type *names,
170 : const gss_buffer_t input_name_buffer,
171 : gss_const_OID input_name_type,
172 : gss_name_t *output_name)
173 : {
174 0 : struct _gss_name_type *name;
175 0 : gss_buffer_t name_buffer = input_name_buffer;
176 0 : gss_buffer_desc export_name;
177 :
178 0 : *minor_status = 0;
179 :
180 0 : if (output_name == NULL)
181 0 : return GSS_S_CALL_INACCESSIBLE_WRITE;
182 :
183 0 : *output_name = GSS_C_NO_NAME;
184 :
185 : /*
186 : * If its a exported name, strip of the mech glue.
187 : */
188 :
189 0 : if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) {
190 0 : unsigned char *p;
191 0 : uint32_t length;
192 :
193 0 : if (name_buffer->length < 10 + mech->length)
194 0 : return GSS_S_BAD_NAME;
195 :
196 : /* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */
197 :
198 0 : p = name_buffer->value;
199 :
200 0 : if (memcmp(&p[0], "\x04\x01\x00", 3) != 0 ||
201 0 : p[3] != mech->length + 2 ||
202 0 : p[4] != 0x06 ||
203 0 : p[5] != mech->length ||
204 0 : memcmp(&p[6], mech->elements, mech->length) != 0)
205 0 : return GSS_S_BAD_NAME;
206 :
207 0 : p += 6 + mech->length;
208 :
209 0 : length = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
210 0 : p += 4;
211 :
212 0 : if (length > name_buffer->length - 10 - mech->length)
213 0 : return GSS_S_BAD_NAME;
214 :
215 : /*
216 : * Point this to the mech specific name part, don't modifity
217 : * orignal input_name_buffer.
218 : */
219 :
220 0 : export_name.length = length;
221 0 : export_name.value = p;
222 :
223 0 : name_buffer = &export_name;
224 : }
225 :
226 0 : for (name = names; name->gnt_parse != NULL; name++) {
227 0 : if (gss_oid_equal(input_name_type, name->gnt_name_type)
228 0 : || (name->gnt_name_type == GSS_C_NO_OID && input_name_type == GSS_C_NO_OID))
229 0 : return name->gnt_parse(minor_status, mech, name_buffer,
230 : input_name_type, output_name);
231 : }
232 :
233 0 : return GSS_S_BAD_NAMETYPE;
234 : }
235 :
236 : OM_uint32
237 0 : _gss_mech_inquire_names_for_mech(OM_uint32 * minor_status,
238 : struct _gss_name_type *names,
239 : gss_OID_set *name_types)
240 : {
241 0 : struct _gss_name_type *name;
242 0 : OM_uint32 ret, junk;
243 :
244 0 : ret = gss_create_empty_oid_set(minor_status, name_types);
245 0 : if (ret != GSS_S_COMPLETE)
246 0 : return ret;
247 :
248 0 : for (name = names; name->gnt_parse != NULL; name++) {
249 0 : if (name->gnt_name_type == GSS_C_NO_OID)
250 0 : continue;
251 0 : ret = gss_add_oid_set_member(minor_status,
252 : name->gnt_name_type,
253 : name_types);
254 0 : if (ret != GSS_S_COMPLETE)
255 0 : break;
256 : }
257 :
258 0 : if (ret != GSS_S_COMPLETE)
259 0 : gss_release_oid_set(&junk, name_types);
260 :
261 0 : return GSS_S_COMPLETE;
262 : }
|