tcell_agent 1.1.12 → 2.0.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 (163) hide show
  1. checksums.yaml +5 -5
  2. data/bin/tcell_agent +26 -14
  3. data/lib/tcell_agent.rb +16 -10
  4. data/lib/tcell_agent/agent.rb +78 -97
  5. data/lib/tcell_agent/agent/route_manager.rb +0 -16
  6. data/lib/tcell_agent/agent/static_agent.rb +9 -30
  7. data/lib/tcell_agent/authlogic.rb +3 -6
  8. data/lib/tcell_agent/config/unknown_options.rb +4 -8
  9. data/lib/tcell_agent/configuration.rb +38 -119
  10. data/lib/tcell_agent/devise.rb +25 -27
  11. data/lib/tcell_agent/hooks/login_fraud.rb +30 -33
  12. data/lib/tcell_agent/instrument_servers.rb +25 -0
  13. data/lib/tcell_agent/instrumentation.rb +12 -10
  14. data/lib/tcell_agent/instrumentation/cmdi.rb +19 -15
  15. data/lib/tcell_agent/instrumentation/lfi.rb +73 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
  17. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +123 -0
  18. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +159 -0
  19. data/lib/tcell_agent/logger.rb +50 -114
  20. data/lib/tcell_agent/patches.rb +6 -7
  21. data/lib/tcell_agent/policies/appfirewall_policy.rb +26 -0
  22. data/lib/tcell_agent/policies/command_injection_policy.rb +28 -0
  23. data/lib/tcell_agent/policies/dataloss_policy.rb +44 -44
  24. data/lib/tcell_agent/policies/headers_policy.rb +25 -0
  25. data/lib/tcell_agent/policies/http_redirect_policy.rb +13 -79
  26. data/lib/tcell_agent/policies/js_agent_policy.rb +27 -0
  27. data/lib/tcell_agent/policies/local_file_access.rb +28 -0
  28. data/lib/tcell_agent/policies/login_policy.rb +43 -0
  29. data/lib/tcell_agent/policies/patches_policy.rb +27 -0
  30. data/lib/tcell_agent/policies/policies_manager.rb +68 -0
  31. data/lib/tcell_agent/policies/policy_polling.rb +58 -0
  32. data/lib/tcell_agent/policies/policy_types.rb +14 -0
  33. data/lib/tcell_agent/policies/system_enablements.rb +27 -0
  34. data/lib/tcell_agent/rails/auth/authlogic.rb +43 -68
  35. data/lib/tcell_agent/rails/auth/devise.rb +20 -23
  36. data/lib/tcell_agent/rails/auth/doorkeeper.rb +63 -74
  37. data/lib/tcell_agent/rails/csrf_exception.rb +2 -2
  38. data/lib/tcell_agent/rails/dlp.rb +25 -15
  39. data/lib/tcell_agent/rails/dlp_handler.rb +1 -2
  40. data/lib/tcell_agent/rails/js_agent_insert.rb +12 -13
  41. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +4 -25
  42. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -12
  43. data/lib/tcell_agent/rails/middleware/global_middleware.rb +0 -1
  44. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +14 -34
  45. data/lib/tcell_agent/rails/on_start.rb +32 -31
  46. data/lib/tcell_agent/rails/routes.rb +7 -6
  47. data/lib/tcell_agent/rails/routes/grape.rb +1 -3
  48. data/lib/tcell_agent/rails/routes/route_id.rb +3 -1
  49. data/lib/tcell_agent/rails/settings_reporter.rb +23 -36
  50. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +12 -0
  51. data/lib/tcell_agent/rails/tcell_body_proxy.rb +6 -4
  52. data/lib/tcell_agent/rust/agent_config.rb +49 -0
  53. data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.2.so → libtcellagent-4.14.0.dylib} +0 -0
  54. data/lib/tcell_agent/rust/libtcellagent-4.14.0.so +0 -0
  55. data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-alpine-4.14.0.so} +0 -0
  56. data/lib/tcell_agent/rust/models.rb +0 -55
  57. data/lib/tcell_agent/rust/native_agent.rb +531 -0
  58. data/lib/tcell_agent/rust/native_agent_response.rb +42 -0
  59. data/lib/tcell_agent/rust/native_library.rb +68 -0
  60. data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
  61. data/lib/tcell_agent/sensor_events/agent_setting_event.rb +12 -0
  62. data/lib/tcell_agent/sensor_events/{app_config.rb → app_config_setting_event.rb} +0 -6
  63. data/lib/tcell_agent/sensor_events/dlp.rb +2 -6
  64. data/lib/tcell_agent/sensor_events/sensor.rb +0 -62
  65. data/lib/tcell_agent/sensor_events/server_agent.rb +13 -18
  66. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -108
  67. data/lib/tcell_agent/sensor_events/util/utils.rb +0 -2
  68. data/lib/tcell_agent/servers/passenger.rb +1 -28
  69. data/lib/tcell_agent/servers/puma.rb +3 -21
  70. data/lib/tcell_agent/servers/rails_server.rb +1 -1
  71. data/lib/tcell_agent/servers/thin.rb +2 -2
  72. data/lib/tcell_agent/servers/unicorn.rb +19 -80
  73. data/lib/tcell_agent/servers/webrick.rb +1 -1
  74. data/lib/tcell_agent/settings_reporter.rb +24 -24
  75. data/lib/tcell_agent/sinatra.rb +14 -16
  76. data/lib/tcell_agent/tcell_context.rb +40 -14
  77. data/lib/tcell_agent/utils/headers.rb +14 -0
  78. data/lib/tcell_agent/version.rb +1 -1
  79. data/spec/lib/tcell_agent/cmdi_spec.rb +0 -585
  80. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -18
  81. data/spec/lib/tcell_agent/configuration_spec.rb +4 -140
  82. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +46 -173
  83. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +504 -0
  84. data/spec/lib/tcell_agent/instrumentation/cmdi/kernel_cmdi_spec.rb +435 -0
  85. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +326 -0
  86. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +556 -0
  87. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +249 -0
  88. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +105 -0
  89. data/spec/lib/tcell_agent/patches_spec.rb +25 -43
  90. data/spec/lib/tcell_agent/policies/appfirewall_policy_spec.rb +183 -0
  91. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +57 -0
  92. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +84 -773
  93. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +161 -0
  94. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +9 -9
  95. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +243 -198
  96. data/spec/lib/tcell_agent/policies/js_agent_policy_spec.rb +75 -0
  97. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +165 -33
  98. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +84 -277
  99. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +104 -0
  100. data/spec/lib/tcell_agent/policies/policy_polling_spec.rb +6 -0
  101. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +56 -0
  102. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +9 -18
  103. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +13 -30
  104. data/spec/lib/tcell_agent/rails/logger_spec.rb +27 -7
  105. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +17 -12
  106. data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +14 -14
  107. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +0 -35
  108. data/spec/lib/tcell_agent/settings_reporter_spec.rb +127 -153
  109. data/spec/spec_helper.rb +1 -1
  110. data/spec/support/builders.rb +104 -0
  111. data/spec/support/force_logger_mocking.rb +38 -0
  112. data/spec/support/resources/lfi_sample_file.txt +2 -0
  113. data/spec/support/static_agent_overrides.rb +0 -15
  114. metadata +63 -74
  115. data/lib/tcell_agent/agent/event_processor.rb +0 -326
  116. data/lib/tcell_agent/agent/fork_pipe_manager.rb +0 -113
  117. data/lib/tcell_agent/agent/policy_manager.rb +0 -219
  118. data/lib/tcell_agent/agent/policy_types.rb +0 -30
  119. data/lib/tcell_agent/api.rb +0 -91
  120. data/lib/tcell_agent/appsensor/injections_reporter.rb +0 -24
  121. data/lib/tcell_agent/config/child_process_events.rb +0 -8
  122. data/lib/tcell_agent/instrumentation/cmdi/backtick.rb +0 -10
  123. data/lib/tcell_agent/instrumentation/cmdi/exec.rb +0 -14
  124. data/lib/tcell_agent/instrumentation/cmdi/popen.rb +0 -28
  125. data/lib/tcell_agent/instrumentation/cmdi/spawn.rb +0 -11
  126. data/lib/tcell_agent/instrumentation/cmdi/system.rb +0 -11
  127. data/lib/tcell_agent/policies/http_tx_policy.rb +0 -60
  128. data/lib/tcell_agent/policies/login_fraud_policy.rb +0 -45
  129. data/lib/tcell_agent/policies/rust_policies.rb +0 -110
  130. data/lib/tcell_agent/rails.rb +0 -40
  131. data/lib/tcell_agent/rust/libtcellagent-1.3.2.dylib +0 -0
  132. data/lib/tcell_agent/rust/tcellagent-1.3.2.dll +0 -0
  133. data/lib/tcell_agent/rust/whisperer.rb +0 -308
  134. data/lib/tcell_agent/sensor_events/appsensor_event.rb +0 -52
  135. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +0 -45
  136. data/lib/tcell_agent/sensor_events/command_injection.rb +0 -75
  137. data/lib/tcell_agent/sensor_events/honeytokens.rb +0 -16
  138. data/lib/tcell_agent/sensor_events/login_fraud.rb +0 -60
  139. data/lib/tcell_agent/sensor_events/metrics.rb +0 -123
  140. data/lib/tcell_agent/sensor_events/patches.rb +0 -21
  141. data/lib/tcell_agent/start_background_thread.rb +0 -55
  142. data/lib/tcell_agent/system_info.rb +0 -11
  143. data/lib/tcell_agent/utils/io.rb +0 -38
  144. data/lib/tcell_agent/utils/passwords.rb +0 -28
  145. data/lib/tcell_agent/utils/queue_with_timeout.rb +0 -142
  146. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +0 -100
  147. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +0 -535
  148. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +0 -133
  149. data/spec/lib/tcell_agent/api/api_spec.rb +0 -39
  150. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +0 -187
  151. data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
  152. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
  153. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
  154. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
  155. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
  156. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
  157. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
  158. data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
  159. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
  160. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
  161. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
  162. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
  163. data/spec/lib/tcell_agent/utils/passwords_spec.rb +0 -143
