tcell_agent 2.1.2 → 2.4.1

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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/bin/tcell_agent +41 -150
  4. data/lib/tcell_agent.rb +8 -16
  5. data/lib/tcell_agent/agent.rb +87 -52
  6. data/lib/tcell_agent/config_initializer.rb +62 -0
  7. data/lib/tcell_agent/configuration.rb +72 -267
  8. data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
  9. data/lib/tcell_agent/instrument_servers.rb +14 -18
  10. data/lib/tcell_agent/instrumentation.rb +14 -6
  11. data/lib/tcell_agent/instrumentation/cmdi.rb +32 -0
  12. data/lib/tcell_agent/instrumentation/lfi.rb +55 -9
  13. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
  17. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
  18. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
  19. data/lib/tcell_agent/logger.rb +3 -4
  20. data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
  21. data/lib/tcell_agent/policies/headers_policy.rb +2 -2
  22. data/lib/tcell_agent/policies/patches_policy.rb +8 -4
  23. data/lib/tcell_agent/policies/policies_manager.rb +1 -0
  24. data/lib/tcell_agent/policies/policy_polling.rb +4 -3
  25. data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
  26. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  27. data/lib/tcell_agent/rails/auth/devise.rb +103 -102
  28. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  29. data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -57
  30. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  31. data/lib/tcell_agent/rails/better_ip.rb +7 -19
  32. data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
  33. data/lib/tcell_agent/rails/dlp.rb +48 -52
  34. data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
  35. data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
  36. data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
  37. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
  38. data/lib/tcell_agent/rails/middleware/global_middleware.rb +3 -4
  39. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
  40. data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
  41. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  42. data/lib/tcell_agent/rails/routes.rb +3 -6
  43. data/lib/tcell_agent/rails/routes/grape.rb +3 -4
  44. data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
  45. data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
  46. data/lib/tcell_agent/routes/table.rb +3 -0
  47. data/lib/tcell_agent/rust/agent_config.rb +59 -33
  48. data/lib/tcell_agent/rust/{libtcellagent-4.18.0.so → libtcellagent-alpine.so} +0 -0
  49. data/lib/tcell_agent/rust/libtcellagent-x64.dll +0 -0
  50. data/lib/tcell_agent/rust/{libtcellagent-4.18.0.dylib → libtcellagent.dylib} +0 -0
  51. data/lib/tcell_agent/rust/{libtcellagent-alpine-4.18.0.so → libtcellagent.so} +0 -0
  52. data/lib/tcell_agent/rust/models.rb +9 -0
  53. data/lib/tcell_agent/rust/native_agent.rb +58 -50
  54. data/lib/tcell_agent/rust/native_library.rb +8 -10
  55. data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
  56. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
  57. data/lib/tcell_agent/servers/puma.rb +30 -13
  58. data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -0
  59. data/lib/tcell_agent/servers/rails_server.rb +4 -4
  60. data/lib/tcell_agent/servers/unicorn.rb +1 -1
  61. data/lib/tcell_agent/servers/webrick.rb +12 -3
  62. data/lib/tcell_agent/settings_reporter.rb +0 -93
  63. data/lib/tcell_agent/sinatra.rb +1 -0
  64. data/lib/tcell_agent/tcell_context.rb +16 -7
  65. data/lib/tcell_agent/utils/headers.rb +0 -1
  66. data/lib/tcell_agent/utils/strings.rb +2 -2
  67. data/lib/tcell_agent/version.rb +1 -1
  68. data/spec/cruby_spec_helper.rb +26 -0
  69. data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
  70. data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
  71. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
  72. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
  73. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +207 -223
  74. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +89 -70
  75. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +73 -0
  76. data/spec/lib/tcell_agent/patches_spec.rb +2 -1
  77. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
  78. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
  79. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
  80. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
  81. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +14 -8
  82. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
  83. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
  84. data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
  85. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
  86. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
  87. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
  88. data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
  89. data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
  90. data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
  91. data/spec/spec_helper.rb +9 -1
  92. data/spec/support/builders.rb +8 -7
  93. data/spec/support/server_mocks/passenger_mock.rb +7 -0
  94. data/spec/support/server_mocks/puma_mock.rb +21 -0
  95. data/spec/support/server_mocks/rails_mock.rb +7 -0
  96. data/spec/support/server_mocks/thin_mock.rb +7 -0
  97. data/spec/support/server_mocks/unicorn_mock.rb +11 -0
  98. data/spec/support/shared_spec.rb +29 -0
  99. data/tcell_agent.gemspec +14 -14
  100. metadata +44 -27
  101. data/Rakefile +0 -18
  102. data/lib/tcell_agent/authlogic.rb +0 -23
  103. data/lib/tcell_agent/config/unknown_options.rb +0 -119
  104. data/lib/tcell_agent/devise.rb +0 -33
  105. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
  106. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -131
  107. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -102
  108. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
  109. data/lib/tcell_agent/rust/tcellagent-4.18.0.dll +0 -0
  110. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -37,6 +37,7 @@ module TCellAgent
