contrast-agent 6.8.0 → 6.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/lib/contrast/agent/assess/policy/trigger_method.rb +1 -1
  3. data/lib/contrast/agent/assess/property/evented.rb +11 -11
  4. data/lib/contrast/agent/assess.rb +0 -1
  5. data/lib/contrast/agent/excluder.rb +1 -1
  6. data/lib/contrast/agent/middleware.rb +8 -2
  7. data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +116 -0
  8. data/lib/contrast/agent/protect/rule/base.rb +2 -2
  9. data/lib/contrast/agent/protect/rule/bot_blocker.rb +1 -1
  10. data/lib/contrast/agent/protect/rule/cmd_injection.rb +8 -7
  11. data/lib/contrast/agent/protect/rule/cmdi/cmdi_chained_command.rb +0 -5
  12. data/lib/contrast/agent/protect/rule/cmdi/cmdi_dangerous_path.rb +0 -5
  13. data/lib/contrast/agent/protect/rule/path_traversal.rb +4 -3
  14. data/lib/contrast/agent/protect/rule/sqli.rb +4 -3
  15. data/lib/contrast/agent/protect/rule/xss.rb +1 -0
  16. data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +1 -1
  17. data/lib/contrast/agent/reporting/report.rb +1 -0
  18. data/lib/contrast/agent/reporting/reporter.rb +34 -0
  19. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +3 -9
  20. data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +1 -1
  21. data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +12 -7
  22. data/lib/contrast/agent/reporting/reporting_events/application_inventory_activity.rb +6 -1
  23. data/lib/contrast/agent/reporting/reporting_events/finding.rb +2 -2
  24. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +239 -93
  25. data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -23
  26. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +10 -9
  27. data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +12 -0
  28. data/lib/contrast/agent/reporting/reporting_events/server_reporting_event.rb +8 -0
  29. data/lib/contrast/agent/reporting/reporting_events/server_settings.rb +40 -0
  30. data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +6 -0
  31. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +43 -1
  32. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +8 -4
  33. data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +58 -4
  34. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +4 -3
  35. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +76 -16
  36. data/lib/contrast/agent/reporting/server_settings_worker.rb +44 -0
  37. data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +14 -2
  38. data/lib/contrast/agent/reporting/settings/helpers.rb +7 -0
  39. data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +39 -2
  40. data/lib/contrast/agent/reporting/settings/rule_definition.rb +3 -0
  41. data/lib/contrast/agent/reporting/settings/security_logger.rb +77 -0
  42. data/lib/contrast/agent/reporting/settings/server_features.rb +9 -0
  43. data/lib/contrast/agent/reporting/settings/syslog.rb +34 -5
  44. data/lib/contrast/agent/request.rb +1 -0
  45. data/lib/contrast/agent/request_handler.rb +5 -10
  46. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +1 -1
  47. data/lib/contrast/agent/thread_watcher.rb +35 -1
  48. data/lib/contrast/agent/version.rb +1 -1
  49. data/lib/contrast/agent.rb +6 -0
  50. data/lib/contrast/api/communication/connection_status.rb +15 -0
  51. data/lib/contrast/components/agent.rb +34 -0
  52. data/lib/contrast/components/api.rb +23 -0
  53. data/lib/contrast/components/app_context.rb +23 -3
  54. data/lib/contrast/components/assess.rb +34 -4
  55. data/lib/contrast/components/assess_rules.rb +18 -0
  56. data/lib/contrast/components/base.rb +40 -0
  57. data/lib/contrast/components/config/sources.rb +95 -0
  58. data/lib/contrast/components/config.rb +18 -1
  59. data/lib/contrast/components/heap_dump.rb +10 -0
  60. data/lib/contrast/components/inventory.rb +15 -2
  61. data/lib/contrast/components/logger.rb +18 -0
  62. data/lib/contrast/components/polling.rb +36 -0
  63. data/lib/contrast/components/protect.rb +48 -1
  64. data/lib/contrast/components/ruby_component.rb +15 -0
  65. data/lib/contrast/components/sampling.rb +70 -13
  66. data/lib/contrast/components/security_logger.rb +13 -0
  67. data/lib/contrast/components/settings.rb +74 -7
  68. data/lib/contrast/config/certification_configuration.rb +14 -0
  69. data/lib/contrast/config/config.rb +46 -0
  70. data/lib/contrast/config/diagnostics.rb +114 -0
  71. data/lib/contrast/config/diagnostics_tools.rb +98 -0
  72. data/lib/contrast/config/effective_config.rb +65 -0
  73. data/lib/contrast/config/effective_config_value.rb +32 -0
  74. data/lib/contrast/config/exception_configuration.rb +12 -0
  75. data/lib/contrast/config/protect_rule_configuration.rb +1 -1
  76. data/lib/contrast/config/protect_rules_configuration.rb +8 -7
  77. data/lib/contrast/config/request_audit_configuration.rb +13 -0
  78. data/lib/contrast/config/server_configuration.rb +41 -2
  79. data/lib/contrast/configuration.rb +28 -2
  80. data/lib/contrast/extension/assess/erb.rb +1 -1
  81. data/lib/contrast/utils/assess/event_limit_utils.rb +31 -9
  82. data/lib/contrast/utils/assess/trigger_method_utils.rb +5 -4
  83. data/lib/contrast/utils/hash_digest.rb +2 -2
  84. data/lib/contrast/utils/input_classification_base.rb +1 -2
  85. data/lib/contrast/utils/reporting/application_activity_batch_utils.rb +81 -0
  86. data/lib/contrast/utils/routes_sent.rb +60 -0
  87. data/lib/contrast/utils/telemetry_client.rb +1 -2
  88. data/lib/contrast/utils/timer.rb +16 -0
  89. data/lib/contrast.rb +3 -1
  90. data/ruby-agent.gemspec +5 -1
  91. metadata +29 -20
  92. data/lib/contrast/agent/assess/contrast_event.rb +0 -157
  93. data/lib/contrast/agent/assess/events/event_factory.rb +0 -34
  94. data/lib/contrast/agent/assess/events/source_event.rb +0 -46
  95. data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -36