@@ -1,8 +1,6 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
 
3
- require 'logger'
4
3
  require 'cgi'
5
- require 'uri'
6
4
  require 'openssl'
7
5
 
8
6
  module TCellAgent
@@ -1,37 +1,10 @@
1
1
  PhusionPassenger::LoaderSharedHelpers.class_eval do
2
- alias_method :tcell_after_loading_app_code, :after_loading_app_code
3
- def after_loading_app_code(options)
4
- tcell_after_loading_app_code(options)
5
-
6
- TCellAgent::Instrumentation.safe_block('Initial Passenger Instrumentation') do
7
- # This runs in Passenger's AppPreloader (a process which is killed at some point)
8
- # but it's still a good place to do the initial instrumentation so it's only sent once.
9
- # Since this process doesn't receive any requests there is no need to run policy polling
10
- # but we still need the event processor to send the startup events
11
- original_policy_polling = TCellAgent.configuration.enable_policy_polling
12
- TCellAgent.configuration.enable_policy_polling = false
13
- TCellAgent.run_instrumentation('Passenger')
14
- TCellAgent.configuration.enable_policy_polling = original_policy_polling
15
- end
16
- end
17
-
18
2
  alias_method :tcell_before_handling_requests, :before_handling_requests
19
3
  def before_handling_requests(forked, options)
