tcell_agent 2.1.2 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/bin/tcell_agent +41 -150
  4. data/lib/tcell_agent.rb +8 -16
  5. data/lib/tcell_agent/agent.rb +87 -52
  6. data/lib/tcell_agent/config_initializer.rb +62 -0
  7. data/lib/tcell_agent/configuration.rb +72 -267
  8. data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
  9. data/lib/tcell_agent/instrument_servers.rb +14 -18
  10. data/lib/tcell_agent/instrumentation.rb +14 -6
  11. data/lib/tcell_agent/instrumentation/cmdi.rb +32 -0
  12. data/lib/tcell_agent/instrumentation/lfi.rb +55 -9
  13. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
  17. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
  18. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
  19. data/lib/tcell_agent/logger.rb +3 -4
  20. data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
  21. data/lib/tcell_agent/policies/headers_policy.rb +2 -2
  22. data/lib/tcell_agent/policies/patches_policy.rb +8 -4
  23. data/lib/tcell_agent/policies/policies_manager.rb +1 -0
  24. data/lib/tcell_agent/policies/policy_polling.rb +4 -3
  25. data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
  26. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  27. data/lib/tcell_agent/rails/auth/devise.rb +103 -102
  28. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  29. data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -57
  30. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  31. data/lib/tcell_agent/rails/better_ip.rb +7 -19
  32. data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
  33. data/lib/tcell_agent/rails/dlp.rb +48 -52
  34. data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
  35. data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
  36. data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
  37. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
  38. data/lib/tcell_agent/rails/middleware/global_middleware.rb +3 -4
  39. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
  40. data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
  41. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  42. data/lib/tcell_agent/rails/routes.rb +3 -6
  43. data/lib/tcell_agent/rails/routes/grape.rb +3 -4
  44. data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
  45. data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
  46. data/lib/tcell_agent/routes/table.rb +3 -0
  47. data/lib/tcell_agent/rust/agent_config.rb +59 -33
  48. data/lib/tcell_agent/rust/{libtcellagent-4.18.0.so → libtcellagent-alpine.so} +0 -0
  49. data/lib/tcell_agent/rust/libtcellagent-x64.dll +0 -0
  50. data/lib/tcell_agent/rust/{libtcellagent-4.18.0.dylib → libtcellagent.dylib} +0 -0
  51. data/lib/tcell_agent/rust/{libtcellagent-alpine-4.18.0.so → libtcellagent.so} +0 -0
  52. data/lib/tcell_agent/rust/models.rb +9 -0
  53. data/lib/tcell_agent/rust/native_agent.rb +58 -50
  54. data/lib/tcell_agent/rust/native_library.rb +8 -10
  55. data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
  56. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
  57. data/lib/tcell_agent/servers/puma.rb +30 -13
  58. data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -0
  59. data/lib/tcell_agent/servers/rails_server.rb +4 -4
  60. data/lib/tcell_agent/servers/unicorn.rb +1 -1
  61. data/lib/tcell_agent/servers/webrick.rb +12 -3
  62. data/lib/tcell_agent/settings_reporter.rb +0 -93
  63. data/lib/tcell_agent/sinatra.rb +1 -0
  64. data/lib/tcell_agent/tcell_context.rb +16 -7
  65. data/lib/tcell_agent/utils/headers.rb +0 -1
  66. data/lib/tcell_agent/utils/strings.rb +2 -2
  67. data/lib/tcell_agent/version.rb +1 -1
  68. data/spec/cruby_spec_helper.rb +26 -0
  69. data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
  70. data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
  71. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
  72. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
  73. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +207 -223
  74. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +89 -70
  75. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +73 -0
  76. data/spec/lib/tcell_agent/patches_spec.rb +2 -1
  77. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
  78. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
  79. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
  80. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
  81. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +14 -8
  82. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
  83. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
  84. data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
  85. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
  86. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
  87. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
  88. data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
  89. data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
  90. data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
  91. data/spec/spec_helper.rb +9 -1
  92. data/spec/support/builders.rb +8 -7
  93. data/spec/support/server_mocks/passenger_mock.rb +7 -0
  94. data/spec/support/server_mocks/puma_mock.rb +21 -0
  95. data/spec/support/server_mocks/rails_mock.rb +7 -0
  96. data/spec/support/server_mocks/thin_mock.rb +7 -0
  97. data/spec/support/server_mocks/unicorn_mock.rb +11 -0
  98. data/spec/support/shared_spec.rb +29 -0
  99. data/tcell_agent.gemspec +14 -14
  100. metadata +44 -27
  101. data/Rakefile +0 -18
  102. data/lib/tcell_agent/authlogic.rb +0 -23
  103. data/lib/tcell_agent/config/unknown_options.rb +0 -119
  104. data/lib/tcell_agent/devise.rb +0 -33
  105. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
  106. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -131
  107. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -102
  108. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
  109. data/lib/tcell_agent/rust/tcellagent-4.18.0.dll +0 -0
  110. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rack::Handler::Puma.class_eval do