@@ -0,0 +1,95 @@
1
+ # Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'contrast/utils/env_configuration_item'
5
+ require 'ougai'
6
+ require 'contrast/configuration'
7
+
8
+ module Contrast
9
+ module Components
10
+ module Config
11
+ # This component encapsulates storing the source for each entry in the config,
12
+ # so that we can report on where the value was set from.
13
+ class Sources
14
+ ENVIRONMENT = 'ENV'
15
+ CLI = 'CLI'
16
+ CONTRASTUI = 'ContrastUI'
17
+ DEFAULT = 'Default'
18
+ YAML = 'YAML'
19
+
20
+ # @return [Hash]
21
+ attr_reader :data
22
+
23
+ def initialize data = {}
24
+ @data = data
25
+ end
26
+
27
+ # Retrieves the current config source for the specified config path. If no source is
28
+ # set then returns the Default value.
29
+ #
30
+ # @param path [String] the canonical name for the config entry (such as api.proxy.enable)
31
+ # @return [String] the source for the entry
32
+ def get path
33
+ data.dig(*parts_for(path)) || DEFAULT
34
+ rescue TypeError
35
+ DEFAULT
36
+ end
37
+
38
+ # Assigns the config source for a specified config path.
39
+ #
40
+ # @param path [String] the canonical name for the config entry (such as api.proxy.enable)
41
+ # @param [String] the source for the entry
42
+ # @return [String] the source type for the entry
43
+ def set path, source
44
+ assign_value(data, parts_for(path), source)
45
+ end
46
+
47
+ # Finds entries within config source data for the specified type, and returns
48
+ # them along with the current values for each.
49
+ #
50
+ # @param type [String] a source type (ENV, CLI, ContrastUI, YAML)
51
+ # @return [Hash] the entries for the provided source, along with the associated values
52
+ def for type
53
+ deep_select(data.dup, type, [])
54
+ end
55
+
56
+ private
57
+
58
+ # @param path [String] the canonical name for a config entry (such as api.proxy.enable)
59
+ # @return [Array] the path split on periods, and converted to symbols
60
+ def parts_for path
61
+ path.split('.').map(&:to_sym)
62
+ end
63
+
64
+ # @param current_level [Hash] all, or some of, the config source information
65
+ # @param parts [Array] the parts for canonical name of the config entry
66
+ # @param source [String] the source to be set for the specified entry
67
+ # @return [Array] the path split on periods, and converted to symbols
68
+ def assign_value current_level, parts, source
69
+ parts[0...-1].each do |segment|
70
+ current_level[segment] ||= {}
71
+ current_level = current_level[segment]
72
+ end
73
+ return unless current_level.cs__is_a?(Hash)
74
+
75
+ current_level[parts[-1]] = source
76
+ end
77
+
78
+ # @param sources [Hash] all, or some of, the config source information
79
+ # @param type [Array] the source type to look for entries of
80
+ # @param path [String] the entries followed to get to this part of the config
81
+ # @return [Hash] the entries for the provided source, along with the associated values
82
+ def deep_select sources, type, path
83
+ sources.each_with_object({}) do |(k, v), grouping|
84
+ if v.cs__is_a?(Hash)
85
+ nested_data = deep_select(v, type, path.dup.append(k.to_sym))
86
+ grouping[k] = nested_data unless nested_data.empty?
87
+ elsif v == type
88
+ grouping[k] = Contrast::CONFIG.config.loaded_config.dig(*path, k)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -4,6 +4,7 @@
4
4
  require 'contrast/utils/env_configuration_item'
