tcell_agent 0.4.0 → 1.0.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/Rakefile +9 -22
- data/bin/tcell_agent +127 -132
- data/lib/tcell_agent/agent/event_processor.rb +23 -22
- data/lib/tcell_agent/agent/fork_pipe_manager.rb +7 -7
- data/lib/tcell_agent/agent/policy_manager.rb +20 -15
- data/lib/tcell_agent/agent/policy_types.rb +5 -11
- data/lib/tcell_agent/agent/static_agent.rb +5 -1
- data/lib/tcell_agent/agent.rb +6 -4
- data/lib/tcell_agent/api.rb +7 -9
- data/lib/tcell_agent/appsensor/meta_data.rb +11 -4
- data/lib/tcell_agent/authlogic.rb +3 -3
- data/lib/tcell_agent/cmdi.rb +6 -4
- data/lib/tcell_agent/config/unknown_options.rb +3 -1
- data/lib/tcell_agent/configuration.rb +47 -49
- data/lib/tcell_agent/devise.rb +2 -2
- data/lib/tcell_agent/hooks/login_fraud.rb +58 -29
- data/lib/tcell_agent/instrumentation.rb +11 -10
- data/lib/tcell_agent/logger.rb +2 -2
- data/lib/tcell_agent/patches/meta_data.rb +9 -13
- data/lib/tcell_agent/patches.rb +7 -10
- data/lib/tcell_agent/policies/clickjacking_policy.rb +4 -5
- data/lib/tcell_agent/policies/content_security_policy.rb +6 -12
- data/lib/tcell_agent/policies/dataloss_policy.rb +2 -2
- data/lib/tcell_agent/policies/http_redirect_policy.rb +2 -2
- data/lib/tcell_agent/policies/policy.rb +0 -2
- data/lib/tcell_agent/policies/rust_policies.rb +90 -0
- data/lib/tcell_agent/policies/secure_headers_policy.rb +2 -2
- data/lib/tcell_agent/rails/auth/authlogic.rb +42 -24
- data/lib/tcell_agent/rails/auth/devise.rb +44 -23
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +33 -15
- data/lib/tcell_agent/rails/better_ip.rb +1 -1
- data/lib/tcell_agent/rails/csrf_exception.rb +2 -2
- data/lib/tcell_agent/rails/dlp/process_request.rb +1 -1
- data/lib/tcell_agent/rails/dlp.rb +6 -6
- data/lib/tcell_agent/rails/dlp_handler.rb +1 -1
- data/lib/tcell_agent/rails/js_agent_insert.rb +1 -1
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +1 -1
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +3 -2
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +10 -9
- data/lib/tcell_agent/rails/routes/grape.rb +6 -6
- data/lib/tcell_agent/rails/routes.rb +8 -11
- data/lib/tcell_agent/rust/libtcellagent-0.11.1.dylib +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-0.6.1.so → libtcellagent-0.11.1.so} +0 -0
- data/lib/tcell_agent/rust/models.rb +16 -0
- data/lib/tcell_agent/rust/tcellagent-0.11.1.dll +0 -0
- data/lib/tcell_agent/rust/whisperer.rb +119 -48
- data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +17 -20
- data/lib/tcell_agent/sensor_events/command_injection.rb +50 -5
- data/lib/tcell_agent/sensor_events/login_fraud.rb +34 -18
- data/lib/tcell_agent/sensor_events/patches.rb +21 -0
- data/lib/tcell_agent/sensor_events/server_agent.rb +3 -3
- data/lib/tcell_agent/sensor_events/util/utils.rb +4 -3
- data/lib/tcell_agent/servers/puma.rb +2 -2
- data/lib/tcell_agent/servers/unicorn.rb +1 -1
- data/lib/tcell_agent/utils/passwords.rb +28 -0
- data/lib/tcell_agent/version.rb +1 -1
- data/lib/tcell_agent.rb +1 -5
- data/spec/apps/rails-3.2/config/tcell_agent.config +15 -0
- data/spec/apps/rails-3.2/log/development.log +0 -0
- data/spec/apps/rails-3.2/log/test.log +12 -0
- data/spec/apps/rails-4.1/log/test.log +0 -0
- data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +46 -45
- data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +276 -164
- data/spec/lib/tcell_agent/agent/static_agent_spec.rb +44 -47
- data/spec/lib/tcell_agent/api/api_spec.rb +16 -16
- data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +131 -116
- data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +55 -51
- data/spec/lib/tcell_agent/cmdi_spec.rb +413 -436
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +145 -128
- data/spec/lib/tcell_agent/configuration_spec.rb +165 -169
- data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +144 -153
- data/spec/lib/tcell_agent/instrumentation_spec.rb +84 -85
- data/spec/lib/tcell_agent/patches_spec.rb +70 -111
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +313 -244
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +28 -28
- data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +643 -513
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +55 -102
- data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +111 -134
- data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +141 -146
- data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +8 -8
- data/spec/lib/tcell_agent/policies/login_policy_spec.rb +15 -17
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +231 -559
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +27 -27
- data/spec/lib/tcell_agent/rails/better_ip_spec.rb +30 -34
- data/spec/lib/tcell_agent/rails/logger_spec.rb +50 -49
- data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +182 -199
- data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +110 -84
- data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +107 -85
- data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +68 -40
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +81 -67
- data/spec/lib/tcell_agent/rails/responses_spec.rb +33 -37
- data/spec/lib/tcell_agent/rails/routes/grape_spec.rb +116 -121
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +25 -28
- data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +87 -85
- data/spec/lib/tcell_agent/rails_spec.rb +1 -6
- data/spec/lib/tcell_agent/rust/models_spec.rb +112 -0
- data/spec/lib/tcell_agent/rust/whisperer_spec.rb +502 -179
- data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +44 -33
- data/spec/lib/tcell_agent/sensor_events/dlp_spec.rb +4 -4
- data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +183 -169
- data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +25 -25
- data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +17 -20
- data/spec/lib/tcell_agent/utils/params_spec.rb +28 -28
- data/spec/lib/tcell_agent/utils/passwords_spec.rb +143 -0
- data/spec/lib/tcell_agent/utils/strings_spec.rb +35 -35
- data/spec/lib/tcell_agent_spec.rb +8 -8
- data/spec/spec_helper.rb +4 -4
- data/spec/support/middleware_helper.rb +10 -10
- data/spec/support/static_agent_overrides.rb +16 -12
- data/tcell_agent.gemspec +17 -33
- metadata +43 -198
- data/LICENSE_libinjection +0 -32
- data/Readme.txt +0 -7
- data/ext/libinjection/extconf.rb +0 -3
- data/ext/libinjection/libinjection.h +0 -65
- data/ext/libinjection/libinjection_html5.c +0 -847
- data/ext/libinjection/libinjection_html5.h +0 -54
- data/ext/libinjection/libinjection_sqli.c +0 -2317
- data/ext/libinjection/libinjection_sqli.h +0 -295
- data/ext/libinjection/libinjection_sqli_data.h +0 -9004
- data/ext/libinjection/libinjection_wrap.c +0 -3525
- data/ext/libinjection/libinjection_xss.c +0 -531
- data/ext/libinjection/libinjection_xss.h +0 -21
- data/lib/tcell_agent/appsensor/injections_matcher.rb +0 -155
- data/lib/tcell_agent/appsensor/rules/appsensor_rule_manager.rb +0 -49
- data/lib/tcell_agent/appsensor/rules/appsensor_rule_set.rb +0 -67
- data/lib/tcell_agent/appsensor/rules/baserules.json +0 -467
- data/lib/tcell_agent/patches/block_rule.rb +0 -93
- data/lib/tcell_agent/patches/sensors_matcher.rb +0 -31
- data/lib/tcell_agent/policies/appsensor/cmdi_sensor.rb +0 -23
- data/lib/tcell_agent/policies/appsensor/fpt_sensor.rb +0 -23
- data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +0 -117
- data/lib/tcell_agent/policies/appsensor/nullbyte_sensor.rb +0 -26
- data/lib/tcell_agent/policies/appsensor/retr_sensor.rb +0 -22
- data/lib/tcell_agent/policies/appsensor/sqli_sensor.rb +0 -34
- data/lib/tcell_agent/policies/appsensor/xss_sensor.rb +0 -34
- data/lib/tcell_agent/policies/appsensor_policy.rb +0 -49
- data/lib/tcell_agent/policies/command_injection_policy.rb +0 -196
- data/lib/tcell_agent/policies/honeytokens_policy.rb +0 -69
- data/lib/tcell_agent/policies/patches_policy.rb +0 -84
- data/lib/tcell_agent/rust/libtcellagent-0.6.1.dylib +0 -0
- data/lib/tcell_agent/rust/tcellagent-0.6.1.dll +0 -0
- data/spec/apps/rails-3.2/Gemfile +0 -25
- data/spec/apps/rails-3.2/Gemfile.lock +0 -126
- data/spec/apps/rails-3.2/Rakefile +0 -7
- data/spec/apps/rails-3.2/app/assets/images/rails.png +0 -0
- data/spec/apps/rails-3.2/app/assets/javascripts/application.js +0 -15
- data/spec/apps/rails-3.2/app/assets/stylesheets/application.css +0 -13
- data/spec/apps/rails-3.2/app/controllers/application_controller.rb +0 -3
- data/spec/apps/rails-3.2/app/controllers/t_cell_app_controller.rb +0 -5
- data/spec/apps/rails-3.2/app/helpers/application_helper.rb +0 -2
- data/spec/apps/rails-3.2/app/views/layouts/application.html.erb +0 -14
- data/spec/apps/rails-3.2/app/views/t_cell_app/index.html.erb +0 -1
- data/spec/apps/rails-3.2/config/application.rb +0 -63
- data/spec/apps/rails-3.2/config/boot.rb +0 -6
- data/spec/apps/rails-3.2/config/environment.rb +0 -5
- data/spec/apps/rails-3.2/config/environments/test.rb +0 -37
- data/spec/apps/rails-3.2/config/routes.rb +0 -11
- data/spec/apps/rails-3.2/config.ru +0 -4
- data/spec/apps/rails-4.1/Gemfile +0 -7
- data/spec/apps/rails-4.1/Gemfile.lock +0 -114
- data/spec/apps/rails-4.1/Rakefile +0 -6
- data/spec/apps/rails-4.1/app/assets/javascripts/application.js +0 -16
- data/spec/apps/rails-4.1/app/assets/stylesheets/application.css +0 -15
- data/spec/apps/rails-4.1/app/controllers/application_controller.rb +0 -5
- data/spec/apps/rails-4.1/app/controllers/t_cell_app_controller.rb +0 -5
- data/spec/apps/rails-4.1/app/helpers/application_helper.rb +0 -2
- data/spec/apps/rails-4.1/app/views/layouts/application.html.erb +0 -14
- data/spec/apps/rails-4.1/app/views/t_cell_app/index.html.erb +0 -1
- data/spec/apps/rails-4.1/config/application.rb +0 -24
- data/spec/apps/rails-4.1/config/boot.rb +0 -4
- data/spec/apps/rails-4.1/config/environment.rb +0 -5
- data/spec/apps/rails-4.1/config/environments/test.rb +0 -41
- data/spec/apps/rails-4.1/config/initializers/assets.rb +0 -8
- data/spec/apps/rails-4.1/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/apps/rails-4.1/config/initializers/cookies_serializer.rb +0 -3
- data/spec/apps/rails-4.1/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/apps/rails-4.1/config/initializers/inflections.rb +0 -16
- data/spec/apps/rails-4.1/config/initializers/mime_types.rb +0 -4
- data/spec/apps/rails-4.1/config/initializers/session_store.rb +0 -3
- data/spec/apps/rails-4.1/config/initializers/wrap_parameters.rb +0 -14
- data/spec/apps/rails-4.1/config/locales/en.yml +0 -23
- data/spec/apps/rails-4.1/config/routes.rb +0 -12
- data/spec/apps/rails-4.1/config/secrets.yml +0 -22
- data/spec/apps/rails-4.1/config.ru +0 -4
- data/spec/controllers/application_controller.rb +0 -12
- data/spec/lib/tcell_agent/appsensor/injections_matcher_spec.rb +0 -522
- data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_manager_spec.rb +0 -23
- data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_set_spec.rb +0 -159
- data/spec/lib/tcell_agent/patches/block_rule_spec.rb +0 -458
- data/spec/lib/tcell_agent/patches/sensors_matcher_spec.rb +0 -35
- data/spec/lib/tcell_agent/policies/appsensor/cmdi_sensor_spec.rb +0 -139
- data/spec/lib/tcell_agent/policies/appsensor/fpt_sensor_spec.rb +0 -139
- data/spec/lib/tcell_agent/policies/appsensor/nullbyte_sensor_spec.rb +0 -167
- data/spec/lib/tcell_agent/policies/appsensor/retr_sensor_spec.rb +0 -139
- data/spec/lib/tcell_agent/policies/appsensor/sqli_sensor_spec.rb +0 -246
- data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +0 -882
- data/spec/lib/tcell_agent/policies/honeytokens_policy_spec.rb +0 -22
|
@@ -1,75 +1,76 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
module TCellAgent
|
|
4
|
-
|
|
5
4
|
module Cmdi
|
|
6
|
-
describe
|
|
7
|
-
context
|
|
5
|
+
describe '.parse_command' do
|
|
6
|
+
context 'with env' do
|
|
8
7
|
before(:each) do
|
|
9
|
-
@env = {
|
|
8
|
+
@env = { 'TCELL_VAR' => 'enabled' }
|
|
10
9
|
end
|
|
11
10
|
|
|
12
|
-
context
|
|
13
|
-
it
|
|
14
|
-
cmd = TCellAgent::Cmdi.parse_command(@env,
|
|
15
|
-
expect(cmd).to eq(
|
|
11
|
+
context 'with string command' do
|
|
12
|
+
it 'should parse the command properly' do
|
|
13
|
+
cmd = TCellAgent::Cmdi.parse_command(@env, 'echo')
|
|
14
|
+
expect(cmd).to eq('echo')
|
|
16
15
|
|
|
17
|
-
cmd = TCellAgent::Cmdi.parse_command(@env,
|
|
18
|
-
expect(cmd).to eq(
|
|
16
|
+
cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', :unsetenv_others => true)
|
|
17
|
+
expect(cmd).to eq('echo')
|
|
19
18
|
end
|
|
20
19
|
end
|
|
21
20
|
|
|
22
|
-
context
|
|
23
|
-
it
|
|
24
|
-
cmd = TCellAgent::Cmdi.parse_command(@env,
|
|
25
|
-
expect(cmd).to eq(
|
|
21
|
+
context 'with string command and arguments' do
|
|
22
|
+
it 'should parse the command' do
|
|
23
|
+
cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', 'test', :unsetenv_others => true)
|
|
24
|
+
expect(cmd).to eq('echo test')
|
|
26
25
|
|
|
27
|
-
cmd = TCellAgent::Cmdi.parse_command(@env,
|
|
28
|
-
expect(cmd).to eq(
|
|
26
|
+
cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', 'test', 'one', :unsetenv_others => true)
|
|
27
|
+
expect(cmd).to eq('echo test one')
|
|
29
28
|
|
|
30
29
|
cmd = TCellAgent::Cmdi.parse_command(
|
|
31
30
|
@env,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
'magick',
|
|
32
|
+
'-size',
|
|
33
|
+
'320x85',
|
|
34
|
+
'canvas:none',
|
|
35
|
+
'-font',
|
|
36
|
+
'Bookman-DemiItalic',
|
|
37
|
+
'-draw',
|
|
39
38
|
"\"text 25,60 \'Magick\'\"",
|
|
40
|
-
:unsetenv_others => true
|
|
39
|
+
:unsetenv_others => true
|
|
40
|
+
)
|
|
41
41
|
expect(cmd).to eq(
|
|
42
42
|
"magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
43
43
|
)
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
context
|
|
48
|
-
it
|
|
49
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, [
|
|
50
|
-
expect(cmd).to eq(
|
|
47
|
+
context 'with array command' do
|
|
48
|
+
it 'should parse the command properly' do
|
|
49
|
+
cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], :unsetenv_others => true)
|
|
50
|
+
expect(cmd).to eq('echo')
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
context
|
|
55
|
-
it
|
|
56
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, [
|
|
57
|
-
expect(cmd).to eq(
|
|
54
|
+
context 'with array command and arguments' do
|
|
55
|
+
it 'should parse the command properly' do
|
|
56
|
+
cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], 'test', :unsetenv_others => true)
|
|
57
|
+
expect(cmd).to eq('echo test')
|
|
58
58
|
|
|
59
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, [
|
|
60
|
-
expect(cmd).to eq(
|
|
59
|
+
cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], 'test', 'one', :unsetenv_others => true)
|
|
60
|
+
expect(cmd).to eq('echo test one')
|
|
61
61
|
|
|
62
62
|
cmd = TCellAgent::Cmdi.parse_command(
|
|
63
63
|
@env,
|
|
64
|
-
[
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
%w[magick argv0],
|
|
65
|
+
'-size',
|
|
66
|
+
'320x85',
|
|
67
|
+
'canvas:none',
|
|
68
|
+
'-font',
|
|
69
|
+
'Bookman-DemiItalic',
|
|
70
|
+
'-draw',
|
|
71
71
|
"\"text 25,60 \'Magick\'\"",
|
|
72
|
-
:unsetenv_others => true
|
|
72
|
+
:unsetenv_others => true
|
|
73
|
+
)
|
|
73
74
|
expect(cmd).to eq(
|
|
74
75
|
"magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
75
76
|
)
|
|
@@ -77,66 +78,68 @@ module TCellAgent
|
|
|
77
78
|
end
|
|
78
79
|
end
|
|
79
80
|
|
|
80
|
-
context
|
|
81
|
-
context
|
|
82
|
-
it
|
|
83
|
-
cmd = TCellAgent::Cmdi.parse_command(
|
|
84
|
-
expect(cmd).to eq(
|
|
81
|
+
context 'without env' do
|
|
82
|
+
context 'with string command' do
|
|
83
|
+
it 'should parse the command properly' do
|
|
84
|
+
cmd = TCellAgent::Cmdi.parse_command('echo')
|
|
85
|
+
expect(cmd).to eq('echo')
|
|
85
86
|
|
|
86
|
-
cmd = TCellAgent::Cmdi.parse_command(
|
|
87
|
-
expect(cmd).to eq(
|
|
87
|
+
cmd = TCellAgent::Cmdi.parse_command('echo', :unsetenv_others => true)
|
|
88
|
+
expect(cmd).to eq('echo')
|
|
88
89
|
end
|
|
89
90
|
end
|
|
90
91
|
|
|
91
|
-
context
|
|
92
|
-
it
|
|
93
|
-
cmd = TCellAgent::Cmdi.parse_command(
|
|
94
|
-
expect(cmd).to eq(
|
|
92
|
+
context 'with string command and arguments' do
|
|
93
|
+
it 'should parse the command' do
|
|
94
|
+
cmd = TCellAgent::Cmdi.parse_command('echo', 'test', :unsetenv_others => true)
|
|
95
|
+
expect(cmd).to eq('echo test')
|
|
95
96
|
|
|
96
|
-
cmd = TCellAgent::Cmdi.parse_command(
|
|
97
|
-
expect(cmd).to eq(
|
|
97
|
+
cmd = TCellAgent::Cmdi.parse_command('echo', 'test', 'one', :unsetenv_others => true)
|
|
98
|
+
expect(cmd).to eq('echo test one')
|
|
98
99
|
|
|
99
100
|
cmd = TCellAgent::Cmdi.parse_command(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
'magick',
|
|
102
|
+
'-size',
|
|
103
|
+
'320x85',
|
|
104
|
+
'canvas:none',
|
|
105
|
+
'-font',
|
|
106
|
+
'Bookman-DemiItalic',
|
|
107
|
+
'-draw',
|
|
107
108
|
"\"text 25,60 \'Magick\'\"",
|
|
108
|
-
:unsetenv_others => true
|
|
109
|
+
:unsetenv_others => true
|
|
110
|
+
)
|
|
109
111
|
expect(cmd).to eq(
|
|
110
112
|
"magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
111
113
|
)
|
|
112
114
|
end
|
|
113
115
|
end
|
|
114
116
|
|
|
115
|
-
context
|
|
116
|
-
it
|
|
117
|
-
cmd = TCellAgent::Cmdi.parse_command([
|
|
118
|
-
expect(cmd).to eq(
|
|
117
|
+
context 'with array command' do
|
|
118
|
+
it 'should parse the command properly' do
|
|
119
|
+
cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], :unsetenv_others => true)
|
|
120
|
+
expect(cmd).to eq('echo')
|
|
119
121
|
end
|
|
120
122
|
end
|
|
121
123
|
|
|
122
|
-
context
|
|
123
|
-
it
|
|
124
|
-
cmd = TCellAgent::Cmdi.parse_command([
|
|
125
|
-
expect(cmd).to eq(
|
|
124
|
+
context 'with array command and arguments' do
|
|
125
|
+
it 'should parse the command properly' do
|
|
126
|
+
cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], 'test', :unsetenv_others => true)
|
|
127
|
+
expect(cmd).to eq('echo test')
|
|
126
128
|
|
|
127
|
-
cmd = TCellAgent::Cmdi.parse_command([
|
|
128
|
-
expect(cmd).to eq(
|
|
129
|
+
cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], 'test', 'one', :unsetenv_others => true)
|
|
130
|
+
expect(cmd).to eq('echo test one')
|
|
129
131
|
|
|
130
132
|
cmd = TCellAgent::Cmdi.parse_command(
|
|
131
|
-
[
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
%w[magick argv0],
|
|
134
|
+
'-size',
|
|
135
|
+
'320x85',
|
|
136
|
+
'canvas:none',
|
|
137
|
+
'-font',
|
|
138
|
+
'Bookman-DemiItalic',
|
|
139
|
+
'-draw',
|
|
138
140
|
"\"text 25,60 \'Magick\'\"",
|
|
139
|
-
:unsetenv_others => true
|
|
141
|
+
:unsetenv_others => true
|
|
142
|
+
)
|
|
140
143
|
expect(cmd).to eq(
|
|
141
144
|
"magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
142
145
|
)
|
|
@@ -147,228 +150,225 @@ module TCellAgent
|
|
|
147
150
|
end
|
|
148
151
|
|
|
149
152
|
describe IO do
|
|
150
|
-
describe
|
|
151
|
-
context
|
|
152
|
-
it
|
|
153
|
-
expect
|
|
154
|
-
IO.popen
|
|
155
|
-
|
|
156
|
-
expect
|
|
153
|
+
describe '.popen' do
|
|
154
|
+
context 'empty command' do
|
|
155
|
+
it 'should raise an error' do
|
|
156
|
+
expect do
|
|
157
|
+
IO.popen
|
|
158
|
+
end.to raise_error(ArgumentError)
|
|
159
|
+
expect do
|
|
157
160
|
IO.popen(nil)
|
|
158
|
-
|
|
159
|
-
expect
|
|
160
|
-
IO.popen(
|
|
161
|
-
|
|
161
|
+
end.to raise_error(TypeError)
|
|
162
|
+
expect do
|
|
163
|
+
IO.popen('')
|
|
164
|
+
end.to raise_error(Errno::ENOENT)
|
|
162
165
|
end
|
|
163
166
|
end
|
|
164
167
|
|
|
165
|
-
context
|
|
166
|
-
it
|
|
167
|
-
expect
|
|
168
|
-
IO.popen(
|
|
169
|
-
|
|
168
|
+
context 'non existent command' do
|
|
169
|
+
it 'should return nil' do
|
|
170
|
+
expect do
|
|
171
|
+
IO.popen('foobar')
|
|
172
|
+
end.to raise_error(Errno::ENOENT)
|
|
170
173
|
end
|
|
171
174
|
end
|
|
172
175
|
|
|
173
|
-
context
|
|
174
|
-
it
|
|
175
|
-
expect(IO.popen(
|
|
176
|
+
context 'with a valid command' do
|
|
177
|
+
it 'should execute command' do
|
|
178
|
+
expect(IO.popen('echo test').read.chomp).to eq('test')
|
|
176
179
|
end
|
|
177
180
|
end
|
|
178
181
|
|
|
179
|
-
context
|
|
180
|
-
context
|
|
181
|
-
it
|
|
182
|
+
context 'with a non blocked command present' do
|
|
183
|
+
context 'with no command injection' do
|
|
184
|
+
it 'should execute the command' do
|
|
182
185
|
expect(TCellAgent).to receive(:policy).with(
|
|
183
|
-
TCellAgent::PolicyTypes::
|
|
186
|
+
TCellAgent::PolicyTypes::Rust
|
|
184
187
|
).and_return(nil)
|
|
185
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
186
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
188
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
189
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
187
190
|
|
|
188
|
-
IO.popen(
|
|
191
|
+
IO.popen('echo test')
|
|
189
192
|
end
|
|
190
193
|
end
|
|
191
194
|
|
|
192
|
-
context
|
|
193
|
-
it
|
|
194
|
-
|
|
195
|
-
expect(
|
|
195
|
+
context 'with command injection disabled' do
|
|
196
|
+
it 'should execute the command' do
|
|
197
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
198
|
+
expect(rust_policies.cmdi_enabled).to eq(false)
|
|
196
199
|
|
|
197
200
|
expect(TCellAgent).to receive(:policy).with(
|
|
198
|
-
TCellAgent::PolicyTypes::
|
|
199
|
-
).and_return(
|
|
200
|
-
expect(
|
|
201
|
-
expect(
|
|
201
|
+
TCellAgent::PolicyTypes::Rust
|
|
202
|
+
).and_return(rust_policies)
|
|
203
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_call_original
|
|
204
|
+
expect(rust_policies).to_not receive(:block_command?)
|
|
202
205
|
|
|
203
|
-
IO.popen(
|
|
206
|
+
IO.popen('echo test')
|
|
204
207
|
end
|
|
205
208
|
end
|
|
206
209
|
|
|
207
|
-
context
|
|
208
|
-
it
|
|
209
|
-
|
|
210
|
-
command_injection_policy.enabled = true
|
|
211
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
210
|
+
context 'with command injection enabled' do
|
|
211
|
+
it 'should execute the command' do
|
|
212
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
212
213
|
|
|
213
214
|
expect(TCellAgent).to receive(:policy).with(
|
|
214
|
-
TCellAgent::PolicyTypes::
|
|
215
|
-
).and_return(
|
|
216
|
-
expect(
|
|
217
|
-
expect(
|
|
215
|
+
TCellAgent::PolicyTypes::Rust
|
|
216
|
+
).and_return(rust_policies)
|
|
217
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
218
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(false)
|
|
218
219
|
|
|
219
|
-
IO.popen(
|
|
220
|
+
IO.popen('echo test')
|
|
220
221
|
end
|
|
221
222
|
end
|
|
222
223
|
end
|
|
223
224
|
|
|
224
|
-
context
|
|
225
|
-
context
|
|
226
|
-
it
|
|
227
|
-
|
|
228
|
-
command_injection_policy.enabled = true
|
|
229
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
225
|
+
context 'with a blocked command present' do
|
|
226
|
+
context 'with command injection enabled' do
|
|
227
|
+
it 'should raise a Errno::ENOENT' do
|
|
228
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
230
229
|
|
|
231
230
|
expect(TCellAgent).to receive(:policy).with(
|
|
232
|
-
TCellAgent::PolicyTypes::
|
|
233
|
-
).and_return(
|
|
234
|
-
expect(
|
|
235
|
-
expect(
|
|
231
|
+
TCellAgent::PolicyTypes::Rust
|
|
232
|
+
).and_return(rust_policies)
|
|
233
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
234
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
236
235
|
|
|
237
|
-
expect
|
|
238
|
-
IO.popen(
|
|
239
|
-
|
|
236
|
+
expect do
|
|
237
|
+
IO.popen('echo test')
|
|
238
|
+
end.to raise_error(Errno::ENOENT)
|
|
240
239
|
end
|
|
241
240
|
end
|
|
242
241
|
end
|
|
243
242
|
|
|
244
|
-
context
|
|
243
|
+
context 'with env' do
|
|
245
244
|
before(:each) do
|
|
246
|
-
@env = {
|
|
245
|
+
@env = { 'TCELL_VAR' => 'enabled' }
|
|
247
246
|
end
|
|
248
247
|
|
|
249
|
-
context
|
|
250
|
-
it
|
|
251
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
252
|
-
IO.popen(@env,
|
|
248
|
+
context 'with string command' do
|
|
249
|
+
it 'should execute the command' do
|
|
250
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
251
|
+
IO.popen(@env, 'echo', 'w+')
|
|
253
252
|
|
|
254
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
255
|
-
IO.popen(@env,
|
|
253
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
254
|
+
IO.popen(@env, 'echo', 'w+', :unsetenv_others => true)
|
|
256
255
|
end
|
|
257
256
|
end
|
|
258
257
|
|
|
259
|
-
context
|
|
260
|
-
it
|
|
261
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
262
|
-
IO.popen(@env,
|
|
258
|
+
context 'with string command and arguments' do
|
|
259
|
+
it 'should parse the command' do
|
|
260
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
261
|
+
IO.popen(@env, 'echo test')
|
|
263
262
|
|
|
264
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
265
|
-
IO.popen(@env,
|
|
263
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
264
|
+
IO.popen(@env, 'echo test', 'w+')
|
|
266
265
|
|
|
267
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
268
|
-
IO.popen(@env,
|
|
266
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
267
|
+
IO.popen(@env, 'echo test', :unsetenv_others => true)
|
|
269
268
|
|
|
270
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
271
|
-
IO.popen(@env,
|
|
269
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
270
|
+
IO.popen(@env, 'echo test', 'w+', :unsetenv_others => true)
|
|
272
271
|
end
|
|
273
272
|
end
|
|
274
273
|
|
|
275
|
-
context
|
|
276
|
-
it
|
|
277
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
278
|
-
IO.popen(@env, [[
|
|
274
|
+
context 'with array command' do
|
|
275
|
+
it 'should parse the command properly' do
|
|
276
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
277
|
+
IO.popen(@env, [%w[echo argv0]], 'w+')
|
|
279
278
|
|
|
280
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
281
|
-
IO.popen(@env, [[
|
|
279
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
280
|
+
IO.popen(@env, [%w[echo argv0]], :unsetenv_others => true)
|
|
282
281
|
|
|
283
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
284
|
-
IO.popen(@env, [[
|
|
282
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
283
|
+
IO.popen(@env, [%w[echo argv0]], 'w+', :unsetenv_others => true)
|
|
285
284
|
|
|
286
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
287
|
-
IO.popen(@env, [
|
|
285
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
286
|
+
IO.popen(@env, ['echo'], 'w+')
|
|
288
287
|
|
|
289
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
290
|
-
IO.popen(@env, [
|
|
288
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
289
|
+
IO.popen(@env, ['echo'], :unsetenv_others => true)
|
|
291
290
|
|
|
292
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
293
|
-
IO.popen(@env, [
|
|
291
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
292
|
+
IO.popen(@env, ['echo'], 'w+', :unsetenv_others => true)
|
|
294
293
|
end
|
|
295
294
|
end
|
|
296
295
|
|
|
297
|
-
context
|
|
298
|
-
it
|
|
299
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
300
|
-
IO.popen(@env, [[
|
|
296
|
+
context 'with array command and arguments' do
|
|
297
|
+
it 'should parse the command properly' do
|
|
298
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
299
|
+
IO.popen(@env, [%w[echo argv0], 'test'])
|
|
301
300
|
|
|
302
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
303
|
-
IO.popen(@env, [[
|
|
301
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
302
|
+
IO.popen(@env, [%w[echo argv0], 'test'], 'w+')
|
|
304
303
|
|
|
305
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
306
|
-
IO.popen(@env, [[
|
|
304
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
305
|
+
IO.popen(@env, [%w[echo argv0], 'test'], :unsetenv_others => true)
|
|
307
306
|
|
|
308
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
309
|
-
IO.popen(@env, [[
|
|
307
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
308
|
+
IO.popen(@env, [%w[echo argv0], 'test'], 'w+', :unsetenv_others => true)
|
|
310
309
|
|
|
311
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
312
|
-
IO.popen(@env, [
|
|
310
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
311
|
+
IO.popen(@env, %w[echo test])
|
|
313
312
|
|
|
314
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
315
|
-
IO.popen(@env, [
|
|
313
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
314
|
+
IO.popen(@env, %w[echo test], 'w+')
|
|
316
315
|
|
|
317
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
318
|
-
IO.popen(@env, [
|
|
316
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
317
|
+
IO.popen(@env, %w[echo test], :unsetenv_others => true)
|
|
319
318
|
|
|
320
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
321
|
-
IO.popen(@env, [
|
|
319
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
320
|
+
IO.popen(@env, %w[echo test], 'w+', :unsetenv_others => true)
|
|
322
321
|
|
|
323
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
324
|
-
IO.popen([@env,
|
|
322
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
323
|
+
IO.popen([@env, 'echo', 'test', :unsetenv_others => true], 'w+')
|
|
325
324
|
|
|
326
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
327
|
-
IO.popen(@env, [@env,
|
|
325
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
326
|
+
IO.popen(@env, [@env, 'echo', 'test', :unsetenv_others => true], 'w+', :err => %i[child out])
|
|
328
327
|
end
|
|
329
328
|
end
|
|
330
329
|
end
|
|
331
330
|
|
|
332
|
-
context
|
|
333
|
-
context
|
|
334
|
-
it
|
|
335
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
336
|
-
IO.popen([[
|
|
331
|
+
context 'without env' do
|
|
332
|
+
context 'with array command and arguments' do
|
|
333
|
+
it 'should parse the command properly' do
|
|
334
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
335
|
+
IO.popen([%w[echo argv0], 'test'])
|
|
337
336
|
|
|
338
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
339
|
-
IO.popen([[
|
|
337
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
338
|
+
IO.popen([%w[echo argv0], 'test'], 'w+')
|
|
340
339
|
|
|
341
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
342
|
-
IO.popen([[
|
|
340
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
341
|
+
IO.popen([%w[echo argv0], 'test'], :unsetenv_others => true)
|
|
343
342
|
|
|
344
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
345
|
-
IO.popen([[
|
|
343
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
344
|
+
IO.popen([%w[echo argv0], 'test'], 'w+', :unsetenv_others => true)
|
|
346
345
|
|
|
347
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
348
|
-
IO.popen([
|
|
346
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
347
|
+
IO.popen(%w[echo test])
|
|
349
348
|
|
|
350
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
351
|
-
IO.popen([
|
|
349
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
350
|
+
IO.popen(%w[echo test], 'w+')
|
|
352
351
|
|
|
353
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
354
|
-
IO.popen([
|
|
352
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
353
|
+
IO.popen(%w[echo test], :unsetenv_others => true)
|
|
355
354
|
|
|
356
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
357
|
-
IO.popen([
|
|
355
|
+
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
356
|
+
IO.popen(%w[echo test], 'w+', :unsetenv_others => true)
|
|
358
357
|
|
|
359
358
|
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
360
359
|
"echo -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
361
360
|
)
|
|
362
361
|
IO.popen(
|
|
363
|
-
[[
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
:unsetenv_others => true
|
|
362
|
+
[%w[echo argv0],
|
|
363
|
+
'-size',
|
|
364
|
+
'320x85',
|
|
365
|
+
'canvas:none',
|
|
366
|
+
'-font',
|
|
367
|
+
'Bookman-DemiItalic',
|
|
368
|
+
'-draw',
|
|
369
|
+
"\"text 25,60 \'Magick\'\""],
|
|
370
|
+
:unsetenv_others => true
|
|
371
|
+
)
|
|
372
372
|
end
|
|
373
373
|
end
|
|
374
374
|
end
|
|
@@ -376,370 +376,347 @@ module TCellAgent
|
|
|
376
376
|
end
|
|
377
377
|
|
|
378
378
|
describe Kernel do
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
expect {
|
|
379
|
+
describe '.backtick' do
|
|
380
|
+
context 'empty command' do
|
|
381
|
+
it 'should raise Errno::ENOENT' do
|
|
382
|
+
expect do
|
|
384
383
|
``
|
|
385
|
-
|
|
384
|
+
end.to raise_error(Errno::ENOENT)
|
|
386
385
|
end
|
|
387
386
|
end
|
|
388
387
|
|
|
389
|
-
context
|
|
390
|
-
context
|
|
391
|
-
it
|
|
388
|
+
context 'with a non blocked command present' do
|
|
389
|
+
context 'with no command injection' do
|
|
390
|
+
it 'should execute the command' do
|
|
392
391
|
expect(TCellAgent).to receive(:policy).with(
|
|
393
|
-
TCellAgent::PolicyTypes::
|
|
392
|
+
TCellAgent::PolicyTypes::Rust
|
|
394
393
|
).and_return(nil)
|
|
395
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
396
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
394
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
395
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
397
396
|
|
|
398
397
|
`echo test`
|
|
399
398
|
end
|
|
400
399
|
end
|
|
401
400
|
|
|
402
|
-
context
|
|
403
|
-
it
|
|
404
|
-
|
|
405
|
-
expect(command_injection_policy.enabled).to eq(false)
|
|
401
|
+
context 'with command injection disabled' do
|
|
402
|
+
it 'should execute the command' do
|
|
403
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
406
404
|
|
|
407
405
|
expect(TCellAgent).to receive(:policy).with(
|
|
408
|
-
TCellAgent::PolicyTypes::
|
|
409
|
-
).and_return(
|
|
410
|
-
expect(
|
|
411
|
-
expect(
|
|
406
|
+
TCellAgent::PolicyTypes::Rust
|
|
407
|
+
).and_return(rust_policies)
|
|
408
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(false)
|
|
409
|
+
expect(rust_policies).to_not receive(:block_command?)
|
|
412
410
|
|
|
413
411
|
`echo test`
|
|
414
412
|
end
|
|
415
413
|
end
|
|
416
414
|
|
|
417
|
-
context
|
|
418
|
-
it
|
|
419
|
-
|
|
420
|
-
command_injection_policy.enabled = true
|
|
421
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
415
|
+
context 'with command injection enabled' do
|
|
416
|
+
it 'should execute the command' do
|
|
417
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
422
418
|
|
|
423
419
|
expect(TCellAgent).to receive(:policy).with(
|
|
424
|
-
TCellAgent::PolicyTypes::
|
|
425
|
-
).and_return(
|
|
426
|
-
expect(
|
|
427
|
-
expect(
|
|
420
|
+
TCellAgent::PolicyTypes::Rust
|
|
421
|
+
).and_return(rust_policies)
|
|
422
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
423
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(false)
|
|
428
424
|
|
|
429
425
|
`echo test`
|
|
430
426
|
end
|
|
431
427
|
end
|
|
432
428
|
end
|
|
433
429
|
|
|
434
|
-
context
|
|
435
|
-
context
|
|
436
|
-
it
|
|
437
|
-
|
|
438
|
-
command_injection_policy.enabled = true
|
|
439
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
430
|
+
context 'with a blocked command present' do
|
|
431
|
+
context 'with command injection enabled' do
|
|
432
|
+
it 'should raise a Errno::ENOENT' do
|
|
433
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
440
434
|
|
|
441
435
|
expect(TCellAgent).to receive(:policy).with(
|
|
442
|
-
TCellAgent::PolicyTypes::
|
|
443
|
-
).and_return(
|
|
444
|
-
expect(
|
|
445
|
-
expect(
|
|
436
|
+
TCellAgent::PolicyTypes::Rust
|
|
437
|
+
).and_return(rust_policies)
|
|
438
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
439
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
446
440
|
|
|
447
|
-
expect
|
|
441
|
+
expect do
|
|
448
442
|
`echo test`
|
|
449
|
-
|
|
443
|
+
end.to raise_error(Errno::ENOENT)
|
|
450
444
|
end
|
|
451
445
|
end
|
|
452
446
|
end
|
|
453
447
|
end
|
|
454
448
|
|
|
455
|
-
describe
|
|
456
|
-
context
|
|
457
|
-
it
|
|
458
|
-
expect
|
|
459
|
-
|
|
460
|
-
|
|
449
|
+
describe '%x methods' do
|
|
450
|
+
context 'empty command' do
|
|
451
|
+
it 'should raise Errno::ENOENT' do
|
|
452
|
+
expect do
|
|
453
|
+
``
|
|
454
|
+
end.to raise_error(Errno::ENOENT)
|
|
461
455
|
end
|
|
462
456
|
end
|
|
463
457
|
|
|
464
|
-
context
|
|
465
|
-
context
|
|
466
|
-
it
|
|
458
|
+
context 'with a non blocked command present' do
|
|
459
|
+
context 'with no command injection' do
|
|
460
|
+
it 'should execute the command' do
|
|
467
461
|
expect(TCellAgent).to receive(:policy).with(
|
|
468
|
-
TCellAgent::PolicyTypes::
|
|
462
|
+
TCellAgent::PolicyTypes::Rust
|
|
469
463
|
).and_return(nil)
|
|
470
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
471
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
464
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
465
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
472
466
|
|
|
473
|
-
|
|
467
|
+
`echo test`
|
|
474
468
|
end
|
|
475
469
|
end
|
|
476
470
|
|
|
477
|
-
context
|
|
478
|
-
it
|
|
479
|
-
|
|
480
|
-
expect(command_injection_policy.enabled).to eq(false)
|
|
471
|
+
context 'with command injection disabled' do
|
|
472
|
+
it 'should execute the command' do
|
|
473
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
481
474
|
|
|
482
475
|
expect(TCellAgent).to receive(:policy).with(
|
|
483
|
-
TCellAgent::PolicyTypes::
|
|
484
|
-
).and_return(
|
|
485
|
-
expect(
|
|
486
|
-
expect(
|
|
476
|
+
TCellAgent::PolicyTypes::Rust
|
|
477
|
+
).and_return(rust_policies)
|
|
478
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(false)
|
|
479
|
+
expect(rust_policies).to_not receive(:block_command?)
|
|
487
480
|
|
|
488
|
-
|
|
481
|
+
`echo test`
|
|
489
482
|
end
|
|
490
483
|
end
|
|
491
484
|
|
|
492
|
-
context
|
|
493
|
-
it
|
|
494
|
-
|
|
495
|
-
command_injection_policy.enabled = true
|
|
496
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
485
|
+
context 'with command injection enabled' do
|
|
486
|
+
it 'should execute the command' do
|
|
487
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
497
488
|
|
|
498
489
|
expect(TCellAgent).to receive(:policy).with(
|
|
499
|
-
TCellAgent::PolicyTypes::
|
|
500
|
-
).and_return(
|
|
501
|
-
expect(
|
|
502
|
-
expect(
|
|
490
|
+
TCellAgent::PolicyTypes::Rust
|
|
491
|
+
).and_return(rust_policies)
|
|
492
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
493
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(false)
|
|
503
494
|
|
|
504
|
-
|
|
495
|
+
`echo test`
|
|
505
496
|
end
|
|
506
497
|
end
|
|
507
498
|
end
|
|
508
499
|
|
|
509
|
-
context
|
|
510
|
-
context
|
|
511
|
-
it
|
|
512
|
-
|
|
513
|
-
command_injection_policy.enabled = true
|
|
514
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
500
|
+
context 'with a blocked command present' do
|
|
501
|
+
context 'with command injection enabled' do
|
|
502
|
+
it 'should raise a Errno::ENOENT' do
|
|
503
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
515
504
|
|
|
516
505
|
expect(TCellAgent).to receive(:policy).with(
|
|
517
|
-
TCellAgent::PolicyTypes::
|
|
518
|
-
).and_return(
|
|
519
|
-
expect(
|
|
520
|
-
expect(
|
|
506
|
+
TCellAgent::PolicyTypes::Rust
|
|
507
|
+
).and_return(rust_policies)
|
|
508
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
509
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
521
510
|
|
|
522
|
-
expect
|
|
523
|
-
|
|
524
|
-
|
|
511
|
+
expect do
|
|
512
|
+
`echo test`
|
|
513
|
+
end.to raise_error(Errno::ENOENT)
|
|
525
514
|
end
|
|
526
515
|
end
|
|
527
516
|
end
|
|
528
517
|
end
|
|
529
518
|
|
|
530
|
-
describe
|
|
531
|
-
context
|
|
532
|
-
it
|
|
533
|
-
expect
|
|
534
|
-
system
|
|
535
|
-
|
|
536
|
-
expect
|
|
519
|
+
describe '.system' do
|
|
520
|
+
context 'empty command' do
|
|
521
|
+
it 'should raise an error' do
|
|
522
|
+
expect do
|
|
523
|
+
system
|
|
524
|
+
end.to raise_error(ArgumentError)
|
|
525
|
+
expect do
|
|
537
526
|
system(nil)
|
|
538
|
-
|
|
527
|
+
end.to raise_error(TypeError)
|
|
539
528
|
|
|
540
|
-
expect(system(
|
|
529
|
+
expect(system('')).to be_nil
|
|
541
530
|
end
|
|
542
531
|
end
|
|
543
532
|
|
|
544
|
-
context
|
|
545
|
-
it
|
|
546
|
-
expect(system(
|
|
533
|
+
context 'non existent command' do
|
|
534
|
+
it 'should return nil' do
|
|
535
|
+
expect(system('foobar')).to be_nil
|
|
547
536
|
end
|
|
548
537
|
end
|
|
549
538
|
|
|
550
|
-
context
|
|
551
|
-
it
|
|
552
|
-
pid = system(
|
|
539
|
+
context 'with a valid command' do
|
|
540
|
+
it 'should execute command' do
|
|
541
|
+
pid = system('echo test > /dev/null 2>&1')
|
|
553
542
|
expect(pid).to eq(true)
|
|
554
543
|
|
|
555
|
-
pid = system(RbConfig.ruby, "-e'Hello World!'",
|
|
544
|
+
pid = system(RbConfig.ruby, "-e'Hello World!'", '>', '/dev/null', '2>&1')
|
|
556
545
|
expect(pid).to eq(true)
|
|
557
546
|
end
|
|
558
547
|
end
|
|
559
548
|
|
|
560
|
-
context
|
|
561
|
-
context
|
|
562
|
-
it
|
|
549
|
+
context 'with a non blocked command present' do
|
|
550
|
+
context 'with no command injection' do
|
|
551
|
+
it 'should execute the command' do
|
|
563
552
|
expect(TCellAgent).to receive(:policy).with(
|
|
564
|
-
TCellAgent::PolicyTypes::
|
|
553
|
+
TCellAgent::PolicyTypes::Rust
|
|
565
554
|
).and_return(nil)
|
|
566
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
567
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
555
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
556
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
568
557
|
|
|
569
|
-
system(
|
|
558
|
+
system('echo test > /dev/null 2>&1')
|
|
570
559
|
end
|
|
571
560
|
end
|
|
572
561
|
|
|
573
|
-
context
|
|
574
|
-
it
|
|
575
|
-
|
|
576
|
-
expect(command_injection_policy.enabled).to eq(false)
|
|
562
|
+
context 'with command injection disabled' do
|
|
563
|
+
it 'should execute the command' do
|
|
564
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
577
565
|
|
|
578
566
|
expect(TCellAgent).to receive(:policy).with(
|
|
579
|
-
TCellAgent::PolicyTypes::
|
|
580
|
-
).and_return(
|
|
581
|
-
expect(
|
|
582
|
-
expect(
|
|
567
|
+
TCellAgent::PolicyTypes::Rust
|
|
568
|
+
).and_return(rust_policies)
|
|
569
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(false)
|
|
570
|
+
expect(rust_policies).to_not receive(:block_command?)
|
|
583
571
|
|
|
584
|
-
system(
|
|
572
|
+
system('echo test > /dev/null 2>&1')
|
|
585
573
|
end
|
|
586
574
|
end
|
|
587
575
|
|
|
588
|
-
context
|
|
589
|
-
it
|
|
590
|
-
|
|
591
|
-
command_injection_policy.enabled = true
|
|
592
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
576
|
+
context 'with command injection enabled' do
|
|
577
|
+
it 'should execute the command' do
|
|
578
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
593
579
|
|
|
594
580
|
expect(TCellAgent).to receive(:policy).with(
|
|
595
|
-
TCellAgent::PolicyTypes::
|
|
596
|
-
).and_return(
|
|
597
|
-
expect(
|
|
598
|
-
expect(
|
|
581
|
+
TCellAgent::PolicyTypes::Rust
|
|
582
|
+
).and_return(rust_policies)
|
|
583
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
584
|
+
expect(rust_policies).to receive(:block_command?).with('echo test > /dev/null 2>&1', nil).and_return(false)
|
|
599
585
|
|
|
600
|
-
system(
|
|
586
|
+
system('echo test > /dev/null 2>&1')
|
|
601
587
|
end
|
|
602
588
|
end
|
|
603
589
|
end
|
|
604
590
|
|
|
605
|
-
context
|
|
606
|
-
context
|
|
607
|
-
it
|
|
608
|
-
|
|
609
|
-
command_injection_policy.enabled = true
|
|
610
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
591
|
+
context 'with a blocked command present' do
|
|
592
|
+
context 'with command injection enabled' do
|
|
593
|
+
it 'should raise a Errno::ENOENT' do
|
|
594
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
611
595
|
|
|
612
596
|
expect(TCellAgent).to receive(:policy).with(
|
|
613
|
-
TCellAgent::PolicyTypes::
|
|
614
|
-
).and_return(
|
|
615
|
-
expect(
|
|
616
|
-
expect(
|
|
597
|
+
TCellAgent::PolicyTypes::Rust
|
|
598
|
+
).and_return(rust_policies)
|
|
599
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
600
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
617
601
|
|
|
618
|
-
expect
|
|
619
|
-
system(
|
|
620
|
-
|
|
602
|
+
expect do
|
|
603
|
+
system('echo test')
|
|
604
|
+
end.to raise_error(Errno::ENOENT)
|
|
621
605
|
end
|
|
622
606
|
end
|
|
623
607
|
end
|
|
624
608
|
end
|
|
625
609
|
|
|
626
|
-
describe
|
|
627
|
-
context
|
|
628
|
-
it
|
|
629
|
-
expect
|
|
630
|
-
spawn
|
|
631
|
-
|
|
632
|
-
expect
|
|
610
|
+
describe '.spawn' do
|
|
611
|
+
context 'empty command' do
|
|
612
|
+
it 'should raise an error' do
|
|
613
|
+
expect do
|
|
614
|
+
spawn
|
|
615
|
+
end.to raise_error(ArgumentError)
|
|
616
|
+
expect do
|
|
633
617
|
spawn(nil)
|
|
634
|
-
|
|
635
|
-
expect
|
|
636
|
-
spawn(
|
|
637
|
-
|
|
618
|
+
end.to raise_error(TypeError)
|
|
619
|
+
expect do
|
|
620
|
+
spawn('')
|
|
621
|
+
end.to raise_error(Errno::ENOENT)
|
|
638
622
|
end
|
|
639
623
|
end
|
|
640
624
|
|
|
641
|
-
context
|
|
642
|
-
it
|
|
643
|
-
expect
|
|
644
|
-
spawn(
|
|
645
|
-
|
|
625
|
+
context 'non existent command' do
|
|
626
|
+
it 'should raise error' do
|
|
627
|
+
expect do
|
|
628
|
+
spawn('foobar')
|
|
629
|
+
end.to raise_error(Errno::ENOENT)
|
|
646
630
|
end
|
|
647
631
|
end
|
|
648
632
|
|
|
649
|
-
context
|
|
650
|
-
it
|
|
651
|
-
pid = spawn(
|
|
633
|
+
context 'with a valid command' do
|
|
634
|
+
it 'should execute command' do
|
|
635
|
+
pid = spawn('echo test > /dev/null 2>&1')
|
|
652
636
|
expect(pid).to_not be_nil
|
|
653
637
|
|
|
654
|
-
pid = spawn(RbConfig.ruby, "-e'Hello World!'",
|
|
638
|
+
pid = spawn(RbConfig.ruby, "-e'Hello World!'", '>', '/dev/null', '2>&1')
|
|
655
639
|
expect(pid).to_not be_nil
|
|
656
640
|
end
|
|
657
641
|
end
|
|
658
642
|
|
|
659
|
-
context
|
|
660
|
-
context
|
|
661
|
-
it
|
|
643
|
+
context 'with a non blocked command present' do
|
|
644
|
+
context 'with no command injection' do
|
|
645
|
+
it 'should execute the command' do
|
|
662
646
|
expect(TCellAgent).to receive(:policy).with(
|
|
663
|
-
TCellAgent::PolicyTypes::
|
|
647
|
+
TCellAgent::PolicyTypes::Rust
|
|
664
648
|
).and_return(nil)
|
|
665
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
666
|
-
expect_any_instance_of(TCellAgent::Policies::
|
|
649
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
650
|
+
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
667
651
|
|
|
668
|
-
spawn(
|
|
652
|
+
spawn('echo test > /dev/null 2>&1')
|
|
669
653
|
end
|
|
670
654
|
end
|
|
671
655
|
|
|
672
|
-
context
|
|
673
|
-
it
|
|
674
|
-
|
|
675
|
-
expect(command_injection_policy.enabled).to eq(false)
|
|
656
|
+
context 'with command injection disabled' do
|
|
657
|
+
it 'should execute the command' do
|
|
658
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
676
659
|
|
|
677
660
|
expect(TCellAgent).to receive(:policy).with(
|
|
678
|
-
TCellAgent::PolicyTypes::
|
|
679
|
-
).and_return(
|
|
680
|
-
expect(
|
|
681
|
-
expect(
|
|
661
|
+
TCellAgent::PolicyTypes::Rust
|
|
662
|
+
).and_return(rust_policies)
|
|
663
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(false)
|
|
664
|
+
expect(rust_policies).to_not receive(:block_command?)
|
|
682
665
|
|
|
683
|
-
spawn(
|
|
666
|
+
spawn('echo test > /dev/null 2>&1')
|
|
684
667
|
end
|
|
685
668
|
end
|
|
686
669
|
|
|
687
|
-
context
|
|
688
|
-
it
|
|
689
|
-
|
|
690
|
-
command_injection_policy.enabled = true
|
|
691
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
670
|
+
context 'with command injection enabled' do
|
|
671
|
+
it 'should execute the command' do
|
|
672
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
692
673
|
|
|
693
674
|
expect(TCellAgent).to receive(:policy).with(
|
|
694
|
-
TCellAgent::PolicyTypes::
|
|
695
|
-
).and_return(
|
|
696
|
-
expect(
|
|
697
|
-
expect(
|
|
675
|
+
TCellAgent::PolicyTypes::Rust
|
|
676
|
+
).and_return(rust_policies)
|
|
677
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
678
|
+
expect(rust_policies).to receive(:block_command?).with('echo test > /dev/null 2>&1', nil).and_return(false)
|
|
698
679
|
|
|
699
|
-
spawn(
|
|
680
|
+
spawn('echo test > /dev/null 2>&1')
|
|
700
681
|
end
|
|
701
682
|
end
|
|
702
683
|
end
|
|
703
684
|
|
|
704
|
-
context
|
|
705
|
-
context
|
|
706
|
-
it
|
|
707
|
-
|
|
708
|
-
command_injection_policy.enabled = true
|
|
709
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
685
|
+
context 'with a blocked command present' do
|
|
686
|
+
context 'with command injection enabled' do
|
|
687
|
+
it 'should raise a Errno::ENOENT' do
|
|
688
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
710
689
|
|
|
711
690
|
expect(TCellAgent).to receive(:policy).with(
|
|
712
|
-
TCellAgent::PolicyTypes::
|
|
713
|
-
).and_return(
|
|
714
|
-
expect(
|
|
715
|
-
expect(
|
|
691
|
+
TCellAgent::PolicyTypes::Rust
|
|
692
|
+
).and_return(rust_policies)
|
|
693
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
694
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
716
695
|
|
|
717
|
-
expect
|
|
718
|
-
spawn(
|
|
719
|
-
|
|
696
|
+
expect do
|
|
697
|
+
spawn('echo test')
|
|
698
|
+
end.to raise_error(Errno::ENOENT)
|
|
720
699
|
end
|
|
721
700
|
end
|
|
722
701
|
end
|
|
723
702
|
end
|
|
724
703
|
|
|
725
|
-
describe
|
|
704
|
+
describe '.exec' do
|
|
726
705
|
# can only test this case since exec replaces current process with new process
|
|
727
|
-
context
|
|
728
|
-
context
|
|
729
|
-
it
|
|
730
|
-
|
|
731
|
-
command_injection_policy.enabled = true
|
|
732
|
-
expect(command_injection_policy.enabled).to eq(true)
|
|
706
|
+
context 'with a blocked command present' do
|
|
707
|
+
context 'with command injection enabled' do
|
|
708
|
+
it 'should raise a Errno::ENOENT' do
|
|
709
|
+
rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
733
710
|
|
|
734
711
|
expect(TCellAgent).to receive(:policy).with(
|
|
735
|
-
TCellAgent::PolicyTypes::
|
|
736
|
-
).and_return(
|
|
737
|
-
expect(
|
|
738
|
-
expect(
|
|
739
|
-
|
|
740
|
-
expect
|
|
741
|
-
exec(
|
|
742
|
-
|
|
712
|
+
TCellAgent::PolicyTypes::Rust
|
|
713
|
+
).and_return(rust_policies)
|
|
714
|
+
expect(rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
715
|
+
expect(rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
716
|
+
|
|
717
|
+
expect do
|
|
718
|
+
exec('echo test')
|
|
719
|
+
end.to raise_error(Errno::ENOENT)
|
|
743
720
|
end
|
|
744
721
|
end
|
|
745
722
|
end
|