tcell_agent 2.1.2 → 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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/bin/tcell_agent +42 -146
  3. data/lib/tcell_agent.rb +8 -16
  4. data/lib/tcell_agent/agent.rb +76 -46
  5. data/lib/tcell_agent/config_initializer.rb +66 -0
  6. data/lib/tcell_agent/configuration.rb +72 -267
  7. data/lib/tcell_agent/instrument_servers.rb +14 -16
  8. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +1 -1
  9. data/lib/tcell_agent/logger.rb +1 -2
  10. data/lib/tcell_agent/rails/auth/authlogic.rb +46 -50
  11. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  12. data/lib/tcell_agent/rails/auth/devise.rb +101 -103
  13. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  14. data/lib/tcell_agent/rails/auth/doorkeeper.rb +55 -58
  15. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  16. data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
  17. data/lib/tcell_agent/rails/dlp.rb +0 -4
  18. data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -1
  19. data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
  20. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  21. data/lib/tcell_agent/rails/routes.rb +3 -6
  22. data/lib/tcell_agent/rails/routes/grape.rb +1 -3
  23. data/lib/tcell_agent/rails/tcell_body_proxy.rb +0 -1
  24. data/lib/tcell_agent/rust/agent_config.rb +43 -32
  25. data/lib/tcell_agent/rust/{libtcellagent-4.18.0.dylib → libtcellagent-5.0.2.dylib} +0 -0
  26. data/lib/tcell_agent/rust/{libtcellagent-4.18.0.so → libtcellagent-5.0.2.so} +0 -0
  27. data/lib/tcell_agent/rust/{libtcellagent-alpine-4.18.0.so → libtcellagent-alpine-5.0.2.so} +0 -0
  28. data/lib/tcell_agent/rust/models.rb +9 -0
  29. data/lib/tcell_agent/rust/native_agent.rb +18 -0
  30. data/lib/tcell_agent/rust/native_library.rb +2 -1
  31. data/lib/tcell_agent/rust/{tcellagent-4.18.0.dll → tcellagent-5.0.2.dll} +0 -0
  32. data/lib/tcell_agent/servers/rails_server.rb +0 -1
  33. data/lib/tcell_agent/servers/unicorn.rb +1 -1
  34. data/lib/tcell_agent/servers/webrick.rb +0 -1
  35. data/lib/tcell_agent/settings_reporter.rb +0 -79
  36. data/lib/tcell_agent/version.rb +1 -1
  37. data/spec/lib/tcell_agent/configuration_spec.rb +56 -211
  38. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +2 -2
  39. data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
  40. data/spec/lib/tcell_agent/settings_reporter_spec.rb +0 -73
  41. data/spec/support/builders.rb +5 -6
  42. metadata +14 -14
  43. data/lib/tcell_agent/authlogic.rb +0 -23
  44. data/lib/tcell_agent/config/unknown_options.rb +0 -119
  45. data/lib/tcell_agent/devise.rb +0 -33
  46. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
  47. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -1,25 +1,23 @@
1
- tcell_server = ENV['TCELL_AGENT_SERVER']
1
+ # frozen_string_literal: true
2
2
 
3
- if TCellAgent.configuration.should_instrument?
4
- unless tcell_server && tcell_server == 'mock'
5
- if (tcell_server && tcell_server == 'webrick') || defined?(Rails::Server)
6
- require('tcell_agent/servers/rails_server')
3
+ tcell_server = ENV['TCELL_AGENT_SERVER']
7
4
 
8
- elsif (tcell_server && tcell_server == 'thin') || defined?(Thin)
9
- require('tcell_agent/servers/thin')
5
+ if tcell_server && tcell_server == 'mock'
6
+ TCellAgent.thread_agent.instrument_built_ins
7
+ end
10
8
 
11
- elsif (tcell_server && tcell_server == 'puma') || defined?(Puma)
12
- require('tcell_agent/servers/puma')
9
+ if (tcell_server && tcell_server == 'webrick') || defined?(Rails::Server)
10
+ require('tcell_agent/servers/rails_server')
13
11
 
