tcell_agent 1.1.12 → 2.2.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 (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,13 +1,7 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
 
3
- require 'tcell_agent/logger'
4
- require 'tcell_agent/version'
5
- require 'tcell_agent/api'
6
- require 'tcell_agent/configuration'
7
-
8
3
  require 'tcell_agent/routes/table'
9
4
  require 'tcell_agent/sensor_events/discovery'
10
- require 'tcell_agent'
11
5
 
12
6
  module TCellAgent
13
7
  class Agent
@@ -23,16 +17,6 @@ module TCellAgent
23
17
  def discover_database_fields(route_id, database, schema, table, fields)
24
18
  return if route_id.nil? || database.nil? || schema.nil? || table.nil? || fields.nil?
25
19
 
26
- if TCellAgent::Agent.parent_process? == false
27
- TCellAgent.queue_metric('_type' => 'discover_database_fields',
28
- 'route_id' => route_id,
29
- 'database' => database,
30
- 'schema' => schema,
31
- 'table' => table,
32
- 'fields' => fields)
33
- return
34
- end
35
-
36
20
  query_hash = TCellAgent::Agent.get_database_discovery_identifier(database, schema, table, fields)
37
21
 
38
22
  return if @route_table.routes[route_id].database_queries_discovered.fetch(query_hash, false)
@@ -1,24 +1,15 @@
1
- # See the file "LICENSE" for the full license governing this code.
2
- require 'tcell_agent/sensor_events/metrics'
3
- require 'monitor'
4
-
5
1
  module TCellAgent
6
2
  @@instance_lock = Mutex.new
7
3
  @@my_thread_agent = nil
8
4
 
9
5
  def self.thread_agent
10
- if thread_agent_defined? == false
6
+ unless @@my_thread_agent
11
7
  @@instance_lock.synchronize do
12
- if thread_agent_defined? == false
13
- @@my_thread_agent = TCellAgent::Agent.new(Process.pid)
14
- end
8
+ @@my_thread_agent ||= TCellAgent::Agent.new
15
9
  end
16
10
  end
17
- @@my_thread_agent
18
- end
19
11
 
20
- def self.thread_agent_defined?
21
- @@my_thread_agent != nil
12
+ @@my_thread_agent
22
13
  end
23
14
 
24
15
  def self.thread_agent=(some_agent)
@@ -31,35 +22,23 @@ module TCellAgent
31
22
  thread_agent.queue_sensor_event(event)
32
23
  end
33
24
 
34
- def self.queue_metric(event)
35
- thread_agent._queue_metric(event)
25
+ def self.report_metrics(response_time, tcell_context)
26
+ thread_agent.report_metrics(response_time, tcell_context)
36
27
  end
37
28
 
38
29
  def self.policy(policy_type)
39
30
  thread_agent.policies.fetch(policy_type, nil)
40
31
  end
41
32
 
42
- def self.increment_session_info(hmac_session_id, user_id, ip_address, user_agent)
43
- thread_agent.increment_session_info(hmac_session_id, user_id, ip_address, user_agent)
44
- end
45
-
46
- def self.increment_route(route_id, response_time)
47
- thread_agent.increment_route(route_id, response_time)
48
- end
49
-
50
33
  def self.discover_database_fields(route_id, database, schema, table, fields)
51
34
  thread_agent.discover_database_fields(route_id, database, schema, table, fields)
52
35
  end
53
36
 
54
- def self.stop_agent
55
- thread_agent.stop_agent = true
37
+ def self.safe_to_check_cmdi?
38
+ thread_agent && thread_agent.safe_to_check_cmdi
56
39
  end
57
40
 
58
- def self.ensure_event_processor_running
59
- thread_agent.ensure_event_processor_running
60
- end
61
-
62
- def self.safe_to_send_cmdi_events?
63
- thread_agent.safe_to_send_cmdi_events?
41
+ def self.stop_agent
42
+ thread_agent.stop_agent = true
64
43
  end
65
44
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TCellAgent
4
+ class ConfigInitializer < Configuration
5
+ # Common config shared across agents
6
+ attr_accessor :app_id, :api_key, :tcell_api_url,
7
+ :tcell_input_url, :log_dir, :fetch_policies_from_tcell,
8
+ :preload_policy_filename, :reverse_proxy,
9
+ :reverse_proxy_ip_address_header, :host_identifier,
10
+ :hmac_key, :password_hmac_key,
11
+ :js_agent_url, :js_agent_api_base_url,
12
+ :max_csp_header_bytes, :allow_payloads
13
+
14
+ attr_reader :logging_options
15
+
16
+ # Ruby only config
17
+ attr_accessor :disable_all, :enabled, :enable_event_manager,
18
+ :enable_policy_polling,
19
+ :data_exposure
20
+
21
+ attr_reader :instrument_for_events,
22
+ :enable_instrumentation
23
+
24
+ # New config
25
+ attr_accessor :disabled_instrumentation, :instrument
26
+
27
+ def initialize
28
+ # ruby agent defaults
29
+ @logging_options = {}
30
+ end
31
+
32
+ def logging_options=(hash)
33
+ @logging_options = hash.each_with_object({}) do |(key, val), memo|
34
+ memo[key.to_sym] = val
35
+ end
36
+ end
37
+
38
+ # legacy config mapping
39
+ def enabled_instrumentations=(hash)
40
+ @disabled_instrumentation ||= []
41
+ hash.each do |key, val|
42
+ @disabled_instrumentation << key.to_s.strip.downcase unless TCellAgent.configuration.to_bool(val)
43
+ end
44
+ end
45
+
46
+ def agent_log_dir=(path)
47
+ @log_dir = path
48
+ end
49
+
50
+ def instrument_for_events=(bool)
51
+ @instrument = bool
52
+ end
53
+
54
+ def enable_instrumentation=(bool)
55
+ @instrument = bool
56
+ end
57
+
58
+ def enable_intercept_requests=(bool)
59
+ @disabled_instrumentation << 'intercept_requests' unless TCellAgent.configuration.to_bool(bool)
60
+ end
61
+
62
+ def get_config_file_dir
63
+ super
64
+ end
65
+ end
66
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # See the file "LICENSE" for the full license governing this code.
2
4
  require 'fileutils'
3
5
  require 'json'
@@ -6,396 +8,118 @@ require 'socket'
6
8
  require 'securerandom'
7
9
  require 'uri'
8
10
 
9
- require 'tcell_agent/config/unknown_options'
10
-
11
11
  module TCellAgent
12
12
  class ConfigurationException < StandardError
13
13
  end
14
14
 
15
15
  class << self
16
16
  attr_accessor :configuration
17
+ attr_accessor :initializer_configuration
17
18
  end
18
19
 
19
20
  def self.configure
20
- self.configuration ||= Configuration.new
21
- yield(configuration)
22
- end
23
-
24
- class Configuration # rubocop:disable Metrics/ClassLength
25
- attr_accessor :version,
26
- :app_id,
27
- :api_key,
28
- :hmac_key,
29
- :tcell_input_url,
30
- :logging_options,
31
- :logger,
32
- :appfirewall_payloads_logger, # appfirewall_payloads_logger can be specified from initializers
33
- :fetch_policies_from_tcell, :instrument_for_events,
34
- :preload_policy_filename,
35
- :host_identifier,
36
- :uuid,
37
- :event_batch_size_limit, :event_time_limit_seconds,
38
- :base_dir,
39
- :cache_filename,
40
- :js_agent_api_base_url,
41
- :js_agent_url,
42
- :config_filename,
43
- :agent_log_dir,
44
- :max_data_ex_db_records_per_request,
45
- :agent_home_dir,
46
- :agent_home_owner,
47
- :reverse_proxy,
48
- :reverse_proxy_ip_address_header,
49
- :log_file_name,
50
- :log_tag,
51
- :max_csp_header_bytes,
52
- :demomode,
53
- :allow_payloads,
54
- :password_hmac_key
55
-
56
- attr_reader :tcell_api_url
57
-
58
- attr_accessor :disable_all,
59
- :enabled,
60
- :enable_event_manager, # false = Do not start the even manager
61
- :enable_event_consumer, # false = Do not consume events, drop them
62
- :enable_policy_polling, # false = Do not poll for policies
63
- :enable_instrumentation, # false = Do not add instrumentation
64
- :enable_intercept_requests, # false = Do not insert middleware
65
- :enable_child_process_events # true = Start an event processor on all processes, even children
21
+ require 'tcell_agent/config_initializer'
22
+ self.initializer_configuration ||= ConfigInitializer.new
66
23
 
67
- attr_accessor :enabled_instrumentations
24
+ yield(initializer_configuration)
25
+ rescue NoMethodError => e
26
+ logger = TCellAgent::ModuleLogger.new(TCellAgent::RubyLogger.new, name)
27
+ logger.error("Error configuring tcell_agent with initializers: #{e}")
28
+ end
68
29
 
69
- attr_accessor :exp_config_settings
30
+ class Configuration
31
+ # internal Ruby configurations
32
+ attr_accessor :disable_all
70
33
 
71
- attr_accessor :disable_cmdi_exec_instrumentation # true = disable cmdi Kernel::exec instrumentation
34
+ # Common config returned by libtcellagent
35
+ attr_accessor :api_key, :app_id, :disabled_instrumentation, :enabled,
36
+ :enable_intercept_requests, :fetch_policies_from_tcell, :hmac_key,
37
+ :host_identifier, :instrument, :log_dir, :logging_options,
38
+ :password_hmac_key, :reverse_proxy, :reverse_proxy_ip_address_header,
39
+ :tcell_api_url
72
40
 
73
- def tcell_api_url=(value)
74
- @tcell_api_url = value
75
- @tcell_api_url = compose_api_url!
76
- end
77
-
78
- def should_start_event_manager?
79
- @enabled && @enable_event_manager
80
- end
81
-
82
- def should_start_event_manager_in_child_processes?
83
- @enabled && @enable_event_manager && @enable_child_process_events
84
- end
85
-
86
- def should_consume_event?
87
- @enabled && @enable_event_manager && @enable_event_consumer
88
- end
41
+ # Ruby config returned by libtcellagent
42
+ attr_accessor :enable_policy_polling
89
43
 
90
44
  def should_start_policy_poll?
91
45
  @enabled && @enable_policy_polling && @fetch_policies_from_tcell # fetch_policies_from_tcel = legacy
92
46
  end
93
47
 
94
- def should_instrument?
95
- @enabled && @enable_instrumentation && @instrument_for_events # instrument_for_events = legacy
96
- end
97
-
98
- def should_intercept_requests?
99
- @enabled && @enable_instrumentation && @enable_intercept_requests
100
- end
101
-
102
- def should_instrument_doorkeeper?
103
- if @enabled_instrumentations.key?('doorkeeper') || @enabled_instrumentations.key?(:doorkeeper)
104
- !!(@enabled_instrumentations['doorkeeper'] || @enabled_instrumentations[:doorkeeper]) # rubocop:disable Style/DoubleNegation
105
- else
106
- true
107
- end
108
- end
109
-
110
- def should_instrument_devise?
111
- if @enabled_instrumentations.key?('devise') || @enabled_instrumentations.key?(:devise)
112
- !!(@enabled_instrumentations['devise'] || @enabled_instrumentations[:devise]) # rubocop:disable Style/DoubleNegation
113
- else
114
- true
115
- end
116
- end
48
+ def should_instrument?(func = nil)
49
+ return false unless @enabled && @instrument # never instrument if disabled
50
+ return true if func.nil? # always instrument if enabled and nothing given
117
51
 
118
- def should_instrument_authlogic?
119
- if @enabled_instrumentations.key?('authlogic') || @enabled_instrumentations.key?(:authlogic)
120
- !!(@enabled_instrumentations['authlogic'] || @enabled_instrumentations[:authlogic]) # rubocop:disable Style/DoubleNegation
121
- else
122
- true
123
- end
52
+ !@disabled_instrumentation.include?(func)
124
53
  end
125
54
 
126
- def should_instrument_cmdi_exec?
127
- !@disable_cmdi_exec_instrumentation
55
+ def should_intercept_requests?
56
+ @enabled && @enable_intercept_requests
128
57
  end
129
58
 
130
- def initialize(filename = 'config/tcell_agent.config', _useapp = nil)
131
- # These will be set when the agent starts up, to give rails initializers
132
- # a chance to run
133
- @cache_filename = nil
134
- @agent_log_dir = nil
135
- @log_tag = nil
136
-
137
- @logger = nil
138
- @appfirewall_payloads_logger = nil
139
-
140
- @version = 0
141
- @exp_config_settings = true
142
- @demomode = false
143
-
144
- @fetch_policies_from_tcell = true
145
- @instrument_for_events = true
146
-
59
+ def initialize
60
+ # ruby agent defaults
147
61
  @disable_all = false
148
- @enabled = true
149
- @enable_event_manager = true
150
- @enable_event_consumer = true
151
- @enable_policy_polling = true
152
- @enable_instrumentation = true
153
- @enable_intercept_requests = true
154
- @enable_child_process_events = false
155
-
156
- @enabled_instrumentations = {
157
- :doorkeeper => true,
158
- :devise => true,
159
- :authlogic => true
160
- }
161
-
162
- @disable_cmdi_exec_instrumentation = false
163
-
164
- @log_file_name = 'tcell_agent.log'
165
-
166
- @event_batch_size_limit = 50
167
- @event_time_limit_seconds = 15
168
-
169
- @max_data_ex_db_records_per_request = 1000
170
- @reverse_proxy = true
171
- @reverse_proxy_ip_address_header = nil
172
- @allow_payloads = true
173
-
174
- @max_csp_header_bytes = nil
175
- @password_hmac_key = nil
176
-
177
- @agent_home_dir = ENV['TCELL_AGENT_HOME'] || File.join(Dir.getwd, 'tcell')
178
- @config_filename = ENV['TCELL_AGENT_CONFIG'] || File.join(Dir.getwd, filename)
179
-
180
- read_config_from_file(@config_filename)
181
- read_config_using_env
182
-
183
- if @demomode
184
- @event_batch_size_limit = 1
185
- @event_time_limit_seconds = 2
186
- end
187
-
188
- if ENV['TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS']
189
- puts 'tCell.io Agent: [DEPRECATED] TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS is deprecated and will be removed in a future release. Please switch to TCELL_AGENT_ALLOW_PAYLOADS.'
190
- end
62
+ @logging_options = {}
191
63
 
192
- if ENV['TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS']
193
- puts 'tCell.io Agent: [DEPRECATED] TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS is deprecated and will be removed in a future release. Please switch to TCELL_AGENT_ALLOW_PAYLOADS.'
194
- end
195
-
196
- unless ENV['TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS'].nil?
197
- @allow_payloads = [true, 'true', 'yes', '1'].include?(ENV['TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS'])
198
- end
199
- unless ENV['TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS'].nil?
200
- @allow_payloads = [true, 'true', 'yes', '1'].include?(ENV['TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS'])
201
- end
202
- unless ENV['TCELL_AGENT_ALLOW_PAYLOADS'].nil?
203
- @allow_payloads = [true, 'true', 'yes', '1'].include?(ENV['TCELL_AGENT_ALLOW_PAYLOADS'])
204
- end
205
-
206
- @tcell_api_url = compose_api_url!
207
- @tcell_input_url ||= 'https://input.tcell.io/api/v1'
208
- @js_agent_url ||= 'https://jsagent.tcell.io/tcellagent.min.js'
209
-
210
- if @host_identifier.nil?
211
- begin
212
- @host_identifier = (Socket.gethostname || 'localhost')
213
- rescue StandardError
214
- @host_identifier = 'host_identifier_not_found'
215
- end
216
- end
217
-
218
- @uuid = SecureRandom.uuid
64
+ check_for_disabled_instrumentation(get_config_file_name)
219
65
  end
220
66
 
221
- def compose_api_url!
222
- @tcell_api_url ||= 'https://api.tcell.io'
223
- parsed_uri = URI.parse(@tcell_api_url)
224
-
225
- api_url = [
226
- parsed_uri.scheme,
227
- '://',
228
- parsed_uri.host
229
- ]
67
+ def get_config_file_dir
68
+ return nil unless ENV['TCELL_AGENT_HOME']
69
+ return nil if ENV['TCELL_AGENT_CONFIG']
230
70
 
231
- api_url.push(":#{parsed_uri.port}") unless [80, 443].include?(parsed_uri.port)
232
-
233
- @js_agent_api_base_url ||= "#{api_url.join('')}/api/v1"
234
-
235
- [
236
- api_url.join(''),
237
- '/agents/api/v1/apps/',
238
- '{app_id}',
239
- '/policies/latest',
240
- '?',
241
- 'type=jsagentinjection:v1',
242
- '&type=http-redirect:v1',
243
- '&type=clickjacking:v1',
244
- '&type=secure-headers:v1',
245
- '&type=cmdi:v1',
246
- '&type=csp-headers:v1',
247
- '&type=dlp:v1',
248
- '&type=login:v1',
249
- '&type=regex:v1',
250
- '&type=appsensor:v2',
251
- '&type=patches:v1'
252
- ].join('')
253
- end
254
-
255
- def cache_filename_with_app_id
256
- @cache_filename ||= File.join(@agent_home_dir, 'cache', 'tcell_agent.cache')
257
-
258
- if @app_id
259
- "#{@cache_filename}.#{@app_id}"
260
- else
261
- @cache_filename
262
- end
71
+ File.join(Dir.getwd, '/config')
263
72
  end
264
73
 
265
- def read_config_using_env
266
- @app_id = ENV['TCELL_AGENT_APP_ID'] || @app_id
267
- @api_key = ENV['TCELL_AGENT_API_KEY'] || @api_key
268
- @hmac_key = ENV['TCELL_HMAC_KEY'] || @hmac_key
269
- @password_hmac_key = ENV['TCELL_PASSWORD_HMAC_KEY'] || @password_hmac_key
270
- @host_identifier = ENV['TCELL_AGENT_HOST_IDENTIFIER'] || @host_identifier
271
- @tcell_api_url = ENV['TCELL_API_URL'] || @tcell_api_url
272
- @tcell_input_url = ENV['TCELL_INPUT_URL'] || @tcell_input_url
273
- @demomode = ENV['TCELL_DEMOMODE'] || @demomode
274
-
275
- @agent_home_owner = ENV['TCELL_AGENT_HOME_OWNER'] || @agent_home_owner
276
- @agent_log_dir = ENV['TCELL_AGENT_LOG_DIR'] || @agent_log_dir
277
-
278
- @disable_cmdi_exec_instrumentation = ENV['TCELL_CMDI_EXEC_DISABLED'] || @disable_cmdi_exec_instrumentation
279
-
280
- @enabled = ENV['TCELL_AGENT_ENABLED'].to_s.casecmp('true').zero? if %w[true false].include? ENV['TCELL_AGENT_ENABLED'].to_s.downcase
74
+ def get_config_file_name
75
+ ENV['TCELL_AGENT_CONFIG'] || File.join(Dir.getwd, '/config/tcell_agent.config')
281
76
  end
282
77
 
283
- def read_config_from_file(filename)
78
+ def check_for_disabled_instrumentation(filename)
284
79
  return unless File.file?(filename)
285
80
 
286
81
  begin
287
- config_text = File.open(filename).read
288
- config = JSON.parse(config_text)
289
-
290
- messages = TCellAgent::Config::Validate.get_unknown_options(config)
291
- messages.each do |message|
292
- puts message
293
- end
82
+ config = JSON.parse(File.open(filename).read)
294
83
 
295
84
  if config['version'] == 1
296
- # Required
297
- app_data = config['applications'][0] # Default
298
- @version = 1
299
- @app_id = app_data['app_id']
300
- @api_key = app_data['api_key']
301
-
302
- # Optional
303
- @preload_policy_filename = app_data.fetch('preload_policy_filename', nil)
304
-
305
- @disable_all = app_data.fetch('disable_all', @disable_all)
306
- @enabled = app_data.fetch('enabled', @enabled)
307
-
308
- @enable_event_manager = app_data.fetch('enable_event_manager', @enable_event_manager)
309
- @enable_event_consumer = app_data.fetch('enable_event_consumer', @enable_event_consumer)
310
- @enable_policy_polling = app_data.fetch('enable_policy_polling', @enable_policy_polling)
311
- @enable_instrumentation = app_data.fetch('enable_instrumentation', @enable_instrumentation)
312
- @enable_intercept_requests = app_data.fetch('enable_intercept_requests', @enable_intercept_requests)
313
- @fetch_policies_from_tcell = app_data.fetch('fetch_policies_from_tcell', @fetch_policies_from_tcell)
314
- @instrument_for_events = app_data.fetch('instrument_for_events', @instrument_for_events)
315
- @enable_child_process_events = app_data.fetch('enable_child_process_events', @enable_child_process_events)
316
-
317
- @agent_home_owner = app_data.fetch('agent_home_owner', @agent_home_owner)
318
-
319
- @logging_options = app_data.fetch('logging_options', {})
320
- @agent_log_dir = app_data.fetch('log_dir', @agent_log_dir)
321
- @log_file_name = @logging_options.fetch('filename', @log_file_name)
322
-
323
- @tcell_api_url = app_data.fetch('tcell_api_url', @tcell_api_url)
324
- @tcell_input_url = app_data.fetch('tcell_input_url', @tcell_input_url)
325
-
326
- @max_csp_header_bytes = app_data.fetch('max_csp_header_bytes', @max_csp_header_bytes)
327
-
328
- @allow_payloads = app_data.fetch(
329
- 'allow_unencrypted_appsensor_payloads',
330
- @allow_payloads
331
- )
332
- @allow_payloads = app_data.fetch(
333
- 'allow_unencrypted_appfirewall_payloads',
334
- @allow_payloads
335
- )
336
- @allow_payloads = app_data.fetch(
337
- 'allow_payloads',
338
- @allow_payloads
339
- )
340
-
341
- data_exposure = app_data.fetch('data_exposure', {})
342
- @max_data_ex_db_records_per_request = data_exposure.fetch('max_data_ex_db_records_per_request', @max_data_ex_db_records_per_request)
343
-
344
- @enabled_instrumentations = app_data.fetch('enabled_instrumentations', @enabled_instrumentations)
345
-
346
- @reverse_proxy = app_data.fetch('reverse_proxy', @reverse_proxy)
347
- @reverse_proxy_ip_address_header = app_data.fetch('reverse_proxy_ip_address_header', @reverse_proxy_ip_address_header)
348
-
349
- @host_identifier = app_data.fetch('host_identifier', @host_identifier)
350
- @hmac_key = app_data.fetch('hmac_key', @hmac_key)
351
-
352
- @password_hmac_key = app_data.fetch('password_hmac_key', @password_hmac_key)
353
-
354
- @uuid = SecureRandom.uuid
355
- @uuid = 'secure-random-failed' if @uuid.nil?
356
-
357
- if app_data.key?('js_agent_api_base_url')
358
- @js_agent_api_base_url = app_data['js_agent_api_base_url']
359
- end
360
- if app_data.key?('js_agent_url')
361
- @js_agent_url = app_data['js_agent_url']
362
- end
363
-
364
- @demomode = app_data.fetch('demomode', @demomode)
365
- else
366
- puts ' ********* ********* ********* *********'
367
- puts '* tCell.io *'
368
- puts '* Unsupported config file version *'
369
- puts ' ********* ********* ********* *********'
85
+ app_data = config['applications'][0]
86
+ @disable_all = to_bool(app_data.fetch('disable_all', @disable_all))
370
87
  end
371
- rescue StandardError => e
372
- puts ' ********* ********* ********* *********'
373
- puts '* tCell.io *'
374
- puts '* Could not load config file *'
375
- puts ' ********* ********* ********* *********'
376
- puts e
88
+ rescue StandardError # rubocop:disable Lint/HandleExceptions
377
89
  end
378
90
  end
379
91
 
380
- # old value could be set via initializers, this makes sure those initializers still work
381
- # properly
382
- def allow_unencrypted_appfirewall_payloads=(val)
383
- @allow_payloads = val
92
+ def to_bool(var)
93
+ { 'true' => true, 'false' => false }[var.to_s.downcase]
384
94
  end
385
95
 
386
- # keep this around in case the value was read as well
387
- def allow_unencrypted_appfirewall_payloads
388
- @allow_payloads
389
- end
96
+ def populate_configuration(native_agent_config_response)
97
+ # config
98
+ @enabled = native_agent_config_response['enabled']
99
+ @disabled_instrumentation = Set.new(native_agent_config_response['disabled_instrumentation'])
100
+ @fetch_policies_from_tcell = native_agent_config_response['update_policy']
101
+ @instrument = native_agent_config_response['instrument']
390
102
 
391
- def log_filename
392
- @agent_log_dir ||= File.join(@agent_home_dir, 'logs')
393
- File.join(@agent_log_dir, @log_file_name)
394
- end
103
+ # app config
104
+ apps = native_agent_config_response['applications'] ? native_agent_config_response['applications']['first'] : {}
105
+ @app_id = apps['app_id']
106
+ @api_key = apps['api_key']
107
+ @hmac_key = apps['hmac_key']
108
+ @password_hmac_key = apps['password_hmac_key']
109
+
110
+ # proxy config
111
+ proxy_config = apps['proxy_config'] || {}
112
+ @reverse_proxy = proxy_config['reverse_proxy']
113
+ @reverse_proxy_ip_address_header = proxy_config['reverse_proxy_ip_address_header']
114
+
115
+ # endpoint config
116
+ endpoint = native_agent_config_response['endpoint_config'] || {}
117
+ @tcell_api_url = endpoint['api_url']
395
118
 
396
- def appfirewall_payloads_log_filename
397
- @agent_log_dir ||= File.join(@agent_home_dir, 'logs')
398
- File.join(@agent_log_dir, 'tcell_agent_payloads.log')
119
+ # ruby config
120
+ ruby_config = native_agent_config_response['ruby_config'] || {}
121
+ @enable_policy_polling = ruby_config['enable_policy_polling']
122
+ @enable_intercept_requests = !@disabled_instrumentation.include?('intercept_requests')
399
123
  end
400
124
  end
401
125