4
+ class << self
5
+ alias_method :tcell_original_config, :config
6
+ def config(app, options = {})
7
+ conf = tcell_original_config(app, options)
8
+
9
+ if defined?(Puma::Server) && !Puma::Server.instance_methods.include?(:tcell_original_run)
10
+ Puma::Server.class_eval do
11
+ alias_method :tcell_original_run, :run
12
+
13
+ if defined?(Gem::Version) &&
14
+ defined?(Puma::Const::PUMA_VERSION) &&
15
+ (Gem::Version.new(Puma::Const::PUMA_VERSION) >= Gem::Version.new('5.1.0'))
16
+ def run(background = true, thread_name: 'server')
17
+ TCellAgent.thread_agent.start('Puma')
18
+ original_run(background, :thread_name => thread_name)
19
+ end
20
+ else
21
+ def run(background = true)
22
+ TCellAgent.thread_agent.start('Puma')
23
+
24
+ tcell_original_run(background)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ conf
31
+ end
32
+ end
33
+ end
@@ -5,17 +5,17 @@
5
5
  Rails::Server.class_eval do
6
6
  alias_method :tcell_build_app, :build_app
7
7
  def build_app(app)
8
+ require('tcell_agent/servers/rack_puma_handler') if defined?(Rack::Handler::Puma)
8
9
  require('tcell_agent/servers/unicorn') if defined?(Unicorn::HttpServer)
9
10
  require('tcell_agent/servers/webrick') if defined?(Rack::Handler::WEBrick)
10
11
  require('tcell_agent/servers/thin') if defined?(Thin::Server)
11
12
 
12
13
  if defined?(Puma::Server)
13
14
  Puma::Server.class_eval do
14
- alias_method :original_run, :run
15
+ alias_method :tcell_original_run, :run
15
16
  def run(background = true)
16
- TCellAgent.thread_agent.start('Puma Single Mode')
17
-
18
- original_run(background)
17
+ TCellAgent.thread_agent.start('Puma')
18
+ tcell_original_run(background)
19
19
  end
20
20
  end
21
21
  end
@@ -3,7 +3,7 @@ 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
- require 'tcell_agent/rails/start_agent_after_initializers'
6
+ require 'tcell_agent/rails/railties/tcell_agent_unicorn_railties'
7
7
  end
8
8
 
9
9
  # This only gets instrumented when preload_app is true
@@ -1,10 +1,19 @@
1
1
  Rack::Handler::WEBrick.class_eval do
2
2
  class << self
3
3
  alias_method :original_run, :run
4
- def run(app, options = {})
5
- TCellAgent.thread_agent.start('WEBrick')
6
4
 
7
- original_run(app, options)
5
+ if defined?(Gem::Version) &&
6
+ defined?(Rack.release) &&
7
+ Gem::Version.new(Rack.release) < Gem::Version.new('2.2.0')
8
+ def run(app, options = {})
9
+ TCellAgent.thread_agent.start('WEBrick')
10
+ original_run(app, options)
11
+ end
12
+ else
13
+ def run(app, **options)
14
+ TCellAgent.thread_agent.start('WEBrick')
15
+ original_run(app, **options)
16
+ end
8
17
  end
9
18
  end
10
19
  end
@@ -7,25 +7,11 @@ require 'thread'
7
7
  module TCellAgent