5
5
  require 'ougai'
6
6
  require 'contrast/configuration'
7
+ require 'contrast/config/diagnostics'
7
8
 
8
9
  module Contrast
9
10
  module Components
@@ -26,6 +27,7 @@ module Contrast
26
27
  CONTRAST_ENV_MARKER = 'CONTRAST__'
27
28
  CONTRAST_LOG = 'contrast_agent.log'
28
29
  CONTRAST_NAME = 'Contrast Agent'
30
+ DATE_TIME = '%Y-%m-%dT%H:%M:%S.%L%z'
29
31
 
30
32
  class Interface # :nodoc: # rubocop:disable Metrics/ClassLength
31
33
  SESSION_VARIABLES = 'Invalid configuration. '\
@@ -50,7 +52,7 @@ module Contrast
50
52
  @_proto_logger.progname = CONTRAST_NAME
51
53
  @_proto_logger.level = ::Ougai::Logging::Severity::WARN
52
54
  @_proto_logger.formatter = Contrast::Logger::Format.new
53
- @_proto_logger.formatter.datetime_format = '%Y-%m-%dT%H:%M:%S.%L%z'
55
+ @_proto_logger.formatter.datetime_format = DATE_TIME
54
56
  @_proto_logger
55
57
  end
56
58
  end
@@ -109,6 +111,10 @@ module Contrast
109
111
  @config.enable
110
112
  end
111
113
 
114
+ def sources
115
+ @config.sources
116
+ end
117
+
112
118
  def invalid?
113
119
  !valid?
114
120
  end
@@ -130,6 +136,11 @@ module Contrast
130
136
  application.session_metadata
131
137
  end
132
138
 
139
+ # @return [String, nil] the path to the YAML config file, if any.
140
+ def config_file_path
141
+ config.config_file
142
+ end
143
+
133
144
  private
134
145
 
135
146
  # The config has information about how to construct the logger. If the config is invalid, and you want to know
@@ -221,6 +232,11 @@ module Contrast
221
232
  agent.logger.path
222
233
  end
223
234
 
