tcell_agent 2.3.0 → 2.4.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.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/bin/tcell_agent +6 -11
- data/lib/tcell_agent/agent.rb +18 -13
- data/lib/tcell_agent/config_initializer.rb +0 -4
- data/lib/tcell_agent/configuration.rb +4 -4
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrumentation.rb +14 -6
- data/lib/tcell_agent/instrumentation/cmdi.rb +32 -0
- data/lib/tcell_agent/instrumentation/lfi.rb +55 -9
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
- data/lib/tcell_agent/logger.rb +2 -2
- data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
- data/lib/tcell_agent/policies/headers_policy.rb +2 -2
- data/lib/tcell_agent/policies/patches_policy.rb +8 -4
- data/lib/tcell_agent/policies/policies_manager.rb +1 -0
- data/lib/tcell_agent/policies/policy_polling.rb +4 -3
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +1 -0
- data/lib/tcell_agent/rails/better_ip.rb +7 -19
- data/lib/tcell_agent/rails/dlp.rb +48 -48
- data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
- data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
- data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -5
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
- data/lib/tcell_agent/rails/routes/grape.rb +2 -1
- data/lib/tcell_agent/rails/settings_reporter.rb +0 -8
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -6
- data/lib/tcell_agent/routes/table.rb +3 -0
- data/lib/tcell_agent/rust/agent_config.rb +9 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-6.2.1.so → libtcellagent-alpine.so} +0 -0
- data/lib/tcell_agent/rust/{tcellagent-6.2.1.dll → libtcellagent-x64.dll} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-6.2.1.dylib → libtcellagent.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-6.2.1.so → libtcellagent.so} +0 -0
- data/lib/tcell_agent/rust/native_agent.rb +48 -58
- data/lib/tcell_agent/rust/native_library.rb +7 -10
- data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
- data/lib/tcell_agent/servers/puma.rb +25 -8
- data/lib/tcell_agent/servers/rack_puma_handler.rb +13 -3
- data/lib/tcell_agent/servers/webrick.rb +13 -3
- data/lib/tcell_agent/settings_reporter.rb +0 -14
- data/lib/tcell_agent/sinatra.rb +1 -0
- data/lib/tcell_agent/tcell_context.rb +15 -6
- data/lib/tcell_agent/utils/headers.rb +0 -1
- data/lib/tcell_agent/utils/strings.rb +2 -2
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/cruby_spec_helper.rb +26 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
- data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
- data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +207 -223
- data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +89 -70
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +73 -0
- data/spec/lib/tcell_agent/patches_spec.rb +2 -1
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
- data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +14 -8
- data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -16
- data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
- data/spec/spec_helper.rb +3 -1
- data/spec/support/builders.rb +2 -1
- data/spec/support/server_mocks/puma_mock.rb +4 -0
- data/spec/support/shared_spec.rb +29 -0
- data/tcell_agent.gemspec +14 -14
- metadata +23 -19
- data/Rakefile +0 -18
- data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
- data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -131
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -102
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fff25fa4bd2400f1d20a402195e1523f047165a7e1f8b5d0b268174c51060d38
|
|
4
|
+
data.tar.gz: 9db1a3680edbc8fda323cfede15dbe294637d6bfe3763566a6fe5a55986ea047
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9dd315c9a05c09aef2e12d9808b5f792fd293375efa3d2531cba22c1df78d38ee87d4d0bb284e75fee643379ebcda9069ddff22a5b3e6b0c1a04d38fff795a2a
|
|
7
|
+
data.tar.gz: 3687803fa5c02436b44e08d75ac3665bf2e9583559525aad45f743c41ef1fb195c10b5e8fef9b8fadd134f890513e590314558fd474841662e4c4e4c66a0ddd6
|
data/LICENSE
CHANGED
data/bin/tcell_agent
CHANGED
|
@@ -9,7 +9,7 @@ options = {}
|
|
|
9
9
|
def yesno(default = true)
|
|
10
10
|
begin
|
|
11
11
|
system('stty raw -echo')
|
|
12
|
-
str =
|
|
12
|
+
str = $stdin.getc
|
|
13
13
|
ensure
|
|
14
14
|
system('stty -raw echo')
|
|
15
15
|
end
|
|
@@ -33,8 +33,6 @@ global = OptionParser.new do |opts|
|
|
|
33
33
|
Kernel.exit(1)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
opts.on('test', 'Run diagnostics and test event sending') do |_v|
|
|
37
|
-
end
|
|
38
36
|
opts.separator ''
|
|
39
37
|
opts.separator subtext
|
|
40
38
|
end
|
|
@@ -53,15 +51,11 @@ subcommands = {
|
|
|
53
51
|
|
|
54
52
|
global.order!
|
|
55
53
|
command = ARGV.shift
|
|
56
|
-
deprecated_commands = %w[setup loglevel preload demomode enable disable]
|
|
57
54
|
if command.nil?
|
|
58
55
|
puts global
|
|
59
56
|
Kernel.exit(1)
|
|
60
57
|
elsif subcommands[command]
|
|
61
58
|
subcommands[command].order!
|
|
62
|
-
elsif !deprecated_commands.include?(command)
|
|
63
|
-
puts global
|
|
64
|
-
Kernel.exit(1)
|
|
65
59
|
end
|
|
66
60
|
|
|
67
61
|
if command == 'setup'
|
|
@@ -87,9 +81,9 @@ if command == 'setup'
|
|
|
87
81
|
end
|
|
88
82
|
end
|
|
89
83
|
print 'Enter your API Key (ie gAABAAAA...): '
|
|
90
|
-
api_key =
|
|
84
|
+
api_key = $stdin.gets.chomp
|
|
91
85
|
print 'Enter your App ID (ie MyApp-Fdk4j): '
|
|
92
|
-
app_id =
|
|
86
|
+
app_id = $stdin.gets.chomp
|
|
93
87
|
config_hash = {
|
|
94
88
|
'version' => 1,
|
|
95
89
|
'applications' => [
|
|
@@ -176,10 +170,11 @@ elsif command == 'demomode'
|
|
|
176
170
|
puts 'done.'
|
|
177
171
|
|
|
178
172
|
elsif command == 'test'
|
|
179
|
-
Dir[Dir.pwd
|
|
173
|
+
Dir["#{Dir.pwd}/config/initializers/*.rb"].sort.each do |f|
|
|
180
174
|
begin
|
|
181
175
|
require f
|
|
182
|
-
rescue NameError
|
|
176
|
+
rescue NameError
|
|
177
|
+
# do nothing
|
|
183
178
|
rescue StandardError => e
|
|
184
179
|
puts "[ERROR] Loading initializers failed. #{e}"
|
|
185
180
|
end
|
data/lib/tcell_agent/agent.rb
CHANGED
|
@@ -56,19 +56,25 @@ module TCellAgent
|
|
|
56
56
|
require 'tcell_agent/instrumentation/cmdi'
|
|
57
57
|
require 'tcell_agent/instrumentation/lfi'
|
|
58
58
|
|
|
59
|
+
variant = if RUBY_VERSION.start_with?('3')
|
|
60
|
+
'ruby_3'
|
|
61
|
+
else
|
|
62
|
+
'ruby_2'
|
|
63
|
+
end
|
|
64
|
+
|
|
59
65
|
if TCellAgent.configuration.should_instrument?('io')
|
|
60
66
|
module_logger.info('Instrumenting Ruby Class: IO')
|
|
61
|
-
require
|
|
67
|
+
require "tcell_agent/instrumentation/monkey_patches/#{variant}/io"
|
|
62
68
|
end
|
|
63
69
|
|
|
64
70
|
if TCellAgent.configuration.should_instrument?('file')
|
|
65
71
|
module_logger.info('Instrumenting Ruby Class: File')
|
|
66
|
-
require
|
|
72
|
+
require "tcell_agent/instrumentation/monkey_patches/#{variant}/file"
|
|
67
73
|
end
|
|
68
74
|
|
|
69
75
|
if TCellAgent.configuration.should_instrument?('kernel') # rubocop:disable Style/GuardClause
|
|
70
76
|
module_logger.info('Instrumenting Ruby Module: Kernel')
|
|
71
|
-
require
|
|
77
|
+
require "tcell_agent/instrumentation/monkey_patches/#{variant}/kernel"
|
|
72
78
|
end
|
|
73
79
|
end
|
|
74
80
|
|
|
@@ -100,18 +106,18 @@ module TCellAgent
|
|
|
100
106
|
@native_agent.send_sanitized_events(
|
|
101
107
|
[event]
|
|
102
108
|
)
|
|
103
|
-
rescue StandardError =>
|
|
104
|
-
module_logger.error("Error sending event: (#{
|
|
105
|
-
module_logger.exception(
|
|
109
|
+
rescue StandardError => e
|
|
110
|
+
module_logger.error("Error sending event: (#{e.class}) #{e.message}")
|
|
111
|
+
module_logger.exception(e)
|
|
106
112
|
end
|
|
107
113
|
|
|
108
114
|
def report_metrics(request_time, tcell_context)
|
|
109
115
|
@native_agent.report_metrics(
|
|
110
116
|
request_time, tcell_context
|
|
111
117
|
)
|
|
112
|
-
rescue StandardError =>
|
|
113
|
-
module_logger.error("Error reporting metric: (#{
|
|
114
|
-
module_logger.exception(
|
|
118
|
+
rescue StandardError => e
|
|
119
|
+
module_logger.error("Error reporting metric: (#{e.class}) #{e.message}")
|
|
120
|
+
module_logger.exception(e)
|
|
115
121
|
end
|
|
116
122
|
|
|
117
123
|
def start(server_name)
|
|
@@ -135,12 +141,11 @@ module TCellAgent
|
|
|
135
141
|
|
|
136
142
|
module_logger.info("Started thread agent: #{server_name}")
|
|
137
143
|
TCellAgent.report_settings
|
|
138
|
-
TCellAgent::Instrumentation::Rails.send_framework_info
|
|
139
144
|
TCellAgent::Instrumentation::Rails.send_settings
|
|
140
|
-
rescue StandardError =>
|
|
145
|
+
rescue StandardError => e
|
|
141
146
|
TCellAgent.configuration.enabled = false
|
|
142
|
-
module_logger.error("Error starting agent: (#{
|
|
143
|
-
module_logger.exception(
|
|
147
|
+
module_logger.error("Error starting agent: (#{e.class}) #{e.message}")
|
|
148
|
+
module_logger.exception(e)
|
|
144
149
|
end
|
|
145
150
|
end
|
|
146
151
|
end
|
|
@@ -85,7 +85,8 @@ module TCellAgent
|
|
|
85
85
|
app_data = config['applications'][0]
|
|
86
86
|
@disable_all = to_bool(app_data.fetch('disable_all', @disable_all))
|
|
87
87
|
end
|
|
88
|
-
rescue StandardError
|
|
88
|
+
rescue StandardError
|
|
89
|
+
# do nothing
|
|
89
90
|
end
|
|
90
91
|
end
|
|
91
92
|
|
|
@@ -108,9 +109,8 @@ module TCellAgent
|
|
|
108
109
|
@password_hmac_key = apps['password_hmac_key']
|
|
109
110
|
|
|
110
111
|
# proxy config
|
|
111
|
-
|
|
112
|
-
@
|
|
113
|
-
@reverse_proxy_ip_address_header = proxy_config['reverse_proxy_ip_address_header']
|
|
112
|
+
@reverse_proxy = apps['reverse_proxy']
|
|
113
|
+
@reverse_proxy_ip_address_header = apps['reverse_proxy_ip_address_header']
|
|
114
114
|
|
|
115
115
|
# endpoint config
|
|
116
116
|
endpoint = native_agent_config_response['endpoint_config'] || {}
|
|
@@ -3,7 +3,7 @@ require 'tcell_agent/agent'
|
|
|
3
3
|
module TCellAgent
|
|
4
4
|
module Hooks
|
|
5
5
|
module LoginFraud
|
|
6
|
-
#
|
|
6
|
+
# NOTE: mock out in tests
|
|
7
7
|
def self.get_logger
|
|
8
8
|
unless defined?(@login_fraud_logger)
|
|
9
9
|
@login_fraud_logger = TCellAgent::ModuleLogger.new(TCellAgent.logger, name)
|
|
@@ -65,7 +65,8 @@ module TCellAgent
|
|
|
65
65
|
:password, :route_id, :path, :uri, :fullpath, :context_filters_by_term,
|
|
66
66
|
:database_filters, :remote_address, :user_agent, :request_method,
|
|
67
67
|
:path_parameters, :patches_blocking_triggered, :grape_mount_endpoint,
|
|
68
|
-
:referrer, :csrf_exception_name, :sql_exceptions, :database_result_sizes
|
|
68
|
+
:referrer, :csrf_exception_name, :sql_exceptions, :database_result_sizes,
|
|
69
|
+
:reverse_proxy_header_value
|
|
69
70
|
|
|
70
71
|
def self.filterx(sanitize_string, event_flag, replace_flag, term)
|
|
71
72
|
send_event = false
|
|
@@ -91,26 +92,31 @@ module TCellAgent
|
|
|
91
92
|
|
|
92
93
|
def valid_term?(term)
|
|
93
94
|
return true if !term.nil? && term != '' && term.to_s.length >= 5
|
|
95
|
+
|
|
94
96
|
false
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
def add_response_db_filter(term, action_obj, database, schema, table, field)
|
|
98
100
|
return unless valid_term?(term)
|
|
101
|
+
|
|
99
102
|
context_filters_by_term[term.to_s].add(ContextFilter.new.for_database(database, schema, table, field, action_obj))
|
|
100
103
|
end
|
|
101
104
|
|
|
102
105
|
def add_filter_for_request_parameter(term, rule, parameter_name)
|
|
103
106
|
return unless valid_term?(term)
|
|
107
|
+
|
|
104
108
|
context_filters_by_term[term.to_s].add(ContextFilter.new.for_request('form', parameter_name, rule))
|
|
105
109
|
end
|
|
106
110
|
|
|
107
111
|
def add_filter_for_header_value(term, rule, header_name)
|
|
108
112
|
return unless valid_term?(term)
|
|
113
|
+
|
|
109
114
|
context_filters_by_term[term.to_s].add(ContextFilter.new.for_request('header', header_name, rule))
|
|
110
115
|
end
|
|
111
116
|
|
|
112
117
|
def add_filter_for_cookie_value(term, rule, cookie_name)
|
|
113
118
|
return unless valid_term?(term)
|
|
119
|
+
|
|
114
120
|
context_filters_by_term[term.to_s].add(ContextFilter.new.for_request('cookie', cookie_name, rule))
|
|
115
121
|
end
|
|
116
122
|
|
|
@@ -139,6 +145,7 @@ module TCellAgent
|
|
|
139
145
|
send_flag = TCellData.filterx(body, !event_filters.empty?, !replace_filters.empty?, term)
|
|
140
146
|
send_flag ||= TCellData.filterx(body, !event_filters.empty?, !replace_filters.empty?, CGI.escapeHTML(term))
|
|
141
147
|
next unless send_flag
|
|
148
|
+
|
|
142
149
|
(replace_filters + event_filters).each do |filter|
|
|
143
150
|
base_event = TCellAgent::SensorEvents::DlpEvent.new(
|
|
144
151
|
route_id,
|
|
@@ -183,6 +190,7 @@ module TCellAgent
|
|
|
183
190
|
event_filters = (context_filters.select { |context_filter| (context_filter.rule.log_redact != true && context_filter.rule.log_event == true) })
|
|
184
191
|
send_flag = TCellData.filterx(log_msg, !event_filters.empty?, !replace_filters.empty?, term)
|
|
185
192
|
next unless send_flag
|
|
193
|
+
|
|
186
194
|
(replace_filters + event_filters).each do |filter|
|
|
187
195
|
base_event = TCellAgent::SensorEvents::DlpEvent.new(
|
|
188
196
|
route_id,
|
|
@@ -213,7 +221,7 @@ module TCellAgent
|
|
|
213
221
|
end
|
|
214
222
|
end
|
|
215
223
|
|
|
216
|
-
#
|
|
224
|
+
# NOTE: mock for tests
|
|
217
225
|
def self.get_safe_block_logger
|
|
218
226
|
unless defined?(@safe_block_logger)
|
|
219
227
|
@safe_block_logger = TCellAgent::ModuleLogger.new(TCellAgent.logger, name)
|
|
@@ -224,15 +232,15 @@ module TCellAgent
|
|
|
224
232
|
|
|
225
233
|
def self.safe_block(message, &block)
|
|
226
234
|
block.call
|
|
227
|
-
rescue StandardError =>
|
|
235
|
+
rescue StandardError => e
|
|
228
236
|
logger = get_safe_block_logger
|
|
229
|
-
logger.error("Error #{message} (#{
|
|
230
|
-
logger.exception(
|
|
237
|
+
logger.error("Error #{message} (#{e.class}): #{e.message}")
|
|
238
|
+
logger.exception(e)
|
|
231
239
|
end
|
|
232
240
|
|
|
233
241
|
def self.safe_block_no_log(_message, &block)
|
|
234
242
|
block.call
|
|
235
|
-
rescue StandardError
|
|
243
|
+
rescue StandardError
|
|
236
244
|
# do nothing
|
|
237
245
|
end
|
|
238
246
|
end
|
|
@@ -56,5 +56,37 @@ module TCellAgent
|
|
|
56
56
|
|
|
57
57
|
cmd
|
|
58
58
|
end
|
|
59
|
+
|
|
60
|
+
def self.raise_if_block(cmd)
|
|
61
|
+
return unless TCellAgent::Cmdi.block_command?(cmd)
|
|
62
|
+
|
|
63
|
+
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.default_cmdi_handler(args)
|
|
67
|
+
cmd = TCellAgent::Cmdi.parse_command(*args)
|
|
68
|
+
|
|
69
|
+
raise_if_block(cmd)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.popen_cmdi_handler(args)
|
|
73
|
+
return if args.empty?
|
|
74
|
+
|
|
75
|
+
cmd = ''
|
|
76
|
+
|
|
77
|
+
TCellAgent::Instrumentation.safe_block('CMDI Parsing popen *args') do
|
|
78
|
+
args_copy = Array.new(args)
|
|
79
|
+
args_copy.shift if args_copy.first.is_a?(Hash)
|
|
80
|
+
args_copy.pop if args_copy.last.is_a?(Hash)
|
|
81
|
+
|
|
82
|
+
cmd = if args_copy.first.is_a?(String)
|
|
83
|
+
args_copy.shift
|
|
84
|
+
else
|
|
85
|
+
TCellAgent::Cmdi.parse_command(*args_copy.shift)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
raise_if_block(cmd)
|
|
90
|
+
end
|
|
59
91
|
end
|
|
60
92
|
end
|
|
@@ -5,6 +5,8 @@ require 'tcell_agent/configuration'
|
|
|
5
5
|
module TCellAgent
|
|
6
6
|
module Instrumentation
|
|
7
7
|
module Lfi
|
|
8
|
+
extend TCellAgent::ModuleLoggerAccess
|
|
9
|
+
|
|
8
10
|
def self.block_file_access?(path, mode)
|
|
9
11
|
TCellAgent::Instrumentation.safe_block('Checking Local Files Policy') do
|
|
10
12
|
if TCellAgent::Utils::Strings.present?(path)
|
|
@@ -54,17 +56,27 @@ module TCellAgent
|
|
|
54
56
|
mode = 'Read'
|
|
55
57
|
|
|
56
58
|
TCellAgent::Instrumentation.safe_block('LFI Parsing ARGF') do
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
path = argv_copy.shift
|
|
60
|
-
else
|
|
61
|
-
path = ARGF.filename
|
|
62
|
-
end
|
|
59
|
+
begin
|
|
60
|
+
return ['', ''] if ARGF.file == $stdin
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
if ARGF.eof? && !ARGV.empty?
|
|
63
|
+
argv_copy = Array.new(ARGV)
|
|
64
|
+
path = argv_copy.shift
|
|
65
|
+
else
|
|
66
|
+
path = ARGF.filename
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
if path && path.to_s[0] != '|'
|
|
70
|
+
[File.expand_path(path.to_s), mode]
|
|
71
|
+
else
|
|
72
|
+
['', '']
|
|
73
|
+
end
|
|
74
|
+
rescue Errno::ENOENT
|
|
75
|
+
module_logger.debug('LFI Parsing ARGF: attempted to read a non-existent file')
|
|
67
76
|
['', '']
|
|
77
|
+
rescue Errno::EISDIR
|
|
78
|
+
module_logger.debug('LFI Parsing ARGF: attempted to read a directory')
|
|
79
|
+
[ARGF.filename, mode]
|
|
68
80
|
end
|
|
69
81
|
end
|
|
70
82
|
end
|
|
@@ -79,6 +91,40 @@ module TCellAgent
|
|
|
79
91
|
end
|
|
80
92
|
'Read'
|
|
81
93
|
end
|
|
94
|
+
|
|
95
|
+
def self.raise_if_block(path, mode)
|
|
96
|
+
return unless block_file_access?(path, mode)
|
|
97
|
+
|
|
98
|
+
raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def self.default_open_handler(args, override_mode = '')
|
|
102
|
+
path, mode = extract_path_mode(*args)
|
|
103
|
+
|
|
104
|
+
mode = override_mode unless override_mode.empty?
|
|
105
|
+
|
|
106
|
+
raise_if_block(path, mode)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def self.argf_open_handler
|
|
110
|
+
path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
|
|
111
|
+
|
|
112
|
+
raise_if_block(path, mode)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def self.cmdi_open_handler(args, override_mode = '')
|
|
116
|
+
path, mode = extract_path_mode(*args)
|
|
117
|
+
|
|
118
|
+
mode = override_mode unless override_mode.empty?
|
|
119
|
+
|
|
120
|
+
raise_if_block(path, mode)
|
|
121
|
+
|
|
122
|
+
return unless path.empty?
|
|
123
|
+
|
|
124
|
+
cmd = TCellAgent::Cmdi.parse_command_from_open(*args)
|
|
125
|
+
|
|
126
|
+
TCellAgent::Cmdi.raise_if_block(cmd) if cmd
|
|
127
|
+
end
|
|
82
128
|
end
|
|
83
129
|
end
|
|
84
130
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class File
|
|
2
|
+
class << self
|
|
3
|
+
if TCellAgent.configuration.should_instrument?('File::new')
|
|
4
|
+
alias_method :tcell_original_new, :new
|
|
5
|
+
def new(*args, &block)
|
|
6
|
+
TCellAgent::Instrumentation::Lfi.default_open_handler(args)
|
|
7
|
+
|
|
8
|
+
tcell_original_new(*args, &block)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
if TCellAgent.configuration.should_instrument?('File::open')
|
|
13
|
+
alias_method :tcell_original_open, :open
|
|
14
|
+
def open(*args, &block)
|
|
15
|
+
TCellAgent::Instrumentation::Lfi.default_open_handler(args)
|
|
16
|
+
|
|
17
|
+
tcell_original_open(*args, &block)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
class IO
|
|
2
|
+
class << self
|
|
3
|
+
if TCellAgent.configuration.should_instrument?('IO::binread')
|
|
4
|
+
alias_method :tcell_original_binread, :binread
|
|
5
|
+
def binread(*args, &block)
|
|
6
|
+
TCellAgent::Instrumentation::Lfi.cmdi_open_handler(args)
|
|
7
|
+
|
|
8
|
+
tcell_original_binread(*args, &block)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
if TCellAgent.configuration.should_instrument?('IO::binwrite')
|
|
13
|
+
alias_method :tcell_original_binwrite, :binwrite
|
|
14
|
+
def binwrite(*args, &block)
|
|
15
|
+
TCellAgent::Instrumentation::Lfi.default_open_handler(args, 'Write')
|
|
16
|
+
|
|
17
|
+
tcell_original_binwrite(*args, &block)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if TCellAgent.configuration.should_instrument?('IO::foreach')
|
|
22
|
+
alias_method :tcell_original_foreach, :foreach
|
|
23
|
+
def foreach(*args, &block)
|
|
24
|
+
TCellAgent::Instrumentation::Lfi.default_open_handler(args, 'Read')
|
|
25
|
+
|
|
26
|
+
tcell_original_foreach(*args, &block)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if TCellAgent.configuration.should_instrument?('IO::popen')
|
|
31
|
+
alias_method :tcell_original_popen, :popen
|
|
32
|
+
def popen(*args, &block)
|
|
33
|
+
TCellAgent::Cmdi.popen_cmdi_handler(args)
|
|
34
|
+
|
|
35
|
+
tcell_original_popen(*args, &block)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if TCellAgent.configuration.should_instrument?('IO::read')
|
|
40
|
+
alias_method :tcell_original_read, :read
|
|
41
|
+
def read(*args, &block)
|
|
42
|
+
TCellAgent::Instrumentation::Lfi.cmdi_open_handler(args, 'Read')
|
|
43
|
+
|
|
44
|
+
tcell_original_read(*args, &block)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
if TCellAgent.configuration.should_instrument?('IO::readlines')
|
|
49
|
+
alias_method :tcell_original_readlines, :readlines
|
|
50
|
+
def readlines(*args, &block)
|
|
51
|
+
TCellAgent::Instrumentation::Lfi.cmdi_open_handler(args, 'Read')
|
|
52
|
+
|
|
53
|
+
tcell_original_readlines(*args, &block)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
if TCellAgent.configuration.should_instrument?('IO::sysopen')
|
|
58
|
+
alias_method :tcell_original_sysopen, :sysopen
|
|
59
|
+
def sysopen(*args, &block)
|
|
60
|
+
TCellAgent::Instrumentation::Lfi.default_open_handler(args)
|
|
61
|
+
|
|
62
|
+
tcell_original_sysopen(*args, &block)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if TCellAgent.configuration.should_instrument?('IO::write')
|
|
67
|
+
alias_method :tcell_original_write, :write
|
|
68
|
+
def write(*args, &block)
|
|
69
|
+
TCellAgent::Instrumentation::Lfi.default_open_handler(args, 'Write')
|
|
70
|
+
|
|
71
|
+
tcell_original_write(*args, &block)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|