20
4
  result_if_needed = tcell_before_handling_requests(forked, options)
21
5
 
22
- TCellAgent.run_instrumentation('Passenger', false)
6
+ TCellAgent.thread_agent.start('Passenger')
23
7
 
24
8
  result_if_needed
25
9
  end
26
10
  end
27
-
28
- # Passenger's parent process is known as the AppPreloader, the problem is this
29
- # process seems to disappear at some point taking the event processor with it.
30
- # This will give every child process its own event manager to avoid the dependency
31
- # on this disappearing process
32
- class << TCellAgent::Agent
33
- alias_method :tcell_parent_process?, :parent_process?
34
- def parent_process?
35
- true
36
- end
37
- end
@@ -6,35 +6,17 @@ if defined?(Puma.cli_config)
6
6
  Puma::Runner.class_eval do
7
7
  alias_method :original_start_server, :start_server
8
8
  def start_server
9
- TCellAgent.run_instrumentation('Puma Single Mode')
9
+ TCellAgent.thread_agent.start('Puma Single Mode')
10
10
 
11
11
  original_start_server
12
12
  end
13
13
  end
14
14
 
15
15
  else
16
-
17
- # Runs initial instrumentation only once on the master process
18
- puma_server_starting = proc { TCellAgent.run_instrumentation('Puma Cluster Mode') }
19
-
20
- # before_fork was added in Puma v2.13.0
21
- if Puma.cli_config.options[:before_fork]
22
- Puma.cli_config.options[:before_fork].push(puma_server_starting)
23
- else
24
- Puma.cli_config.options[:before_fork] = [puma_server_starting]
25
- end
26
-
27
- # Each puma worker still needs the agent started but no need to run
28
- # initial instrumentation again
29
16
  Puma::Server.class_eval do