235
+ # This methods is here to add the proper forward towards @config
236
+ def enable= value
237
+ @config.enable = value
238
+ end
239
+
224
240
  # Assign the value from an ENV variable to the Contrast::Config::RootConfiguration object, when
225
241
  # appropriate.
226
242
  #
@@ -233,6 +249,7 @@ module Contrast
233
249
  return unless current_level.nil? == false && current_level.cs__respond_to?(dot_path_array[-1])
234
250
 
235
251
  current_level.send("#{ dot_path_array[-1] }=", value)
252
+ sources.set(dot_path_array.join('.'), Contrast::Components::Config::Sources::ENVIRONMENT)
236
253
  end
237
254
  end
238
255
  end
@@ -10,12 +10,22 @@ module Contrast
10
10
  # Interface used to build the HeapDump settings and component.
11
11
  class Interface
12
12
  include Contrast::Config::BaseConfiguration
13
+ include Contrast::Components::ComponentBase
14
+
15
+ # @return [String]
16
+ attr_reader :canon_name
17
+ # @return [Array]
18
+ attr_reader :config_values
13
19
 
14
20
  DEFAULT_PATH = 'contrast_heap_dumps' # saved
15
21
  DEFAULT_MS = 10_000
16
22
  DEFAULT_COUNT = 5
23
+ CANON_NAME = 'agent.heap_dump'
24
+ CONFIG_VALUES = %w[enable path delay_ms window_ms count clean].cs__freeze
17
25
 
18
26
  def initialize hsh = {}
27
+ @config_values = CONFIG_VALUES
28
+ @canon_name = CANON_NAME
19
29
  return unless hsh
20
30
 
21
31
  @_enable = hsh[:enable]
@@ -11,10 +11,18 @@ module Contrast
11
11
  class Interface
12
12
  include Contrast::Components::ComponentBase
13
13
 
14
- # @return [Array, nil] tags
15
- attr_accessor :tags
14
+ CANON_NAME = 'inventory'
15
+ CONFIG_VALUES = %w[enable analyze_libraries tags].cs__freeze
16
+
17
+ attr_writer :tags
18
+ # @return [String]
19
+ attr_reader :canon_name
20
+ # @return [Array]
21
+ attr_reader :config_values
16
22
 
17
23
  def initialize hsh = {}
24
+ @config_values = CONFIG_VALUES
25
+ @canon_name = CANON_NAME
18
26
  return unless hsh
19
27
 
20
28
  @enable = !false?(hsh[:enable])
@@ -31,6 +39,11 @@ module Contrast
31
39
  def analyze_libraries
32
40
  @analyze_libraries.nil? ? true : @analyze_libraries
33
41
  end
42
+
43
+ # @return [String, nil] tags
44
+ def tags
45
+ stringify_array(@tags)
46
+ end
34
47
  end
35
48
  end
36
49
  end
@@ -13,6 +13,14 @@ module Contrast
13
13
  Contrast::Logger::Log.instance.logger
14
14
  end
15
15
 
16
+ # When calling this method from any instance
17
+ # The CEF logger will be initialized and it's
18
+ # path and level will be set. Since we don't
19
+ # call this method unless protect is started,
20
+ # on Agent Startup no file is created before is
21
+ # needed.
22
+ #
23
+ # @return [Logger]
16
24
  def cef_logger
17
25
  @_cef_logger ||= Contrast::Logger::CEFLog.instance.tap(&:build_logger)
18
26
  end
@@ -23,6 +31,10 @@ module Contrast
23
31
  # instance methods and will initialize new instances for where they're needed
24
32
  class Interface
25
33
  include InstanceMethods
34
+ include Contrast::Components::ComponentBase
35
+
36
+ CANON_NAME = 'agent.logger'
37
+ CONFIG_VALUES = %w[path level progname].cs__freeze
26
38
 
27
39
  # @return [String, nil]
28
40
  attr_accessor :path
@@ -30,8 +42,14 @@ module Contrast
30
42
  attr_accessor :level
31
43
  # @return [String, nil]