14
- elsif (tcell_server && tcell_server == 'unicorn') || defined?(Unicorn)
15
- require('tcell_agent/servers/unicorn')
12
+ elsif (tcell_server && tcell_server == 'thin') || defined?(Thin)
13
+ require('tcell_agent/servers/thin')
16
14
 
17
- elsif (tcell_server && tcell_server == 'passenger') || defined?(PhusionPassenger)
18
- require('tcell_agent/servers/passenger')
19
- end
20
- end
15
+ elsif (tcell_server && tcell_server == 'puma') || defined?(Puma)
16
+ require('tcell_agent/servers/puma')
21
17
 
22
18
  elsif (tcell_server && tcell_server == 'unicorn') || defined?(Unicorn)
23
- # unicorn is always instrumented to support rolling restarts
24
19
  require('tcell_agent/servers/unicorn')
20
+
21
+ elsif (tcell_server && tcell_server == 'passenger') || defined?(PhusionPassenger)
22
+ require('tcell_agent/servers/passenger')
25
23
  end
@@ -26,7 +26,7 @@ module Kernel
26
26
  tcell_original_backtick(cmd)
27
27
  end
28
28
 
29
- if TCellAgent.configuration.should_instrument_cmdi_exec?
29
+ if TCellAgent.configuration.should_instrument?('kernel_exec')
30
30
  def exec(*args)
31
31
  cmd = TCellAgent::Cmdi.parse_command(*args)
32
32
  if TCellAgent::Cmdi.block_command?(cmd)
@@ -14,7 +14,6 @@ module TCellAgent
14
14
  def initialize(logger, module_name)
15
15
  @logger = logger
16
16
  @module_name = module_name
17
- @module_name = "#{TCellAgent.configuration.log_tag} #{module_name}" if TCellAgent.configuration.log_tag
18
17
  end
19
18
 
20
19
  %i[exception debug info warn error].each do |method_name|
@@ -80,7 +79,7 @@ module TCellAgent
80
79
  @native_logger
81
80
  end
82
81
 
83
- def self.native_agent=(native_agent)
82
+ def self.native_logger=(native_agent)
84
83
  @native_logger = NativeLogger.new(native_agent)
85
84
  end
86
85
  end
@@ -1,56 +1,52 @@
1
- if TCellAgent.configuration.should_instrument_authlogic? && defined?(Authlogic)
2
-
3
- require 'tcell_agent/configuration'
4
- require 'tcell_agent/instrumentation'
5
-
6
- module TCellAgent
7
- require 'tcell_agent/agent'
8
-
9
- Authlogic::Session::Base.class_eval do
10
- alias_method :tcell_save, :save
11
- def save(&block)
12
- return tcell_save(&block) unless TCellAgent.configuration.should_intercept_requests?
13
-
14
- user_logged_in_before = !user.nil?
15
- success = tcell_save(&block)
16
- user_logged_in_after = !user.nil?
17
-
18
- TCellAgent::Instrumentation.safe_block('Authlogic login info') do
19
- user_id = nil
20
- password = nil
21
- user_valid = nil
22
- TCellAgent::Instrumentation.safe_block('getting userid for login form') do
23
- user_id = send(self.class.login_field.to_sym)
24
- end
25
-
26
- request = Authlogic::Session::Base.controller.request
27
- tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
28
-
29
- return success unless tcell_data
30
-
31
- login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
32
- if user_logged_in_before && user_logged_in_after
33
- # password changed or logged in as another user
34
- elsif !user_logged_in_before && !user_logged_in_after
35
- login_policy.report_login_failure(
36
- user_id,
37
- password,
38
- request.env,
39
- user_valid,
40
- tcell_data
41
- )
42
- elsif !user_logged_in_before && user_logged_in_after
43
- login_policy.report_login_success(
44
- user_id,
45
- request.env,
46
- tcell_data
47
- )
48
- end
1
+ require 'tcell_agent/configuration'
2
+ require 'tcell_agent/instrumentation'
3
+
4
+ module TCellAgent
5
+ require 'tcell_agent/agent'
6
+
7
+ Authlogic::Session::Base.class_eval do
8
+ alias_method :tcell_save, :save
9
+ def save(&block)
10
+ return tcell_save(&block) unless TCellAgent.configuration.should_intercept_requests?
11
+
12
+ user_logged_in_before = !user.nil?
13
+ success = tcell_save(&block)
14
+ user_logged_in_after = !user.nil?
15
+
16
+ TCellAgent::Instrumentation.safe_block('Authlogic login info') do
17
+ user_id = nil
18
+ password = nil
19
+ user_valid = nil
20
+ TCellAgent::Instrumentation.safe_block('getting userid for login form') do
21
+ user_id = send(self.class.login_field.to_sym)
49
22
  end