30
17
  alias_method :original_run, :run
31
18
  def run(background = true)
32
- begin
33
- TCellAgent.logger.debug('Instrumenting: Puma Cluster Mode (Worker)')
34
- TCellAgent.thread_agent.start
35
- rescue StandardError => e
36
- TCellAgent.logger.error("Could not start thread agent. #{e.message}")
37
- end
19
+ TCellAgent.thread_agent.start('Puma Cluster Mode (Worker)')
38
20
 
39
21
  original_run(background)
40
22
  end
@@ -48,7 +30,7 @@ if defined?(Puma.cli_config)
48
30
  Puma::Server.class_eval do
49
31
  alias_method :original_run, :run
50
32
  def run(background = true)
51
- TCellAgent.run_instrumentation('Puma Cluster Mode (Worker)')
33
+ TCellAgent.thread_agent.start('Puma Cluster Mode (Worker)')
52
34
 
53
35
  original_run(background)
54
36
  end
@@ -13,7 +13,7 @@ Rails::Server.class_eval do
13
13
  Puma::Server.class_eval do
14
14
  alias_method :original_run, :run
15
15
  def run(background = true)
16
- TCellAgent.run_instrumentation('Puma Single Mode')
16
+ TCellAgent.thread_agent.start('Puma Single Mode')
17
17
 
18
18
  original_run(background)
19
19
  end
@@ -1,9 +1,9 @@
1
1
  require('tcell_agent/servers/unicorn') if defined?(Unicorn::HttpServer)
2
-
3
2
  Thin::Server.class_eval do
4
3
  alias_method :original_start, :start
5
4
  def start
6
- TCellAgent.run_instrumentation('Thin Server')
5
+ TCellAgent.thread_agent.start('Thin Server')
6
+
7
7
  original_start
8
8
  end
9
9
  end
@@ -3,17 +3,22 @@ Unicorn::HttpServer.class_eval do
3
3
  # - This check also ensures that a server is running as opposed to a different command such
4
4
  # as `bundle exec rails runner User.count`.
5
5
  unless Unicorn::HttpServer::START_CTX && Unicorn::HttpServer::START_CTX[0]
6
- TCellAgent.run_instrumentation('Unicorn')
6
+ require 'tcell_agent/rails/start_agent_after_initializers'
7
7
  end
8
8
 
9
+ # This only gets instrumented when preload_app is true
9
10
  # this only runs when preload_app=true because when preload_app=false
10
11
  # the gems aren't loaded early enough for tcell to override
11
12
  # the class definitions
