tcell_agent 1.1.12 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +5 -5
  2. data/bin/tcell_agent +45 -137
  3. data/lib/tcell_agent.rb +12 -14
  4. data/lib/tcell_agent/agent.rb +108 -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/config_initializer.rb +66 -0
  8. data/lib/tcell_agent/configuration.rb +69 -345
  9. data/lib/tcell_agent/hooks/login_fraud.rb +30 -33
  10. data/lib/tcell_agent/instrument_servers.rb +23 -0
  11. data/lib/tcell_agent/instrumentation.rb +12 -10
  12. data/lib/tcell_agent/instrumentation/cmdi.rb +29 -25
  13. data/lib/tcell_agent/instrumentation/lfi.rb +84 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +131 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +102 -0
  17. data/lib/tcell_agent/logger.rb +49 -114
  18. data/lib/tcell_agent/patches.rb +6 -7
  19. data/lib/tcell_agent/policies/appfirewall_policy.rb +26 -0
  20. data/lib/tcell_agent/policies/command_injection_policy.rb +28 -0
  21. data/lib/tcell_agent/policies/dataloss_policy.rb +44 -44
  22. data/lib/tcell_agent/policies/headers_policy.rb +25 -0
  23. data/lib/tcell_agent/policies/http_redirect_policy.rb +13 -79
  24. data/lib/tcell_agent/policies/js_agent_policy.rb +27 -0
  25. data/lib/tcell_agent/policies/local_file_access.rb +28 -0
  26. data/lib/tcell_agent/policies/login_policy.rb +43 -0
  27. data/lib/tcell_agent/policies/patches_policy.rb +27 -0
  28. data/lib/tcell_agent/policies/policies_manager.rb +68 -0
  29. data/lib/tcell_agent/policies/policy_polling.rb +58 -0
  30. data/lib/tcell_agent/policies/policy_types.rb +14 -0
  31. data/lib/tcell_agent/policies/system_enablements.rb +27 -0
  32. data/lib/tcell_agent/rails/auth/authlogic.rb +46 -75
  33. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  34. data/lib/tcell_agent/rails/auth/devise.rb +100 -105
  35. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  36. data/lib/tcell_agent/rails/auth/doorkeeper.rb +62 -76
  37. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  38. data/lib/tcell_agent/rails/csrf_exception.rb +2 -10
  39. data/lib/tcell_agent/rails/dlp.rb +35 -23
  40. data/lib/tcell_agent/rails/dlp_handler.rb +1 -2
  41. data/lib/tcell_agent/rails/js_agent_insert.rb +12 -13
  42. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +4 -25
  43. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -12
  44. data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -2
  45. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +14 -34
  46. data/lib/tcell_agent/{rails.rb → rails/railties/tcell_agent_railties.rb} +11 -16
  47. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  48. data/lib/tcell_agent/rails/routes.rb +10 -12
  49. data/lib/tcell_agent/rails/routes/grape.rb +4 -14
  50. data/lib/tcell_agent/rails/routes/route_id.rb +3 -1
  51. data/lib/tcell_agent/rails/settings_reporter.rb +23 -36
  52. data/lib/tcell_agent/rails/tcell_body_proxy.rb +5 -4
  53. data/lib/tcell_agent/rust/agent_config.rb +60 -0
  54. data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.2.so → libtcellagent-5.0.2.dylib} +0 -0
  55. data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-5.0.2.so} +0 -0
  56. data/lib/tcell_agent/rust/libtcellagent-alpine-5.0.2.so +0 -0
  57. data/lib/tcell_agent/rust/models.rb +6 -52
  58. data/lib/tcell_agent/rust/native_agent.rb +549 -0
  59. data/lib/tcell_agent/rust/native_agent_response.rb +42 -0
  60. data/lib/tcell_agent/rust/native_library.rb +69 -0
  61. data/lib/tcell_agent/rust/tcellagent-5.0.2.dll +0 -0
  62. data/lib/tcell_agent/sensor_events/agent_setting_event.rb +12 -0
  63. data/lib/tcell_agent/sensor_events/{app_config.rb → app_config_setting_event.rb} +0 -6
  64. data/lib/tcell_agent/sensor_events/dlp.rb +2 -6
  65. data/lib/tcell_agent/sensor_events/sensor.rb +0 -62
  66. data/lib/tcell_agent/sensor_events/server_agent.rb +13 -18
  67. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -108
  68. data/lib/tcell_agent/sensor_events/util/utils.rb +0 -2
  69. data/lib/tcell_agent/servers/passenger.rb +1 -28
  70. data/lib/tcell_agent/servers/puma.rb +3 -21
  71. data/lib/tcell_agent/servers/rails_server.rb +1 -2
  72. data/lib/tcell_agent/servers/thin.rb +2 -2
  73. data/lib/tcell_agent/servers/unicorn.rb +19 -80
  74. data/lib/tcell_agent/servers/webrick.rb +1 -2
  75. data/lib/tcell_agent/settings_reporter.rb +11 -90
  76. data/lib/tcell_agent/sinatra.rb +14 -16
  77. data/lib/tcell_agent/tcell_context.rb +40 -14
  78. data/lib/tcell_agent/utils/headers.rb +14 -0
  79. data/lib/tcell_agent/version.rb +1 -1
  80. data/spec/lib/tcell_agent/configuration_spec.rb +55 -346
  81. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +46 -173
  82. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +504 -0
  83. data/spec/lib/tcell_agent/instrumentation/cmdi/kernel_cmdi_spec.rb +435 -0
  84. data/spec/lib/tcell_agent/instrumentation/cmdi_spec.rb +201 -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 +562 -0
  87. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +264 -0
  88. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +150 -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/rust/agent_config_spec.rb +27 -0
  108. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +0 -35
  109. data/spec/lib/tcell_agent/settings_reporter_spec.rb +56 -155
  110. data/spec/spec_helper.rb +1 -1
  111. data/spec/support/builders.rb +103 -0
  112. data/spec/support/force_logger_mocking.rb +38 -0
  113. data/spec/support/resources/lfi_sample_file.txt +2 -0
  114. data/spec/support/static_agent_overrides.rb +0 -15
  115. metadata +72 -83
  116. data/lib/tcell_agent/agent/event_processor.rb +0 -326
  117. data/lib/tcell_agent/agent/fork_pipe_manager.rb +0 -113
  118. data/lib/tcell_agent/agent/policy_manager.rb +0 -219
  119. data/lib/tcell_agent/agent/policy_types.rb +0 -30
  120. data/lib/tcell_agent/api.rb +0 -91
  121. data/lib/tcell_agent/appsensor/injections_reporter.rb +0 -24
  122. data/lib/tcell_agent/authlogic.rb +0 -26
  123. data/lib/tcell_agent/config/child_process_events.rb +0 -8
  124. data/lib/tcell_agent/config/unknown_options.rb +0 -123
  125. data/lib/tcell_agent/devise.rb +0 -35
  126. data/lib/tcell_agent/instrumentation/cmdi/backtick.rb +0 -10
  127. data/lib/tcell_agent/instrumentation/cmdi/exec.rb +0 -14
  128. data/lib/tcell_agent/instrumentation/cmdi/popen.rb +0 -28
  129. data/lib/tcell_agent/instrumentation/cmdi/spawn.rb +0 -11
  130. data/lib/tcell_agent/instrumentation/cmdi/system.rb +0 -11
  131. data/lib/tcell_agent/policies/http_tx_policy.rb +0 -60
  132. data/lib/tcell_agent/policies/login_fraud_policy.rb +0 -45
  133. data/lib/tcell_agent/policies/rust_policies.rb +0 -110
  134. data/lib/tcell_agent/rails/on_start.rb +0 -41
  135. data/lib/tcell_agent/rust/libtcellagent-1.3.2.dylib +0 -0
  136. data/lib/tcell_agent/rust/tcellagent-1.3.2.dll +0 -0
  137. data/lib/tcell_agent/rust/whisperer.rb +0 -308
  138. data/lib/tcell_agent/sensor_events/appsensor_event.rb +0 -52
  139. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +0 -45
  140. data/lib/tcell_agent/sensor_events/command_injection.rb +0 -75
  141. data/lib/tcell_agent/sensor_events/honeytokens.rb +0 -16
  142. data/lib/tcell_agent/sensor_events/login_fraud.rb +0 -60
  143. data/lib/tcell_agent/sensor_events/metrics.rb +0 -123
  144. data/lib/tcell_agent/sensor_events/patches.rb +0 -21
  145. data/lib/tcell_agent/start_background_thread.rb +0 -55
  146. data/lib/tcell_agent/system_info.rb +0 -11
  147. data/lib/tcell_agent/utils/io.rb +0 -38
  148. data/lib/tcell_agent/utils/passwords.rb +0 -28
  149. data/lib/tcell_agent/utils/queue_with_timeout.rb +0 -142
  150. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +0 -100
  151. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +0 -535
  152. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +0 -133
  153. data/spec/lib/tcell_agent/api/api_spec.rb +0 -39
  154. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +0 -187
  155. data/spec/lib/tcell_agent/cmdi_spec.rb +0 -736
  156. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -213
  157. data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
  158. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
  159. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
  160. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
  161. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
  162. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
  163. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
  164. data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
  165. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
  166. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
  167. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
  168. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
  169. 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,8 +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')