50
23
 
51
- success
24
+ request = Authlogic::Session::Base.controller.request
25
+ tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
26
+
27
+ return success unless tcell_data
28
+
29
+ login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
30
+ if user_logged_in_before && user_logged_in_after
31
+ # password changed or logged in as another user
32
+ elsif !user_logged_in_before && !user_logged_in_after
33
+ login_policy.report_login_failure(
34
+ user_id,
35
+ password,
36
+ request.env,
37
+ user_valid,
38
+ tcell_data
39
+ )
40
+ elsif !user_logged_in_before && user_logged_in_after
41
+ login_policy.report_login_success(
42
+ user_id,
43
+ request.env,
44
+ tcell_data
45
+ )
46
+ end
52
47
  end
48
+
49
+ success
53
50
  end
54
51
  end
55
-
56
52
  end
@@ -0,0 +1,20 @@
1
+ require 'tcell_agent/rails/auth/userinfo'
2
+
3
+ module TCellAgent
4
+ TCellAgent::UserInformation.class_eval do
5
+ class << self
6
+ alias_method :original_get_user_from_request, :get_user_from_request
7
+ def get_user_from_request(request)
8
+ orig_user_id = original_get_user_from_request(request)
9
+ begin
10
+ if request.session && request.session.key?('user_credentials_id')
11
+ return request.session['user_credentials_id'].to_s
12
+ end
13
+ rescue StandardError
14
+ return orig_user_id
15
+ end
16
+ orig_user_id
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,127 +1,125 @@
1
- if TCellAgent.configuration.should_instrument_devise? && defined?(Devise)
2
- module TCellAgent
3
- require 'base64'
4
- require 'tcell_agent/agent'
5
-
6
- module DeviseInstrumentation
7
- module TCellFailureAppRespond
8
- def respond
9
- TCellAgent::Instrumentation.safe_block('Devise Failure App Respond') do
10
- if TCellAgent.configuration.should_intercept_requests?
11
- tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
12
- if tcell_data
13
- # in the case of http auth, user_id is set in
14
- # Devise::Strategies::Authenticatable.valid_for_http_auth?
15
- user_id = tcell_data.user_id
16
- user_id ||= _get_tcell_username
17
-
18
- # in the case of http auth, password is set in
19
- # Devise::Strategies::Authenticatable.valid_for_http_auth?
20
- password = tcell_data.password
21
- password ||= _get_tcell_password
22
-
23
- user_valid = nil
24
- login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
25
- login_policy.report_login_failure(
26
- user_id,
27
- password,
28
- request.env,
29
- user_valid,
30
- tcell_data
31
- )
32
- end
1
+ module TCellAgent
2
+ require 'base64'
3
+ require 'tcell_agent/agent'
4
+
5
+ module DeviseInstrumentation
6
+ module TCellFailureAppRespond
7
+ def respond
8
+ TCellAgent::Instrumentation.safe_block('Devise Failure App Respond') do
9
+ if TCellAgent.configuration.should_intercept_requests?
10
+ tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
11
+ if tcell_data
12
+ # in the case of http auth, user_id is set in
13
+ # Devise::Strategies::Authenticatable.valid_for_http_auth?
14
+ user_id = tcell_data.user_id
15
+ user_id ||= _get_tcell_username
16
+
17
+ # in the case of http auth, password is set in
18
+ # Devise::Strategies::Authenticatable.valid_for_http_auth?
19
+ password = tcell_data.password
20
+ password ||= _get_tcell_password
21
+
22
+ user_valid = nil
23
+ login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
24
+ login_policy.report_login_failure(
25
+ user_id,
26
+ password,
27
+ request.env,
28
+ user_valid,
29
+ tcell_data
30
+ )
33
31
  end