12
- alias_method :tcell_bind_new_listeners!, :bind_new_listeners!
13
- def bind_new_listeners!
14
- TCellAgent.run_instrumentation('Unicorn')
13
+ alias_method :tcell_init_worker_process, :init_worker_process
14
+ def init_worker_process(work)
15
+ start_process = tcell_init_worker_process(work)
16
+
17
+ TCellAgent.logger.debug('Instrumenting Unicorn server', 'TCellAgent::Unicorn')
15
18
 
16
- tcell_bind_new_listeners!
19
+ TCellAgent.thread_agent.start('Unicorn Worker')
20
+
21
+ start_process
17
22
  end
18
23
 
19
24
  # This gets called when unicorn receives the HUP signal to reload its config.
@@ -21,86 +26,20 @@ Unicorn::HttpServer.class_eval do
21
26
  # or stopped accordingly
22
27
  alias_method :tcell_load_config!, :load_config!
23
28
  def load_config!
24
- tcell_load_config!
25
-
26
- TCellAgent::Instrumentation.safe_block('Reloading Tcell Config') do
27
- new_config = TCellAgent::Configuration.new
28
- TCellAgent.logger.debug('Reloading config')
29
- TCellAgent.logger.debug(
30
- "ENABLED:#{new_config.enabled}" \
31
- "|ENABLE_EVENT_MANAGER:#{new_config.enable_event_manager}" \
32
- "|ENABLE_EVENT_CONSUMER:#{new_config.enable_event_consumer}" \
33
- "|ENABLE_POLICY_POLLING:#{new_config.enable_policy_polling}" \
34
- "|ENABLE_INSTRUMENTATION:#{new_config.enable_instrumentation}" \
35
- "|ENABLE_INTERCEPT_REQUESTS:#{new_config.enable_intercept_requests}"
36
- )
37
- old_config = TCellAgent.configuration
38
-
39
- TCellAgent.configuration = new_config
40
-
41
- if new_config.enabled ^ old_config.enabled
42
- if new_config.enabled
43
- TCellAgent.run_instrumentation('Unicorn')
44
-
45
- else
46
- TCellAgent.thread_agent.stop_event_processor
47
- TCellAgent.thread_agent.stop_metrics_event_thread
48
- TCellAgent.thread_agent.stop_policy_polling
49
- end
50
- end
51
-
52
- if new_config.enable_event_manager ^ old_config.enable_event_manager
53
- if new_config.enable_event_manager
54
- TCellAgent.run_instrumentation('Unicorn Restart')
55
- else
56
- TCellAgent.thread_agent.stop_event_processor
57
- end
58
- elsif new_config.enable_event_manager
59
- # Just in case
60
- TCellAgent.thread_agent.ensure_event_processor_running
61
- end
29
+ result_if_exists = tcell_load_config!
62
30
 
63
- if new_config.enable_event_consumer ^ old_config.enable_event_consumer
64
- if new_config.enable_event_consumer
65
- TCellAgent.thread_agent.ensure_metrics_event_thread_running
66
- else
67
- TCellAgent.thread_agent.stop_metrics_event_thread
68
- end
69
- elsif new_config.enable_event_consumer
70
- # Just in case
71
- TCellAgent.thread_agent.ensure_metrics_event_thread_running
72
- end
31
+ hot_reload_tcell_agent
73
32
 
74
- if new_config.enable_policy_polling ^ old_config.enable_policy_polling
75
- if new_config.enable_policy_polling
76
- TCellAgent.thread_agent.ensure_policy_polling_running
77
- else
78
- TCellAgent.thread_agent.stop_policy_polling
79
- end
80
- elsif new_config.enable_policy_polling
81
- # Just in case
82
- TCellAgent.thread_agent.ensure_policy_polling_running
83
- end
84
- end
33
+ result_if_exists
85
34
  end
86
35
 
87
- # this only runs when preload_app=true because when preload_app=false
88
- # the gems aren't loaded early enough for tcell to override
89
- # the class definitions
90
- alias_method :tcell_init_worker_process, :init_worker_process
91
- def init_worker_process(work)
92
- start_process = tcell_init_worker_process(work)
36
+ def hot_reload_tcell_agent
37
+ TCellAgent::Instrumentation.safe_block('Reloading Tcell Config') do
38
+ TCellAgent.logger.debug('[TCellAgent] Reloading configuration', 'TCellAgent::Unicorn')
93
39
 
