Sdiff g_accept_sec_context.c
  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 }