1 /*
2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "@(#)g_accept_sec_context.c 1.20 04/09/08 SMI"
7
8 /*
9 * glue routine for gss_accept_sec_context
10 */
11
12 #include <mechglueP.h>
13 #ifdef HAVE_STDLIB_H
14 #include <stdlib.h>
15 #endif
16 #include <string.h>
17 #include <errno.h>
18
19 OM_uint32
20 gss_accept_sec_context(minor_status,
21 context_handle,
22 verifier_cred_handle,
23 input_token_buffer,
24 input_chan_bindings,
25 src_name,
26 mech_type,
29 time_rec,
30 d_cred)
31
32 OM_uint32 *minor_status;
33 gss_ctx_id_t *context_handle;
34 const gss_cred_id_t verifier_cred_handle;
35 const gss_buffer_t input_token_buffer;
36 const gss_channel_bindings_t input_chan_bindings;
37 gss_name_t *src_name;
38 gss_OID *mech_type;
39 gss_buffer_t output_token;
40 OM_uint32 *ret_flags;
41 OM_uint32 *time_rec;
42 gss_cred_id_t *d_cred; /* delegated cred handle */
43
44 {
45 OM_uint32 status, temp_status, temp_minor_status;
46 gss_union_ctx_id_t union_ctx_id;
47 gss_union_cred_t union_cred;
48 gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL;
49 gss_name_t internal_name;
50 gss_name_t tmp_src_name;
51 gss_OID_desc token_mech_type_desc;
52 gss_OID token_mech_type = &token_mech_type_desc;
53 gss_mechanism mech;
54
55 gss_initialize();
56
57 if (context_handle == NULL)
58 return (GSS_S_NO_CONTEXT);
59
60 /*
61 * if context_handle is GSS_C_NO_CONTEXT, allocate a union context
62 * descriptor to hold the mech type information as well as the
63 * underlying mechanism context handle. Otherwise, cast the
64 * value of *context_handle to the union context variable.
65 */
66
67 if (*context_handle == GSS_C_NO_CONTEXT) {
68
69 /* Get the token mech type */
70 status = __gss_get_mech_type(token_mech_type,
71 input_token_buffer);
72
73 if (status)
74 return (status);
75
76 status = GSS_S_FAILURE;
77 union_ctx_id = (gss_union_ctx_id_t)
78 malloc(sizeof (gss_union_ctx_id_desc));
79 if (!union_ctx_id) {
80 *minor_status = ENOMEM;
81 goto error_out;
82 }
83 union_ctx_id->mech_type = (gss_OID) malloc(sizeof(gss_OID_desc));
84 if (!union_ctx_id->mech_type) {
85 *minor_status = ENOMEM;
86 goto error_out;
87 }
88
89 union_ctx_id->mech_type->elements = (void *)
90 malloc(token_mech_type->length);
91 if (!union_ctx_id->mech_type->elements) {
92 *minor_status = ENOMEM;
93 goto error_out;
94 }
95
96 union_ctx_id->mech_type->length = token_mech_type->length;
97 memcpy(union_ctx_id->mech_type->elements,
98 token_mech_type->elements,
99 token_mech_type->length);
100
101 /* copy the supplied context handle */
102
103 union_ctx_id->internal_ctx_id = *context_handle;
104 } else {
105 union_ctx_id = *context_handle;
106 token_mech_type = union_ctx_id->mech_type;
107 }
108
109 /*
110 * get the appropriate cred handle from the union cred struct.
111 * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will
112 * use the default credential.
113 */
114 union_cred = (gss_union_cred_t)verifier_cred_handle;
115 input_cred_handle = __gss_get_mechanism_cred(union_cred,
116 token_mech_type);
117
118 /*
119 * now select the approprate underlying mechanism routine and
120 * call it.
121 */
122
123 mech = __gss_get_mechanism(token_mech_type);
124 if (mech && mech->gss_accept_sec_context) {
125 status = mech->gss_accept_sec_context(
126 mech->context,
127 minor_status,
128 &union_ctx_id->internal_ctx_id,
129 input_cred_handle,
130 input_token_buffer,
131 input_chan_bindings,
132 &internal_name,
133 mech_type,
134 output_token,
135 ret_flags,
136 time_rec,
137 delegated_cred_handle);
138
139 /* If there's more work to do, keep going... */
140 if (status == GSS_S_CONTINUE_NEEDED)
141 return (GSS_S_CONTINUE_NEEDED);
142
143 /* if the call failed, return with failure */
144 if (status != GSS_S_COMPLETE)
145 goto error_out;
146
147 /*
148 * if src_name is non-NULL,
149 * convert internal_name into a union name equivalent
150 * First call the mechanism specific display_name()
151 * then call gss_import_name() to create
152 * the union name struct cast to src_name
153 */
154 if (src_name != NULL && status == GSS_S_COMPLETE) {
155 temp_status = __gss_convert_name_to_union_name(
156 &temp_minor_status, mech,
157 internal_name, src_name);
158 if (temp_status != GSS_S_COMPLETE) {
159 if (minor_status)
160 *minor_status = temp_minor_status;
161 (void) gss_release_buffer(
162 &temp_minor_status,
163 output_token);
164 __gss_release_internal_name(&temp_minor_status,
165 &mech->mech_type, &internal_name);
166 return (temp_status);
167 }
168 }
169
170 if(*context_handle == GSS_C_NO_CONTEXT)
171 *context_handle = (gss_ctx_id_t *) union_ctx_id;
172
173 return(status);
174 }
175
176 return(GSS_S_BAD_MECH);
177
178 error_out:
179 if (union_ctx_id) {
180 if (union_ctx_id->mech_type) {
181 if (union_ctx_id->mech_type->elements)
182 free(union_ctx_id->mech_type->elements);
183 free(union_ctx_id->mech_type);
184 }
185 free(union_ctx_id);
186 }
187 return (status);
188 }
|
1 /*
2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "@(#)g_accept_sec_context.c 1.19 04/02/23 SMI"
7
8 /*
9 * glue routine for gss_accept_sec_context
10 */
11
12 #include <mechglueP.h>
13 #ifdef HAVE_STDLIB_H
14 #include <stdlib.h>
15 #endif
16 #include <string.h>
17 #include <errno.h>
18
19 OM_uint32
20 gss_accept_sec_context(minor_status,
21 context_handle,
22 verifier_cred_handle,
23 input_token_buffer,
24 input_chan_bindings,
25 src_name,
26 mech_type,
29 time_rec,
30 d_cred)
31
32 OM_uint32 *minor_status;
33 gss_ctx_id_t *context_handle;
34 const gss_cred_id_t verifier_cred_handle;
35 const gss_buffer_t input_token_buffer;
36 const gss_channel_bindings_t input_chan_bindings;
37 gss_name_t *src_name;
38 gss_OID *mech_type;
39 gss_buffer_t output_token;
40 OM_uint32 *ret_flags;
41 OM_uint32 *time_rec;
42 gss_cred_id_t *d_cred; /* delegated cred handle */
43
44 {
45 OM_uint32 status, temp_status, temp_minor_status;
46 gss_union_ctx_id_t union_ctx_id;
47 gss_union_cred_t union_cred;
48 gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL;
49 gss_cred_id_t tmp_d_cred = GSS_C_NO_CREDENTIAL;
50 gss_name_t internal_name = GSS_C_NO_NAME;
51 gss_name_t tmp_src_name = GSS_C_NO_NAME;
52 gss_OID_desc token_mech_type_desc;
53 gss_OID token_mech_type = &token_mech_type_desc;
54 gss_mechanism mech;
55
56 /* check parameters first */
57 if (minor_status == NULL)
58 return (GSS_S_CALL_INACCESSIBLE_WRITE);
59 *minor_status = 0;
60
61 if (context_handle == NULL || output_token == NULL)
62 return (GSS_S_CALL_INACCESSIBLE_WRITE);
63
64 /* clear optional fields */
65 output_token->value = NULL;
66 output_token->length = 0;
67 if (src_name)
68 *src_name = NULL;
69
70 if (mech_type)
71 *mech_type = NULL;
72
73 if (d_cred)
74 *d_cred = NULL;
75 /*
76 * if context_handle is GSS_C_NO_CONTEXT, allocate a union context
77 * descriptor to hold the mech type information as well as the
78 * underlying mechanism context handle. Otherwise, cast the
79 * value of *context_handle to the union context variable.
80 */
81
82 if (*context_handle == GSS_C_NO_CONTEXT) {
83
84 if (GSS_EMPTY_BUFFER(input_token_buffer))
85 return (GSS_S_CALL_INACCESSIBLE_READ);
86
87 /* Get the token mech type */
88 status = __gss_get_mech_type(token_mech_type,
89 input_token_buffer);
90
91 if (status)
92 return (status);
93
94 status = GSS_S_FAILURE;
95 union_ctx_id = (gss_union_ctx_id_t)
96 malloc(sizeof (gss_union_ctx_id_desc));
97 if (!union_ctx_id)
98 return (GSS_S_FAILURE);
99
100 union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
101 status = generic_gss_copy_oid(&temp_minor_status,
102 token_mech_type,
103 &union_ctx_id->mech_type);
104 if (status != GSS_S_COMPLETE) {
105 free(union_ctx_id);
106 return (status);
107 }
108
109 /* set the new context handle to caller's data */
110 *context_handle = (gss_ctx_id_t)union_ctx_id;
111 } else {
112 union_ctx_id = (gss_union_ctx_id_t)*context_handle;
113 token_mech_type = union_ctx_id->mech_type;
114 }
115
116 /*
117 * get the appropriate cred handle from the union cred struct.
118 * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will
119 * use the default credential.
120 */
121 union_cred = (gss_union_cred_t)verifier_cred_handle;
122 input_cred_handle = __gss_get_mechanism_cred(union_cred,
123 token_mech_type);
124
125 /*
126 * now select the approprate underlying mechanism routine and
127 * call it.
128 */
129
130 mech = __gss_get_mechanism(token_mech_type);
131 if (mech && mech->gss_accept_sec_context) {
132 status = mech->gss_accept_sec_context(
133 mech->context,
134 minor_status,
135 &union_ctx_id->internal_ctx_id,
136 input_cred_handle,
137 input_token_buffer,
138 input_chan_bindings,
139 &internal_name,
140 mech_type,
141 output_token,
142 ret_flags,
143 time_rec,
144 d_cred ? &tmp_d_cred : NULL);
145
146 /* If there's more work to do, keep going... */
147 if (status == GSS_S_CONTINUE_NEEDED)
148 return (GSS_S_CONTINUE_NEEDED);
149
150 /* if the call failed, return with failure */
151 if (status != GSS_S_COMPLETE)
152 goto error_out;
153
154 /*
155 * if src_name is non-NULL,
156 * convert internal_name into a union name equivalent
157 * First call the mechanism specific display_name()
158 * then call gss_import_name() to create
159 * the union name struct cast to src_name
160 */
161 if (internal_name != NULL) {
162 temp_status = __gss_convert_name_to_union_name(
163 &temp_minor_status, mech,
164 internal_name, &tmp_src_name);
165 if (temp_status != GSS_S_COMPLETE) {
166 *minor_status = temp_minor_status;
167 if (output_token->length)
168 (void) gss_release_buffer(
169 &temp_minor_status,
170 output_token);
171 if (internal_name != GSS_C_NO_NAME)
172 mech->gss_release_name(
173 mech->context,
174 &temp_minor_status,
175 &internal_name);
176 return (temp_status);
177 }
178 if (src_name != NULL) {
179 *src_name = tmp_src_name;
180 }
181 } else if (src_name != NULL) {
182 *src_name = GSS_C_NO_NAME;
183 }
184
185 /* Ensure we're returning correct creds format */
186 if ((ret_flags && GSS_C_DELEG_FLAG) &&
187 tmp_d_cred != GSS_C_NO_CREDENTIAL) {
188 gss_union_cred_t d_u_cred = NULL;
189
190 d_u_cred = malloc(sizeof (gss_union_cred_desc));
191 if (d_u_cred == NULL) {
192 status = GSS_S_FAILURE;
193 goto error_out;
194 }
195 (void) memset(d_u_cred, 0,
196 sizeof (gss_union_cred_desc));
197
198 d_u_cred->count = 1;
199
200 status = generic_gss_copy_oid(&temp_minor_status,
201 token_mech_type,
202 &d_u_cred->mechs_array);
203
204 if (status != GSS_S_COMPLETE) {
205 free(d_u_cred);
206 goto error_out;
207 }
208
209 d_u_cred->cred_array = malloc(sizeof (gss_cred_id_t));
210 if (d_u_cred->cred_array != NULL) {
211 d_u_cred->cred_array[0] = tmp_d_cred;
212 } else {
213 free(d_u_cred);
214 status = GSS_S_FAILURE;
215 goto error_out;
216 }
217
218 if (status != GSS_S_COMPLETE) {
219 free(d_u_cred->cred_array);
220 free(d_u_cred);
221 goto error_out;
222 }
223
224 internal_name = GSS_C_NO_NAME;
225
226 d_u_cred->auxinfo.creation_time = time(0);
227 d_u_cred->auxinfo.time_rec = 0;
228
229 if (mech->gss_inquire_cred) {
230 status = mech->gss_inquire_cred(mech->context,
231 minor_status,
232 tmp_d_cred,
233 &internal_name,
234 &d_u_cred->auxinfo.time_rec,
235 &d_u_cred->auxinfo.cred_usage,
236 NULL);
237 }
238
239 if (internal_name != NULL) {
240 temp_status = __gss_convert_name_to_union_name(
241 &temp_minor_status, mech,
242 internal_name, &tmp_src_name);
243 if (temp_status != GSS_S_COMPLETE) {
244 *minor_status = temp_minor_status;
245 if (output_token->length)
246 (void) gss_release_buffer(
247 &temp_minor_status,
248 output_token);
249 free(d_u_cred->cred_array);
250 free(d_u_cred);
251 return (temp_status);
252 }
253 }
254
255 if (tmp_src_name != NULL) {
256 status = gss_display_name(
257 &temp_minor_status,
258 tmp_src_name,
259 &d_u_cred->auxinfo.name,
260 &d_u_cred->auxinfo.name_type);
261 }
262
263 *d_cred = (gss_cred_id_t)d_u_cred;
264 }
265
266 if (src_name == NULL && tmp_src_name != NULL)
267 (void) gss_release_name(&temp_minor_status,
268 &tmp_src_name);
269 return (status);
270 } else {
271
272 status = GSS_S_BAD_MECH;
273 }
274
275 error_out:
276 if (union_ctx_id) {
277 if (union_ctx_id->mech_type) {
278 if (union_ctx_id->mech_type->elements)
279 free(union_ctx_id->mech_type->elements);
280 free(union_ctx_id->mech_type);
281 }
282 free(union_ctx_id);
283 *context_handle = GSS_C_NO_CONTEXT;
284 }
285
286 if (output_token->length)
287 (void) gss_release_buffer(&temp_minor_status, output_token);
288
289 if (src_name)
290 *src_name = GSS_C_NO_NAME;
291
292 if (tmp_src_name != GSS_C_NO_NAME)
293 (void) gss_release_buffer(&temp_minor_status,
294 (gss_buffer_t)tmp_src_name);
295
296 return (status);
297 }
|