37
37
  dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
38
38
  tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
39
39
  return unless tcell_context && dataex_policy && dataex_policy.actions_for_form_parameter?
40
+
40
41
  for_params(request) do |_method, param_name, param_value|
41
42
  actions = dataex_policy.get_actions_for_form_parameter(param_name, tcell_context.route_id)
42
43
  if actions
@@ -51,11 +52,13 @@ module TCellAgent
51
52
  dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
52
53
  tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
53
54
  return unless tcell_context && dataex_policy && dataex_policy.actions_for_headers?
55
+
54
56
  headers = request.env.select { |k, _v| k.start_with? 'HTTP_' }
55
57
  headers.each do |header_name, header_value|
56
58
  header_name = header_name.sub(/^HTTP_/, '').tr('_', '-')
57
59
  actions = dataex_policy.get_actions_for_header(header_name)
58
60
  next unless actions
61
+
59
62
  actions.each do |action|
60
63
  tcell_context.add_filter_for_header_value(header_value, action, header_name)
61
64
  end
@@ -66,9 +69,11 @@ module TCellAgent
66
69
  dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
67
70
  tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
68
71
  return unless tcell_context && dataex_policy && dataex_policy.actions_for_cookie?
72
+
69
73
  request.cookies.each do |cookie_name, cookie_value|
70
74
  actions = dataex_policy.get_actions_for_cookie(cookie_name)
71
75
  next unless actions
76
+
72
77
  actions.each do |action|
73
78
  tcell_context.add_filter_for_cookie_value(cookie_value, action, cookie_name)
74
79
  end
@@ -39,19 +39,18 @@ module TCellAgent
39
39
 
40
40
  TCellAgent::Instrumentation.safe_block('DLP Handler get handler and context') do
41
41
  if TCellAgent.configuration.should_instrument? &&
42
- TCellAgent.configuration.should_intercept_requests?
42
+ TCellAgent.configuration.should_intercept_requests? &&
43
+ TCellAgent::Utils::Rails.processable_response?(response_headers)
43
44
 
44
45
  # do all this work so that dlp doesn't run at all unless it's on and there
45
46
  # are rules to run
46
- if TCellAgent::Utils::Rails.processable_response?(response_headers)
47
- dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
48
- if dlp_policy && dlp_policy.get_actions_for_session_id
49
- tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
50
- if tcell_context && tcell_context.session_id
51
- dlp_handler = proc { |tc, resp|
52
- handle_dlp!(tc, resp)
53
- }
54
- end
47
+ dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
48
+ if dlp_policy && dlp_policy.get_actions_for_session_id
49
+ tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
50
+ if tcell_context && tcell_context.session_id
51
+ dlp_handler = proc { |tc, resp|
52
+ handle_dlp!(tc, resp)
53
+ }
55
54
  end
56
55
  end
57
56
  end
@@ -4,8 +4,7 @@ module TCellAgent
4
4
  module Instrumentation
5
5
  module Rails
6
6
  module JSAgent
7
- HEAD_SEARCH_REGEX = /<head>/
8
-
7
+ HEAD_SEARCH_REGEX = Regexp.new('(<head>|<head( |\n).*?>)', Regexp::IGNORECASE)
9
8
  def self.insert_now(js_agent_handler, script_insert, rack_body, content_length)
10
9
  TCellAgent::Instrumentation.safe_block('Handling JSAgent Insert Now') do
11
10
  if js_agent_handler
@@ -32,7 +31,7 @@ module TCellAgent
32
31
  TCellAgent::Instrumentation.safe_block('Handling JSAgent insert') do
