Branch data Line data Source code
1 : : /* misc.c --- Implementation of GSS-API Miscellaneous functions.
2 : : * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Simon Josefsson
3 : : *
4 : : * This file is part of the Generic Security Service (GSS).
5 : : *
6 : : * GSS is free software; you can redistribute it and/or modify it
7 : : * under the terms of the GNU General Public License as published by
8 : : * the Free Software Foundation; either version 3 of the License, or
9 : : * (at your option) any later version.
10 : : *
11 : : * GSS is distributed in the hope that it will be useful, but WITHOUT
12 : : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 : : * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 : : * License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with GSS; if not, see http://www.gnu.org/licenses or write to
18 : : * the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 : : * Floor, Boston, MA 02110-1301, USA.
20 : : *
21 : : */
22 : :
23 : : #include "internal.h"
24 : :
25 : : /* _gss_indicate_mechs1 */
26 : : #include "meta.h"
27 : :
28 : : /**
29 : : * gss_create_empty_oid_set:
30 : : * @minor_status: (integer, modify) Mechanism specific status code.
31 : : * @oid_set: (Set of Object IDs, modify) The empty object identifier
32 : : * set. The routine will allocate the gss_OID_set_desc object,
33 : : * which the application must free after use with a call to
34 : : * gss_release_oid_set().
35 : : *
36 : : * Create an object-identifier set containing no object identifiers,
37 : : * to which members may be subsequently added using the
38 : : * gss_add_oid_set_member() routine. These routines are intended to
39 : : * be used to construct sets of mechanism object identifiers, for
40 : : * input to gss_acquire_cred.
41 : : *
42 : : * Return value:
43 : : *
44 : : * `GSS_S_COMPLETE`: Successful completion.
45 : : **/
46 : : OM_uint32
47 : 6 : gss_create_empty_oid_set (OM_uint32 * minor_status, gss_OID_set * oid_set)
48 : : {
49 [ + - ]: 6 : if (minor_status)
50 : 6 : *minor_status = 0;
51 : :
52 : 6 : *oid_set = malloc (sizeof (**oid_set));
53 [ - + ]: 6 : if (!*oid_set)
54 : : {
55 [ # # ]: 0 : if (minor_status)
56 : 0 : *minor_status = ENOMEM;
57 : 0 : return GSS_S_FAILURE;
58 : : }
59 : 6 : (*oid_set)->count = 0;
60 : 6 : (*oid_set)->elements = NULL;
61 : :
62 : 6 : return GSS_S_COMPLETE;
63 : : }
64 : :
65 : : /*
66 : : * gss_copy_oid:
67 : : * @minor_status: (integer, modify) Mechanism specific status code.
68 : : * @src_oid: (Object ID, read) The object identifier to copy.
69 : : * @dest_oid: (Object ID, modify) The resultant copy of @src_oid.
70 : : * Storage associated with this name must be freed by the
71 : : * application, but gss_release_oid() cannot be used generally as it
72 : : * deallocate the oid structure itself too.
73 : : *
74 : : * Make an exact copy of the given OID, that shares no memory areas
75 : : * with the original.
76 : : *
77 : : * WARNING: This function is a GNU GSS specific extension, and is not
78 : : * part of the official GSS API.
79 : : *
80 : : * Return value:
81 : : *
82 : : * `GSS_S_COMPLETE`: Successful completion.
83 : : **/
84 : : static OM_uint32
85 : 11 : _gss_copy_oid (OM_uint32 * minor_status,
86 : : const gss_OID src_oid, gss_OID dest_oid)
87 : : {
88 [ + - ]: 11 : if (minor_status)
89 : 11 : *minor_status = 0;
90 : :
91 [ - + ]: 11 : if (!src_oid)
92 : 0 : return GSS_S_FAILURE | GSS_S_CALL_INACCESSIBLE_READ;
93 : :
94 [ + - ][ - + ]: 11 : if (src_oid->length == 0 || src_oid->elements == NULL)
95 : 0 : return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
96 : :
97 : 11 : dest_oid->length = src_oid->length;
98 : 11 : dest_oid->elements = malloc (src_oid->length);
99 [ - + ]: 11 : if (!dest_oid->elements)
100 : : {
101 [ # # ]: 0 : if (minor_status)
102 : 0 : *minor_status = ENOMEM;
103 : 0 : return GSS_S_FAILURE;
104 : : }
105 : 11 : memcpy (dest_oid->elements, src_oid->elements, src_oid->length);
106 : :
107 : 11 : return GSS_S_COMPLETE;
108 : : }
109 : :
110 : : /**
111 : : * gss_add_oid_set_member:
112 : : * @minor_status: (integer, modify) Mechanism specific status code.
113 : : * @member_oid: (Object ID, read) The object identifier to copied into
114 : : * the set.
115 : : * @oid_set: (Set of Object ID, modify) The set in which the object
116 : : * identifier should be inserted.
117 : : *
118 : : * Add an Object Identifier to an Object Identifier set. This routine
119 : : * is intended for use in conjunction with gss_create_empty_oid_set
120 : : * when constructing a set of mechanism OIDs for input to
121 : : * gss_acquire_cred. The oid_set parameter must refer to an OID-set
122 : : * that was created by GSS-API (e.g. a set returned by
123 : : * gss_create_empty_oid_set()). GSS-API creates a copy of the
124 : : * member_oid and inserts this copy into the set, expanding the
125 : : * storage allocated to the OID-set's elements array if necessary.
126 : : * The routine may add the new member OID anywhere within the elements
127 : : * array, and implementations should verify that the new member_oid is
128 : : * not already contained within the elements array; if the member_oid
129 : : * is already present, the oid_set should remain unchanged.
130 : : *
131 : : * Return value:
132 : : *
133 : : * `GSS_S_COMPLETE`: Successful completion.
134 : : **/
135 : : OM_uint32
136 : 11 : gss_add_oid_set_member (OM_uint32 * minor_status,
137 : : const gss_OID member_oid, gss_OID_set * oid_set)
138 : : {
139 : : OM_uint32 major_stat;
140 : : int present;
141 : :
142 [ + - ][ + - ]: 11 : if (!member_oid || member_oid->length == 0 || member_oid->elements == NULL)
[ - + ]
143 : : {
144 [ # # ]: 0 : if (minor_status)
145 : 0 : *minor_status = 0;
146 : 0 : return GSS_S_FAILURE;
147 : : }
148 : :
149 : 11 : major_stat = gss_test_oid_set_member (minor_status, member_oid,
150 : : *oid_set, &present);
151 [ - + ]: 11 : if (GSS_ERROR (major_stat))
152 : 0 : return major_stat;
153 : :
154 [ - + ]: 11 : if (present)
155 : : {
156 [ # # ]: 0 : if (minor_status)
157 : 0 : *minor_status = 0;
158 : 0 : return GSS_S_COMPLETE;
159 : : }
160 : :
161 [ - + ]: 11 : if ((*oid_set)->count + 1 == 0) /* integer overflow */
162 : : {
163 [ # # ]: 0 : if (minor_status)
164 : 0 : *minor_status = 0;
165 : 0 : return GSS_S_FAILURE;
166 : : }
167 : :
168 : 11 : (*oid_set)->count++;
169 : : {
170 : : gss_OID tmp;
171 : :
172 : 11 : tmp = realloc ((*oid_set)->elements, (*oid_set)->count *
173 : : sizeof (*(*oid_set)->elements));
174 [ - + ]: 11 : if (!tmp)
175 : : {
176 [ # # ]: 0 : if (minor_status)
177 : 0 : *minor_status = ENOMEM;
178 : 0 : return GSS_S_FAILURE;
179 : : }
180 : :
181 : 11 : (*oid_set)->elements = tmp;
182 : : }
183 : :
184 : 11 : major_stat = _gss_copy_oid (minor_status, member_oid,
185 : 22 : (*oid_set)->elements + ((*oid_set)->count - 1));
186 [ - + ]: 11 : if (GSS_ERROR (major_stat))
187 : 0 : return major_stat;
188 : :
189 : 11 : return GSS_S_COMPLETE;
190 : : }
191 : :
192 : : /**
193 : : * gss_test_oid_set_member:
194 : : * @minor_status: (integer, modify) Mechanism specific status code.
195 : : * @member: (Object ID, read) The object identifier whose presence is
196 : : * to be tested.
197 : : * @set: (Set of Object ID, read) The Object Identifier set.
198 : : * @present: (Boolean, modify) Non-zero if the specified OID is a
199 : : * member of the set, zero if not.
200 : : *
201 : : * Interrogate an Object Identifier set to determine whether a
202 : : * specified Object Identifier is a member. This routine is intended
203 : : * to be used with OID sets returned by gss_indicate_mechs(),
204 : : * gss_acquire_cred(), and gss_inquire_cred(), but will also work with
205 : : * user-generated sets.
206 : : *
207 : : * Return value:
208 : : *
209 : : * `GSS_S_COMPLETE`: Successful completion.
210 : : **/
211 : : OM_uint32
212 : 23 : gss_test_oid_set_member (OM_uint32 * minor_status,
213 : : const gss_OID member,
214 : : const gss_OID_set set, int *present)
215 : : {
216 : : gss_OID cur;
217 : : size_t i;
218 : :
219 [ + - ]: 23 : if (minor_status)
220 : 23 : *minor_status = 0;
221 : :
222 : 23 : *present = 0;
223 : :
224 [ - + ]: 23 : if (member == GSS_C_NO_OID)
225 : 0 : return GSS_S_COMPLETE;
226 : :
227 [ + + ]: 38 : for (i = 0, cur = set->elements; i < set->count; i++, cur++)
228 : : {
229 [ + + ][ + + ]: 23 : if (cur->length == member->length &&
230 : 13 : memcmp (cur->elements, member->elements, member->length) == 0)
231 : : {
232 : 8 : *present = 1;
233 : 8 : return GSS_S_COMPLETE;
234 : : }
235 : : }
236 : :
237 : 23 : return GSS_S_COMPLETE;
238 : : }
239 : :
240 : : /**
241 : : * gss_release_oid_set:
242 : : * @minor_status: (integer, modify) Mechanism specific status code.
243 : : * @set: (Set of Object IDs, modify) The storage associated with the
244 : : * gss_OID_set will be deleted.
245 : : *
246 : : * Free storage associated with a GSSAPI-generated gss_OID_set object.
247 : : * The set parameter must refer to an OID-set that was returned from a
248 : : * GSS-API routine. gss_release_oid_set() will free the storage
249 : : * associated with each individual member OID, the OID set's elements
250 : : * array, and the gss_OID_set_desc.
251 : : *
252 : : * The gss_OID_set parameter is set to GSS_C_NO_OID_SET on successful
253 : : * completion of this routine.
254 : : *
255 : : * Return value:
256 : : *
257 : : * `GSS_S_COMPLETE`: Successful completion.
258 : : **/
259 : : OM_uint32
260 : 6 : gss_release_oid_set (OM_uint32 * minor_status, gss_OID_set * set)
261 : : {
262 : : gss_OID cur;
263 : : size_t i;
264 : :
265 [ + - ]: 6 : if (minor_status)
266 : 6 : *minor_status = 0;
267 : :
268 [ + - ][ - + ]: 6 : if (!set || *set == GSS_C_NO_OID_SET)
269 : 0 : return GSS_S_COMPLETE;
270 : :
271 [ + + ]: 17 : for (i = 0, cur = (*set)->elements; i < (*set)->count; i++, cur++)
272 : 11 : free (cur->elements);
273 : 6 : free ((*set)->elements);
274 : 6 : free (*set);
275 : 6 : *set = GSS_C_NO_OID_SET;
276 : :
277 : 6 : return GSS_S_COMPLETE;
278 : : }
279 : :
280 : : /**
281 : : * gss_indicate_mechs:
282 : : * @minor_status: (integer, modify) Mechanism specific status code.
283 : : * @mech_set: (set of Object IDs, modify) Set of
284 : : * implementation-supported mechanisms. The returned gss_OID_set
285 : : * value will be a dynamically-allocated OID set, that should be
286 : : * released by the caller after use with a call to
287 : : * gss_release_oid_set().
288 : : *
289 : : * Allows an application to determine which underlying security
290 : : * mechanisms are available.
291 : : *
292 : : * Return value:
293 : : *
294 : : * `GSS_S_COMPLETE`: Successful completion.
295 : : **/
296 : : OM_uint32
297 : 2 : gss_indicate_mechs (OM_uint32 * minor_status, gss_OID_set * mech_set)
298 : : {
299 : : OM_uint32 maj_stat;
300 : :
301 : 2 : maj_stat = gss_create_empty_oid_set (minor_status, mech_set);
302 [ - + ]: 2 : if (GSS_ERROR (maj_stat))
303 : 0 : return maj_stat;
304 : :
305 : 2 : maj_stat = _gss_indicate_mechs1 (minor_status, mech_set);
306 [ - + ]: 2 : if (GSS_ERROR (maj_stat))
307 : : {
308 : 0 : gss_release_oid_set (NULL, mech_set);
309 : 0 : return maj_stat;
310 : : }
311 : :
312 [ + - ]: 2 : if (minor_status)
313 : 2 : *minor_status = 0;
314 : 2 : return GSS_S_COMPLETE;
315 : : }
316 : :
317 : : /**
318 : : * gss_release_buffer:
319 : : * @minor_status: (integer, modify) Mechanism specific status code.
320 : : * @buffer: (buffer, modify) The storage associated with the buffer
321 : : * will be deleted. The gss_buffer_desc object will not be freed,
322 : : * but its length field will be zeroed.
323 : : *
324 : : * Free storage associated with a buffer. The storage must have been
325 : : * allocated by a GSS-API routine. In addition to freeing the
326 : : * associated storage, the routine will zero the length field in the
327 : : * descriptor to which the buffer parameter refers, and
328 : : * implementations are encouraged to additionally set the pointer
329 : : * field in the descriptor to NULL. Any buffer object returned by a
330 : : * GSS-API routine may be passed to gss_release_buffer (even if there
331 : : * is no storage associated with the buffer).
332 : : *
333 : : * Return value:
334 : : *
335 : : * `GSS_S_COMPLETE`: Successful completion.
336 : : **/
337 : : OM_uint32
338 : 18 : gss_release_buffer (OM_uint32 * minor_status, gss_buffer_t buffer)
339 : : {
340 [ + - ]: 18 : if (minor_status)
341 : 18 : *minor_status = 0;
342 : :
343 [ + - ]: 18 : if (buffer != GSS_C_NO_BUFFER)
344 : : {
345 : 18 : free (buffer->value);
346 : 18 : buffer->value = NULL;
347 : 18 : buffer->length = 0;
348 : : }
349 : :
350 : 18 : return GSS_S_COMPLETE;
351 : : }
|