32
44
  attr_accessor :progname
45
+ # @return [String]
46
+ attr_reader :canon_name
47
+ # @return [Array]
48
+ attr_reader :config_values
33
49
 
34
50
  def initialize hsh = {}
51
+ @config_values = CONFIG_VALUES
52
+ @canon_name = CANON_NAME
35
53
  return unless hsh
36
54
 
37
55
  @path = hsh[:path]
@@ -0,0 +1,36 @@
1
+ # Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'contrast/components/base'
5
+
6
+ module Contrast
7
+ module Components
8
+ module Polling
9
+ # A wrapper build around the agent.polling config
10
+ class Interface
11
+ include Contrast::Components::ComponentBase
12
+
13
+ # @return [Integer, nil]
14
+ attr_reader :server_settings_ms
15
+ # @return [String]
16
+ attr_reader :canon_name
17
+ # @return [Array]
18
+ attr_reader :config_values
19
+ # @return [Integer, nil]
20
+ attr_reader :batch_reporting_interval_ms
21
+
22
+ CANON_NAME = 'agent.polling'
23
+ CONFIG_VALUES = %w[server_settings_ms batch_reporting_interval_ms].cs__freeze
24
+
25
+ def initialize hsh = {}
26
+ @config_values = CONFIG_VALUES
27
+ @canon_name = CANON_NAME
28
+ return unless hsh
29
+
30
+ @server_settings_ms = hsh[:server_settings_ms]
31
+ @batch_reporting_interval_ms = hsh[:batch_reporting_interval_ms]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -14,12 +14,23 @@ module Contrast
14
14
  include Contrast::Components::ComponentBase
15
15
  include Contrast::Config::BaseConfiguration
16
16
 
17
+ CANON_NAME = 'protect'
18
+ CONFIG_VALUES = %w[enabled?].cs__freeze
19
+ RULES = 'rules'
20
+ MODE = 'mode'
21
+
17
22
  # @return [Boolean, nil]
18
23
  attr_accessor :enable
24
+ # @return [String]
25
+ attr_reader :canon_name
26
+ # @return [Array]
27
+ attr_reader :config_values
19
28
  # @return [Boolean, nil]
20
29
  attr_accessor :agent_lib
21
30
 
22
31
  def initialize hsh = {}
32
+ @config_values = CONFIG_VALUES
33
+ @canon_name = CANON_NAME
23
34
  return unless hsh
24
35
 
25
36
  @_exceptions = Contrast::Config::ExceptionConfiguration.new(hsh[:exceptions])
@@ -57,6 +68,9 @@ module Contrast
57
68
  ::Contrast::SETTINGS.protect_state.enabled == true
58
69
  end
59
70
 
71
+ # Current Configuration for the protect rules
72
+ #
73
+ # @return [Contrast::Config::ProtectRulesConfiguration]
60
74
  def rule_config
61
75
  ::Contrast::CONFIG.protect.rules
62
76
  end
@@ -65,11 +79,17 @@ module Contrast
65
79
  # protect rules.
66
80
  #
67
81
  # @return defend_rules[Hash<Contrast::SETTINGS.protect_state.rules>]
68
- #
69
82
  def defend_rules
70
83
  ::Contrast::SETTINGS.protect_state.rules
71
84
  end
72
85
 
86
+ # The Contrast::CONFIG.protect.rules is object so we need to check it's
87
+ # corresponding method call for each rule of interest. If there is no
88
+ # status available we search for any Settings available received form
89
+ # TS response.
90
+ #
91
+ # @param rule_id [String]
92
+ # @return mode [Symbol]
73
93
  def rule_mode rule_id
74
94
  str = rule_id.tr('-', '_')
75
95
  ::Contrast::CONFIG.protect.rules[str]&.applicable_mode ||
@@ -77,6 +97,9 @@ module Contrast
77
97
  :NO_ACTION
78
98
  end
79
99
 
100
+ # Name of the protect rule
101
+ #
102
+ # @return [String]
80
103
  def rule name