33
32
  new_response = response.sub(
34
33
  TCellAgent::Instrumentation::Rails::JSAgent::HEAD_SEARCH_REGEX,
35
- "<head>#{script_insert}"
34
+ "\\1#{script_insert}"
36
35
  )
37
36
  end
38
37
 
@@ -26,7 +26,8 @@ module TCellAgent
26
26
  env[TCellAgent::Instrumentation::TCELL_ID].path = request.path
27
27
  env[TCellAgent::Instrumentation::TCELL_ID].user_agent = request.user_agent
28
28
  env[TCellAgent::Instrumentation::TCELL_ID].referrer = request.referrer
29
- env[TCellAgent::Instrumentation::TCELL_ID].remote_address = TCellAgent::Utils::Rails.better_ip(request)
29
+ env[TCellAgent::Instrumentation::TCELL_ID].remote_address = request.ip
30
+ env[TCellAgent::Instrumentation::TCELL_ID].reverse_proxy_header_value = TCellAgent::Utils::Rails.reverse_proxy_header(request)
30
31
  if request.request_method
31
32
  env[TCellAgent::Instrumentation::TCELL_ID].request_method = request.request_method
32
33
  end
@@ -7,7 +7,7 @@ require 'tcell_agent/sensor_events/sensor'
7
7
  require 'tcell_agent/sensor_events/server_agent'
8
8
  require 'tcell_agent/sensor_events/util/sanitizer_utilities'
9
9
 
10
- require 'tcell_agent/userinfo'
10
+ require 'tcell_agent/rails/auth/userinfo'
11
11
  require 'cgi'
12
12
 
13
13
  require 'tcell_agent/instrumentation'
@@ -24,6 +24,7 @@ module TCellAgent
24
24
  def call(env)
25
25
  if TCellAgent.configuration.should_intercept_requests?
26
26
  request = Rack::Request.new(env)
27
+
27
28
  TCellAgent::Instrumentation.safe_block('Setting session_id & user_id') do
28
29
  if request.session
29
30
  env[TCellAgent::Instrumentation::TCELL_ID].session_id =
@@ -41,9 +42,7 @@ module TCellAgent
41
42
  end
42
43
  end
43
44
 
44
- response = @app.call(env)
45
-
46
- response
45
+ @app.call(env)
47
46
  end
48
47
  end
49
48
  end
@@ -39,6 +39,7 @@ module TCellAgent
39
39
  TCellAgent::Instrumentation.safe_block('Handling headers') do
40
40
  headers_policy = TCellAgent.policy(TCellAgent::PolicyTypes::HEADERS)
41
41
  policy_headers = headers_policy.get_headers(
42
+ headers['Content-Type'],
42
43
  request.env[TCellAgent::Instrumentation::TCELL_ID]
43
44
  )
44
45
  policy_headers.each do |header_info|
@@ -2,36 +2,21 @@
2
2
 
3
3
  require 'rails'
4
4
 
5
- require 'tcell_agent/rails/routes'
6
-
7
5
  require 'tcell_agent/rails/middleware/global_middleware'
8
6
  require 'tcell_agent/rails/middleware/body_filter_middleware'
9
7
  require 'tcell_agent/rails/middleware/headers_middleware'
10
8
  require 'tcell_agent/rails/middleware/context_middleware'
11
9
 
10
+ require 'tcell_agent/rails/routes'
12
11
  require 'tcell_agent/rails/settings_reporter'
13
12
  require 'tcell_agent/rails/dlp'
14
13
  require 'tcell_agent/rails/csrf_exception'
15
14
 
16
- require 'tcell_agent/userinfo'
17
15
  require 'cgi'
18
16
  require 'thread'
19
17
 
20
18
  module TCellAgent
21
19
  class TCellAgentStartupRailtie < Rails::Railtie
22
- # TCellAgent config can be specified thru
23
- # Rails initializer's (https://guides.rubyonrails.org/v2.3/configuring.html#using-initializers)
24
- # so those need to run first since this relies on configuration
25
- initializer :tcell_instrument_auth_frameworks, :after => :load_config_initializers do |_app|
26
- next unless TCellAgent.configuration.should_instrument?
27
-
28
- require 'tcell_agent/devise'
29
- require 'tcell_agent/rails/auth/devise'
30
- require 'tcell_agent/authlogic'
31
- require 'tcell_agent/rails/auth/authlogic'
32
- require 'tcell_agent/rails/auth/doorkeeper'
33
- end
34
-
35
20
  initializer :tcell_insert_middleware, :before => :build_middleware_stack do |app|