8
8
  def self.report_settings
9
9
  Thread.new do
10
- TCellAgent::Instrumentation.safe_block('Instrumenting Agent Details') do
11
- event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
12
- TCellAgent.send_event(event)
13
- end
14
-
15
10
  TCellAgent::Instrumentation.safe_block('Instrumenting Server Packages') do
16
11
  event = TCellAgent::SensorEvents::ServerAgentPackagesSensorEvent.new
17
12
  TCellAgent.send_event(event)
18
13
  end
19
14
 
20
- TCellAgent::Instrumentation.safe_block('Instrumenting Language Info') do
21
- TCellAgent.send_event(
22
- TCellAgent::SensorEvents::ServerAgentDetailsLanguageEvent.new(
23
- 'Ruby',
24
- RUBY_VERSION
25
- )
26
- )
27
- end
28
-
29
15
  TCellAgent::Instrumentation.safe_block('Instrumenting Native Lib Status') do
30
16
  require 'tcell_agent/rust/native_agent'
31
17
 
@@ -37,85 +23,6 @@ module TCellAgent
37
23
  )
38
24
  end
39
25
 
40
- TCellAgent::Instrumentation.safe_block('Instrumenting Initial Config') do
41
- TCellAgent.send_event(
42
- TCellAgent::SensorEvents::AgentSettingEvent.new(
43
- 'allow_payloads',
44
- (!!TCellAgent.configuration.allow_payloads).to_s # rubocop:disable Style/DoubleNegation
45
- )
46
- )
47
-
48
- TCellAgent.send_event(
49
- TCellAgent::SensorEvents::AgentSettingEvent.new(
50
- 'reverse_proxy',
51
- (!!TCellAgent.configuration.reverse_proxy).to_s # rubocop:disable Style/DoubleNegation
52
- )
53
- )
54
-
55
- # Because of all the diff ways to initialize the agent
56
- # some some of the following vars might not be set until
57
- # we call this method, so call this method to set all
58
- # the variables
59
- TCellAgent.configuration.log_filename
60
-
61
- TCellAgent.send_event(
62
- TCellAgent::SensorEvents::AgentSettingEvent.new(
63
- 'config_filename',
64
- TCellAgent.configuration.config_filename
65
- )
66
- )
67
- TCellAgent.send_event(
68
- TCellAgent::SensorEvents::AgentSettingEvent.new(
69
- 'logging_directory',
70
- TCellAgent.configuration.agent_log_dir
71
- )
72
- )
73
-
74
- TCellAgent.send_event(
75
- TCellAgent::SensorEvents::AgentSettingEvent.new(
76
- 'agent_home_directory',
77
- TCellAgent.configuration.agent_home_dir
78
- )
79
- )
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::AgentSettingEvent.new('logging_enabled', 'true')
86
- )
87
-
88
- TCellAgent.send_event(
89
- TCellAgent::SensorEvents::AgentSettingEvent.new(
90
- 'logging_level',
91
- logging_options[:level] || logging_options['level'] || 'INFO'
92
- )
93
- )
94
- else
95
- TCellAgent.send_event(
96
- TCellAgent::SensorEvents::AgentSettingEvent.new('logging_enabled', 'false')
97
- )
98
- end
99
-
100
- if TCellAgent.configuration.hmac_key
101
- TCellAgent.send_event(
102
- TCellAgent::SensorEvents::AgentSettingEvent.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::AgentSettingEvent.new(
112
- 'reverse_proxy_ip_address_header',
113
- TCellAgent.configuration.reverse_proxy_ip_address_header
114
- )
115
- )
116
- end
117
- end
118
-
119
26
  if defined?(::Rails)
120
27
  TCellAgent::Instrumentation.safe_block('Instrumenting routes') do
121
28
  TCellAgent::Instrumentation::Rails.instrument_routes
@@ -16,6 +16,7 @@ module TCellAgent
16
16
  TCellAgent::Instrumentation.safe_block('Setting Headers') do
17
17
  headers_policy = TCellAgent.policy(TCellAgent::PolicyTypes::HEADERS)
18
18
  policy_headers = headers_policy.get_headers(
19
+ headers['Content-Type'],
19
20
  request.env[TCellAgent::Instrumentation::TCELL_ID]
20
21
  )
