contrast-agent 6.15.3 → 7.1.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.
- checksums.yaml +4 -4
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +1 -1
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +1 -1
- data/ext/cs__assess_module/cs__assess_module.c +0 -19
- data/ext/cs__assess_test/cs__assess_tests.c +1 -1
- data/ext/cs__common/cs__common.c +17 -18
- data/ext/cs__common/cs__common.h +7 -11
- data/ext/cs__contrast_patch/cs__contrast_patch.c +16 -24
- data/ext/extconf_common.rb +79 -0
- data/lib/contrast/agent/assess/policy/policy.rb +1 -1
- data/lib/contrast/agent/assess/policy/source_method.rb +1 -0
- data/lib/contrast/agent/deadzone/policy/policy.rb +1 -1
- data/lib/contrast/agent/patching/policy/policy.rb +2 -2
- data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +3 -0
- data/lib/contrast/agent/protect/rule/no_sqli/no_sqli.rb +1 -1
- data/lib/contrast/agent/reporting/reporter.rb +19 -4
- data/lib/contrast/agent/reporting/reporting_events/agent_effective_config.rb +32 -0
- data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +7 -0
- data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +3 -1
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +11 -7
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +15 -7
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +4 -2
- data/lib/contrast/agent/reporting/reporting_workers/application_server_worker.rb +3 -0
- data/lib/contrast/agent/reporting/reporting_workers/reporter_heartbeat.rb +3 -0
- data/lib/contrast/agent/reporting/reporting_workers/server_settings_worker.rb +3 -0
- data/lib/contrast/agent/telemetry/base.rb +37 -12
- data/lib/contrast/agent/telemetry/client.rb +1 -3
- data/lib/contrast/agent/telemetry/telemetry.rb +0 -7
- data/lib/contrast/agent/thread/thread_watcher.rb +2 -2
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/components/agent.rb +1 -1
- data/lib/contrast/components/api.rb +3 -3
- data/lib/contrast/components/app_context.rb +1 -1
- data/lib/contrast/components/assess.rb +1 -1
- data/lib/contrast/components/assess_rules.rb +2 -2
- data/lib/contrast/components/base.rb +3 -3
- data/lib/contrast/components/config/sources.rb +12 -9
- data/lib/contrast/components/config.rb +2 -2
- data/lib/contrast/components/protect.rb +2 -2
- data/lib/contrast/components/sampling.rb +7 -5
- data/lib/contrast/components/settings.rb +1 -1
- data/lib/contrast/config/certification_configuration.rb +1 -1
- data/lib/contrast/config/configuration_files.rb +47 -0
- data/lib/contrast/config/diagnostics/command_line.rb +24 -0
- data/lib/contrast/config/{config.rb → diagnostics/config.rb} +21 -6
- data/lib/contrast/config/diagnostics/contrast_ui.rb +24 -0
- data/lib/contrast/config/diagnostics/effective_config.rb +28 -0
- data/lib/contrast/config/diagnostics/effective_config_value.rb +14 -0
- data/lib/contrast/config/diagnostics/environment_variables.rb +51 -0
- data/lib/contrast/config/{diagnostics.rb → diagnostics/monitor.rb} +10 -10
- data/lib/contrast/config/diagnostics/source_config_value.rb +51 -0
- data/lib/contrast/config/diagnostics/tools.rb +188 -0
- data/lib/contrast/config/diagnostics/user_configuration_file.rb +44 -0
- data/lib/contrast/config/request_audit_configuration.rb +1 -1
- data/lib/contrast/config/server_configuration.rb +1 -1
- data/lib/contrast/configuration.rb +90 -57
- data/lib/contrast/utils/hash_utils.rb +43 -0
- data/lib/contrast/utils/json.rb +46 -0
- data/lib/contrast/utils/middleware_utils.rb +4 -4
- data/lib/contrast/utils/net_http_base.rb +75 -26
- data/lib/contrast/utils/object_share.rb +3 -3
- data/lib/contrast.rb +0 -16
- data/ruby-agent.gemspec +4 -8
- metadata +40 -25
- data/lib/contrast/config/diagnostics_tools.rb +0 -99
- data/lib/contrast/config/effective_config.rb +0 -131
- data/lib/contrast/config/effective_config_value.rb +0 -32
@@ -5,14 +5,15 @@ require 'json'
|
|
5
5
|
require 'net/http'
|
6
6
|
require 'contrast/components/logger'
|
7
7
|
require 'contrast/utils/net_http_base'
|
8
|
+
require 'contrast/config/diagnostics/monitor'
|
8
9
|
require 'contrast/agent/reporting/connection_status'
|
9
|
-
require 'contrast/agent/reporting/reporting_utilities/response_handler'
|
10
|
-
require 'contrast/agent/reporting/reporting_utilities/reporter_client_utils'
|
11
|
-
require 'contrast/agent/reporting/reporting_utilities/endpoints'
|
12
10
|
require 'contrast/agent/reporting/reporting_utilities/headers'
|
11
|
+
require 'contrast/agent/reporting/reporting_utilities/endpoints'
|
13
12
|
require 'contrast/agent/reporting/reporting_events/server_settings'
|
13
|
+
require 'contrast/agent/reporting/reporting_utilities/response_handler'
|
14
14
|
require 'contrast/agent/reporting/reporting_events/application_settings'
|
15
|
-
require 'contrast/
|
15
|
+
require 'contrast/agent/reporting/reporting_events/agent_effective_config'
|
16
|
+
require 'contrast/agent/reporting/reporting_utilities/reporter_client_utils'
|
16
17
|
|
17
18
|
module Contrast
|
18
19
|
module Agent
|
@@ -57,6 +58,7 @@ module Contrast
|
|
57
58
|
# @param connection [Net::HTTP] open connection
|
58
59
|
def startup! connection
|
59
60
|
return if status.startup_messages_sent?
|
61
|
+
return unless connection
|
60
62
|
|
61
63
|
send_agent_startup(connection)
|
62
64
|
end
|
@@ -76,7 +78,7 @@ module Contrast
|
|
76
78
|
response = connection.request(request)
|
77
79
|
audit&.audit_event(event, response) if ::Contrast::API.request_audit_enable
|
78
80
|
process_settings_response(response, event)
|
79
|
-
|
81
|
+
report_configuration(response, event)
|
80
82
|
process_preflight_response(event, response, connection)
|
81
83
|
response
|
82
84
|
rescue StandardError => e
|
@@ -90,7 +92,7 @@ module Contrast
|
|
90
92
|
#
|
91
93
|
# @param response [Contrast::Agent::Reporting::Response, nil]
|
92
94
|
# @param event [Contrast::Agent::Reporting::ReportingEvent]
|
93
|
-
def
|
95
|
+
def report_configuration response, event
|
94
96
|
return unless response
|
95
97
|
|
96
98
|
diagnostics.config.determine_config_status(response_handler.last_response_code || response.code)
|
@@ -99,6 +101,8 @@ module Contrast
|
|
99
101
|
|
100
102
|
logger.info('[Reporter Diagnostics] last response code:', response_code: response_handler.last_response_code)
|
101
103
|
diagnostics.write_to_file
|
104
|
+
config_event = Contrast::Agent::Reporting::AgentEffectiveConfig.new(diagnostics)
|
105
|
+
Contrast::Agent.reporter.send_event(config_event)
|
102
106
|
end
|
103
107
|
|
104
108
|
def status
|
@@ -110,7 +114,7 @@ module Contrast
|
|
110
114
|
end
|
111
115
|
|
112
116
|
def diagnostics
|
113
|
-
@_diagnostics ||= Contrast::
|
117
|
+
@_diagnostics ||= Contrast::Config::Diagnostics::Monitor.new(Contrast::LOGGER.path)
|
114
118
|
end
|
115
119
|
|
116
120
|
def sleep?
|
@@ -53,19 +53,15 @@ module Contrast
|
|
53
53
|
# @param request [Net::HTTPRequest]
|
54
54
|
# @return [Net::HTTPRequest]
|
55
55
|
def build_headers request
|
56
|
-
|
57
|
-
request
|
58
|
-
request['Application-Language'] = @headers.app_language
|
59
|
-
request['Application-Name'] = @headers.app_name
|
60
|
-
request['Application-Path'] = @headers.app_path
|
61
|
-
request['Application-Version'] = app_version if app_version
|
56
|
+
build_application_headers(request)
|
57
|
+
build_encode_and_compress_headers(request)
|
62
58
|
request['Authorization'] = @headers.authorization
|
63
59
|
request['Server-Name'] = @headers.server_name
|
64
60
|
request['Server-Path'] = @headers.server_path
|
65
61
|
request['Server-Type'] = @headers.server_type
|
66
62
|
request['X-Contrast-Agent'] = @headers.agent_version
|
67
63
|
request['X-Contrast-Header-Encoding'] = @headers.encoding
|
68
|
-
|
64
|
+
request['Session-ID'] = @headers.session_id
|
69
65
|
request
|
70
66
|
end
|
71
67
|
|
@@ -155,6 +151,18 @@ module Contrast
|
|
155
151
|
request['X-Contrast-Encoding'] = @headers.compression
|
156
152
|
request['Content-Encoding'] = @headers.compression
|
157
153
|
end
|
154
|
+
|
155
|
+
# Adds corresponding application headers to request.
|
156
|
+
#
|
157
|
+
# @param request [Net::HTTPRequest]
|
158
|
+
def build_application_headers request
|
159
|
+
app_version = @headers.app_version
|
160
|
+
request['API-Key'] = @headers.api_key
|
161
|
+
request['Application-Language'] = @headers.app_language
|
162
|
+
request['Application-Name'] = @headers.app_name
|
163
|
+
request['Application-Path'] = @headers.app_path
|
164
|
+
request['Application-Version'] = app_version if app_version
|
165
|
+
end
|
158
166
|
end
|
159
167
|
end
|
160
168
|
end
|
@@ -4,6 +4,7 @@
|
|
4
4
|
require 'contrast/agent/reporting/reporting_utilities/ng_response_extractor'
|
5
5
|
require 'contrast/agent/reporting/reporting_utilities/response_extractor'
|
6
6
|
require 'contrast/agent/reactions/disable_reaction'
|
7
|
+
require 'contrast/utils/json'
|
7
8
|
|
8
9
|
module Contrast
|
9
10
|
module Agent
|
@@ -32,7 +33,8 @@ module Contrast
|
|
32
33
|
FORBIDDEN_NO_ACTION_MSG = 'Report access was forbidden because the supplied credentials failed ' \
|
33
34
|
'to authenticate the Agent'
|
34
35
|
UNPROCESSABLE_ENTITY_MSG = 'Reporter received Unprocessable Entity response. Disabling permanently.'
|
35
|
-
RETRY_AFTER_MSG =
|
36
|
+
RETRY_AFTER_MSG = 'There are too many requests of this type being sent by this Agent. ' \
|
37
|
+
"#{ SUSPEND_MSG }".cs__freeze
|
36
38
|
|
37
39
|
def last_response_code
|
38
40
|
@_last_response_code ||= ''
|
@@ -256,7 +258,7 @@ module Contrast
|
|
256
258
|
response_body = response&.body
|
257
259
|
return unless response_body
|
258
260
|
|
259
|
-
response_data =
|
261
|
+
response_data = Contrast::Utils::Json.parse(response_body, deep_symbolize: true)
|
260
262
|
return unless response_data.cs__is_a?(Hash)
|
261
263
|
|
262
264
|
extract_response_last_modified(response, event)
|
@@ -13,11 +13,14 @@ module Contrast
|
|
13
13
|
RESEND_INTERVAL_MS = 30_000.cs__freeze
|
14
14
|
|
15
15
|
def start_thread!
|
16
|
+
return unless attempt_to_start?
|
16
17
|
return if running?
|
17
18
|
|
18
19
|
@_thread = Contrast::Agent::Thread.new do
|
19
20
|
logger.info('[ApplicationSettingsWorker] Starting thread.', sending_interval: application_server_ms)
|
20
21
|
loop do
|
22
|
+
break unless attempt_to_start?
|
23
|
+
|
21
24
|
logger.info('[ApplicationSettingsWorker] Fetching Settings', sending_interval: application_server_ms)
|
22
25
|
Contrast::Agent.reporter&.send_event(application_settings_message)
|
23
26
|
sleep(application_server_ms / 1000)
|
@@ -19,11 +19,14 @@ module Contrast
|
|
19
19
|
REFRESH_INTERVAL_SEC = 60
|
20
20
|
|
21
21
|
def start_thread!
|
22
|
+
return unless attempt_to_start?
|
22
23
|
return if running?
|
23
24
|
|
24
25
|
@_thread = Contrast::Agent::Thread.new do
|
25
26
|
logger.info('[Heartbeat] Starting thread.')
|
26
27
|
loop do
|
28
|
+
break unless attempt_to_start?
|
29
|
+
|
27
30
|
polling_events.each do |event|
|
28
31
|
Contrast::Agent.reporter&.send_event(event)
|
29
32
|
end
|
@@ -13,11 +13,14 @@ module Contrast
|
|
13
13
|
RESEND_INTERVAL_MS = 60_000.cs__freeze
|
14
14
|
|
15
15
|
def start_thread!
|
16
|
+
return unless attempt_to_start?
|
16
17
|
return if running?
|
17
18
|
|
18
19
|
@_thread = Contrast::Agent::Thread.new do
|
19
20
|
logger.info('[ServerSettingsWorker] Starting thread.', sending_interval: server_settings_resend_ms)
|
20
21
|
loop do
|
22
|
+
break unless attempt_to_start?
|
23
|
+
|
21
24
|
logger.info('[ServerSettingsWorker] Fetching Settings', sending_interval: server_settings_resend_ms)
|
22
25
|
Contrast::Agent.reporter&.send_event(settings_message)
|
23
26
|
sleep(server_settings_resend_ms / 1000)
|
@@ -46,6 +46,39 @@ module Contrast
|
|
46
46
|
@enabled
|
47
47
|
end
|
48
48
|
|
49
|
+
# In case of connection error, do not create the background thread or queue,
|
50
|
+
# as if the opt-out env var was set.
|
51
|
+
#
|
52
|
+
# @return [Boolean]
|
53
|
+
def ip_opt_out?
|
54
|
+
@_ip_opt_out ||= begin
|
55
|
+
test_conn = Contrast::Agent::Telemetry::Client.new.initialize_connection(URL)
|
56
|
+
|
57
|
+
if test_conn.nil? || Contrast::Utils::NetHttpBase.last_error
|
58
|
+
# log if error:
|
59
|
+
if defined?(Contrast) && defined?(Contrast::CONFIG) && defined?(Contrast::CONFIG)
|
60
|
+
Contrast::CONFIG.proto_logger.warn('[Telemetry] connection error disabling...',
|
61
|
+
error: Contrast::Utils::NetHttpBase.last_error)
|
62
|
+
|
63
|
+
end
|
64
|
+
# Disable telemetry:
|
65
|
+
@enabled = false
|
66
|
+
true
|
67
|
+
else
|
68
|
+
# Close the connection
|
69
|
+
test_conn.finish if test_conn.started?
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
rescue StandardError
|
74
|
+
@enabled = false
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
78
|
+
def disable!
|
79
|
+
@enabled = false
|
80
|
+
end
|
81
|
+
|
49
82
|
private
|
50
83
|
|
51
84
|
def telemetry_enabled?
|
@@ -56,15 +89,7 @@ module Contrast
|
|
56
89
|
|
57
90
|
# In case of connection error, do not create the background thread or queue,
|
58
91
|
# as if the opt-out env var was set
|
59
|
-
|
60
|
-
ip_opt_out_telemetry = @_client.initialize_connection(URL)
|
61
|
-
if ip_opt_out_telemetry.nil?
|
62
|
-
# TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
|
63
|
-
# an infinite loop w/ telemetry
|
64
|
-
logger.debug("[Telemetry] Connection was not established properly!!! \n
|
65
|
-
Telemetry reporting will be disabled!")
|
66
|
-
return false
|
67
|
-
end
|
92
|
+
return false if ip_opt_out?
|
68
93
|
|
69
94
|
true
|
70
95
|
end
|
@@ -91,6 +116,7 @@ module Contrast
|
|
91
116
|
end
|
92
117
|
|
93
118
|
def start_thread!
|
119
|
+
return unless attempt_to_start?
|
94
120
|
return if running?
|
95
121
|
|
96
122
|
logger.debug('[Telemetry] Starting background telemetry thread.')
|
@@ -140,6 +166,7 @@ module Contrast
|
|
140
166
|
Contrast::Agent::Thread.new do
|
141
167
|
loop do
|
142
168
|
next unless client && connection
|
169
|
+
break unless attempt_to_start?
|
143
170
|
|
144
171
|
# Start pushing exceptions to queue for reporting.
|
145
172
|
Contrast::TELEMETRY_EXCEPTIONS.each_value { |value| queue << value }
|
@@ -155,9 +182,7 @@ module Contrast
|
|
155
182
|
sleep(retry_sleep_time) unless retry_sleep_time.nil?
|
156
183
|
end
|
157
184
|
rescue StandardError => e
|
158
|
-
|
159
|
-
# an infinite loop w/ telemetry
|
160
|
-
logger.debug('[Telemetry] Could not send message to service from telemetry queue.', e)
|
185
|
+
logger.error('[Telemetry] Could not send message to service from telemetry queue.', e)
|
161
186
|
stop!
|
162
187
|
end
|
163
188
|
end
|
@@ -100,9 +100,7 @@ module Contrast
|
|
100
100
|
def get_event_json event
|
101
101
|
Array(event.to_controlled_hash).to_json
|
102
102
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
103
|
-
|
104
|
-
# an infinite loop w/ telemetry
|
105
|
-
logger.debug('[Telemetry] Unable to convert TelemetryEvent to JSON string', e, hsh)
|
103
|
+
logger.error('[Telemetry] Unable to convert TelemetryEvent to JSON string', e, hsh)
|
106
104
|
raise(e)
|
107
105
|
end
|
108
106
|
end
|
@@ -92,13 +92,6 @@ module Contrast
|
|
92
92
|
#
|
93
93
|
# @return [Boolean]
|
94
94
|
def telemetry_exceptions_enabled?
|
95
|
-
opts_out_telemetry = return_value(:telemetry_opt_outs).to_s
|
96
|
-
return false if opts_out_telemetry.casecmp?('true') || opts_out_telemetry == '1'
|
97
|
-
# Double check if telemetry is enabled, this includes a check for Agent enable setting in the
|
98
|
-
# config. In case of disabled Agent the queue won't be created and the Telemetry would not
|
99
|
-
# be enabled. This check is here to prevent a loop of error creations that could no be added
|
100
|
-
# to a queue ( because the client cannot be initialized if the Agent is disabled or settings are
|
101
|
-
# missing).
|
102
95
|
return false unless Contrast::Agent::Telemetry::Base.enabled?
|
103
96
|
|
104
97
|
true
|
@@ -6,7 +6,7 @@ require 'contrast/agent/reporting/report'
|
|
6
6
|
require 'contrast/agent/reporting/reporting_workers/reporting_workers'
|
7
7
|
require 'contrast/agent/telemetry/base'
|
8
8
|
require 'contrast/agent/protect/input_analyzer/worth_watching_analyzer'
|
9
|
-
require 'contrast/config/diagnostics'
|
9
|
+
require 'contrast/config/diagnostics/monitor'
|
10
10
|
require 'contrast/utils/job_servers_running'
|
11
11
|
|
12
12
|
module Contrast
|
@@ -114,7 +114,7 @@ module Contrast
|
|
114
114
|
def check_before_start
|
115
115
|
return if Contrast::CONFIG.send(:validate)
|
116
116
|
|
117
|
-
@_diagnostics = Contrast::
|
117
|
+
@_diagnostics = Contrast::Config::Diagnostics::Monitor.new(Contrast::AGENT.logger.path ||
|
118
118
|
Contrast::Components::Config::CONTRAST_LOG)
|
119
119
|
@_diagnostics.config.populate_fail_connection
|
120
120
|
@_diagnostics.write_to_file_logic(false, reset: false)
|
@@ -137,7 +137,7 @@ module Contrast
|
|
137
137
|
# Converts current configuration to effective config values class and appends them to
|
138
138
|
# EffectiveConfig class.
|
139
139
|
#
|
140
|
-
# @param effective_config [Contrast::
|
140
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
141
141
|
def to_effective_config effective_config
|
142
142
|
super
|
143
143
|
logger&.to_effective_config(effective_config)
|
@@ -18,7 +18,7 @@ module Contrast
|
|
18
18
|
include Contrast::Config::BaseConfiguration
|
19
19
|
|
20
20
|
CANON_NAME = 'api'
|
21
|
-
PROXY_NAME = "#{ CANON_NAME }.proxy"
|
21
|
+
PROXY_NAME = "#{ CANON_NAME }.proxy".cs__freeze
|
22
22
|
CONFIG_VALUES = %w[api_key user_name service_key url].cs__freeze
|
23
23
|
|
24
24
|
# @return [String]
|
@@ -127,7 +127,7 @@ module Contrast
|
|
127
127
|
# Converts current configuration to effective config values class and appends them to
|
128
128
|
# EffectiveConfig class.
|
129
129
|
#
|
130
|
-
# @param effective_config [Contrast::
|
130
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
131
131
|
def to_effective_config effective_config
|
132
132
|
add_effective_config_values(effective_config, CONFIG_VALUES, CANON_NAME, CONTRAST)
|
133
133
|
effective_proxy(effective_config)
|
@@ -137,7 +137,7 @@ module Contrast
|
|
137
137
|
|
138
138
|
private
|
139
139
|
|
140
|
-
# @param effective_config [Contrast::
|
140
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
141
141
|
def effective_proxy effective_config
|
142
142
|
add_single_effective_value(effective_config, ENABLE, proxy_enable.to_s, PROXY_NAME, "#{ CONTRAST }.proxy")
|
143
143
|
return unless proxy_url && proxy_enable
|
@@ -161,7 +161,7 @@ module Contrast
|
|
161
161
|
# Converts current configuration to effective config values class and appends them to
|
162
162
|
# EffectiveConfig class.
|
163
163
|
#
|
164
|
-
# @param effective_config [Contrast::
|
164
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
165
165
|
def to_effective_config effective_config
|
166
166
|
super
|
167
167
|
Contrast::CONFIG.server.to_effective_config(effective_config)
|
@@ -218,7 +218,7 @@ module Contrast
|
|
218
218
|
# Converts current configuration to effective config values class and appends them to
|
219
219
|
# EffectiveConfig class.
|
220
220
|
#
|
221
|
-
# @param effective_config [Contrast::
|
221
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
222
222
|
def to_effective_config effective_config
|
223
223
|
super
|
224
224
|
sampling&.to_effective_config(effective_config)
|
@@ -16,7 +16,7 @@ module Contrast
|
|
16
16
|
|
17
17
|
SPEC_KEY = :disabled_rules.cs__freeze
|
18
18
|
CANON_NAME = 'assess.rules'
|
19
|
-
NAME_PREFIX = "#{ CONTRAST }.#{ CANON_NAME }"
|
19
|
+
NAME_PREFIX = "#{ CONTRAST }.#{ CANON_NAME }".cs__freeze
|
20
20
|
|
21
21
|
# @return [Array, nil] list of disabled assess rules
|
22
22
|
attr_accessor :disabled_rules
|
@@ -34,7 +34,7 @@ module Contrast
|
|
34
34
|
# Converts current configuration to effective config values class and appends them to
|
35
35
|
# EffectiveConfig class.
|
36
36
|
#
|
37
|
-
# @param effective_config [Contrast::
|
37
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
38
38
|
def to_effective_config effective_config
|
39
39
|
add_single_effective_value(effective_config, SPEC_KEY.to_s, disabled_rules, canon_name, NAME_PREFIX)
|
40
40
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2023 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/config/
|
4
|
+
require 'contrast/config/diagnostics/tools'
|
5
5
|
require 'contrast/utils/object_share'
|
6
6
|
|
7
7
|
module Contrast
|
@@ -9,7 +9,7 @@ module Contrast
|
|
9
9
|
# All components should inherit from this,
|
10
10
|
# whether Interfaces, InstanceMethods or ClassMethods.
|
11
11
|
module ComponentBase
|
12
|
-
include Contrast::
|
12
|
+
include Contrast::Config::Diagnostics::Tools
|
13
13
|
|
14
14
|
CONTRAST = 'contrast'
|
15
15
|
ENABLE = 'enable'
|
@@ -84,7 +84,7 @@ module Contrast
|
|
84
84
|
# Converts current configuration to effective config values class and appends them to
|
85
85
|
# EffectiveConfig class.
|
86
86
|
#
|
87
|
-
# @param effective_config [Contrast::
|
87
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
88
88
|
def to_effective_config effective_config
|
89
89
|
add_effective_config_values(effective_config, config_values, canon_name, "#{ CONTRAST }.#{ canon_name }")
|
90
90
|
end
|
@@ -11,11 +11,14 @@ module Contrast
|
|
11
11
|
# This component encapsulates storing the source for each entry in the config,
|
12
12
|
# so that we can report on where the value was set from.
|
13
13
|
class Sources
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
ENVIRONMENT_VARIABLE = 'ENV'
|
15
|
+
COMMAND_LINE = 'CLI'
|
16
|
+
CONTRAST_UI = 'ContrastUI'
|
17
|
+
DEFAULT_VALUE = 'Default'
|
18
|
+
# Order matters for the Configurations files. This is read when Agent starts up and will always go
|
19
|
+
# through the YAML as priority.
|
20
|
+
# Do not change the order!
|
21
|
+
APP_CONFIGURATION_FILE = %w[YAML YML].cs__freeze
|
19
22
|
|
20
23
|
# @return [Hash]
|
21
24
|
attr_reader :data
|
@@ -30,15 +33,15 @@ module Contrast
|
|
30
33
|
# @param path [String] the canonical name for the config entry (such as api.proxy.enable)
|
31
34
|
# @return [String] the source for the entry
|
32
35
|
def get path
|
33
|
-
data.dig(*parts_for(path)) ||
|
36
|
+
data.dig(*parts_for(path)) || DEFAULT_VALUE
|
34
37
|
rescue TypeError
|
35
|
-
|
38
|
+
DEFAULT_VALUE
|
36
39
|
end
|
37
40
|
|
38
41
|
# Assigns the config source for a specified config path.
|
39
42
|
#
|
40
43
|
# @param path [String] the canonical name for the config entry (such as api.proxy.enable)
|
41
|
-
# @param [String] the source for the entry
|
44
|
+
# @param source[String] the source for the entry
|
42
45
|
# @return [String] the source type for the entry
|
43
46
|
def set path, source
|
44
47
|
assign_value(data, parts_for(path), source)
|
@@ -64,7 +67,7 @@ module Contrast
|
|
64
67
|
# @param current_level [Hash] all, or some of, the config source information
|
65
68
|
# @param parts [Array] the parts for canonical name of the config entry
|
66
69
|
# @param source [String] the source to be set for the specified entry
|
67
|
-
# @return [
|
70
|
+
# @return [String] the path split on periods, and converted to symbols
|
68
71
|
def assign_value current_level, parts, source
|
69
72
|
parts[0...-1].each do |segment|
|
70
73
|
current_level[segment] ||= {}
|
@@ -4,7 +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
|
+
require 'contrast/config/diagnostics/monitor'
|
8
8
|
|
9
9
|
module Contrast
|
10
10
|
module Components
|
@@ -249,7 +249,7 @@ module Contrast
|
|
249
249
|
return unless current_level.nil? == false && current_level.cs__respond_to?(dot_path_array[-1])
|
250
250
|
|
251
251
|
current_level.send("#{ dot_path_array[-1] }=", value)
|
252
|
-
sources.set(dot_path_array.join('.'), Contrast::Components::Config::Sources::
|
252
|
+
sources.set(dot_path_array.join('.'), Contrast::Components::Config::Sources::ENVIRONMENT_VARIABLE)
|
253
253
|
end
|
254
254
|
end
|
255
255
|
end
|
@@ -130,7 +130,7 @@ module Contrast
|
|
130
130
|
# Converts current configuration to effective config values class and appends them to
|
131
131
|
# EffectiveConfig class.
|
132
132
|
#
|
133
|
-
# @param effective_config [Contrast::
|
133
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
134
134
|
def to_effective_config effective_config
|
135
135
|
super
|
136
136
|
protect_rules_to_effective_config(effective_config)
|
@@ -138,7 +138,7 @@ module Contrast
|
|
138
138
|
|
139
139
|
private
|
140
140
|
|
141
|
-
# @param effective_config [Contrast::
|
141
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
142
142
|
def protect_rules_to_effective_config effective_config
|
143
143
|
return unless defend_rules
|
144
144
|
|
@@ -103,7 +103,7 @@ module Contrast
|
|
103
103
|
include Contrast::Config::BaseConfiguration
|
104
104
|
|
105
105
|
CANON_NAME = 'assess.sampling'
|
106
|
-
NAME_PREFIX = "#{ CONTRAST }.#{ CANON_NAME }"
|
106
|
+
NAME_PREFIX = "#{ CONTRAST }.#{ CANON_NAME }".cs__freeze
|
107
107
|
CONFIG_VALUES = %w[enable baseline request_frequency response_frequency window_ms].cs__freeze
|
108
108
|
|
109
109
|
# @return [Integer, nil]
|
@@ -136,7 +136,7 @@ module Contrast
|
|
136
136
|
# Converts current configuration to effective config values class and appends them to
|
137
137
|
# EffectiveConfig class.
|
138
138
|
#
|
139
|
-
# @param effective_config [Contrast::
|
139
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
140
140
|
def to_effective_config effective_config
|
141
141
|
confirm_sources
|
142
142
|
|
@@ -161,10 +161,11 @@ module Contrast
|
|
161
161
|
# back to the default values.
|
162
162
|
def confirm_sources
|
163
163
|
if sampling_control[:enabled] == DEFAULT_SAMPLING_ENABLED
|
164
|
-
Contrast::CONFIG.sources.set('assess.sampling.enable', Contrast::Components::Config::Sources::
|
164
|
+
Contrast::CONFIG.sources.set('assess.sampling.enable', Contrast::Components::Config::Sources::DEFAULT_VALUE)
|
165
165
|
end
|
166
166
|
if sampling_control[:window] == DEFAULT_SAMPLING_WINDOW_MS
|
167
|
-
Contrast::CONFIG.sources.set('assess.sampling.window_ms',
|
167
|
+
Contrast::CONFIG.sources.set('assess.sampling.window_ms',
|
168
|
+
Contrast::Components::Config::Sources::DEFAULT_VALUE)
|
168
169
|
end
|
169
170
|
{
|
170
171
|
'baseline' => :baseline,
|
@@ -172,7 +173,8 @@ module Contrast
|
|
172
173
|
'response_frequency' => :response_frequency
|
173
174
|
}.each do |k, v|
|
174
175
|
if sampling_control[v] == cs__class.cs__const_get("DEFAULT_SAMPLING_#{ v.upcase }")
|
175
|
-
Contrast::CONFIG.sources.set("assess.sampling.#{ k }",
|
176
|
+
Contrast::CONFIG.sources.set("assess.sampling.#{ k }",
|
177
|
+
Contrast::Components::Config::Sources::DEFAULT_VALUE)
|
176
178
|
end
|
177
179
|
end
|
178
180
|
end
|
@@ -283,7 +283,7 @@ module Contrast
|
|
283
283
|
return unless level.cs__is_a?(Hash)
|
284
284
|
|
285
285
|
level[parts[-1]] = value
|
286
|
-
Contrast::CONFIG.sources.set(parts.join('.'), Contrast::Components::Config::Sources::
|
286
|
+
Contrast::CONFIG.sources.set(parts.join('.'), Contrast::Components::Config::Sources::CONTRAST_UI)
|
287
287
|
end
|
288
288
|
end
|
289
289
|
end
|
@@ -38,7 +38,7 @@ module Contrast
|
|
38
38
|
# Converts current configuration to effective config values class and appends them to
|
39
39
|
# EffectiveConfig class.
|
40
40
|
#
|
41
|
-
# @param effective_config [Contrast::
|
41
|
+
# @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
|
42
42
|
def to_effective_config effective_config
|
43
43
|
add_effective_config_values(effective_config, CONFIG_VALUES, CANON_NAME, CONTRAST)
|
44
44
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/utils/duck_utils'
|
5
|
+
require 'contrast/utils/object_share'
|
6
|
+
require 'contrast/components/config/sources'
|
7
|
+
require 'contrast/config/diagnostics/tools'
|
8
|
+
|
9
|
+
module Contrast
|
10
|
+
module Config
|
11
|
+
# This class will hold all the references for the configuration files. It will safe read values used to
|
12
|
+
# identify the source of configuration in Configuration Diagnostics reported to TS.
|
13
|
+
class ConfigurationFiles
|
14
|
+
# @return [String] path of the main configuration file.
|
15
|
+
attr_accessor :main_file
|
16
|
+
|
17
|
+
# @return [Array<Contrast::Config::LocalSourceValue>]
|
18
|
+
def source_files
|
19
|
+
@_source_files ||= []
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param path [String]
|
23
|
+
# @param values [Hash]
|
24
|
+
def add_source_file path, values
|
25
|
+
source_files << Contrast::Config::LocalSourceValue.new(path, values)
|
26
|
+
@main_file = path if source_files.length == 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# This class will hold all the info about the read file.
|
31
|
+
class LocalSourceValue
|
32
|
+
YML_EXT = '.yml'
|
33
|
+
YAML_EXT = '.yaml'
|
34
|
+
# @return [String]
|
35
|
+
attr_reader :path
|
36
|
+
# @return [Hash]
|
37
|
+
attr_reader :values
|
38
|
+
|
39
|
+
# @param path [String]
|
40
|
+
# @param values [Hash]
|
41
|
+
def initialize path = '', values = {}
|
42
|
+
@path = path unless Contrast::Utils::DuckUtils.empty_duck?(path)
|
43
|
+
@values = values
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/config/diagnostics/effective_config_value'
|
5
|
+
require 'contrast/config/diagnostics/tools'
|
6
|
+
require 'contrast/utils/object_share'
|
7
|
+
|
8
|
+
module Contrast
|
9
|
+
module Config
|
10
|
+
module Diagnostics
|
11
|
+
# Reads All ENV variables.
|
12
|
+
module CommandLine
|
13
|
+
class << self
|
14
|
+
def command_line_settings
|
15
|
+
cli = Contrast::Config::Diagnostics::Tools.flatten_settings(Contrast::CONFIG.sources.
|
16
|
+
for(Contrast::Components::Config::Sources::COMMAND_LINE))
|
17
|
+
|
18
|
+
Contrast::Config::Diagnostics::Tools.to_config_values(cli, source: true)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|