36
21
  app.config.middleware.insert_before(0, TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware)
37
22
  app.config.middleware.insert_after(0, TCellAgent::Instrumentation::Rails::Middleware::HeadersMiddleware)
@@ -39,4 +24,12 @@ module TCellAgent
39
24
  app.config.middleware.use TCellAgent::Instrumentation::Rails::Middleware::GlobalMiddleware
40
25
  end
41
26
  end
27
+
28
+ class TCellAgentCSRFRailtie < Rails::Railtie
29
+ initializer 'tcell.sensors' do |_app|
30
+ ActiveSupport.on_load :action_controller do
31
+ ActionController::Base.send(:include, TCellAgent::CsrfExceptionReporter)
32
+ end
33
+ end
34
+ end
42
35
  end
@@ -0,0 +1,8 @@
1
+ module TCellAgent
2
+ class TCellAgentStartupRailtie < Rails::Railtie
3
+ initializer :start_tcell_agent,
4
+ :after => :load_config_initializers do |_app|
5
+ TCellAgent.thread_agent.start('Unicorn')
6
+ end
7
+ end
8
+ end
@@ -136,8 +136,7 @@ module TCellAgent
136
136
  prepend_around_filter :tcell_around_filter_routes
137
137
  end
138
138
  def tcell_around_filter_routes
139
- if TCellAgent.configuration.should_instrument? &&
140
- TCellAgent.configuration.should_intercept_requests?
139
+ if TCellAgent.configuration.should_intercept_requests?
141
140
  TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
142
141
  _match, parameters, route = ::Rails.application.routes.router.recognize(request) { |r, _| r }.first
143
142
 
@@ -192,8 +191,7 @@ module TCellAgent
192
191
  ActionDispatch::Journey::Router.class_eval do
193
192
  alias_method :tcell_serve, :serve
194
193
  def serve(req)
195
- if TCellAgent.configuration.should_instrument? &&
196
- TCellAgent.configuration.should_intercept_requests?
194
+ if TCellAgent.configuration.should_intercept_requests?
197
195
  TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
198
196
  _match, parameters, route = find_routes(req).first
199
197
 
@@ -220,8 +218,7 @@ module TCellAgent
220
218
  def call(env)
221
219
  env['PATH_INFO'] = ActionDispatch::Journey::Router::Utils.normalize_path(env['PATH_INFO'])
222
220
 
223
- if TCellAgent.configuration.should_instrument? &&
224
- TCellAgent.configuration.should_intercept_requests?
221
+ if TCellAgent.configuration.should_intercept_requests?
225
222
  TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
226
223
  _match, parameters, route = find_routes(env).first
227
224
 
@@ -7,8 +7,9 @@ module TCellAgent
7
7
  begin
8
8
  return route.app < Grape::API if ::Rails::VERSION::MAJOR == 4 &&
9
9
  ::Rails::VERSION::MINOR < 2
10
+
10
11
  return route.app.app < Grape::API
11
- rescue StandardError # rubocop:disable Lint/HandleExceptions
12
+ rescue StandardError
12
13
  # do nothing
13
14
  end
14
15
  end
@@ -70,9 +71,7 @@ module TCellAgent
70
71
  Grape::Endpoint.class_eval do
71
72
  alias_method :tcell_call!, :call!
72
73
  def call!(env)
73
- if TCellAgent.configuration.should_instrument? &&
74
- TCellAgent.configuration.should_intercept_requests?
75
-
74
+ if TCellAgent.configuration.should_intercept_requests?
76
75
  TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
77
76
  tcell_context = env[TCellAgent::Instrumentation::TCELL_ID]
78
77
  if tcell_context && tcell_context.grape_mount_endpoint && respond_to?(:routes)
@@ -6,12 +6,9 @@ require 'tcell_agent/sensor_events/server_agent'
6
6
  module TCellAgent
7
7
  module Instrumentation
8
8
  module Rails