17
-
16
+ TCellAgent.thread_agent.start('Puma Single Mode')
18
17
  original_run(background)
19
18
  end
20
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/railties/tcell_agent_unicorn_railties'
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,8 +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')
6
-
5
+ TCellAgent.thread_agent.start('WEBrick')
7
6
  original_run(app, options)
8
7
  end
9
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,101 +17,24 @@ module TCellAgent
19
17
  TCellAgent.send_event(event)
20
18
  end
21
19
 
22
- TCellAgent::Instrumentation.safe_block('Instrumenting Native Lib Status') do
23
- require 'tcell_agent/rust/whisperer'
24
-
20
+ TCellAgent::Instrumentation.safe_block('Instrumenting Language Info') do
25
21
  TCellAgent.send_event(
26
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
27
- 'native_lib_loaded',
28
- TCellAgent::Rust::Wrapper.common_lib_available?.to_s
22
+ TCellAgent::SensorEvents::ServerAgentDetailsLanguageEvent.new(
23
+ 'Ruby',
24
+ RUBY_VERSION
29
25
  )
30
26
  )
31
27
  end
32
28
 
33
- TCellAgent::Instrumentation.safe_block('Instrumenting Initial Config') do
34
- TCellAgent.send_event(
35
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
36
- 'allow_payloads',
37
- (!!TCellAgent.configuration.allow_payloads).to_s # rubocop:disable Style/DoubleNegation
38
- )
39
- )
40
-
41
- TCellAgent.send_event(
42
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
43
- 'reverse_proxy',
44
- (!!TCellAgent.configuration.reverse_proxy).to_s # rubocop:disable Style/DoubleNegation
45
- )
46
- )
47
-
48
- # Because of all the diff ways to initialize the agent
49
- # some some of the following vars might not be set until
50
- # we call this method, so call this method to set all
51
- # the variables
52
- TCellAgent.configuration.log_filename
53
-
54
- TCellAgent.send_event(
55
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
56
- 'config_filename',
57
- TCellAgent.configuration.config_filename
58
- )
59
- )
60
- TCellAgent.send_event(
61
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
62
- 'logging_directory',
63
- TCellAgent.configuration.agent_log_dir
64
- )
65
- )
66
-
67
- TCellAgent.send_event(
68
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
69
- 'agent_home_directory',
70
- TCellAgent.configuration.agent_home_dir
71
- )
72
- )
29
+ TCellAgent::Instrumentation.safe_block('Instrumenting Native Lib Status') do
30
+ require 'tcell_agent/rust/native_agent'
73
31
 
