/** * @brief Set Security Context Option * @ingroup globus_gsi_gssapi_extensions * @details * GSSAPI routine to initiate the sending of a security context * See: <draft-ietf-cat-gssv2-cbind-04.txt> * * @param minor_status * @param context_handle * @param option * @param value * * @return */ OM_uint32 GSS_CALLCONV gss_set_sec_context_option( OM_uint32 * minor_status, gss_ctx_id_t * context_handle, const gss_OID option, const gss_buffer_t value) { gss_ctx_id_desc * context = NULL; OM_uint32 major_status = GSS_S_COMPLETE; OM_uint32 local_minor_status; globus_result_t local_result = GLOBUS_SUCCESS; int index; GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER; if(minor_status == NULL) { major_status = GSS_S_FAILURE; goto exit; } *minor_status = (OM_uint32) GLOBUS_SUCCESS; if(context_handle == NULL) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid context_handle passed to function - cannot be NULL"))); major_status = GSS_S_FAILURE; goto exit; } context = *context_handle; if(option == GSS_C_NO_OID) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid option passed to function with value: GSS_C_NO_OID"))); major_status = GSS_S_FAILURE; goto exit; } if (*context_handle == GSS_C_NO_CONTEXT) { /* for now just malloc and zero the context */ context = (gss_ctx_id_desc *) malloc(sizeof(gss_ctx_id_desc)); if (context == NULL) { GLOBUS_GSI_GSSAPI_MALLOC_ERROR(minor_status); major_status = GSS_S_FAILURE; goto exit; } *context_handle = context; memset(context, 0, sizeof(gss_ctx_id_desc)); context->ctx_flags = 0; major_status = gss_create_empty_oid_set( &local_minor_status, (gss_OID_set *) &context->extension_oids); /* initialize the callback_data in the context. This needs * to be done so the verify_callback func can be set later. */ local_result = globus_gsi_callback_data_init( &context->callback_data); if(local_result != GLOBUS_SUCCESS) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GSS_CONTEXT, (_GGSL("The callback data in the context " "could not be initialized."))); major_status = GSS_S_FAILURE; goto exit; } } else if(context->ctx_flags & GSS_I_CTX_INITIALIZED) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GSS_CONTEXT, (_GGSL("The context has already been initialized! %s should be " "called on a context before initialization"), __func__)); major_status = GSS_S_FAILURE; goto exit; } if(g_OID_equal(option, GSS_DISALLOW_ENCRYPTION)) { context->ctx_flags |= GSS_I_DISALLOW_ENCRYPTION; } else if(g_OID_equal(option, GSS_PROTECTION_FAIL_ON_CONTEXT_EXPIRATION)) { context->ctx_flags |= GSS_I_PROTECTION_FAIL_ON_CONTEXT_EXPIRATION; } else if(g_OID_equal(option, GSS_APPLICATION_WILL_HANDLE_EXTENSIONS)) { if(value == GSS_C_NO_BUFFER) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid buffer passed to function"))); major_status = GSS_S_FAILURE; goto exit; } for(index = 0; index < ((gss_OID_set_desc *) value->value)->count; index++) { major_status = gss_add_oid_set_member( &local_minor_status, (gss_OID) &((gss_OID_set_desc *) value->value)->elements[index], (gss_OID_set *) &context->extension_oids); if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_OID); goto exit; } } local_result = globus_gsi_callback_set_extension_cb( context->callback_data, globus_i_gsi_gss_verify_extensions_callback); if(local_result != GLOBUS_SUCCESS) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_result, GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA); major_status = GSS_S_FAILURE; goto exit; } /* if the extension_oids are set, * then we set them in the callback data */ local_result = globus_gsi_callback_set_extension_oids( context->callback_data, (void *) context->extension_oids); if(local_result != GLOBUS_SUCCESS) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_result, GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA); major_status = GSS_S_FAILURE; goto exit; } context->ctx_flags |= GSS_I_APPLICATION_WILL_HANDLE_EXTENSIONS; } else { /* unknown option */ GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_UNKNOWN_OPTION, (NULL)); major_status = GSS_S_FAILURE; goto exit; } *context_handle = context; exit: GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT; return major_status; }
/** * This function copies a globus_gsi_callback_data_t. * @ingroup globus_gsi_callback_data * * @param source * The structure to be copied * @param dest * The destination of the copy * * @return * GLOBUS_SUCCESS unless an error occurred, in which case, * a globus error object ID is returned */ globus_result_t globus_gsi_callback_data_copy( globus_gsi_callback_data_t source, globus_gsi_callback_data_t * dest) { int index; globus_result_t result = GLOBUS_SUCCESS; static char * _function_name_ = "globus_gsi_callback_data_copy"; GLOBUS_I_GSI_CALLBACK_DEBUG_ENTER; if(!source) { GLOBUS_GSI_CALLBACK_ERROR_RESULT( result, GLOBUS_GSI_CALLBACK_ERROR_CALLBACK_DATA, (_CLS("NULL callback data source parameter passed to function: %s"), _function_name_)); goto exit; } if(!dest) { GLOBUS_GSI_CALLBACK_ERROR_RESULT( result, GLOBUS_GSI_CALLBACK_ERROR_CALLBACK_DATA, (_CLS("NULL callback data dest parameter passed to function: %s"), _function_name_)); goto exit; } globus_gsi_callback_data_init(dest); (*dest)->cert_depth = source->cert_depth; (*dest)->proxy_depth = source->proxy_depth; (*dest)->cert_type = source->cert_type; (*dest)->cert_chain = sk_X509_new_null(); for(index = 0; index < sk_X509_num(source->cert_chain); ++index) { if(!sk_X509_insert((*dest)->cert_chain, X509_dup(sk_X509_value(source->cert_chain, index)), index)) { GLOBUS_GSI_CALLBACK_OPENSSL_ERROR_RESULT( result, GLOBUS_GSI_CALLBACK_ERROR_CERT_CHAIN, (_CLS("Couldn't copy cert chain from callback data"))); goto exit; } } (*dest)->cert_dir = strdup(source->cert_dir); (*dest)->extension_cb = source->extension_cb; /* just copy the pointer location - these get created * and destroyed in gss code */ (*dest)->extension_oids = source->extension_oids; (*dest)->error = source->error; exit: GLOBUS_I_GSI_CALLBACK_DEBUG_EXIT; return result; }