94
- if TCellAgent.configuration.enabled && TCellAgent.configuration.should_instrument?
95
- begin
96
- TCellAgent.thread_agent.policy_polling_worker_mutex = Mutex.new
97
- TCellAgent.thread_agent.policy_polling_thread = nil
98
- TCellAgent.thread_agent.start
99
- rescue StandardError => e
100
- TCellAgent.logger.error("Could not start thread agent. #{e.message}")
101
- end
102
- end
40
+ new_config = TCellAgent::Configuration.new
103
41
 
104
- start_process
42
+ TCellAgent.configuration = new_config
43
+ end
105
44
  end
106
45
  end
@@ -2,7 +2,7 @@ Rack::Handler::WEBrick.class_eval do
2
2
  class << self
3
3
  alias_method :original_run, :run
4
4
  def run(app, options = {})
5
- TCellAgent.run_instrumentation('WEBrick')
5
+ TCellAgent.thread_agent.start('WEBrick')
6
6
 
7
7
  original_run(app, options)
8
8
  end
@@ -1,13 +1,11 @@
1
1
  require 'tcell_agent/agent'
2
2
  require 'tcell_agent/configuration'
3
- require 'tcell_agent/sensor_events/app_config'
3
+ require 'tcell_agent/sensor_events/agent_setting_event'
4
4
  require 'tcell_agent/sensor_events/server_agent'
5
5
  require 'thread'
6
6
 
7
7
  module TCellAgent
8
- def self.report_settings(send_startup_events)
9
- return unless send_startup_events && TCellAgent.configuration.should_instrument?
10
-
8
+ def self.report_settings
11
9
  Thread.new do
12
10
  TCellAgent::Instrumentation.safe_block('Instrumenting Agent Details') do
13
11
  event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
@@ -19,27 +17,36 @@ module TCellAgent
19
17
  TCellAgent.send_event(event)
20
18
  end
21
19
 
20
+ TCellAgent::Instrumentation.safe_block('Instrumenting Language Info') do
21
+ TCellAgent.send_event(
22
+ TCellAgent::SensorEvents::ServerAgentDetailsLanguageEvent.new(
23
+ 'Ruby',
24
+ RUBY_VERSION
25
+ )
26
+ )
27
+ end
28
+
22
29
  TCellAgent::Instrumentation.safe_block('Instrumenting Native Lib Status') do
23
- require 'tcell_agent/rust/whisperer'
30
+ require 'tcell_agent/rust/native_agent'
24
31
 
25
32
  TCellAgent.send_event(
26
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
33
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
27
34
  'native_lib_loaded',
28
- TCellAgent::Rust::Wrapper.common_lib_available?.to_s
35
+ TCellAgent::Rust::NativeLibrary.common_lib_available?.to_s
29
36
  )
30
37
  )
31
38
  end
32
39
 
33
40
  TCellAgent::Instrumentation.safe_block('Instrumenting Initial Config') do
34
41
  TCellAgent.send_event(
35
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
42
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
36
43
  'allow_payloads',
37
44
  (!!TCellAgent.configuration.allow_payloads).to_s # rubocop:disable Style/DoubleNegation
38
45
  )
39
46
  )
40
47
 
41
48
  TCellAgent.send_event(
42
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
49
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
43
50
  'reverse_proxy',
44
51
  (!!TCellAgent.configuration.reverse_proxy).to_s # rubocop:disable Style/DoubleNegation
45
52
  )
@@ -52,54 +59,47 @@ module TCellAgent
52
59
  TCellAgent.configuration.log_filename
53
60
 
54
61
  TCellAgent.send_event(
55
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
62
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
56
63
  'config_filename',
57
64
  TCellAgent.configuration.config_filename
58
65
  )
59
66
  )