34
32
  end
35
-
36
- super if defined?(super)
37
33
  end
38
34
 
39
- def _get_tcell_username
40
- tcell_username = nil
41
- TCellAgent::Instrumentation.safe_block('Devise Get TCell Username') do
42
- keys = scope_class.authentication_keys.dup
43
- user_params = request.POST.fetch('user', {})
44
- keys.each do |key|
45
- next_usename = user_params.fetch(key, nil)
46
- if next_usename
47
- tcell_username ||= ''
48
- tcell_username += next_usename
49
- end
35
+ super if defined?(super)
36
+ end
37
+
38
+ def _get_tcell_username
39
+ tcell_username = nil
40
+ TCellAgent::Instrumentation.safe_block('Devise Get TCell Username') do
41
+ keys = scope_class.authentication_keys.dup
42
+ user_params = request.POST.fetch('user', {})
43
+ keys.each do |key|
44
+ next_usename = user_params.fetch(key, nil)
45
+ if next_usename
46
+ tcell_username ||= ''
47
+ tcell_username += next_usename
50
48
  end
51
49
  end
52
- tcell_username
53
50
  end
51
+ tcell_username
52
+ end
54
53
 
55
- def _get_tcell_password
56
- tcell_password = nil
57
- TCellAgent::Instrumentation.safe_block('Devise Get TCell Password') do
58
- user_params = request.POST.fetch('user', {})
59
- tcell_password = user_params['password']
60
- end
61
- tcell_password
54
+ def _get_tcell_password
55
+ tcell_password = nil
56
+ TCellAgent::Instrumentation.safe_block('Devise Get TCell Password') do
57
+ user_params = request.POST.fetch('user', {})
58
+ tcell_password = user_params['password']
62
59
  end
60
+ tcell_password
63
61
  end
64
62
  end
63
+ end
65
64
 
66
- # prepend is ruby 2+ feature
67
- Devise::FailureApp.send(:prepend, DeviseInstrumentation::TCellFailureAppRespond)
68
-
69
- Devise::Strategies::Authenticatable.class_eval do
70
- alias_method :tcell_valid_for_http_auth?, :valid_for_http_auth?
71
- def valid_for_http_auth?
72
- is_valid = tcell_valid_for_http_auth?
73
-
74
- TCellAgent::Instrumentation.safe_block('Devise set username for http basic auth') do
75
- tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
76
- if http_auth_hash && tcell_data
77
- username = http_auth_hash[http_authentication_key]
78
- password = http_auth_hash[:password]
79
- tcell_data.user_id = username if username && !tcell_data.user_id
80
- tcell_data.password = password if password && !tcell_data.password
81
- end
65
+ # prepend is ruby 2+ feature
66
+ Devise::FailureApp.send(:prepend, DeviseInstrumentation::TCellFailureAppRespond)
67
+
68
+ Devise::Strategies::Authenticatable.class_eval do
69
+ alias_method :tcell_valid_for_http_auth?, :valid_for_http_auth?
70
+ def valid_for_http_auth?
71
+ is_valid = tcell_valid_for_http_auth?
72
+
73
+ TCellAgent::Instrumentation.safe_block('Devise set username for http basic auth') do
74
+ tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
75
+ if http_auth_hash && tcell_data
76
+ username = http_auth_hash[http_authentication_key]
77
+ password = http_auth_hash[:password]
78
+ tcell_data.user_id = username if username && !tcell_data.user_id
79
+ tcell_data.password = password if password && !tcell_data.password
82
80
  end