21
22
  policy_headers.each do |header_info|
@@ -40,10 +40,11 @@ module TCellAgent
40
40
  tcell_context.request_method,
41
41
  tcell_context.remote_address,
42
42
  tcell_context.route_id,
43
- tcell_context.hmac_session_id,
43
+ tcell_context.session_id,
44
44
  tcell_context.user_id,
45
45
  tcell_context.transaction_id,
46
- tcell_context.uri
46
+ tcell_context.uri,
47
+ tcell_context.reverse_proxy_header_value
47
48
  )
48
49
  meta_data.path = tcell_context.path
49
50
 
@@ -70,7 +71,8 @@ module TCellAgent
70
71
  :response_headers,
71
72
  :csrf_exception_name,
72
73
  :sql_exceptions,
73
- :database_result_sizes
74
+ :database_result_sizes,
75
+ :reverse_proxy_header_value
74
76
 
75
77
  attr_reader :flattened_get_dict,
76
78
  :flattened_cookie_dict,
@@ -85,7 +87,8 @@ module TCellAgent
85
87
  session_id,
86
88
  user_id,
87
89
  transaction_id,
88
- location)
90
+ location,
91
+ reverse_proxy_header_value)
89
92
  @method = method
90
93
  @remote_address = remote_address
91
94
  @route_id = route_id
@@ -93,7 +96,7 @@ module TCellAgent
93
96
  @user_id = user_id
94
97
  @transaction_id = transaction_id
95
98
  @location = location
96
- @path = path
99
+ @reverse_proxy_header_value = reverse_proxy_header_value
97
100
 
98
101
  @flattened_get_dict = {}
99
102
  @flattened_cookie_dict = {}
@@ -148,6 +151,7 @@ module TCellAgent
148
151
  if !content_length.nil? && content_length > TCELL_MAX_BODY_LENGTH || request.content_type.nil?
149
152
  return nil
150
153
  end
154
+
151
155
  raw_post_data = nil
152
156
  # Positions strio to the beginning of input, resetting lineno to zero.
153
157
  # rails 4.1 seems to read the stringIO directly and so body.gets is empty
@@ -171,10 +175,15 @@ module TCellAgent
171
175
  self.get_dict = request.GET
172
176
  self.cookie_dict = request.cookies
173
177
 
174
- self.post_dict = if @content_type.start_with?('application/json', 'application/xml')
178
+ self.post_dict = if @content_type.start_with?('application/json', 'application/xml') ||
179
+ (@content_type.start_with?('multipart/form-data') && @request_content_bytes_len == 0)
175
180
  {}
176
181
  else
177
- request.POST
182
+ begin
183
+ request.POST
184
+ rescue EOFError
185
+ {}
186
+ end
178
187
  end
179
188
 
180
189
  self.headers_dict = request.env
@@ -1,4 +1,3 @@
1
-
2
1
  module TCellAgent
3
2
  module Utils
4
3
  module Headers
@@ -1,10 +1,10 @@
1
1
  module TCellAgent
2
2
  module Utils
3
3
  module Strings
4
- BLANK_RE = /\A[[:space:]]*\z/
4
+ BLANK_RE = /\A[[:space:]]*\z/.freeze
5
5
 
6
6
  def self.blank?(str)
7
- str.nil? || str.empty? || BLANK_RE === str # rubocop:disable Style/CaseEquality
7
+ str.nil? || str.empty? || BLANK_RE === str
8
8
  end
9
9
 
10
10
  def self.present?(str)
@@ -1,5 +1,5 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
 
3
3
  module TCellAgent
4
- VERSION = '2.1.2'.freeze
4
+ VERSION = '2.4.1'.freeze
5
5
  end
