tcell_agent 2.0.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/bin/tcell_agent +41 -150
  4. data/lib/tcell_agent/agent.rb +87 -52
  5. data/lib/tcell_agent/config_initializer.rb +63 -0
  6. data/lib/tcell_agent/configuration.rb +72 -267
  7. data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
  8. data/lib/tcell_agent/instrument_servers.rb +14 -18
  9. data/lib/tcell_agent/instrumentation/cmdi.rb +47 -15
  10. data/lib/tcell_agent/instrumentation/lfi.rb +72 -15
  11. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
  12. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
  13. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
  17. data/lib/tcell_agent/instrumentation.rb +14 -6
  18. data/lib/tcell_agent/logger.rb +3 -4
  19. data/lib/tcell_agent/policies/command_injection_policy.rb +1 -1
  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/process_request.rb +5 -0
  34. data/lib/tcell_agent/rails/dlp.rb +58 -56
  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/grape.rb +5 -12
  43. data/lib/tcell_agent/rails/routes.rb +6 -9
  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 +62 -33
  48. data/lib/tcell_agent/rust/{libtcellagent-4.14.0.so → libtcellagent-alpine.so} +0 -0
  49. data/lib/tcell_agent/rust/{libtcellagent-4.14.0.dylib → libtcellagent-x64.dll} +0 -0
  50. data/lib/tcell_agent/rust/{libtcellagent-alpine-4.14.0.so → libtcellagent.dylib} +0 -0
  51. data/lib/tcell_agent/rust/libtcellagent.so +0 -0
  52. data/lib/tcell_agent/rust/models.rb +9 -0
  53. data/lib/tcell_agent/rust/native_agent.rb +61 -51
  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/lib/tcell_agent.rb +8 -16
  69. data/spec/cruby_spec_helper.rb +26 -0
  70. data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
  71. data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
  72. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
  73. data/spec/lib/tcell_agent/{cmdi_spec.rb → instrumentation/cmdi_spec.rb} +50 -0
  74. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
  75. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +213 -223
  76. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +95 -61
  77. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +120 -2
  78. data/spec/lib/tcell_agent/patches_spec.rb +2 -1
  79. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
  80. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
  81. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
  82. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
  83. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +13 -8
  84. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
  85. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
  86. data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
  87. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
  88. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
  89. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
  90. data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
  91. data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
  92. data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
  93. data/spec/spec_helper.rb +9 -1
  94. data/spec/support/builders.rb +8 -7
  95. data/spec/support/server_mocks/passenger_mock.rb +7 -0
  96. data/spec/support/server_mocks/puma_mock.rb +21 -0
  97. data/spec/support/server_mocks/rails_mock.rb +7 -0
  98. data/spec/support/server_mocks/thin_mock.rb +7 -0
  99. data/spec/support/server_mocks/unicorn_mock.rb +11 -0
  100. data/spec/support/shared_spec.rb +29 -0
  101. data/tcell_agent.gemspec +14 -14
  102. metadata +46 -29
  103. data/Rakefile +0 -18
  104. data/lib/tcell_agent/authlogic.rb +0 -23
  105. data/lib/tcell_agent/config/unknown_options.rb +0 -119
  106. data/lib/tcell_agent/devise.rb +0 -33
  107. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
  108. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -123
  109. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -159
  110. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
  111. data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
  112. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0b98e0366f6de14a287a83e13f08a0b5fdc9f13d12d8c6d1f0a2fa7f1caad9c
4
- data.tar.gz: 88cfc253d06f635d54ab72d83e4d3a28829526c3df47e2e1e7cad19fd47c9293
3
+ metadata.gz: 4460b2fd01c8b788c8139cbeb2cee7f8a2505e4cc365c279a518778766d9cdb0
4
+ data.tar.gz: 18dfdd5e944e91155d6b58fa22262b027292038192fac0b6afd4693314f74fd8
5
5
  SHA512:
6
- metadata.gz: 04c30f374634daf21590a07f94e3ea27cf09cd6931570b43a215f8d424983a86519c393faad76f7c809580dc9a02a905de00e6e28c4017d789b7baa6b86c5a3f
7
- data.tar.gz: 39119777a798add18175e51c5935fb08d8ea85f2cde16d237e87f9175f477d9d3333cf91e4cecf089b39b355db31052a5047a444a420ea778e505631952be623
6
+ metadata.gz: a2404786f0663783fd45194043c4a12efda21db0e933c14aca5f2d4532e900aac3b3f700ca8282b1995b38c718b6e0eade2a2b1ffbc9df467bf8ab5b4f144b18
7
+ data.tar.gz: 5021cff2601b66fd94a41b710ab0ab0211be35b2bd442afc0ca992ce4236d6c65e3ef69e14cd2ca9455fb4282d8affa1ba3e7aa3f05c75e4285ff6b5ab77e871
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (C) 2015 tCell.io, Inc. - All Rights Reserved
1
+ Copyright (C) 2020 Rapid7, Inc. - All Rights Reserved
2
2
  Proprietary and confidential
3
3
 
4
- http://choosealicense.com/licenses/no-license/
4
+ https://docs.rapid7.com/tcell/ruby-agent-install/
data/bin/tcell_agent CHANGED
@@ -1,29 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # TODO: so a small bit becames something, larger, rewrite as a real cmdline script
4
-
5
- require 'fileutils'
6
- require 'json'
3
+ require 'tcell_agent'
7
4
  require 'optparse'
8
5
 
6
+ CONFIG_DIR = 'config'.freeze
7
+ CONFIG_FILE = 'config/tcell_agent.config'.freeze
9
8
  options = {}
10
-
11
- subtext = <<HELP
12
- Commonly used command are:
13
- setup : Setup new config file
14
- test : Run diagnostics classes and config
15
- loglevel : Set the loglevel of the tcell agent
16
- enable : Enable the agent
17
- disable : Disable the agent
18
-
19
- See 'tcell_agent COMMAND --help' for more information on a specific command.
20
-
21
- HELP
22
-
23
9
  def yesno(default = true)
24
10
  begin
25
11
  system('stty raw -echo')
26
- str = STDIN.getc
12
+ str = $stdin.getc
27
13
  ensure
28
14
  system('stty -raw echo')
29
15
  end
@@ -34,74 +20,53 @@ def yesno(default = true)
34
20
  default
35
21
  end
36
22
 
37
- CONFIG_DIR = 'config'.freeze
38
- CONFIG_FILE = 'config/tcell_agent.config'.freeze
23
+ subtext = <<HELP
24
+ Commonly used commands are:
25
+ test : Run diagnostics and test event sending
26
+ HELP
39
27
 
40
28
  global = OptionParser.new do |opts|
41
- opts.banner = 'Usage: tcell_agent [options] [subcommand [options]]'
29
+ opts.banner = 'Usage: tcell_agent [options] [subcommand]'
30
+
42
31
  opts.on('--version', 'Print version') do |_v|
43
- require 'tcell_agent/version'
44
- puts "TCell.io Ruby Agent (Version #{TCellAgent::VERSION})"
32
+ puts "tCell Ruby Agent Version #{TCellAgent::VERSION}"
45
33
  Kernel.exit(1)
46
34
  end
47
- opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
48
- options[:verbose] = v
49
- end
35
+
50
36
  opts.separator ''
51
37
  opts.separator subtext
52
38
  end
53
39
 
54
40
  subcommands = {
55
- 'setup' => OptionParser.new do |opts|
56
- opts.banner = 'Usage: setup'
41
+ 'test' => OptionParser.new do |opts|
42
+ opts.banner = 'Usage: test'
57
43
  end,
58
44
  'loglevel' => OptionParser.new do |opts|
59
45
  opts.banner = 'Usage: loglevel [options] error|warn|info|debug'
60
46
  opts.on('-o', '--off', 'turn logging off ') do |v|
61
47
  options[:off] = v
62
48
  end
63
- end,
64
- 'preload' => OptionParser.new do |opts|
65
- opts.banner = 'Usage: loglevel [options] [preload_filename]'
66
- opts.on('-o', '--off', 'turn preloading filename off ') do |v|
67
- options[:off] = v
68
- end
69
- end,
70
- 'demomode' => OptionParser.new do |opts|
71
- opts.banner = 'Usage: loglevel [options]'
72
- opts.on('-o', '--off', 'turn preloading filename off ') do |v|
73
- options[:off] = v
74
- end
75
- end,
76
- 'enable' => OptionParser.new do |opts|
77
- opts.banner = 'Usage: enable'
78
- end,
79
- 'disable' => OptionParser.new do |opts|
80
- opts.banner = 'Usage: disable'
81
- end,
82
- 'test' => OptionParser.new do |opts|
83
- opts.banner = 'Usage: test'
84
- # opts.on("-q", "--[no-]quiet", "quietly run ") do |v|
85
- # options[:quiet] = v
86
- # end
87
- end
49
+ end
88
50
  }
