# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true cs__scoped_require 'rubygems/version' module Contrast module Components module Agent # A wrapper build around the Common Agent Configuration project to allow # for access of the values contained in its # parent_configuration_spec.yaml. # Specifically, this allows for querying the state of the Agent. class Interface include Contrast::Components::ComponentBase include Contrast::Components::Interface access_component :config def enabled? !!@enabled end def disabled? !enabled? end def enable! @enabled = true end def disable! @enabled = false end def unavailable? !enabled? end def ready? state.agent_ready? end def patch_interpolation? interpolation_patch_possible? end def rewrite_interpolation? !interpolation_patch_possible? end def patch_yield? !Contrast::Utils::BooleanUtil.false?(CONFIG.root.agent.ruby.propagate_yield) end def interpolation_enabled? !Contrast::Utils::BooleanUtil.false?(CONFIG.root.agent.ruby.interpolate) end def report_custom_code_sysfile_access? Contrast::Agent::FeatureState.instance.report_custom_code_sysfile_access? end def skip_instrumentation? loaded_module_name return true unless loaded_module_name loaded_module_name.start_with?(*CONFIG.root.agent.ruby.uninstrument_namespace) end # All this method chain does anymore is load the Thread patch that # propagates request contexts. That can go away RUBY-700. SHARED_LIBRARIES = %w[contrast/extensions/ruby_core/thread].cs__freeze def run_instrumentation Contrast::Agent::FeatureState.instance.tap do |settings| SHARED_LIBRARIES.each { |lib| settings.instrument lib } end Contrast::Agent::Patching::Policy::Patcher.patch # This acts as a catch up for everything we didn't see get loaded enable_tracepoint # This handles all class loads & required instrumentation going forward end # TODO: RUBY-564: This responsibility should be extracted out of this agent component and moved to # the new component that handles one-time-whole-app initialization procedures. def insert_middleware app app.middleware.insert_before 0, Contrast::Agent::Middleware # Keep our middleware at the outermost layer of the onion end def enable_tracepoint Contrast::Agent::TracePointHook.enable! end protected INTERPOLATION_HOOKABLE_VERSION = Gem::Version.new('2.6.0') # Ruby exposed the C method for interpolation in version 2.6.0, meaning # we can attempt to patch using Funchook for that version and later. def interpolation_patch_possible? @_interpolation_patch_possible = Gem::Version.new(RUBY_VERSION) >= INTERPOLATION_HOOKABLE_VERSION if @_interpolation_patch_possible.nil? @_interpolation_patch_possible end end COMPONENT_INTERFACE = Interface.new end end end