tcell_agent 1.1.3 → 1.1.4
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/bin/tcell_agent +10 -2
- data/lib/tcell_agent.rb +3 -3
- data/lib/tcell_agent/agent.rb +42 -52
- data/lib/tcell_agent/agent/event_processor.rb +129 -162
- data/lib/tcell_agent/agent/fork_pipe_manager.rb +57 -62
- data/lib/tcell_agent/agent/policy_manager.rb +83 -104
- data/lib/tcell_agent/agent/policy_types.rb +24 -29
- data/lib/tcell_agent/agent/route_manager.rb +36 -46
- data/lib/tcell_agent/agent/static_agent.rb +19 -21
- data/lib/tcell_agent/api.rb +23 -28
- data/lib/tcell_agent/appsensor/injections_reporter.rb +7 -11
- data/lib/tcell_agent/authlogic.rb +7 -7
- data/lib/tcell_agent/cmdi.rb +22 -23
- data/lib/tcell_agent/config/unknown_options.rb +71 -69
- data/lib/tcell_agent/configuration.rb +187 -191
- data/lib/tcell_agent/devise.rb +13 -15
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrumentation.rb +120 -124
- data/lib/tcell_agent/logger.rb +29 -45
- data/lib/tcell_agent/patches.rb +5 -5
- data/lib/tcell_agent/policies/dataloss_policy.rb +263 -288
- data/lib/tcell_agent/policies/http_redirect_policy.rb +25 -37
- data/lib/tcell_agent/policies/http_tx_policy.rb +48 -52
- data/lib/tcell_agent/policies/login_fraud_policy.rb +15 -20
- data/lib/tcell_agent/policies/policy.rb +0 -2
- data/lib/tcell_agent/policies/rust_policies.rb +24 -29
- data/lib/tcell_agent/rails.rb +2 -3
- data/lib/tcell_agent/rails/auth/authlogic.rb +2 -2
- data/lib/tcell_agent/rails/auth/devise.rb +2 -2
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +2 -2
- data/lib/tcell_agent/rails/better_ip.rb +12 -16
- data/lib/tcell_agent/rails/csrf_exception.rb +4 -7
- data/lib/tcell_agent/rails/dlp.rb +208 -107
- data/lib/tcell_agent/rails/dlp/process_request.rb +37 -47
- data/lib/tcell_agent/rails/dlp_handler.rb +9 -11
- data/lib/tcell_agent/rails/js_agent_insert.rb +11 -14
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +8 -7
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +4 -5
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +5 -8
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +24 -27
- data/lib/tcell_agent/rails/on_start.rb +5 -5
- data/lib/tcell_agent/rails/responses.rb +7 -9
- data/lib/tcell_agent/rails/routes.rb +62 -81
- data/lib/tcell_agent/rails/routes/grape.rb +25 -30
- data/lib/tcell_agent/rails/routes/route_id.rb +9 -14
- data/lib/tcell_agent/rails/settings_reporter.rb +44 -33
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +15 -18
- data/lib/tcell_agent/routes/table.rb +31 -33
- data/lib/tcell_agent/rust/{libtcellagent-1.3.0.dylib → libtcellagent-1.3.1.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-1.3.0.so → libtcellagent-1.3.1.so} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.0.so → libtcellagent-alpine-1.3.1.so} +0 -0
- data/lib/tcell_agent/rust/models.rb +32 -37
- data/lib/tcell_agent/rust/tcellagent-1.3.1.dll +0 -0
- data/lib/tcell_agent/rust/whisperer.rb +101 -104
- data/lib/tcell_agent/sensor_events/app_config.rb +7 -7
- data/lib/tcell_agent/sensor_events/appsensor_event.rb +26 -27
- data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +20 -88
- data/lib/tcell_agent/sensor_events/command_injection.rb +52 -80
- data/lib/tcell_agent/sensor_events/discovery.rb +27 -27
- data/lib/tcell_agent/sensor_events/dlp.rb +50 -56
- data/lib/tcell_agent/sensor_events/honeytokens.rb +9 -9
- data/lib/tcell_agent/sensor_events/metrics.rb +20 -21
- data/lib/tcell_agent/sensor_events/patches.rb +10 -12
- data/lib/tcell_agent/sensor_events/sensor.rb +32 -36
- data/lib/tcell_agent/sensor_events/server_agent.rb +130 -127
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +60 -80
- data/lib/tcell_agent/sensor_events/util/utils.rb +3 -5
- data/lib/tcell_agent/servers/passenger.rb +5 -9
- data/lib/tcell_agent/servers/puma.rb +18 -27
- data/lib/tcell_agent/servers/rails_server.rb +5 -9
- data/lib/tcell_agent/servers/thin.rb +2 -4
- data/lib/tcell_agent/servers/unicorn.rb +18 -27
- data/lib/tcell_agent/servers/webrick.rb +2 -4
- data/lib/tcell_agent/settings_reporter.rb +126 -0
- data/lib/tcell_agent/sinatra.rb +24 -26
- data/lib/tcell_agent/start_background_thread.rb +21 -142
- data/lib/tcell_agent/system_info.rb +4 -3
- data/lib/tcell_agent/tcell_context.rb +150 -0
- data/lib/tcell_agent/userinfo.rb +3 -3
- data/lib/tcell_agent/utils/io.rb +19 -24
- data/lib/tcell_agent/utils/params.rb +9 -15
- data/lib/tcell_agent/utils/queue_with_timeout.rb +26 -32
- data/lib/tcell_agent/utils/strings.rb +4 -6
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +5 -5
- data/spec/lib/tcell_agent/agent/static_agent_spec.rb +7 -7
- data/spec/lib/tcell_agent/cmdi_spec.rb +21 -21
- data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +29 -24
- data/spec/lib/tcell_agent/instrumentation_spec.rb +4 -4
- data/spec/lib/tcell_agent/patches_spec.rb +8 -8
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +23 -23
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +2 -2
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +69 -0
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +1039 -0
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +271 -0
- data/spec/lib/tcell_agent/rails/logger_spec.rb +5 -5
- data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +3 -3
- data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +4 -4
- data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +5 -5
- data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +1 -1
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +11 -8
- data/spec/lib/tcell_agent/rails/responses_spec.rb +2 -2
- data/spec/lib/tcell_agent/rails/routes/grape_spec.rb +2 -2
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +1 -1
- data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +4 -4
- data/spec/lib/tcell_agent/rust/models_spec.rb +83 -75
- data/spec/lib/tcell_agent/rust/whisperer_spec.rb +14 -14
- data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +19 -70
- data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +1 -1
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +162 -0
- data/spec/lib/tcell_agent/tcell_context_spec.rb +154 -0
- data/spec/spec_helper.rb +5 -0
- metadata +18 -10
- data/lib/tcell_agent/appsensor/meta_data.rb +0 -132
- data/lib/tcell_agent/patches/meta_data.rb +0 -59
- data/lib/tcell_agent/rust/tcellagent-1.3.0.dll +0 -0
- data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +0 -71
@@ -1,29 +1,24 @@
|
|
1
1
|
module TCellAgent
|
2
2
|
module Instrumentation
|
3
3
|
module RouteId
|
4
|
-
|
5
4
|
def self.update_context(env, parameters, route)
|
6
5
|
tcell_context = env[TCellAgent::Instrumentation::TCELL_ID]
|
7
6
|
|
8
|
-
|
9
|
-
tcell_context.path_parameters = parameters
|
7
|
+
return unless route && tcell_context
|
10
8
|
|
11
|
-
|
9
|
+
tcell_context.path_parameters = parameters
|
10
|
+
route_path = route.path.spec.to_s
|
11
|
+
grape_mount_endpoint = nil
|
12
12
|
|
13
|
-
|
14
|
-
if TCellAgent::Instrumentation::grape_route?(route)
|
15
|
-
grape_mount_endpoint = route_path
|
16
|
-
end
|
13
|
+
grape_mount_endpoint = route_path if TCellAgent::Instrumentation.grape_route?(route)
|
17
14
|
|
18
|
-
|
19
|
-
|
15
|
+
if grape_mount_endpoint
|
16
|
+
tcell_context.grape_mount_endpoint = grape_mount_endpoint
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
end
|
18
|
+
else
|
19
|
+
tcell_context.route_id = TCellAgent::SensorEvents::Util.calculate_route_id(tcell_context.request_method, route_path)
|
24
20
|
end
|
25
21
|
end
|
26
|
-
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
@@ -8,43 +8,54 @@ module TCellAgent
|
|
8
8
|
module Instrumentation
|
9
9
|
module Rails
|
10
10
|
def self.send_framework_info
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
return unless TCellAgent.configuration.exp_config_settings
|
12
|
+
|
13
|
+
TCellAgent.send_event(
|
14
|
+
TCellAgent::SensorEvents::ServerAgentAppFrameworkEvent.new(
|
15
|
+
'Rails', ::Rails.version
|
16
|
+
)
|
17
|
+
)
|
17
18
|
end
|
19
|
+
|
18
20
|
def self.send_language_info
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
return unless TCellAgent.configuration.exp_config_settings
|
22
|
+
|
23
|
+
language = TCellAgent::SystemInfo.get_language
|
24
|
+
language_version = TCellAgent::SystemInfo.get_language_version
|
25
|
+
TCellAgent.send_event(
|
26
|
+
TCellAgent::SensorEvents::ServerAgentDetailsLanguageEvent.new(
|
27
|
+
language, language_version
|
28
|
+
)
|
29
|
+
)
|
26
30
|
end
|
31
|
+
|
27
32
|
def self.send_settings(application)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
33
|
+
return unless TCellAgent.configuration.exp_config_settings
|
34
|
+
|
35
|
+
# Defaults to true
|
36
|
+
csrf_protection = application.config.action_controller.allow_forgery_protection || true
|
37
|
+
TCellAgent.send_event(
|
38
|
+
TCellAgent::SensorEvents::AppConfigSettingEvent.new(
|
39
|
+
'Rails', 'core', '', 'csrf_protection', csrf_protection
|
40
|
+
)
|
41
|
+
)
|
42
|
+
|
43
|
+
# Defaults to false if nil
|
44
|
+
mass_assignment_allowed = application.config.action_controller.permit_all_parameters || false
|
45
|
+
TCellAgent.send_event(
|
46
|
+
TCellAgent::SensorEvents::AppConfigSettingEvent.new(
|
47
|
+
'Rails', 'core', '', 'mass_assignment_allowed', mass_assignment_allowed
|
48
|
+
)
|
49
|
+
)
|
50
|
+
|
51
|
+
# Defaults to never
|
52
|
+
session_expire = application.config.session_options[:expire_after] || -1
|
53
|
+
TCellAgent.send_event(
|
54
|
+
TCellAgent::SensorEvents::AppConfigSettingEvent.new(
|
55
|
+
'Rails', 'session', '', 'timeout', session_expire
|
56
|
+
)
|
57
|
+
)
|
47
58
|
end
|
48
59
|
end
|
49
60
|
end
|
50
|
-
end
|
61
|
+
end
|
@@ -3,10 +3,8 @@ require 'tcell_agent/instrumentation'
|
|
3
3
|
module TCellAgent
|
4
4
|
module Instrumentation
|
5
5
|
module Rails
|
6
|
-
|
7
6
|
class TCellBodyProxy
|
8
|
-
|
9
|
-
attr_accessor :appsensor_meta
|
7
|
+
attr_accessor :appsensor_meta_event
|
10
8
|
|
11
9
|
# for specs
|
12
10
|
attr_accessor :content_length
|
@@ -30,47 +28,47 @@ module TCellAgent
|
|
30
28
|
end
|
31
29
|
|
32
30
|
def close
|
33
|
-
TCellAgent::Instrumentation.safe_block(
|
34
|
-
if @
|
35
|
-
@
|
36
|
-
TCellAgent.send_event(@
|
31
|
+
TCellAgent::Instrumentation.safe_block('Running AppSensor deferred due to streaming') do
|
32
|
+
if @appsensor_meta_event
|
33
|
+
@appsensor_meta_event.meta_data.response_content_bytes_len = @content_length
|
34
|
+
TCellAgent.send_event(@appsensor_meta_event)
|
37
35
|
end
|
38
36
|
end
|
39
37
|
|
40
38
|
@body.close if @body.respond_to?(:close)
|
41
39
|
end
|
42
40
|
|
43
|
-
def each
|
41
|
+
def each
|
44
42
|
return to_enum(:each) unless block_given?
|
45
43
|
|
46
|
-
@body.each
|
44
|
+
@body.each do |body_chunk|
|
47
45
|
body_chunk = process_body(body_chunk)
|
48
46
|
|
49
47
|
yield body_chunk
|
50
|
-
|
48
|
+
end
|
51
49
|
end
|
52
50
|
|
53
|
-
def respond_to?(method_name, include_all=false)
|
51
|
+
def respond_to?(method_name, include_all = false)
|
54
52
|
@body.respond_to?(method_name, include_all)
|
55
53
|
end
|
56
54
|
|
57
|
-
def method_missing(method_name, *args, &block)
|
55
|
+
def method_missing(method_name, *args, &block) # rubocop:disable Style/MethodMissing
|
58
56
|
@body.__send__(method_name, *args, &block)
|
59
57
|
end
|
60
58
|
|
61
59
|
def process_body(body)
|
62
|
-
TCellAgent::Instrumentation.safe_block(
|
60
|
+
TCellAgent::Instrumentation.safe_block('Processing tcell body proxy body') do
|
63
61
|
chunked_response_match = nil
|
64
|
-
if body.class.name ==
|
62
|
+
if body.class.name == 'String'
|
65
63
|
if body =~ /^([[:xdigit:]]+)(;.+)?\r\n/
|
66
|
-
chunked_response_match =
|
64
|
+
chunked_response_match = Regexp.last_match(1)
|
67
65
|
@content_length += chunked_response_match.to_i(16)
|
68
66
|
end
|
69
67
|
end
|
70
68
|
|
71
69
|
new_body = body
|
72
|
-
if body.class.name ==
|
73
|
-
|
70
|
+
if body.class.name == 'ActionView::OutputBuffer' ||
|
71
|
+
(body.class.name == 'String' && !chunked_response_match)
|
74
72
|
if @process_js_and_dlp
|
75
73
|
if @js_agent_insertion_proc
|
76
74
|
new_body = @js_agent_insertion_proc.call(@script_insert, body)
|
@@ -92,7 +90,6 @@ module TCellAgent
|
|
92
90
|
end
|
93
91
|
end
|
94
92
|
end
|
95
|
-
|
96
93
|
end
|
97
94
|
end
|
98
95
|
end
|
@@ -1,37 +1,35 @@
|
|
1
1
|
module TCellAgent
|
2
2
|
module Routes
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
class FieldEndpoint
|
4
|
+
attr_accessor :discovered
|
5
|
+
def initialize
|
6
|
+
super()
|
7
|
+
@discovered = false
|
8
|
+
end
|
9
|
+
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
11
|
+
class RouteEndpoint
|
12
|
+
attr_accessor :database
|
13
|
+
attr_accessor :database_queries_discovered
|
14
|
+
def initialize
|
15
|
+
@database_queries_discovered = {}
|
16
|
+
@database = Hash.new do |d_h, d_k| # Database
|
17
|
+
d_h[d_k] = Hash.new do |s_h, s_k| # Schema
|
18
|
+
s_h[s_k] = Hash.new do |t_h, t_k| # Table
|
19
|
+
t_h[t_k] = Hash.new do |f_h, f_k| # Field
|
20
|
+
f_h[f_k] = FieldEndpoint.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
end #/module Routes
|
37
|
-
end #/module TCellAgent
|
28
|
+
class RouteTable
|
29
|
+
attr_accessor :routes
|
30
|
+
def initialize
|
31
|
+
@routes = Hash.new { |h, k| h[k] = RouteEndpoint.new }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,18 +1,14 @@
|
|
1
1
|
require 'tcell_agent/utils/strings'
|
2
2
|
|
3
|
-
|
4
3
|
module TCellAgent
|
5
4
|
module Rust
|
6
5
|
module Models
|
7
|
-
|
8
6
|
def self.convert_params(params_dict)
|
9
|
-
unless params_dict
|
10
|
-
return []
|
11
|
-
end
|
7
|
+
return [] unless params_dict
|
12
8
|
|
13
9
|
flattened_params = []
|
14
10
|
params_dict.each do |param_name, param_value|
|
15
|
-
flattened_params.push({
|
11
|
+
flattened_params.push({ 'name' => param_name[-1], 'value' => param_value })
|
16
12
|
end
|
17
13
|
|
18
14
|
flattened_params
|
@@ -20,58 +16,57 @@ module TCellAgent
|
|
20
16
|
|
21
17
|
def self.create_request_response(appsensor_meta)
|
22
18
|
post_params = convert_params(appsensor_meta.flattened_post_dict) +
|
23
|
-
|
19
|
+
convert_params(appsensor_meta.flattened_body_dict)
|
24
20
|
|
25
21
|
request_response = {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
22
|
+
'method' => appsensor_meta.method,
|
23
|
+
'status_code' => appsensor_meta.response_code.to_i,
|
24
|
+
'route_id' => appsensor_meta.route_id,
|
25
|
+
'path' => appsensor_meta.path,
|
26
|
+
'query_params' => convert_params(appsensor_meta.flattened_get_dict),
|
27
|
+
'post_params' => post_params,
|
28
|
+
'headers' => convert_params(appsensor_meta.flattened_headers_dict),
|
29
|
+
'cookies' => convert_params(appsensor_meta.flattened_cookie_dict),
|
30
|
+
'path_params' => convert_params(appsensor_meta.flattened_path_parameters),
|
31
|
+
'remote_address' => appsensor_meta.remote_address,
|
32
|
+
'full_uri' => appsensor_meta.location,
|
33
|
+
'session_id' => appsensor_meta.session_id,
|
34
|
+
'user_id' => appsensor_meta.user_id,
|
35
|
+
'user_agent' => appsensor_meta.user_agent,
|
36
|
+
'request_bytes_length' => appsensor_meta.request_content_bytes_len,
|
37
|
+
'response_bytes_length' => appsensor_meta.response_content_bytes_len
|
42
38
|
}
|
43
39
|
|
44
40
|
if TCellAgent::Utils::Strings.present?(appsensor_meta.csrf_exception_name)
|
45
|
-
request_response[
|
41
|
+
request_response['csrf_exception'] = { 'exception_name' => appsensor_meta.csrf_exception_name }
|
46
42
|
end
|
47
43
|
|
48
44
|
if appsensor_meta.sql_exceptions
|
49
|
-
request_response[
|
45
|
+
request_response['sql_exceptions'] = appsensor_meta.sql_exceptions
|
50
46
|
end
|
51
47
|
|
52
48
|
if appsensor_meta.database_result_sizes
|
53
|
-
request_response[
|
49
|
+
request_response['database_result_sizes'] = appsensor_meta.database_result_sizes
|
54
50
|
end
|
55
51
|
|
56
|
-
|
52
|
+
request_response
|
57
53
|
end
|
58
54
|
|
59
55
|
def self.create_patches_request(appsensor_meta)
|
60
56
|
post_params = convert_params(appsensor_meta.flattened_post_dict) +
|
61
|
-
|
57
|
+
convert_params(appsensor_meta.flattened_body_dict)
|
62
58
|
|
63
59
|
{
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
60
|
+
'method' => appsensor_meta.method,
|
61
|
+
'path' => appsensor_meta.path,
|
62
|
+
'remote_address' => appsensor_meta.remote_address,
|
63
|
+
'request_bytes_length' => appsensor_meta.request_content_bytes_len,
|
64
|
+
'query_params' => convert_params(appsensor_meta.flattened_get_dict),
|
65
|
+
'post_params' => post_params,
|
66
|
+
'headers' => convert_params(appsensor_meta.flattened_headers_dict),
|
67
|
+
'cookies' => convert_params(appsensor_meta.flattened_cookie_dict)
|
72
68
|
}
|
73
69
|
end
|
74
|
-
|
75
70
|
end
|
76
71
|
end
|
77
72
|
end
|
Binary file
|
@@ -1,25 +1,24 @@
|
|
1
1
|
require 'tcell_agent/rust/models'
|
2
2
|
require 'tcell_agent/logger'
|
3
3
|
|
4
|
-
|
5
4
|
module TCellAgent
|
6
5
|
module Rust
|
7
|
-
require
|
6
|
+
require 'ffi'
|
8
7
|
|
9
8
|
module Wrapper
|
10
9
|
extend FFI::Library
|
11
10
|
|
12
|
-
VERSION =
|
13
|
-
prefix =
|
14
|
-
extension =
|
15
|
-
variant =
|
11
|
+
VERSION = '1.3.1'.freeze
|
12
|
+
prefix = 'lib'
|
13
|
+
extension = '.so'
|
14
|
+
variant = ''
|
16
15
|
if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
|
17
|
-
extension =
|
18
|
-
prefix =
|
16
|
+
extension = '.dll'
|
17
|
+
prefix = ''
|
19
18
|
elsif /darwin/ =~ RUBY_PLATFORM
|
20
|
-
extension =
|
19
|
+
extension = '.dylib'
|
21
20
|
elsif /musl/ =~ RUBY_PLATFORM
|
22
|
-
variant =
|
21
|
+
variant = 'alpine-'
|
23
22
|
end
|
24
23
|
|
25
24
|
begin
|
@@ -33,24 +32,24 @@ module TCellAgent
|
|
33
32
|
# -2 buffer_out is not big enough for response
|
34
33
|
# -3 buffer_out is null
|
35
34
|
|
36
|
-
attach_function :create_agent, [
|
35
|
+
attach_function :create_agent, %i[pointer size_t pointer size_t], :int
|
37
36
|
attach_function :free_agent, [:pointer], :int
|
38
|
-
attach_function :update_policies, [
|
39
|
-
attach_function :appfirewall_apply, [
|
40
|
-
attach_function :patches_apply, [
|
41
|
-
attach_function :cmdi_apply, [
|
42
|
-
attach_function :get_headers, [
|
43
|
-
attach_function :get_js_agent_script_tag, [
|
37
|
+
attach_function :update_policies, %i[pointer pointer size_t pointer size_t], :int
|
38
|
+
attach_function :appfirewall_apply, %i[pointer pointer size_t pointer size_t], :int
|
39
|
+
attach_function :patches_apply, %i[pointer pointer size_t pointer size_t], :int
|
40
|
+
attach_function :cmdi_apply, %i[pointer pointer size_t pointer size_t], :int
|
41
|
+
attach_function :get_headers, %i[pointer pointer size_t pointer size_t], :int
|
42
|
+
attach_function :get_js_agent_script_tag, %i[pointer pointer size_t pointer size_t], :int
|
44
43
|
|
45
44
|
def self.common_lib_available?
|
46
45
|
true
|
47
46
|
end
|
48
|
-
|
49
47
|
rescue LoadError => load_error
|
50
48
|
puts "tCell.io Failed to load common agent library. #{load_error.message}"
|
51
49
|
TCellAgent.logger.error("Failed to load common agent library. #{load_error.message}")
|
52
50
|
TCellAgent.logger.debug(load_error.backtrace)
|
53
|
-
|
51
|
+
|
52
|
+
def self.common_lib_available? # rubocop:disable Lint/DuplicateMethods
|
54
53
|
false
|
55
54
|
end
|
56
55
|
end
|
@@ -79,41 +78,40 @@ module TCellAgent
|
|
79
78
|
end
|
80
79
|
end
|
81
80
|
|
82
|
-
|
81
|
+
{}
|
83
82
|
end
|
84
83
|
|
85
|
-
def self.create_agent
|
84
|
+
def self.create_agent
|
86
85
|
if TCellAgent::Rust::Wrapper.common_lib_available?
|
87
|
-
allow_payloads = !!TCellAgent.configuration.allow_payloads
|
88
86
|
agent_config = {
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
87
|
+
'skip_logger' => true,
|
88
|
+
'application' => {
|
89
|
+
'app_id' => TCellAgent.configuration.app_id,
|
90
|
+
'api_key' => TCellAgent.configuration.api_key,
|
91
|
+
'allow_payloads' => !!TCellAgent.configuration.allow_payloads, # rubocop:disable Style/DoubleNegation
|
92
|
+
'js_agent_api_base_url' => TCellAgent.configuration.js_agent_api_base_url,
|
93
|
+
'js_agent_url' => TCellAgent.configuration.js_agent_url
|
96
94
|
},
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
95
|
+
'appfirewall' => {
|
96
|
+
'enable_body_xxe_inspection' => false,
|
97
|
+
'enable_body_json_inspection' => false,
|
98
|
+
'allow_log_payloads' => true
|
101
99
|
},
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
100
|
+
'policy_versions' => {
|
101
|
+
'patches' => 1,
|
102
|
+
'login' => 1,
|
103
|
+
'appsensor' => 2,
|
104
|
+
'regex' => 1,
|
105
|
+
'csp-headers' => 1,
|
106
|
+
'http-redirect' => 1,
|
107
|
+
'clickjacking' => 1,
|
108
|
+
'secure-headers' => 1,
|
109
|
+
'canaries' => 1,
|
110
|
+
'dlp' => 1,
|
111
|
+
'cmdi' => 1,
|
112
|
+
'jsagentinjection' => 1
|
115
113
|
},
|
116
|
-
|
114
|
+
'max_header_size' => TCellAgent.configuration.max_csp_header_bytes || (1024 * 1024)
|
117
115
|
}
|
118
116
|
config_pointer = FFI::MemoryPointer.from_string(
|
119
117
|
JSON.dump(agent_config)
|
@@ -124,15 +122,15 @@ module TCellAgent
|
|
124
122
|
result_size = TCellAgent::Rust::Wrapper.create_agent(
|
125
123
|
config_pointer, config_pointer.size - 1, buf, buf.size
|
126
124
|
)
|
127
|
-
return
|
125
|
+
return convert_result('create_agent', result_size, buf)
|
128
126
|
end
|
129
127
|
|
130
|
-
|
128
|
+
{}
|
131
129
|
end
|
132
130
|
|
133
131
|
def self.free_agent(agent_ptr)
|
134
132
|
if TCellAgent::Rust::Wrapper.common_lib_available? &&
|
135
|
-
|
133
|
+
agent_ptr
|
136
134
|
TCellAgent::Rust::Wrapper.free_agent(
|
137
135
|
FFI::Pointer.new(agent_ptr)
|
138
136
|
)
|
@@ -141,8 +139,8 @@ module TCellAgent
|
|
141
139
|
|
142
140
|
def self.update_policies(agent_ptr, policies)
|
143
141
|
if TCellAgent::Rust::Wrapper.common_lib_available? &&
|
144
|
-
|
145
|
-
|
142
|
+
agent_ptr &&
|
143
|
+
TCellAgent::Utils::Strings.present?(policies)
|
146
144
|
policies_pointer = FFI::MemoryPointer.from_string(
|
147
145
|
JSON.dump(policies)
|
148
146
|
)
|
@@ -156,42 +154,42 @@ module TCellAgent
|
|
156
154
|
buf,
|
157
155
|
buf.size
|
158
156
|
)
|
159
|
-
return
|
157
|
+
return convert_result('update_policies', result_size, buf)
|
160
158
|
end
|
161
159
|
|
162
|
-
|
160
|
+
{}
|
163
161
|
end
|
164
162
|
|
165
163
|
def self.apply_appfirewall(agent_ptr, appsensor_meta)
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
164
|
+
if TCellAgent::Rust::Wrapper.common_lib_available? &&
|
165
|
+
agent_ptr &&
|
166
|
+
appsensor_meta
|
167
|
+
request_response_json = TCellAgent::Rust::Models.create_request_response(
|
168
|
+
appsensor_meta
|
169
|
+
)
|
170
|
+
request_response_pointer = FFI::MemoryPointer.from_string(
|
171
|
+
JSON.dump(request_response_json)
|
172
|
+
)
|
173
|
+
|
174
|
+
buf = FFI::MemoryPointer.new(:uint8, 1024 * 32)
|
175
|
+
# request_response_pointer.size - 1: strips null terminator
|
176
|
+
result_size = TCellAgent::Rust::Wrapper.appfirewall_apply(
|
177
|
+
FFI::Pointer.new(agent_ptr),
|
178
|
+
request_response_pointer,
|
179
|
+
request_response_pointer.size - 1,
|
180
|
+
buf,
|
181
|
+
buf.size
|
182
|
+
)
|
183
|
+
return convert_result('apply_appfirewall', result_size, buf)
|
184
|
+
end
|
185
|
+
|
186
|
+
{}
|
189
187
|
end
|
190
188
|
|
191
189
|
def self.apply_patches(agent_ptr, appsensor_meta)
|
192
190
|
if TCellAgent::Rust::Wrapper.common_lib_available? &&
|
193
|
-
|
194
|
-
|
191
|
+
agent_ptr &&
|
192
|
+
appsensor_meta
|
195
193
|
patches_request_json = TCellAgent::Rust::Models.create_patches_request(
|
196
194
|
appsensor_meta
|
197
195
|
)
|
@@ -208,23 +206,22 @@ module TCellAgent
|
|
208
206
|
buf,
|
209
207
|
buf.size
|
210
208
|
)
|
211
|
-
return
|
209
|
+
return convert_result('apply_patches', result_size, buf)
|
212
210
|
end
|
213
211
|
|
214
|
-
|
212
|
+
{}
|
215
213
|
end
|
216
214
|
|
217
215
|
def self.apply_cmdi(agent_ptr, command, tcell_context)
|
218
|
-
|
219
216
|
if TCellAgent::Rust::Wrapper.common_lib_available? &&
|
220
|
-
|
221
|
-
|
217
|
+
agent_ptr &&
|
218
|
+
TCellAgent::Utils::Strings.present?(command)
|
222
219
|
method = tcell_context && tcell_context.request_method
|
223
220
|
path = tcell_context && tcell_context.path
|
224
221
|
command_info = {
|
225
|
-
|
226
|
-
|
227
|
-
|
222
|
+
'command' => command,
|
223
|
+
'method' => method,
|
224
|
+
'path' => path
|
228
225
|
}
|
229
226
|
command_pointer = FFI::MemoryPointer.from_string(
|
230
227
|
JSON.dump(command_info)
|
@@ -239,25 +236,25 @@ module TCellAgent
|
|
239
236
|
buf,
|
240
237
|
buf.size
|
241
238
|
)
|
242
|
-
return
|
239
|
+
return convert_result('apply_cmdi', result_size, buf)
|
243
240
|
end
|
244
241
|
|
245
|
-
|
242
|
+
{}
|
246
243
|
end
|
247
244
|
|
248
245
|
def self.get_headers(agent_ptr, tcell_context)
|
249
246
|
if TCellAgent::Rust::Wrapper.common_lib_available? &&
|
250
|
-
|
251
|
-
|
247
|
+
agent_ptr &&
|
248
|
+
tcell_context
|
252
249
|
method = tcell_context.request_method
|
253
250
|
path = tcell_context.path
|
254
251
|
route_id = tcell_context.route_id
|
255
|
-
session_id = tcell_context.
|
252
|
+
session_id = tcell_context.hmac_session_id
|
256
253
|
headers_request = {
|
257
|
-
method
|
258
|
-
path
|
259
|
-
route_id
|
260
|
-
session_id
|
254
|
+
:method => method,
|
255
|
+
:path => path,
|
256
|
+
:route_id => route_id && route_id.to_s,
|
257
|
+
:session_id => session_id && session_id.to_s
|
261
258
|
}
|
262
259
|
headers_request_pointer = FFI::MemoryPointer.from_string(
|
263
260
|
JSON.dump(headers_request)
|
@@ -272,21 +269,21 @@ module TCellAgent
|
|
272
269
|
buf,
|
273
270
|
buf.size
|
274
271
|
)
|
275
|
-
return
|
272
|
+
return convert_result('get_headers', result_size, buf)
|
276
273
|
end
|
277
274
|
|
278
|
-
|
275
|
+
{}
|
279
276
|
end
|
280
277
|
|
281
278
|
def self.get_js_agent_script_tag(agent_ptr, tcell_context)
|
282
279
|
if TCellAgent::Rust::Wrapper.common_lib_available? &&
|
283
|
-
|
284
|
-
|
280
|
+
agent_ptr &&
|
281
|
+
tcell_context
|
285
282
|
method = tcell_context.request_method
|
286
283
|
path = tcell_context.path
|
287
284
|
jsagent_request = {
|
288
|
-
method
|
289
|
-
path
|
285
|
+
:method => method,
|
286
|
+
:path => path
|
290
287
|
}
|
291
288
|
jsagent_request_pointer = FFI::MemoryPointer.from_string(
|
292
289
|
JSON.dump(jsagent_request)
|
@@ -301,10 +298,10 @@ module TCellAgent
|
|
301
298
|
buf,
|
302
299
|
buf.size
|
303
300
|
)
|
304
|
-
return
|
301
|
+
return convert_result('get_js_agent_script_tag', result_size, buf)
|
305
302
|
end
|
306
303
|
|
307
|
-
|
304
|
+
{}
|
308
305
|
end
|
309
306
|
end
|
310
307
|
end
|