81
104
  ::Contrast::SETTINGS.protect_state.rules[name]
82
105
  end
@@ -104,8 +127,32 @@ module Contrast
104
127
  @_forcibly_disabled = false?(::Contrast::CONFIG.protect.enable)
105
128
  end
106
129
 
130
+ # Converts current configuration to effective config values class and appends them to
131
+ # EffectiveConfig class.
132
+ #
133
+ # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
134
+ def to_effective_config effective_config
135
+ super
136
+ protect_rules_to_effective_config(effective_config)
137
+ end
138
+
107
139
  private
108
140
 
141
+ # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
142
+ def protect_rules_to_effective_config effective_config
143
+ return unless defend_rules
144
+
145
+ defend_rules.each do |key, value|
146
+ next unless key && value
147
+
148
+ config_prefix = "#{ CANON_NAME }.#{ RULES }.#{ key }"
149
+ name_prefix = "#{ CONTRAST }.#{ CANON_NAME }.#{ RULES }.#{ key }"
150
+ add_single_effective_value(effective_config, ENABLE, value.enabled?, config_prefix, name_prefix)
151
+ # Get the mode by checking Current Configs or Settings received:
152
+ add_single_effective_value(effective_config, MODE, rule_mode(key), config_prefix, name_prefix)
153
+ end
154
+ end
155
+
109
156
  def forcibly_enabled?
110
157
  return @_forcibly_enabled unless @_forcibly_enabled.nil?
111
158
 
@@ -1,6 +1,8 @@
1
1
  # Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'contrast/components/base'
5
+
4
6
  module Contrast
5
7
  module Components
6
8
  module Ruby
@@ -23,11 +25,24 @@ module Contrast
23
25
  ].cs__freeze
24
26
 
25
27
  DEFAULT_UNINSTRUMENTED_NAMESPACES = %w[FactoryGirl FactoryBot].cs__freeze
28
+ CANON_NAME = 'agent.ruby'
29
+ CONFIG_VALUES = %w[
30
+ disabled_agent_rake_tasks
31
+ propagate_yield require_scan
32
+ non_request_tracking
33
+ uninstrument_namespace
34
+ ].cs__freeze
26
35
 
27
36
  attr_writer :disabled_agent_rake_tasks, :exceptions, :propagate_yield, :require_scan,
28
37
  :non_request_tracking, :uninstrument_namespace
38
+ # @return [String]
39
+ attr_reader :canon_name
40
+ # @return [Array]
41
+ attr_reader :config_values
29
42
 
30
43
  def initialize hsh = {}
44
+ @config_values = CONFIG_VALUES
45
+ @canon_name = CANON_NAME
31
46
  return unless hsh
32
47
 
33
48
  @disabled_agent_rake_tasks = hsh[:disabled_agent_rake_tasks]
@@ -28,10 +28,10 @@ module Contrast
28
28
  settings = ::Contrast::SETTINGS&.assess_state&.sampling_settings
29
29
  {
30
30
  enabled: enabled?(config_settings, settings),
31
- baseline: baseline(config_settings, settings),
32
- request_frequency: request_frequency(config_settings, settings),
33
- response_frequency: response_frequency(config_settings, settings),
34
- window: window(config_settings, settings)
31
+ baseline: check_baseline(config_settings, settings),
32
+ request_frequency: check_request_frequency(config_settings, settings),
33
+ response_frequency: check_response_frequency(config_settings, settings),
34
+ window: check_window(config_settings, settings)
35
35
  }
36
36
  end
37
37
  end
@@ -45,7 +45,8 @@ module Contrast
45
45
 
46
46
  # @param config_settings [Contrast::Config::SamplingConfiguration] the Sampling configuration as provided by
47
47
  # local user input
48
- # @param settings [Contrast::Api::Settings::Sampling] the Sampling settings as provided by TeamServer
48
+ # @param settings [Contrast::Agent::Reporting::Settings::Sampling, nil] the Sampling settings as provided by
49
+ # TeamServer
49
50
  # @return [Boolean] the resolution of the config_settings, settings, and default value