9
- def self.send_framework_info
10
- TCellAgent.send_event(
11
- TCellAgent::SensorEvents::ServerAgentAppFrameworkEvent.new(
12
- 'Rails', ::Rails.version
13
- )
14
- )
9
+ def self.framework_details
10
+ { 'app_framework' => 'Rails',
11
+ 'app_framework_version' => ::Rails.version }
15
12
  end
16
13
 
17
14
  def self.send_settings
@@ -31,7 +31,6 @@ module TCellAgent
31
31
  TCellAgent::Instrumentation.safe_block('Running AppSensor deferred due to streaming') do
32
32
  if @meta_data
33
33
  @meta_data.response_content_bytes_len = @content_length
34
-
35
34
  appfirewall_policy = TCellAgent.policy(TCellAgent::PolicyTypes::APPSENSOR)
36
35
  appfirewall_policy.check_appfirewall_injections(@meta_data)
37
36
  end
@@ -54,18 +53,16 @@ module TCellAgent
54
53
  @body.respond_to?(method_name, include_all)
55
54
  end
56
55
 
57
- def method_missing(method_name, *args, &block) # rubocop:disable Style/MethodMissing
56
+ def method_missing(method_name, *args, &block)
58
57
  @body.__send__(method_name, *args, &block)
59
58
  end
60
59
 
61
60
  def process_body(body)
62
61
  TCellAgent::Instrumentation.safe_block('Processing tcell body proxy body') do
63
62
  chunked_response_match = nil
64
- if body.class.name == 'String'
65
- if body =~ /^([[:xdigit:]]+)(;.+)?\r\n/
66
- chunked_response_match = Regexp.last_match(1)
67
- @content_length += chunked_response_match.to_i(16)
68
- end
63
+ if body.class.name == 'String' && body =~ /^([[:xdigit:]]+)(;.+)?\r\n/
64
+ chunked_response_match = Regexp.last_match(1)
65
+ @content_length += chunked_response_match.to_i(16)
69
66
  end
70
67
 
71
68
  new_body = body
@@ -2,6 +2,7 @@ module TCellAgent
2
2
  module Routes
3
3
  class FieldEndpoint
4
4
  attr_accessor :discovered
5
+
5
6
  def initialize
6
7
  super()
7
8
  @discovered = false
@@ -11,6 +12,7 @@ module TCellAgent
11
12
  class RouteEndpoint
12
13
  attr_accessor :database
13
14
  attr_accessor :database_queries_discovered
15
+
14
16
  def initialize
15
17
  @database_queries_discovered = {}
16
18
  @database = Hash.new do |d_h, d_k| # Database
@@ -27,6 +29,7 @@ module TCellAgent
27
29
 
28
30
  class RouteTable
29
31
  attr_accessor :routes
32
+
30
33
  def initialize
31
34
  @routes = Hash.new { |h, k| h[k] = RouteEndpoint.new }
32
35
  end
@@ -1,48 +1,74 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tcell_agent/version'
4
+ require 'tcell_agent/rust/models'
2
5
 
3
6
  module TCellAgent
4
7
  module Rust
5
8
  class AgentConfig < Hash
6
9
  def initialize(configuration)
7
- send_mode = 'Normal'
8
- send_mode = 'Demo' if configuration.demomode
9
-
10
- logging_options = configuration.clean_logging_options
11
- unless configuration.js_agent_api_base_url
12
- parsed_uri = URI.parse(configuration.tcell_api_url)
13
- api_url = [parsed_uri.scheme, '://', parsed_uri.host]
14
- api_url.push(":#{parsed_uri.port}") unless [80, 443].include?(parsed_uri.port)
15
- configuration.js_agent_api_base_url = "#{api_url.join('')}/api/v1"
16
- end
17
-
18
- self['disable_event_sending'] = !configuration.should_start_event_manager?
19
- self['send_mode'] = send_mode
20
10
  self['agent_type'] = 'Ruby'
21
11
  self['agent_version'] = TCellAgent::VERSION
