OM_uint32 _gss_ntlm_inquire_sec_context_by_oid(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_OID desired_object, gss_buffer_set_t *data_set) { ntlm_ctx ctx = (ntlm_ctx)context_handle; if (ctx == NULL) { *minor_status = 0; return GSS_S_NO_CONTEXT; } if (gss_oid_equal(desired_object, GSS_NTLM_GET_SESSION_KEY_X) || gss_oid_equal(desired_object, GSS_C_INQ_SSPI_SESSION_KEY)) { gss_buffer_desc value; value.length = ctx->sessionkey.length; value.value = ctx->sessionkey.data; return gss_add_buffer_set_member(minor_status, &value, data_set); } else if (gss_oid_equal(desired_object, GSS_C_INQ_WIN2K_PAC_X)) { if (ctx->pac.length == 0) { *minor_status = ENOENT; return GSS_S_FAILURE; } return gss_add_buffer_set_member(minor_status, &ctx->pac, data_set); } else if (gss_oid_equal(desired_object, GSS_C_NTLM_AVGUEST)) { gss_buffer_desc value; uint32_t num; if (ctx->kcmflags & KCM_NTLM_FLAG_AV_GUEST) num = 1; else num = 0; value.length = sizeof(num); value.value = # return gss_add_buffer_set_member(minor_status, &value, data_set); } else { *minor_status = 0; return GSS_S_FAILURE; } }
static OM_uint32 inquire_sec_context_tkt_flags (OM_uint32 *minor_status, const gsskrb5_ctx context_handle, gss_buffer_set_t *data_set) { OM_uint32 tkt_flags; unsigned char buf[4]; gss_buffer_desc value; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); if (context_handle->ticket == NULL) { HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); _gsskrb5_set_status(EINVAL, "No ticket from which to obtain flags"); *minor_status = EINVAL; return GSS_S_BAD_MECH; } tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); _gsskrb5_encode_om_uint32(tkt_flags, buf); value.length = sizeof(buf); value.value = buf; return gss_add_buffer_set_member(minor_status, &value, data_set); }
static OM_uint32 get_authtime(OM_uint32 *minor_status, gsskrb5_ctx ctx, gss_buffer_set_t *data_set) { gss_buffer_desc value; unsigned char buf[4]; OM_uint32 authtime; HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); if (ctx->ticket == NULL) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); _gsskrb5_set_status(EINVAL, "No ticket to obtain auth time from"); *minor_status = EINVAL; return GSS_S_FAILURE; } authtime = ctx->ticket->ticket.authtime; HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); _gsskrb5_encode_om_uint32(authtime, buf); value.length = sizeof(buf); value.value = buf; return gss_add_buffer_set_member(minor_status, &value, data_set); }
static OM_uint32 get_service_keyblock (OM_uint32 *minor_status, gsskrb5_ctx ctx, gss_buffer_set_t *data_set) { krb5_storage *sp = NULL; krb5_data data; OM_uint32 maj_stat = GSS_S_COMPLETE; krb5_error_code ret = EINVAL; sp = krb5_storage_emem(); if (sp == NULL) { _gsskrb5_clear_status(); *minor_status = ENOMEM; return GSS_S_FAILURE; } HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); if (ctx->service_keyblock == NULL) { HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); _gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context"); *minor_status = EINVAL; return GSS_S_FAILURE; } krb5_data_zero(&data); ret = krb5_store_keyblock(sp, *ctx->service_keyblock); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) goto out; ret = krb5_storage_to_data(sp, &data); if (ret) goto out; { gss_buffer_desc value; value.length = data.length; value.value = data.data; maj_stat = gss_add_buffer_set_member(minor_status, &value, data_set); } out: krb5_data_free(&data); if (sp) krb5_storage_free(sp); if (ret) { *minor_status = ret; maj_stat = GSS_S_FAILURE; } return maj_stat; }
static OM_uint32 inquireSessionKey(OM_uint32 *minor, const gss_ctx_id_t ctx, const gss_OID desired_object GSSEAP_UNUSED, gss_buffer_set_t *dataSet) { OM_uint32 major; gss_buffer_desc buf; if (ctx->encryptionType == ENCTYPE_NULL) { major = GSS_S_UNAVAILABLE; *minor = GSSEAP_KEY_UNAVAILABLE; goto cleanup; } buf.length = KRB_KEY_LENGTH(&ctx->rfc3961Key); buf.value = KRB_KEY_DATA(&ctx->rfc3961Key); major = gss_add_buffer_set_member(minor, &buf, dataSet); if (GSS_ERROR(major)) goto cleanup; major = addEnctypeOidToBufferSet(minor, ctx->encryptionType, dataSet); if (GSS_ERROR(major)) goto cleanup; major = GSS_S_COMPLETE; *minor = 0; cleanup: if (GSS_ERROR(major)) zeroAndReleaseBufferSet(dataSet); return major; }
static OM_uint32 addEnctypeOidToBufferSet(OM_uint32 *minor, krb5_enctype encryptionType, gss_buffer_set_t *dataSet) { OM_uint32 major; unsigned char oidBuf[16]; gss_OID_desc oid; gss_buffer_desc buf; oid.length = sizeof(oidBuf); oid.elements = oidBuf; major = composeOid(minor, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x04", 10, encryptionType, &oid); if (GSS_ERROR(major)) return major; buf.length = oid.length; buf.value = oid.elements; major = gss_add_buffer_set_member(minor, &buf, dataSet); return major; }
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_oid (OM_uint32 * minor_status, const gss_cred_id_t cred_handle, const gss_OID desired_object, gss_buffer_set_t *data_set) { krb5_context context; gsskrb5_cred cred = (gsskrb5_cred)cred_handle; krb5_error_code ret; gss_buffer_desc buffer; char *str; GSSAPI_KRB5_INIT (&context); if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) { *minor_status = EINVAL; return GSS_S_FAILURE; } HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); if (cred->ccache == NULL) { HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); *minor_status = EINVAL; return GSS_S_FAILURE; } ret = krb5_cc_get_full_name(context, cred->ccache, &str); HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } buffer.value = str; buffer.length = strlen(str); ret = gss_add_buffer_set_member(minor_status, &buffer, data_set); if (ret != GSS_S_COMPLETE) _gsskrb5_clear_status (); free(str); *minor_status = 0; return GSS_S_COMPLETE; }
static OM_uint32 inquire_sec_context_authz_data (OM_uint32 *minor_status, const gsskrb5_ctx context_handle, krb5_context context, unsigned ad_type, gss_buffer_set_t *data_set) { krb5_data data; gss_buffer_desc ad_data; OM_uint32 ret; *minor_status = 0; *data_set = GSS_C_NO_BUFFER_SET; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); if (context_handle->ticket == NULL) { HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); *minor_status = EINVAL; _gsskrb5_set_status(EINVAL, "No ticket to obtain authz data from"); return GSS_S_NO_CONTEXT; } ret = krb5_ticket_get_authorization_data_type(context, context_handle->ticket, ad_type, &data); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } ad_data.value = data.data; ad_data.length = data.length; ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set); krb5_data_free(&data); return ret; }
static OM_uint32 inquire_sec_context_get_sspi_session_key (OM_uint32 *minor_status, const gsskrb5_ctx context_handle, krb5_context context, gss_buffer_set_t *data_set) { krb5_keyblock *key; OM_uint32 maj_stat = GSS_S_COMPLETE; krb5_error_code ret; gss_buffer_desc value; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); ret = _gsskrb5i_get_token_key(context_handle, context, &key); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (ret) goto out; if (key == NULL) { ret = EINVAL; goto out; } value.length = key->keyvalue.length; value.value = key->keyvalue.data; maj_stat = gss_add_buffer_set_member(minor_status, &value, data_set); krb5_free_keyblock(context, key); /* MIT also returns the enctype encoded as an OID in data_set[1] */ out: if (ret) { *minor_status = ret; maj_stat = GSS_S_FAILURE; } return maj_stat; }
static OM_uint32 export_lucid_sec_context_v1(OM_uint32 *minor_status, gsskrb5_ctx context_handle, krb5_context context, gss_buffer_set_t *data_set) { krb5_storage *sp = NULL; OM_uint32 major_status = GSS_S_COMPLETE; krb5_error_code ret; krb5_keyblock *key = NULL; int32_t number; int is_cfx; krb5_data data; *minor_status = 0; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); _gsskrb5i_is_cfx(context_handle, &is_cfx); sp = krb5_storage_emem(); if (sp == NULL) { _gsskrb5_clear_status(); ret = ENOMEM; goto out; } ret = krb5_store_int32(sp, 1); if (ret) goto out; ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0); if (ret) goto out; ret = krb5_store_int32(sp, context_handle->lifetime); if (ret) goto out; krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &number); ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ if (ret) goto out; ret = krb5_store_uint32(sp, (uint32_t)number); if (ret) goto out; krb5_auth_getremoteseqnumber (context, context_handle->auth_context, &number); ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ if (ret) goto out; ret = krb5_store_uint32(sp, (uint32_t)number); if (ret) goto out; ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0); if (ret) goto out; ret = _gsskrb5i_get_token_key(context_handle, context, &key); if (ret) goto out; if (is_cfx == 0) { int sign_alg, seal_alg; switch (key->keytype) { case ETYPE_DES_CBC_CRC: case ETYPE_DES_CBC_MD4: case ETYPE_DES_CBC_MD5: sign_alg = 0; seal_alg = 0; break; case ETYPE_DES3_CBC_MD5: case ETYPE_DES3_CBC_SHA1: sign_alg = 4; seal_alg = 2; break; case ETYPE_ARCFOUR_HMAC_MD5: case ETYPE_ARCFOUR_HMAC_MD5_56: sign_alg = 17; seal_alg = 16; break; default: sign_alg = -1; seal_alg = -1; break; } ret = krb5_store_int32(sp, sign_alg); if (ret) goto out; ret = krb5_store_int32(sp, seal_alg); if (ret) goto out; /* ctx_key */ ret = krb5_store_keyblock(sp, *key); if (ret) goto out; } else { int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0; /* have_acceptor_subkey */ ret = krb5_store_int32(sp, subkey_p); if (ret) goto out; /* ctx_key */ ret = krb5_store_keyblock(sp, *key); if (ret) goto out; /* acceptor_subkey */ if (subkey_p) { ret = krb5_store_keyblock(sp, *key); if (ret) goto out; } } ret = krb5_storage_to_data(sp, &data); if (ret) goto out; { gss_buffer_desc ad_data; ad_data.value = data.data; ad_data.length = data.length; ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set); krb5_data_free(&data); if (ret) goto out; } out: if (key) krb5_free_keyblock (context, key); if (sp) krb5_storage_free(sp); if (ret) { *minor_status = ret; major_status = GSS_S_FAILURE; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return major_status; }
static OM_uint32 inquire_sec_context_get_subkey (OM_uint32 *minor_status, const gsskrb5_ctx context_handle, krb5_context context, enum keytype keytype, gss_buffer_set_t *data_set) { krb5_keyblock *key = NULL; krb5_storage *sp = NULL; krb5_data data; OM_uint32 maj_stat = GSS_S_COMPLETE; krb5_error_code ret; krb5_data_zero(&data); sp = krb5_storage_emem(); if (sp == NULL) { _gsskrb5_clear_status(); ret = ENOMEM; goto out; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); switch(keytype) { case ACCEPTOR_KEY: ret = _gsskrb5i_get_acceptor_subkey(context_handle, context, &key); break; case INITIATOR_KEY: ret = _gsskrb5i_get_initiator_subkey(context_handle, context, &key); break; case TOKEN_KEY: ret = _gsskrb5i_get_token_key(context_handle, context, &key); break; default: _gsskrb5_set_status(EINVAL, "%d is not a valid subkey type", keytype); ret = EINVAL; break; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (ret) goto out; if (key == NULL) { _gsskrb5_set_status(EINVAL, "have no subkey of type %d", keytype); ret = EINVAL; goto out; } ret = krb5_store_keyblock(sp, *key); krb5_free_keyblock (context, key); if (ret) goto out; ret = krb5_storage_to_data(sp, &data); if (ret) goto out; { gss_buffer_desc value; value.length = data.length; value.value = data.data; maj_stat = gss_add_buffer_set_member(minor_status, &value, data_set); } out: krb5_data_free(&data); if (sp) krb5_storage_free(sp); if (ret) { *minor_status = ret; maj_stat = GSS_S_FAILURE; } return maj_stat; }
/** * @brief Inquire Sec Context by OID * @ingroup globus_gsi_gssapi_extensions */ OM_uint32 GSS_CALLCONV gss_inquire_sec_context_by_oid( OM_uint32 * minor_status, const gss_ctx_id_t context_handle, const gss_OID desired_object, gss_buffer_set_t * data_set) { OM_uint32 major_status = GSS_S_COMPLETE; OM_uint32 local_minor_status; gss_ctx_id_desc * context = NULL; int found_index; int chain_index; int cert_count; X509_EXTENSION * extension; X509 * cert = NULL; STACK_OF(X509) * cert_chain = NULL; ASN1_OBJECT * asn1_desired_obj = NULL; ASN1_OCTET_STRING * asn1_oct_string; gss_buffer_desc data_set_buffer = GSS_C_EMPTY_BUFFER; globus_result_t local_result = GLOBUS_SUCCESS; unsigned char * tmp_ptr; static char * _function_name_ = "gss_inquire_sec_context_by_oid"; GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER; /* parameter checking goes here */ if(minor_status == NULL) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid minor_status (NULL) passed to function"))); major_status = GSS_S_FAILURE; goto exit; } if(context_handle == GSS_C_NO_CONTEXT) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid context_handle passed to function"))); major_status = GSS_S_FAILURE; goto exit; } *minor_status = (OM_uint32) GLOBUS_SUCCESS; context = (gss_ctx_id_desc *) context_handle; if(desired_object == GSS_C_NO_OID) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid desired_object passed to function"))); major_status = GSS_S_FAILURE; goto exit; } if(data_set == NULL) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid data_set (NULL) passed to function"))); major_status = GSS_S_FAILURE; goto exit; } *data_set = NULL; /* lock the context mutex */ globus_mutex_lock(&context->mutex); local_result = globus_gsi_callback_get_cert_depth(context->callback_data, &cert_count); 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 unlock_exit; } if(cert_count == 0) { goto unlock_exit; } major_status = gss_create_empty_buffer_set(&local_minor_status, data_set); if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER); goto unlock_exit; } local_result = globus_gsi_callback_get_cert_chain( context->callback_data, &cert_chain); 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; cert_chain = NULL; goto unlock_exit; } if(((gss_OID_desc *)desired_object)->length != gss_ext_x509_cert_chain_oid->length || memcmp(((gss_OID_desc *)desired_object)->elements, gss_ext_x509_cert_chain_oid->elements, gss_ext_x509_cert_chain_oid->length)) { /* figure out what object was asked for */ asn1_desired_obj = ASN1_OBJECT_new(); if(!asn1_desired_obj) { GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL, (_GGSL("Couldn't create ASN1 object"))); major_status = GSS_S_FAILURE; goto unlock_exit; } asn1_desired_obj->length = ((gss_OID_desc *)desired_object)->length; asn1_desired_obj->data = ((gss_OID_desc *)desired_object)->elements; found_index = -1; for(chain_index = 0; chain_index < cert_count; chain_index++) { cert = sk_X509_value(cert_chain, chain_index); data_set_buffer.value = NULL; data_set_buffer.length = 0; found_index = X509_get_ext_by_OBJ(cert, asn1_desired_obj, found_index); if(found_index >= 0) { extension = X509_get_ext(cert, found_index); if(!extension) { GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL, (_GGSL("Couldn't get extension at index %d " "from cert in credential."), found_index)); major_status = GSS_S_FAILURE; goto unlock_exit; } asn1_oct_string = X509_EXTENSION_get_data(extension); if(!asn1_oct_string) { GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL, (_GGSL("Couldn't get cert extension in the form of an " "ASN1 octet string."))); major_status = GSS_S_FAILURE; goto unlock_exit; } asn1_oct_string = ASN1_OCTET_STRING_dup(asn1_oct_string); if(!asn1_oct_string) { GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL, (_GGSL("Failed to make copy of extension data"))); major_status = GSS_S_FAILURE; goto unlock_exit; } data_set_buffer.value = asn1_oct_string->data; data_set_buffer.length = asn1_oct_string->length; OPENSSL_free(asn1_oct_string); major_status = gss_add_buffer_set_member( &local_minor_status, &data_set_buffer, data_set); if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER); goto unlock_exit; } } } } else { for(chain_index = 0; chain_index < cert_count; chain_index++) { int certlen; cert = sk_X509_value(cert_chain, chain_index); certlen = i2d_X509(cert, NULL); data_set_buffer.length = certlen; if (certlen < 0) { GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL, (_GGSL("Failed to serialize certificate"))); major_status = GSS_S_FAILURE; goto unlock_exit; } tmp_ptr = realloc(data_set_buffer.value, data_set_buffer.length); if(tmp_ptr == NULL) { GLOBUS_GSI_GSSAPI_MALLOC_ERROR(minor_status); major_status = GSS_S_FAILURE; goto unlock_exit; } data_set_buffer.value = tmp_ptr; if(i2d_X509(cert,&tmp_ptr) < 0) { free(data_set_buffer.value); GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL, (_GGSL("Failed to serialize certificate"))); major_status = GSS_S_FAILURE; goto unlock_exit; } major_status = gss_add_buffer_set_member( &local_minor_status, &data_set_buffer, data_set); if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER); goto unlock_exit; } } if(data_set_buffer.value != NULL) { free(data_set_buffer.value); } } unlock_exit: /* unlock the context mutex */ globus_mutex_unlock(&context->mutex); exit: if (asn1_desired_obj != NULL) { ASN1_OBJECT_free(asn1_desired_obj); } if(cert_chain != NULL) { sk_X509_pop_free(cert_chain, X509_free); } GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT; return major_status; }
static OM_uint32 inquireNegoExKey(OM_uint32 *minor, const gss_ctx_id_t ctx, const gss_OID desired_object, gss_buffer_set_t *dataSet) { OM_uint32 major, tmpMinor; int bInitiatorKey; gss_buffer_desc salt; gss_buffer_desc key = GSS_C_EMPTY_BUFFER; size_t keySize; bInitiatorKey = CTX_IS_INITIATOR(ctx); if (ctx->encryptionType == ENCTYPE_NULL) { major = GSS_S_UNAVAILABLE; *minor = GSSEAP_KEY_UNAVAILABLE; goto cleanup; } /* * If the caller supplied the verify key OID, then we need the acceptor * key if we are the initiator, and vice versa. */ if (desired_object->length == 11 && memcmp(desired_object->elements, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x07", 11) == 0) bInitiatorKey ^= 1; if (bInitiatorKey) { salt.length = NEGOEX_INITIATOR_SALT_LEN; salt.value = NEGOEX_INITIATOR_SALT; } else { salt.length = NEGOEX_ACCEPTOR_SALT_LEN; salt.value = NEGOEX_ACCEPTOR_SALT; } keySize = KRB_KEY_LENGTH(&ctx->rfc3961Key); major = gssEapPseudoRandom(minor, ctx, GSS_C_PRF_KEY_FULL, &salt, keySize, &key); if (GSS_ERROR(major)) goto cleanup; major = gss_add_buffer_set_member(minor, &key, dataSet); if (GSS_ERROR(major)) goto cleanup; major = addEnctypeOidToBufferSet(minor, ctx->encryptionType, dataSet); if (GSS_ERROR(major)) goto cleanup; major = GSS_S_COMPLETE; *minor = 0; cleanup: if (key.value != NULL) { memset(key.value, 0, key.length); gss_release_buffer(&tmpMinor, &key); } if (GSS_ERROR(major)) zeroAndReleaseBufferSet(dataSet); return major; }
/** * Get the proxy group from a GSS name. * * This function will get the proxy group from a GSS name structure. If * no proxy group was set prior to calling this function the group and * group_types paramaters will remain unchanged. * * @param minor_status * The minor status returned by this function. This paramter * will be 0 upon success. * @param name * The GSS name from which the group information is extracted. * @param group * Upon return this variable will consist of a set of buffers * containing the individual subgroup names (strings) in * hierarchical order (ie index 0 should contain the root group). * @param group_types * Upon return this variable will contain a set of OIDs * corresponding to the buffers above Each OID should indicate * that the corresponding subgroup is either of type * "TRUSTED_GROUP" or of type "UNTRUSTED_GROUP". * * @return * GSS_S_COMPLETE upon success * GSS_S_BAD_NAME if the name was found to be faulty * GSS_S_FAILURE upon general failure */ OM_uint32 GSS_CALLCONV gss_get_group( OM_uint32 * minor_status, const gss_name_t name, gss_buffer_set_t * group, gss_OID_set * group_types) { OM_uint32 major_status = GSS_S_COMPLETE; OM_uint32 tmp_minor_status; int i; int num_subgroups; gss_name_desc * internal_name; char * subgroup; gss_buffer_desc buffer; static char * _function_name_ = "gss_get_group"; GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER; internal_name = (gss_name_desc *) name; if(minor_status == NULL) { major_status = GSS_S_FAILURE; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, major_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("NULL parameter minor_status passed to function: %s"), _function_name_)); goto exit; } *minor_status = (OM_uint32) GLOBUS_SUCCESS; if(name == GSS_C_NO_NAME) { major_status = GSS_S_FAILURE; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, major_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid group name passed to function: %s"), _function_name_)); goto exit; } if(group == NULL) { major_status = GSS_S_FAILURE; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, major_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid group passed to function: %s"), _function_name_)); goto exit; } if(group_types == NULL) { major_status = GSS_S_FAILURE; GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, major_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT, (_GGSL("Invalid group types passed to function: %s"), _function_name_)); goto exit; } num_subgroups = sk_num(internal_name->group); if(internal_name->group == NULL || num_subgroups == 0) { goto exit; } if(internal_name->group_types == NULL) { GLOBUS_GSI_GSSAPI_ERROR_RESULT( minor_status, GLOBUS_GSI_GSSAPI_ERROR_BAD_NAME); major_status = GSS_S_BAD_NAME; goto exit; } major_status = gss_create_empty_buffer_set(local_minor_status, group); if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP); goto exit; } major_status = gss_create_empty_oid_set(local_minor_status, group_types); if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP); goto release_buffer; } for(++index = 0; ++index < num_subgroups; ++index) { subgroup = sk_value(internal_name->group, ++index); buffer.value = (void *) subgroup; buffer.length = strlen(subgroup) + 1; major_status = gss_add_buffer_set_member(&local_minor_status, &buffer, group); if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP); goto release_oid; } if(ASN1_BIT_STRING_get_bit(internal_name->group_types, index)) { major_status = gss_add_oid_set_member( &local_minor_status, (gss_OID) gss_untrusted_group, group_types); } else { major_status = gss_add_oid_set_member( &local_minor_status, (gss_OID) gss_trusted_group, group_types); } if(GSS_ERROR(major_status)) { GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT( minor_status, local_minor_status, GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP); goto release_oid; } } goto exit; release_oid: gss_release_oid_set(&local_minor_status, group_types); release_buffer: gss_release_buffer_set(&local_minor_status, group); exit: GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT; return major_status; }