89
51
 
90
52
  global.order!
91
53
  command = ARGV.shift
92
- if command.nil? || subcommands[command].nil?
54
+ if command.nil?
93
55
  puts global
94
56
  Kernel.exit(1)
57
+ elsif subcommands[command]
58
+ subcommands[command].order!
95
59
  end
96
- subcommands[command].order!
97
60
 
98
61
  if command == 'setup'
62
+ puts '[WARN] tcell_agent setup is deprecated and will be removed in the future.'
63
+ puts ' Please download the config file from the tCell dashboard'
99
64
  unless File.directory?(CONFIG_DIR)
100
65
  print "Directory 'config' not found, create? [Y/n]"
101
66
  answer = yesno
102
67
  print "\n"
103
68
  unless answer
104
- puts 'ERROR: Could not create config'
69
+ puts '[ERROR] Could not create config'
105
70
  Kernel.exit(1)
106
71
  end
107
72
  FileUtils.mkdir_p CONFIG_DIR
@@ -116,9 +81,9 @@ if command == 'setup'
116
81
  end
117
82
  end
118
83
  print 'Enter your API Key (ie gAABAAAA...): '
119
- api_key = STDIN.gets.chomp
84
+ api_key = $stdin.gets.chomp
120
85
  print 'Enter your App ID (ie MyApp-Fdk4j): '