60
67
  TCellAgent.send_event(
61
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
68
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
62
69
  'logging_directory',
63
70
  TCellAgent.configuration.agent_log_dir
64
71
  )
65
72
  )
66
73
 
67
74
  TCellAgent.send_event(
68
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
75
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
69
76
  'agent_home_directory',
70
77
  TCellAgent.configuration.agent_home_dir
71
78
  )
72
79
  )
73
80
 
74
- TCellAgent.send_event(
75
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
76
- 'agent_home_owner',
77
- TCellAgent.configuration.agent_home_owner
78
- )
79
- )
80
-
81
81
  logging_options = TCellAgent.configuration.logging_options || {}
82
82
  use_default_setting = !logging_options.key?(:enabled) && !logging_options.key?('enabled')
83
83
  if use_default_setting || logging_options[:enabled] || logging_options['enabled']
84
84
  TCellAgent.send_event(
85
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new('logging_enabled', 'true')
85
+ TCellAgent::SensorEvents::AgentSettingEvent.new('logging_enabled', 'true')
86
86
  )
87
87
 
88
88
  TCellAgent.send_event(
89
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
89
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
90
90
  'logging_level',
91
91
  logging_options[:level] || logging_options['level'] || 'INFO'
92
92
  )
93
93
  )
94
94
  else
95
95
  TCellAgent.send_event(
96
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new('logging_enabled', 'false')
96
+ TCellAgent::SensorEvents::AgentSettingEvent.new('logging_enabled', 'false')
97
97
  )
98
98
  end
99
99
 
100
100
  if TCellAgent.configuration.hmac_key
101
101
  TCellAgent.send_event(
102
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
102
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
103
103
  'hmac_key_present',
104
104
  (!!TCellAgent.configuration.hmac_key).to_s # rubocop:disable Style/DoubleNegation
105
105
  )
@@ -108,7 +108,7 @@ module TCellAgent
108
108
 
109
109
  if TCellAgent.configuration.reverse_proxy
110
110
  TCellAgent.send_event(
111
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
111
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
112
112
  'reverse_proxy_ip_address_header',
113
113
  TCellAgent.configuration.reverse_proxy_ip_address_header
114
114
  )
@@ -14,23 +14,21 @@ module TCellAgent
14
14
  status, headers, response = original_finish
15
15
 
16
16
  TCellAgent::Instrumentation.safe_block('Setting Headers') do
17
- rust_policies = TCellAgent.policy(TCellAgent::PolicyTypes::RUST)
18
- if rust_policies
19
- policy_headers = rust_policies.get_headers(
20
- request.env[TCellAgent::Instrumentation::TCELL_ID]
21
- )
22
- policy_headers.each do |header_info|
23
- header_name = header_info['name']
24
- header_value = header_info['value']
25
- existing_header_value = headers[header_name]
26
- headers[header_name] = if existing_header_value
27
- "#{existing_header_value}, #{header_value}"
28
- else
29
- header_value
30
- end
31
- end
32
- response = [status, headers, active_response]
17
+ headers_policy = TCellAgent.policy(TCellAgent::PolicyTypes::HEADERS)
18
+ policy_headers = headers_policy.get_headers(
19
+ request.env[TCellAgent::Instrumentation::TCELL_ID]
20
+ )
21
+ policy_headers.each do |header_info|
22
+ header_name = header_info['name']
23
+ header_value = header_info['value']
24
+ existing_header_value = headers[header_name]
25
+ headers[header_name] = if existing_header_value
26
+ "#{existing_header_value}, #{header_value}"
27
+ else
28
+ header_value
29
+ end
33
30
  end
31
+ response = [status, headers, active_response]
34
32
  end
35
33
 
36
34
  [status, headers, response]
@@ -12,26 +12,44 @@ TCELL_MAX_BODY_LENGTH = 50_000
12
12
  module TCellAgent
13
13
  class MetaData
14
14
  class << self
