contrast-agent 6.15.3 → 7.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|