121
- app_id = STDIN.gets.chomp
86
+ app_id = $stdin.gets.chomp
122
87
  config_hash = {
123
88
  'version' => 1,
124
89
  'applications' => [
@@ -132,6 +97,7 @@ if command == 'setup'
132
97
  puts 'done.'
133
98
 
134
99
  elsif command == 'loglevel'
100
+ puts '[WARN] tcell_agent loglevel is deprecated and will be removed in the future.'
135
101
  file = File.read(CONFIG_FILE)
136
102
  config_hash = JSON.parse(file)
137
103
  logging_options = config_hash['applications'][0].fetch('logging_options', {})
@@ -158,6 +124,7 @@ elsif command == 'loglevel'
158
124
  puts 'done.'
159
125
 
160
126
  elsif command == 'preload'
127
+ puts '[WARN] tcell_agent preload is deprecated and will be removed in the future.'
161
128
  file = File.read(CONFIG_FILE)
162
129
  config_hash = JSON.parse(file)
163
130
 
@@ -175,6 +142,7 @@ elsif command == 'preload'
175
142
  puts 'done.'
176
143
 
177
144
  elsif command == 'enable'
145
+ puts '[WARN] tcell_agent enable is deprecated and will be removed in the future.'
178
146
  file = File.read(CONFIG_FILE)
179
147
  config_hash = JSON.parse(file)
180
148
  config_hash['applications'][0].delete('enabled')
@@ -182,6 +150,7 @@ elsif command == 'enable'
182
150
  puts 'Enabled, you will need to restart the server.'
183
151
 
184
152
  elsif command == 'disable'
153
+ puts '[WARN] tcell_agent disable is deprecated and will be removed in the future.'
185
154
  file = File.read(CONFIG_FILE)
186
155
  config_hash = JSON.parse(file)
187
156
  config_hash['applications'][0]['enabled'] = false
@@ -189,6 +158,7 @@ elsif command == 'disable'
189
158
  puts 'Disabled, you will need to restart the server.'
190
159
 
191
160
  elsif command == 'demomode'
161
+ puts '[WARN] tcell_agent demomode is deprecated and will be removed in the future.'
192
162
  file = File.read(CONFIG_FILE)
193
163
  config_hash = JSON.parse(file)
194
164
  if options[:off] == true
@@ -200,104 +170,25 @@ elsif command == 'demomode'
200
170
  puts 'done.'
201
171
 
202
172
  elsif command == 'test'
203
- puts
204
- printf '%-50s', 'Config file exists... '
205
- unless File.exist?(CONFIG_FILE)
206
- puts 'failed'
207
- Kernel.exit(1)
208
- end
209
- puts 'passed'
210
-
211
- printf '%-50s', 'Config valid json... '
212
- file = File.read(CONFIG_FILE)
213
- config_hash = JSON.parse(file)
214
- puts 'passed'
215
-
216
- printf '%-50s', 'Config file has valid version... '
217
- if config_hash.fetch('version') != 1
218
- puts 'failed'
219
- Kernel.exit(1)
220
- end
221
- puts 'passed'
222
-
223
- printf '%-50s', 'Config file has application...'
224
- if config_hash.fetch('applications').empty?
225
- puts 'failed'
226
- Kernel.exit(1)
227
- end
228
- puts 'passed'
229
-
230
- printf '%-50s', 'Application has app_id... '
231
- tcell_application = config_hash.fetch('applications')[0]
232
- if !tcell_application.key?('app_id') && !ENV['TCELL_AGENT_APP_ID']
233
- puts 'failed'
234
- Kernel.exit(1)
235
- end
236
- puts 'passed'
237
-
238
- printf '%-50s', 'Application has api_key... '
239
- tcell_application = config_hash.fetch('applications')[0]
240
- if !tcell_application.key?('api_key') && !ENV['TCELL_AGENT_API_KEY']
241
- puts 'failed'
242
- Kernel.exit(1)
243
- end
244
- puts 'passed'
245
-
246
- printf '%-50s', 'Check for unknown settings... '
247
- require 'tcell_agent/config/unknown_options'
248
- messages = TCellAgent::Config::Validate.get_unknown_options(config_hash)
249
- unless messages.empty?
250
- puts 'failed'
251
- messages.each do |message|
252
- puts message
173
+ Dir["#{Dir.pwd}/config/initializers/*.rb"].sort.each do |f|
174
+ begin
175
+ require f
176
+ rescue NameError
177
+ # do nothing
178
+ rescue StandardError => e
179
+ puts "[ERROR] Loading initializers failed. #{e}"
253
180
  end
254
- Kernel.exit(1)
255
181
  end
256
- puts 'passed'
257
182
 
258
- printf '%-50s', 'Requiring configuration library... '
259
- require 'tcell_agent/configuration'
260
- puts 'passed'
261
-
262
- printf '%-50s', 'Loading native library... '
263
183
  require 'tcell_agent/rust/native_library'
264
184
  unless TCellAgent::Rust::NativeLibrary.common_lib_available?
265
- puts 'failed'
266
- Kernel.exit(1)
267
- end
268
- puts 'passed'
269
-
270
- printf '%-50s', 'Make test API call for policies... '
271
- require 'tcell_agent/rust/native_agent'
272
- errors = TCellAgent::Rust::NativeAgent.test_policies
273
- if !errors.empty?
274
- puts 'failed'
275
- puts errors
276
- Kernel.exit(1)
277
- else
278
- puts 'passed'
185
+ puts '[ERROR] Native Library is unavailable'
186
+ return
279
187
  end
280
188
 
281
- printf '%-50s', 'Sending a Test event... '
282
- require 'tcell_agent/logger'
283
- require 'tcell_agent/sensor_events/server_agent'
284
- errors = TCellAgent::Rust::NativeAgent.test_event_sender(
285
- [
286
- TCellAgent::SensorEvents::ServerAgentDetailsLanguageEvent.new(
287
- 'Ruby',
288
- RUBY_VERSION
289
- )
290
- ]
189
+ puts "tCell Ruby Agent Version #{TCellAgent::VERSION}"
190
+ TCellAgent::Rust::NativeAgent.test_agent(
191
+ TCellAgent.initializer_configuration ||
192
+ TCellAgent.configuration
291
193
  )
292
- if !errors.empty?
293
- puts 'failed'
294
- puts errors
295
- Kernel.exit(1)
296
- else
297
- puts 'passed'
298
- end
299
-
300
- puts
301
- puts 'all tests passed, looks good.'
302
- puts 'done.'
303
194
  end
@@ -24,93 +24,128 @@ module TCellAgent
24
24
  include TCellAgent::ModuleLoggerAccess
25
25
 
26
26
  attr_accessor :route_table,
27
- :stop_agent,
28
- :safe_to_check_cmdi
27
+ :stop_agent
29
28
 
30
29
  def initialize
31
30
  @stop_agent = false
32
31
  @native_agent = nil
33
32
  @route_table = TCellAgent::Routes::RouteTable.new
34
- @safe_to_check_cmdi = false
35
33
  @policies_manager = PoliciesManager.new(nil)
36
34
  end
37
35
 
38
- def validate_config
39
- if TCellAgent::Utils::Strings.blank?(TCellAgent.configuration.api_key) ||
40
- TCellAgent::Utils::Strings.blank?(TCellAgent.configuration.app_id) ||
41
- TCellAgent::Utils::Strings.blank?(TCellAgent.configuration.tcell_input_url) ||
42
- TCellAgent::Utils::Strings.blank?(TCellAgent.configuration.tcell_api_url)
43
- puts ' ********* ********* ********* *********'
44
- puts '* tCell.io *'
45
- puts '* Configuration info is missing, you may *'
46
- puts '* need to download config file and place *'
47
- puts '* it in the config/ directory *'
48
- puts ' ********* ********* ********* *********'
49
- TCellAgent.configuration.enabled = false
36
+ def instrument_auth_frameworks
37
+ if defined?(Devise) && TCellAgent.configuration.should_instrument?('devise')
38
+ module_logger.info('Instrumenting Devise authentication framework')
39
+ require 'tcell_agent/rails/auth/devise'
40
+ require 'tcell_agent/rails/auth/devise_helper'
41
+ end
42
+
43
+ if defined?(Authlogic) && TCellAgent.configuration.should_instrument?('authlogic')
44
+ module_logger.info('Instrumenting Authlogic authentication framework')
45
+ require 'tcell_agent/rails/auth/authlogic'
46
+ require 'tcell_agent/rails/auth/authlogic_helper'
47
+ end
48
+
49
+ if defined?(Doorkeeper) && TCellAgent.configuration.should_instrument?('doorkeeper') # rubocop:disable Style/GuardClause
50
+ module_logger.info('Instrumenting Doorkeeper authentication framework')
51
+ require 'tcell_agent/rails/auth/doorkeeper'
50
52
  end
51
53
  end
52
54
 
53
- def start(server_name)
54
- TCellAgent.thread_agent.validate_config
55
- return unless TCellAgent.configuration.should_instrument?
55
+ def instrument_built_ins
56
+ require 'tcell_agent/instrumentation/cmdi'
57
+ require 'tcell_agent/instrumentation/lfi'
56
58
 
57
- @native_agent = TCellAgent::Rust::NativeAgent.create_agent(
58
- TCellAgent.configuration
59
- )
60
- if @native_agent.nil?
61
- TCellAgent.configuration.enabled = false
62
- return
59
+ variant = if RUBY_VERSION.start_with?('3')
60
+ 'ruby_3'
61
+ else
62
+ 'ruby_2'
63
+ end
64
+
65
+ if TCellAgent.configuration.should_instrument?('io')
66
+ module_logger.info('Instrumenting Ruby Class: IO')
67
+ require "tcell_agent/instrumentation/monkey_patches/#{variant}/io"
68
+ end
69
+
70
+ if TCellAgent.configuration.should_instrument?('file')
71
+ module_logger.info('Instrumenting Ruby Class: File')
72
+ require "tcell_agent/instrumentation/monkey_patches/#{variant}/file"
73
+ end
74
+
75
+ if TCellAgent.configuration.should_instrument?('kernel') # rubocop:disable Style/GuardClause
76
+ module_logger.info('Instrumenting Ruby Module: Kernel')
77
+ require "tcell_agent/instrumentation/monkey_patches/#{variant}/kernel"
63
78
  end
79
+ end
64
80
 
65
- TCellAgent.native_agent = @native_agent
81
+ def manage_policies
66
82
  @policies_manager = PoliciesManager.new(@native_agent)
67
- # if preload_policy_filename is used and policy polling is
68
- # disabled, need to call poll policies to make sure
69
- # ruby policies are in sync with native agent enablements
70
- result = @native_agent.poll_new_policies
83
+
84
+ result = {}
85
+ unless TCellAgent.configuration.should_start_policy_poll?
86
+ result = @native_agent.poll_new_policies
87
+ end
88
+
71
89
  policies_and_enablements = result['new_policies_and_enablements'] || {}
90
+
72
91
  @policies_manager.process_policy_json(
73
92
  policies_and_enablements['enablements'],
74
93
  policies_and_enablements['policies']
75
94
  )
76
95
 
77
96
  @policy_polling = PolicyPolling.new(@policies_manager, @native_agent)
78
-
79
- module_logger.info("Starting thread agent: #{server_name}")
80
-
81
- @safe_to_check_cmdi = true
82
-
83
- TCellAgent.report_settings
84
- TCellAgent::Instrumentation::Rails.send_framework_info
85
- TCellAgent::Instrumentation::Rails.send_settings
86
- rescue StandardError => standard_error
87
- TCellAgent.configuration.enabled = false
88
- module_logger.error("Error starting agent: (#{standard_error.class}) #{standard_error.message}")
89
- module_logger.exception(standard_error)
90
97
  end
91
98
 
92
99
  def policies
93
100
  @policies_manager.policies
94
101
  end
95
102
 
103
+ def queue_sensor_event(event)
104
+ return unless @native_agent
105
+
106
+ @native_agent.send_sanitized_events(
107
+ [event]
108
+ )
109
+ rescue StandardError => e
110
+ module_logger.error("Error sending event: (#{e.class}) #{e.message}")
111
+ module_logger.exception(e)
112
+ end
113
+
96
114
  def report_metrics(request_time, tcell_context)
97
115
  @native_agent.report_metrics(
98
116
  request_time, tcell_context
99
117
  )
100
- rescue StandardError => standard_error
101
- module_logger.error("Error reporting metric: (#{standard_error.class}) #{standard_error.message}")
102
- module_logger.exception(standard_error)
118
+ rescue StandardError => e
119
+ module_logger.error("Error reporting metric: (#{e.class}) #{e.message}")
120
+ module_logger.exception(e)
103
121
  end
104
122
 
105
- def queue_sensor_event(event)
106
- return unless @native_agent
107
-
108
- @native_agent.send_sanitized_events(
109
- [event]
123
+ def start(server_name)
124
+ @native_agent = TCellAgent::Rust::NativeAgent.create_agent(
125
+ TCellAgent.initializer_configuration ||
126
+ TCellAgent.configuration
110
127
  )
111
- rescue StandardError => standard_error
112
- module_logger.error("Error sending event: (#{standard_error.class}) #{standard_error.message}")
113
- module_logger.exception(standard_error)
128
+
129
+ if @native_agent.nil?
130
+ TCellAgent.configuration.enabled = false
131
+ return
132
+ end
133
+
134
+ TCellAgent.native_logger = @native_agent
135
+
136
+ module_logger.info('Rails initializer overriding default agent configuration') unless TCellAgent.initializer_configuration.nil?
137
+
138
+ instrument_auth_frameworks
139
+ instrument_built_ins
140
+ manage_policies
141
+
142
+ module_logger.info("Started thread agent: #{server_name}")
143
+ TCellAgent.report_settings
144
+ TCellAgent::Instrumentation::Rails.send_settings
145
+ rescue StandardError => e
146
+ TCellAgent.configuration.enabled = false
147
+ module_logger.error("Error starting agent: (#{e.class}) #{e.message}")
148
+ module_logger.exception(e)
114
149
  end
115
150
  end
116
151
  end
@@ -0,0 +1,63 @@
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
+ :proxy_url, :proxy_username, :proxy_password
14
+
15
+ attr_reader :logging_options
16
+
17
+ # Ruby only config
18
+ attr_accessor :disable_all, :enabled, :enable_event_manager,
19
+ :enable_policy_polling,
20
+ :data_exposure
21
+
22
+ attr_reader :instrument_for_events,
23
+ :enable_instrumentation
24
+
25
+ # New config
26
+ attr_accessor :disabled_instrumentation, :instrument
27
+
28
+ def initialize
29
+ # ruby agent defaults
30
+ @logging_options = {}
31
+ end
32
+
33
+ def logging_options=(hash)
34
+ @logging_options = hash.each_with_object({}) do |(key, val), memo|
35
+ memo[key.to_sym] = val
36
+ end
37
+ end
38
+
39
+ # legacy config mapping
40
+ def enabled_instrumentations=(hash)
41
+ @disabled_instrumentation ||= []
42
+ hash.each do |key, val|
43
+ @disabled_instrumentation << key.to_s.strip.downcase unless TCellAgent.configuration.to_bool(val)
44
+ end
45
+ end
46
+
47
+ def agent_log_dir=(path)
48
+ @log_dir = path
49
+ end
50
+
51
+ def instrument_for_events=(bool)
52
+ @instrument = bool
53
+ end
54
+
55
+ def enable_instrumentation=(bool)
56
+ @instrument = bool
57
+ end
58
+
59
+ def enable_intercept_requests=(bool)
60
+ @disabled_instrumentation << 'intercept_requests' unless TCellAgent.configuration.to_bool(bool)
61
+ end
62
+ end
63
+ end