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,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