74
32
  TCellAgent.send_event(
75
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
76
- 'agent_home_owner',
77
- TCellAgent.configuration.agent_home_owner
33
+ TCellAgent::SensorEvents::AgentSettingEvent.new(
34
+ 'native_lib_loaded',
35
+ TCellAgent::Rust::NativeLibrary.common_lib_available?.to_s
78
36
  )
79
37
  )
80
-
81
- logging_options = TCellAgent.configuration.logging_options || {}
82
- use_default_setting = !logging_options.key?(:enabled) && !logging_options.key?('enabled')
83
- if use_default_setting || logging_options[:enabled] || logging_options['enabled']
84
- TCellAgent.send_event(
85
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new('logging_enabled', 'true')
86
- )
87
-
88
- TCellAgent.send_event(
89
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
90
- 'logging_level',
91
- logging_options[:level] || logging_options['level'] || 'INFO'
92
- )
93
- )
94
- else
95
- TCellAgent.send_event(
96
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new('logging_enabled', 'false')
97
- )
98
- end
99
-
100
- if TCellAgent.configuration.hmac_key
101
- TCellAgent.send_event(
102
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
103
- 'hmac_key_present',
104
- (!!TCellAgent.configuration.hmac_key).to_s # rubocop:disable Style/DoubleNegation
105
- )
106
- )
107
- end
108
-
109
- if TCellAgent.configuration.reverse_proxy
110
- TCellAgent.send_event(
111
- TCellAgent::SensorEvents::TCellAgentSettingEvent.new(
112
- 'reverse_proxy_ip_address_header',
113
- TCellAgent.configuration.reverse_proxy_ip_address_header
114
- )
115
- )
116
- end
117
38
  end
118
39
 
119
40
  if defined?(::Rails)
@@ -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