15
- def from_request(request)
15
+ def for_appfirewall(request, response_content_length, response_code, response_headers)
16
+ meta_data = TCellAgent::MetaData.for_patches(request)
17
+
18
+ tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
19
+ meta_data.csrf_exception_name = tcell_context.csrf_exception_name
20
+ meta_data.user_agent = tcell_context.user_agent
21
+ meta_data.path_parameters = tcell_context.path_parameters
22
+ meta_data.sql_exceptions = tcell_context.sql_exceptions
23
+ meta_data.database_result_sizes = tcell_context.database_result_sizes
24
+
25
+ meta_data.response_content_bytes_len = response_content_length
26
+
27
+ meta_data.response_code = response_code
28
+ meta_data.response_headers = response_headers
29
+
30
+ meta_data
31
+ end
32
+
33
+ def for_patches(request)
16
34
  tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
17
35
  # use uri stored in tcell_context because
18
36
  # rails modifies original request.url
19
37
  # to always return /404 (or whatever error code
20
38
  # it encountered)
21
- meta_event = MetaData.new(
39
+ meta_data = MetaData.new(
22
40
  tcell_context.request_method,
23
- tcell_context.ip_address,
41
+ tcell_context.remote_address,
24
42
  tcell_context.route_id,
25
43
  tcell_context.hmac_session_id,
26
44
  tcell_context.user_id,
27
45
  tcell_context.transaction_id,
28
46
  tcell_context.uri
29
47
  )
30
- meta_event.path = tcell_context.path
48
+ meta_data.path = tcell_context.path
31
49
 
32
- meta_event.set_parameter_dicts(request)
50
+ meta_data.set_parameter_dicts(request)
33
51
 
34
- meta_event
52
+ meta_data
35
53
  end
36
54
  end
37
55
 
@@ -119,6 +137,12 @@ module TCellAgent
119
137
  @flattened_path_parameters = TCellAgent::Utils::Params.flatten(value)
120
138
  end
121
139
 
140
+ def charset
141
+ Rack::MediaType.params(@content_type)['charset'] || Encoding.default_external
142
+ rescue StandardError
143
+ Encoding.default_external
144
+ end
145
+
122
146
  def get_raw_post_data(request)
123
147
  content_length = request.content_length.to_i if request.content_length
124
148
  if !content_length.nil? && content_length > TCELL_MAX_BODY_LENGTH || request.content_type.nil?
@@ -128,30 +152,32 @@ module TCellAgent
128
152
  # Positions strio to the beginning of input, resetting lineno to zero.
129
153
  # rails 4.1 seems to read the stringIO directly and so body.gets is empty
130
154
  # this is called
155
+
131
156
  body = request.body
132
157
  body.rewind if body.respond_to?(:rewind)
133
158
  raw_post_data = body.read(request.content_length.to_i) if request.content_length
134
159
  body.rewind if body.respond_to?(:rewind)
135
- raw_post_data
160
+
161
+ raw_post_data.force_encoding(charset) unless raw_post_data.nil?
136
162
  end
137
163
 
138
164
  def set_parameter_dicts(request)
165
+ @flattened_body_dict = {} # deprecated
166
+ @content_type = request.content_type || ''
167
+ @raw_request_body = get_raw_post_data(request) unless @content_type.start_with?('application/octet-stream',
168
+ 'multipart/form-data')
169
+ @request_content_bytes_len = (request.content_length || 0).to_i
170
+
139
171
  self.get_dict = request.GET
140
172
  self.cookie_dict = request.cookies
141
173
 
142
- self.post_dict = if !(request.content_type =~ %r{application/json}i).nil? ||
143
- !(request.content_type =~ %r{application/xml}i).nil?
174
+ self.post_dict = if @content_type.start_with?('application/json', 'application/xml')
144
175
  {}
145
176
  else
146
177
  request.POST
147
178
  end
148
179
 
149
180
  self.headers_dict = request.env
150
-
151
- @flattened_body_dict = {} # deprecated
152
- @content_type = request.content_type
153
- @raw_request_body = get_raw_post_data(request)
154
- @request_content_bytes_len = (request.content_length || 0).to_i
155
181
  end
156
182
  end
157
183
  end