50
51
  def enabled? config_settings, settings
51
52
  true?([config_settings&.enable, settings&.enabled, DEFAULT_SAMPLING_ENABLED].compact[0])
@@ -53,35 +54,39 @@ module Contrast
53
54
 
54
55
  # @param config_settings [Contrast::Config::SamplingConfiguration] the Sampling configuration as provided by
55
56
  # local user input
56
- # @param settings [Contrast::Api::Settings::Sampling] the Sampling settings as provided by TeamServer
57
+ # @param settings [Contrast::Agent::Reporting::Settings::Sampling] the Sampling settings as provided by
58
+ # TeamServer
57
59
  # @return [Integer] the resolution of the config_settings, settings, and default value
58
- def baseline config_settings, settings
60
+ def check_baseline config_settings, settings
59
61
  [config_settings&.baseline, settings&.baseline].map(&:to_i).find(&:positive?) || DEFAULT_SAMPLING_BASELINE
60
62
  end
61
63
 
62
64
  # @param config_settings [Contrast::Config::SamplingConfiguration] the Sampling configuration as provided by
63
65
  # local user input
64
- # @param settings [Contrast::Api::Settings::Sampling] the Sampling settings as provided by TeamServer
66
+ # @param settings [Contrast::Agent::Reporting::Settings::Sampling] the Sampling settings as provided by
67
+ # TeamServer
65
68
  # @return [Integer] the resolution of the config_settings, settings, and default value
66
- def request_frequency config_settings, settings
69
+ def check_request_frequency config_settings, settings
67
70
  [config_settings&.request_frequency, settings&.request_frequency].map(&:to_i).find(&:positive?) ||
68
71
  DEFAULT_SAMPLING_REQUEST_FREQUENCY
69
72
  end
70
73
 
71
74
  # @param config_settings [Contrast::Config::SamplingConfiguration] the Sampling configuration as provided by
72
75
  # local user input
73
- # @param settings [Contrast::Api::Settings::Sampling] the Sampling settings as provided by TeamServer
76
+ # @param settings [Contrast::Agent::Reporting::Settings::Sampling] the Sampling settings as provided by
77
+ # TeamServer
74
78
  # @return [Integer] the resolution of the config_settings, settings, and default value
75
- def response_frequency config_settings, settings
79
+ def check_response_frequency config_settings, settings
76
80
  [config_settings&.response_frequency, settings&.response_frequency].map(&:to_i).find(&:positive?) ||
77
81
  DEFAULT_SAMPLING_RESPONSE_FREQUENCY
78
82
  end
79
83
 
80
84
  # @param config_settings [Contrast::Config::SamplingConfiguration] the Sampling configuration as provided by
81
85
  # local user input
82
- # @param settings [Contrast::Api::Settings::Sampling] the Sampling settings as provided by TeamServer
86
+ # @param settings [Contrast::Agent::Reporting::Settings::Sampling] the Sampling settings as provided by
87
+ # TeamServer
83
88
  # @return [Integer] the resolution of the config_settings, settings, and default value
84
- def window config_settings, settings
89
+ def check_window config_settings, settings
85
90
  [config_settings&.window_ms, settings&.window_ms].map(&:to_i).find(&:positive?) || DEFAULT_SAMPLING_WINDOW_MS
86
91
  end
87
92
  end
@@ -94,8 +99,13 @@ module Contrast
94
99
 
95
100
  class Interface # :nodoc:
96
101
  include InstanceMethods
102
+ extend ClassMethods
97
103
  include Contrast::Config::BaseConfiguration
98
104
 
105
+ CANON_NAME = 'assess.sampling'
106
+ NAME_PREFIX = "#{ CONTRAST }.#{ CANON_NAME }"
107
+ CONFIG_VALUES = %w[enable baseline request_frequency response_frequency window_ms].cs__freeze
108
+
99
109
  # @return [Integer, nil]