@@ -0,0 +1,26 @@
1
+ require 'tcell_agent'
2
+
3
+ TCellAgent.configuration.enabled = true
4
+ TCellAgent.configuration.instrument = true
5
+ TCellAgent.configuration.enable_intercept_requests = true
6
+ TCellAgent.configuration.disabled_instrumentation = []
7
+ TCellAgent.thread_agent.instrument_built_ins
8
+
9
+ # This monkey patch turns off blocking for LFI/CMDI when run in CRuby specs/
10
+ # test suite. The original method also depends on a Rails installation,
11
+ # which CRuby does not have installed.
12
+ module TCellAgent
13
+ module Instrumentation
14
+ module Lfi
15
+ def self.block_file_access?(_path, _mode)
16
+ false
17
+ end
18
+ end
19
+ end
20
+
21
+ module Cmdi
22
+ def self.block_command?(_cmd)
23
+ false
24
+ end
25
+ end
26
+ end
@@ -2,228 +2,78 @@ require 'spec_helper'
2
2
 
3
3
  module TCellAgent
4
4
  describe Configuration do
5
- describe '#agent_home_dir' do
6
- context 'no TCELL_AGENT_HOME defined' do
7
- it 'should set cache file, config, and log file to defaults' do
8
- configuration = Configuration.new
5
+ describe 'should_instrument?' do
6
+ context 'with the agent disabled' do
7
+ it 'should return false' do
8
+ config = Configuration.new
9
+ config.enabled = false
9
10
 
10
- expect(configuration.log_filename).to eq(
11
- File.join(Dir.getwd, 'tcell/logs/tcell_agent.log')
12
- )
13
- expect(configuration.config_filename).to eq(
14
- File.join(Dir.getwd, 'config/tcell_agent.config')
15
- )
11
+ expect(config.should_instrument?).to be_falsey
16
12
  end
17
13
  end