83
-
84
- is_valid
85
81
  end
86
82
 
87
- alias_method :tcell_validate, :validate
88
- def validate(resource, &block)
89
- is_valid = tcell_validate(resource, &block)
90
- send_event = is_valid
83
+ is_valid
84
+ end
91
85
 
92
- # gets the first entry in the current backtrace
93
- # syntax suggested by rubocop to improve performance
94
- if caller(1..1).first.include? 'two_factor_authenticatable'
95
- TCellAgent.logger.debug('Not sending login success event for Devise::Strategies::TwoFactorAuthenticatable since 2fa is unsupported', 'TCellAgent::DeviseInstrumentation')
96
- send_event = false
97
- end
86
+ alias_method :tcell_validate, :validate
87
+ def validate(resource, &block)
88
+ is_valid = tcell_validate(resource, &block)
89
+ send_event = is_valid
98
90
 
99
- TCellAgent::Instrumentation.safe_block('Devise Authenticatable Validate') do
100
- if send_event && TCellAgent.configuration.enabled &&
101
- TCellAgent.configuration.should_intercept_requests?
102
- username = nil
103
- (authentication_keys || []).each do |auth_key|
104
- attr = authentication_hash[auth_key]
105
- if attr
106
- username ||= ''
107
- username += attr
108
- end
109
- end
91
+ # gets the first entry in the current backtrace
92
+ # syntax suggested by rubocop to improve performance
93
+ if caller(1..1).first.include? 'two_factor_authenticatable'
94
+ TCellAgent.logger.debug('Not sending login success event for Devise::Strategies::TwoFactorAuthenticatable since 2fa is unsupported', 'TCellAgent::DeviseInstrumentation')
95
+ send_event = false
96
+ end
110
97
 
111
- tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
112
- return is_valid unless tcell_data
113
-
114
- login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
115
- login_policy.report_login_success(
116
- username,
117
- request.env,
118
- tcell_data
119
- )
98
+ TCellAgent::Instrumentation.safe_block('Devise Authenticatable Validate') do
99
+ if send_event && TCellAgent.configuration.enabled &&
100
+ TCellAgent.configuration.should_intercept_requests?
101
+ username = nil
102
+ (authentication_keys || []).each do |auth_key|
103
+ attr = authentication_hash[auth_key]
104
+ if attr
105
+ username ||= ''
106
+ username += attr
107
+ end
120
108
  end
121
- end
122
109
 
123
- is_valid
110
+ tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
111
+ return is_valid unless tcell_data
112
+
113
+ login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
114
+ login_policy.report_login_success(
115
+ username,
116
+ request.env,
117
+ tcell_data
118
+ )
119
+ end
124
120
  end
121
+
122
+ is_valid
125
123
  end
126
124
  end
127
125
  end
@@ -0,0 +1,29 @@
1
+ require 'devise'
2
+ require 'devise/rails'
3
+ require 'devise/strategies/database_authenticatable'
4
+ require 'tcell_agent/rails/auth/userinfo'
5
+
6
+ module TCellAgent
7
+ TCellAgent::UserInformation.class_eval do
8
+ class << self
9
+ alias_method :original_get_user_from_request, :get_user_from_request
10
+ def get_user_from_request(request)
11
+ orig_user_id = original_get_user_from_request(request)
12
+ begin
13
+ if request.session && request.session.key?('warden.user.user.key')
14
+ userkey = request.session['warden.user.user.key']
15
+ user_id = if userkey.length == 2
16
+ userkey[0][0]
17
+ else
18
+ userkey[1][0]
19
+ end
20
+ return user_id.to_s if user_id.is_a? Integer
21
+ end
22
+ rescue StandardError
23
+ return orig_user_id
24
+ end
25
+ orig_user_id
26
+ end
27
+ end
28
+ end
29
+ end