100
110
  attr_reader :baseline
101
111
  # @return [Integer, nil]
@@ -104,8 +114,11 @@ module Contrast
104
114
  attr_reader :response_frequency
105
115
  # @return [Integer, nil]
106
116
  attr_reader :window_ms
117
+ # @return [String]
118
+ attr_reader :canon_name
107
119
 
108
120
  def initialize hsh = {}
121
+ @canon_name = CANON_NAME
109
122
  return unless hsh
110
123
 
111
124
  @enable = hsh[:enable]
@@ -119,6 +132,50 @@ module Contrast
119
132
  def enable
120
133
  !!@enable
121
134
  end
135
+
136
+ # Converts current configuration to effective config values class and appends them to
137
+ # EffectiveConfig class.
138
+ #
139
+ # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
140
+ def to_effective_config effective_config
141
+ confirm_sources
142
+
143
+ add_single_effective_value(effective_config, 'enable', sampling_control[:enabled], canon_name, NAME_PREFIX)
144
+ add_single_effective_value(effective_config, 'baseline', sampling_control[:baseline], canon_name, NAME_PREFIX)
145
+ add_single_effective_value(effective_config, 'window_ms', sampling_control[:window], canon_name, NAME_PREFIX)
146
+ add_single_effective_value(effective_config,
147
+ 'request_frequency',
148
+ sampling_control[:request_frequency],
149
+ canon_name,
150
+ NAME_PREFIX)
151
+ add_single_effective_value(effective_config,
152
+ 'response_frequency',
153
+ sampling_control[:response_frequency],
154
+ canon_name,
155
+ NAME_PREFIX)
156
+ end
157
+
158
+ private
159
+
160
+ # Confirm the sources for the sample entries to ensure that we use 'Default' if we've fallen
161
+ # back to the default values.
162
+ def confirm_sources
163
+ if sampling_control[:enabled] == DEFAULT_SAMPLING_ENABLED
164
+ Contrast::CONFIG.sources.set('assess.sampling.enable', Contrast::Components::Config::Sources::DEFAULT)
165
+ end
166
+ if sampling_control[:window] == DEFAULT_SAMPLING_WINDOW_MS
167
+ Contrast::CONFIG.sources.set('assess.sampling.window_ms', Contrast::Components::Config::Sources::DEFAULT)
168
+ end
169
+ {
170
+ 'baseline' => :baseline,
171
+ 'request_frequency' => :request_frequency,
172
+ 'response_frequency' => :response_frequency
173
+ }.each do |k, v|
174
+ if sampling_control[v] == cs__class.cs__const_get("DEFAULT_SAMPLING_#{ v.upcase }")
175
+ Contrast::CONFIG.sources.set("assess.sampling.#{ k }", Contrast::Components::Config::Sources::DEFAULT)
176
+ end
177
+ end
178
+ end
122
179
  end
123
180
  end
124
181
  end
@@ -1,17 +1,30 @@
1
1
  # Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'contrast/components/base'
5
+
4
6
  module Contrast
5
7
  module Components
6
8
  module SecurityLogger
7
9
  # Here we will read and store the setting for the CEF Logging functionality
8
10
  class Interface
11
+ include Contrast::Components::ComponentBase
12
+
13
+ CANON_NAME = 'agent.security_logger'
14
+ CONFIG_VALUES = %w[path level].cs__freeze
15
+
9
16
  # @return [String, nil]
10
17
  attr_accessor :path
11
18
  # @return [String, nil]
12
19
  attr_accessor :level
20
+ # @return [String]
21
+ attr_reader :canon_name
22
+ # @return [Array]
23
+ attr_reader :config_values
13
24
 
14
25
  def initialize hsh = {}
26
+ @config_values = CONFIG_VALUES
27
+ @canon_name = CANON_NAME
15
28
  return unless hsh
16
29
 
17
30
  @path = hsh[:path]