18
-
19
- context 'TCELL_AGENT_HOME defined' do
20
- it 'should set config filename to default, cache file and log file are updated' do
21
- old_tcell_agent_home = ENV['TCELL_AGENT_HOME']
22
-
23
- ENV['TCELL_AGENT_HOME'] = 'spec_tcell_home'
24
-
25
- configuration = Configuration.new
26
-
27
- expect(configuration.log_filename).to eq(
28
- 'spec_tcell_home/logs/tcell_agent.log'
29
- )
30
- expect(configuration.config_filename).to eq(
31
- File.join(Dir.getwd, 'config/tcell_agent.config')
32
- )
33
-
34
- ENV['TCELL_AGENT_HOME'] = old_tcell_agent_home
35
- end
36
- end
37
-
38
- context 'TCELL_AGENT_HOME and TCELL_AGENT_LOG_DIR defined' do
39
- it 'should set config filename to default, cache file and log file are updated' do
40
- old_tcell_agent_home = ENV['TCELL_AGENT_HOME']
41
- old_tcell_agent_log_dir = ENV['TCELL_AGENT_LOG_DIR']
42
-
43
- ENV['TCELL_AGENT_HOME'] = 'spec_tcell_home'
44
- ENV['TCELL_AGENT_LOG_DIR'] = 'spec_tcell_log_dir'
45
-
46
- configuration = Configuration.new
47
-
48
- expect(configuration.log_filename).to eq(
49
- 'spec_tcell_log_dir/tcell_agent.log'
50
- )
51
- expect(configuration.config_filename).to eq(
52
- File.join(Dir.getwd, 'config/tcell_agent.config')
53
- )
54
-
55
- ENV['TCELL_AGENT_HOME'] = old_tcell_agent_home
56
- ENV['TCELL_AGENT_LOG_DIR'] = old_tcell_agent_log_dir
57
- end
58
- end
59
-
60
- context 'TCELL_AGENT_HOME, TCELL_AGENT_LOG_DIR, and TCELL_AGENT_CONFIG defined ' do
61
- it 'should update config filename, cache file, and log file' do
62
- old_tcell_agent_home = ENV['TCELL_AGENT_HOME']
63
- old_tcell_agent_log_dir = ENV['TCELL_AGENT_LOG_DIR']
64
- old_config_filename = ENV['TCELL_AGENT_CONFIG']
65
-
66
- ENV['TCELL_AGENT_HOME'] = 'spec_tcell_home'
67
- ENV['TCELL_AGENT_LOG_DIR'] = 'spec_tcell_log_dir'
68
- ENV['TCELL_AGENT_CONFIG'] = 'spec_config/tcell_agent.config'
69
-
70
- configuration = Configuration.new
71
-
72
- expect(configuration.log_filename).to eq(
73
- 'spec_tcell_log_dir/tcell_agent.log'
74
- )
75
- expect(configuration.config_filename).to eq(
76
- 'spec_config/tcell_agent.config'
77
- )
78
-
79
- ENV['TCELL_AGENT_HOME'] = old_tcell_agent_home
80
- ENV['TCELL_AGENT_LOG_DIR'] = old_tcell_agent_log_dir
81
- ENV['TCELL_AGENT_CONFIG'] = old_config_filename
82
- end
83
- end
84
- end
85
-
86
- describe '#data_exposure' do
87
- context 'no data_exposure defined' do
88
- it 'should set max_data_ex_db_records_per_request to default' do
89
- no_data_ex = double(
90
- 'no_data_ex',
91
- :read => {
92
- :version => 1,
93
- :applications => [
94
- :app_id => 'app_id',
95
- :name => 'test',
96
- :api_key => 'api_key'
97
- ]
98
- }.to_json
99
- )
100
- expect(File).to receive(:file?).with(
101
- File.join(Dir.getwd, 'no_data_ex.config')
102
- ).and_return(true)
103
- expect(File).to receive(:open).with(
104
- File.join(Dir.getwd, 'no_data_ex.config')
105
- ).and_return(no_data_ex)
106
- configuration = Configuration.new('no_data_ex.config')
107
-
108
- expect(configuration.max_data_ex_db_records_per_request).to eq(1000)
109
- end
110
- end
111
-
112
- context 'data_exposure is empty' do
113
- it 'should set max_data_ex_db_records_per_request to default' do
114
- no_data_ex = double(
115
- 'no_data_ex',
116
- :read => {
117
- :version => 1,
118
- :applications => [
119
- :app_id => 'app_id',
120
- :name => 'test',
121
- :api_key => 'api_key',
122
- :data_exposure => {}
123
- ]
124
- }.to_json
125
- )
126
- expect(File).to receive(:file?).with(
127
- File.join(Dir.getwd, 'no_data_ex.config')
128
- ).and_return(true)
129
- expect(File).to receive(:open).with(
130
- File.join(Dir.getwd, 'no_data_ex.config')
131
- ).and_return(no_data_ex)
132
- configuration = Configuration.new('no_data_ex.config')
133
-
134
- expect(configuration.max_data_ex_db_records_per_request).to eq(1000)
14
+ context 'with the agent enabled' do
15
+ context 'with all instrumentation enabled' do
16
+ context 'with no parameters' do
17
+ it 'should return true' do
18
+ config = Configuration.new
19
+ config.enabled = true
20
+ config.instrument = true
21
+
22
+ expect(config.should_instrument?).to be_truthy
23
+ end
24
+ end
25
+ context 'with parameters' do
26
+ it 'should return true' do
27
+ config = Configuration.new
28
+ config.enabled = true
29
+ config.instrument = true
30
+ config.disabled_instrumentation = Set.new
31
+
32
+ expect(config.should_instrument?('devise')).to be_truthy
33
+ end
34
+ end
135
35
  end
136
- end
36
+ context 'with auth frameworks disabled' do
37
+ it 'should return false' do
38
+ config = Configuration.new
39
+ config.disabled_instrumentation = Set.new(%w[authlogic devise doorkeeper])
137
40
 
138
- context 'data_exposure contains an override' do
139
- it 'should set max_data_ex_db_records_per_request to override' do
140
- no_data_ex = double(
141
- 'no_data_ex',
142
- :read => {
143
- :version => 1,
144
- :applications => [
145
- :app_id => 'app_id',
146
- :name => 'test',
147
- :api_key => 'api_key',
148
- :data_exposure => {
149
- :max_data_ex_db_records_per_request => 5000
150
- }
151
- ]
152
- }.to_json
153
- )
154
- expect(File).to receive(:file?).with(
155
- File.join(Dir.getwd, 'no_data_ex.config')
156
- ).and_return(true)
157
- expect(File).to receive(:open).with(
158
- File.join(Dir.getwd, 'no_data_ex.config')
159
- ).and_return(no_data_ex)
160
- configuration = Configuration.new('no_data_ex.config')
161
-
162
- expect(configuration.max_data_ex_db_records_per_request).to eq(5000)
41
+ expect(config.should_instrument?('devise')).to be_falsey
42
+ end
163
43
  end