22
- self['diagnostics_enabled'] = false
23
- self['application'] = {
12
+ self['default_cache_dir'] = File.join(Dir.getwd, 'tcell/cache')
13
+ self['default_config_file_dir'] = File.join(Dir.getwd, 'config')
14
+ self['default_log_dir'] = File.join(Dir.getwd, 'tcell/logs')
15
+ self['default_preload_policy_file_dir'] = Dir.getwd
16
+
17
+ if defined?(ConfigInitializer)
18
+ overrides = Models.clean_nils(AgentConfigOverrides.new(configuration))
19
+ self['overrides'] = overrides
20
+ else
21
+ self['overrides'] = { 'applications' => [{ :enable_json_body_inspection => true }],
22
+ 'config_file_path' => configuration.get_config_file_path }
23
+ end
24
+
25
+ set_agent_details
26
+ end
27
+
28
+ def set_agent_details
29
+ framework_details = if defined?(Rails)
30
+ TCellAgent::Instrumentation::Rails.framework_details
31
+ else
32
+ {}
33
+ end
34
+
35
+ self['agent_details'] = { 'language' => 'Ruby',
36
+ 'language_version' => RUBY_VERSION,
37
+ 'app_framework' => framework_details['app_framework'],
38
+ 'app_framework_version' => framework_details['app_framework_version'] }
39
+ end
40
+ end
41
+
42
+ class AgentConfigOverrides < Hash
43
+ def initialize(configuration)
44
+ applications = {
45
+ :allow_payloads => configuration.allow_payloads,
46
+ :api_key => configuration.api_key,
24
47
  :app_id => configuration.app_id,
25
- :api_key => configuration.api_key,
26
- :tcell_api_url => configuration.tcell_api_url,
27
- :tcell_input_url => configuration.tcell_input_url,
48
+ :enable_json_body_inspection => true,
28
49
  :hmac_key => configuration.hmac_key,
50
+ :max_header_size => configuration.max_csp_header_bytes,
29
51
  :password_hmac_key => configuration.password_hmac_key,
30
- :allow_payloads => configuration.allow_payloads,
31
- :js_agent_api_base_url => configuration.js_agent_api_base_url,
32
- :js_agent_url => configuration.js_agent_url,
33
- :cache_dir => configuration.cache_folder,
34
- :log_dir => configuration.agent_log_dir,
35
- :logging_options => logging_options,
36
- :host_identifier => configuration.host_identifier,
37
- :reverse_proxy_ip_address_header => configuration.reverse_proxy_ip_address_header,
38
- :fetch_policies_from_tcell => configuration.should_start_policy_poll?,
39
- :preload_policy_filename => configuration.preload_policy_filename
52
+ :reverse_proxy => configuration.reverse_proxy,
53
+ :reverse_proxy_ip_address_header => configuration.reverse_proxy_ip_address_header
40
54
  }
41
- self['appfirewall'] = {
42
- :enable_body_json_inspection => true,
43
- :allow_log_payloads => true
44
- }
45
- self['max_header_size'] = configuration.max_csp_header_bytes || (1024 * 1024)
55
+
56
+ self['api_url'] = configuration.tcell_api_url
57
+ self['applications'] = [Models.clean_nils(applications)]
58
+ self['config_file_path'] = configuration.get_config_file_path
59
+ self['disabled_instrumentation'] = configuration.disabled_instrumentation
60
+ self['enabled'] = configuration.enabled
61
+ self['host_identifier'] = configuration.host_identifier
62
+ self['input_url'] = configuration.tcell_input_url
63
+ self['instrument'] = configuration.instrument
64
+ self['js_agent_api_url'] = configuration.js_agent_api_base_url
65
+ self['js_agent_url'] = configuration.js_agent_url
66
+ self['log_destination'] = configuration.logging_options[:destination]
67
+ self['log_dir'] = configuration.log_dir
68
+ self['log_enabled'] = configuration.logging_options[:enabled]
69
+ self['log_filename'] = configuration.logging_options[:log_filename]
70
+ self['log_level'] = configuration.logging_options[:level]
71
+ self['update_policy'] = configuration.fetch_policies_from_tcell
46
72
  end
47
73
  end
48
74
  end
@@ -13,6 +13,15 @@ module TCellAgent
13
13
 
14
14
  flattened_params
15
15
  end
16
+
17
+ def self.clean_nils(hash)
18
+ if hash.respond_to?(:compact!)
19
+ hash.compact!
20
+ else
21
+ hash.delete_if { |_, v| v.nil? }
22
+ end
23
+ hash
24
+ end
16
25
  end
17
26
  end
18
27
  end