164
44
  end
165
45
  end
166
-
167
- describe '#allow_payloads' do
168
- context 'setting it via config' do
169
- context 'using allow_payloads' do
170
- it 'should be false' do
171
- allow_payloads_enabled = double(
172
- 'no_data_ex',
173
- :read => {
174
- :version => 1,
175
- :applications => [
176
- :app_id => 'app_id',
177
- :api_key => 'api_key',
178
- :allow_payloads => false
179
- ]
180
- }.to_json
181
- )
182
- expect(File).to receive(:file?).with(
183
- File.join(Dir.getwd, 'config/tcell_agent.config')
184
- ).and_return(true)
185
- expect(File).to receive(:open).with(
186
- File.join(Dir.getwd, 'config/tcell_agent.config')
187
- ).and_return(allow_payloads_enabled)
188
-
189
- configuration = Configuration.new
190
-
191
- expect(configuration.allow_payloads).to eq(false)
192
- end
46
+ describe 'populate_configuration' do
47
+ context 'with a poor native_agent_config_response' do
48
+ it 'should not throw an error' do
49
+ native_agent_config_response = {}
50
+
51
+ config = Configuration.new
52
+ expect do
53
+ config.populate_configuration(native_agent_config_response)
54
+ end.not_to raise_error
193
55
  end
194
56
  end
195
-
196
- context 'setting it via env var' do
197
- context 'TCELL_AGENT_ALLOW_PAYLOADS overrides everything else' do
198
- it 'should be false' do
199
- old_tcell_agent_allow_payloads = ENV['TCELL_AGENT_ALLOW_PAYLOADS']
200
-
201
- ENV['TCELL_AGENT_ALLOW_PAYLOADS'] = 'false'
202
-
203
- allow_payloads_enabled = double(
204
- 'no_data_ex',
205
- :read => {
206
- :version => 1,
207
- :applications => [
208
- :app_id => 'app_id',
209
- :api_key => 'api_key',
210
- :allow_payloads => true
211
- ]
212
- }.to_json
213
- )
214
- expect(File).to receive(:file?).with(
215
- File.join(Dir.getwd, 'config/tcell_agent.config')
216
- ).and_return(true)
217
- expect(File).to receive(:open).with(
218
- File.join(Dir.getwd, 'config/tcell_agent.config')
219
- ).and_return(allow_payloads_enabled)
220
-
221
- configuration = Configuration.new
222
-
223
- ENV['TCELL_AGENT_ALLOW_PAYLOADS'] = old_tcell_agent_allow_payloads
224
-
225
- expect(configuration.allow_payloads).to eq(false)
226
- end
57
+ context 'with an elaborate native_agent_config_response' do
58
+ it 'should set all the correct configurations' do
59
+ native_agent_config_response = { 'enabled' => true,
60
+ 'disabled_instrumentation' => %w[devise doorkeeper],
61
+ 'update_policy' => 'true',
62
+ 'applications' => { 'first' => { 'app_id' => 'app_id_placeholder',
63
+ 'api_key' => 'api_key_paceholder',
64
+ 'hmac_key' => 'hmac_key_placeholder',
65
+ 'password_hmac_key' => 'password_hmac_key_placeholder',
66
+ 'proxy_config' => { 'reverse_proxy' => true,
67
+ 'reverse_proxy_ip_address_header' => 'X-Forwarded-For' } } },
68
+ 'endpoint_config' => { 'api_url' => 'https://us.agent.tcell.insight.rapid7.com/api/v1' },
69
+ 'ruby_config' => { 'enable_policy_polling' => true } }
70
+
71
+ config = Configuration.new
72
+ config.populate_configuration(native_agent_config_response)
73
+
74
+ expect(config.disabled_instrumentation).to be_a(Set)
75
+ expect(config.disabled_instrumentation).to include('devise', 'doorkeeper')
76
+ expect(config.enable_intercept_requests).to be_truthy
227
77
  end
228
78
  end
229
79
  end