tcell_agent 2.1.2 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/bin/tcell_agent +41 -150
- data/lib/tcell_agent.rb +8 -16
- data/lib/tcell_agent/agent.rb +87 -52
- data/lib/tcell_agent/config_initializer.rb +62 -0
- data/lib/tcell_agent/configuration.rb +72 -267
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrument_servers.rb +14 -18
- 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 +3 -4
- 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/authlogic.rb +49 -44
- data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
- data/lib/tcell_agent/rails/auth/devise.rb +103 -102
- data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -57
- data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
- data/lib/tcell_agent/rails/better_ip.rb +7 -19
- data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
- data/lib/tcell_agent/rails/dlp.rb +48 -52
- 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 +3 -4
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
- data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
- data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
- data/lib/tcell_agent/rails/routes.rb +3 -6
- data/lib/tcell_agent/rails/routes/grape.rb +3 -4
- data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
- data/lib/tcell_agent/routes/table.rb +3 -0
- data/lib/tcell_agent/rust/agent_config.rb +59 -33
- data/lib/tcell_agent/rust/{libtcellagent-4.18.0.so → libtcellagent-alpine.so} +0 -0
- data/lib/tcell_agent/rust/libtcellagent-x64.dll +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-4.18.0.dylib → libtcellagent.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-4.18.0.so → libtcellagent.so} +0 -0
- data/lib/tcell_agent/rust/models.rb +9 -0
- data/lib/tcell_agent/rust/native_agent.rb +58 -50
- data/lib/tcell_agent/rust/native_library.rb +8 -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 +30 -13
- data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -0
- data/lib/tcell_agent/servers/rails_server.rb +4 -4
- data/lib/tcell_agent/servers/unicorn.rb +1 -1
- data/lib/tcell_agent/servers/webrick.rb +12 -3
- data/lib/tcell_agent/settings_reporter.rb +0 -93
- data/lib/tcell_agent/sinatra.rb +1 -0
- data/lib/tcell_agent/tcell_context.rb +16 -7
- 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/configuration_spec.rb +62 -212
- data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -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/rust/agent_config_spec.rb +27 -0
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
- data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
- data/spec/spec_helper.rb +9 -1
- data/spec/support/builders.rb +8 -7
- data/spec/support/server_mocks/passenger_mock.rb +7 -0
- data/spec/support/server_mocks/puma_mock.rb +21 -0
- data/spec/support/server_mocks/rails_mock.rb +7 -0
- data/spec/support/server_mocks/thin_mock.rb +7 -0
- data/spec/support/server_mocks/unicorn_mock.rb +11 -0
- data/spec/support/shared_spec.rb +29 -0
- data/tcell_agent.gemspec +14 -14
- metadata +44 -27
- data/Rakefile +0 -18
- data/lib/tcell_agent/authlogic.rb +0 -23
- data/lib/tcell_agent/config/unknown_options.rb +0 -119
- data/lib/tcell_agent/devise.rb +0 -33
- 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
- data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
- data/lib/tcell_agent/rust/tcellagent-4.18.0.dll +0 -0
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -1,6 +1,9 @@
|
|
1
|
+
# rubocop:disable Style/HashSyntax
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
require 'securerandom'
|
3
5
|
|
6
|
+
FILE_CONTENTS = "This is line one.\nThis is line two.\n".freeze
|
4
7
|
describe 'IO' do
|
5
8
|
before do
|
6
9
|
native_agent = double('native_agent')
|
@@ -17,8 +20,9 @@ describe 'IO' do
|
|
17
20
|
@file_contents = "This is line one.\nThis is line two.\n"
|
18
21
|
@file_length = @file_contents.length
|
19
22
|
|
20
|
-
@new_file_name =
|
23
|
+
@new_file_name = NEW_FILE_NAME
|
21
24
|
@new_file_contents_offset = "This OFFSETe one.\nThis is line two.\n"
|
25
|
+
@new_file_contents_offset_bytes = "\x00\x00\x00\x00\x00OFFSET"
|
22
26
|
end
|
23
27
|
|
24
28
|
describe '.binread' do
|
@@ -50,23 +54,20 @@ describe 'IO' do
|
|
50
54
|
result = IO.binread('|echo test')
|
51
55
|
expect(result).to eq "test\n"
|
52
56
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
57
|
+
|
58
|
+
it 'should read the file normally' do
|
59
|
+
result = IO.binread(@filename)
|
60
|
+
expect(result).to eq @file_contents
|
58
61
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
62
|
+
|
63
|
+
it 'should read 20 bytes of the file' do
|
64
|
+
result = IO.binread(@filename, 20)
|
65
|
+
expect(result).to eq @file_contents[0..19]
|
64
66
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
67
|
+
|
68
|
+
it 'should read 20 bytes starting from the 5th byte' do
|
69
|
+
result = IO.binread(@filename, 20, 5)
|
70
|
+
expect(result).to eq @file_contents[5..24]
|
70
71
|
end
|
71
72
|
end
|
72
73
|
context 'with a file blocked for read/write' do
|
@@ -80,30 +81,27 @@ describe 'IO' do
|
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
83
|
-
it 'should
|
84
|
+
it 'should execute shell commands', :skip_before do
|
84
85
|
result = IO.binread('|echo test')
|
85
86
|
expect(result).to eq "test\n"
|
86
87
|
end
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
88
|
+
|
89
|
+
it 'should receive an IOError' do
|
90
|
+
expect do
|
91
|
+
IO.binread(@filename)
|
92
|
+
end.to raise_error(IOError)
|
93
93
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
94
|
+
|
95
|
+
it 'should receive an IOError' do
|
96
|
+
expect do
|
97
|
+
IO.binread(@filename, 20)
|
98
|
+
end.to raise_error(IOError)
|
100
99
|
end
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
100
|
+
|
101
|
+
it 'should receive an IOError' do
|
102
|
+
expect do
|
103
|
+
IO.binread(@filename, 20, 5)
|
104
|
+
end.to raise_error(IOError)
|
107
105
|
end
|
108
106
|
end
|
109
107
|
end
|
@@ -122,6 +120,7 @@ describe 'IO' do
|
|
122
120
|
end.to raise_error(ArgumentError)
|
123
121
|
end
|
124
122
|
end
|
123
|
+
|
125
124
|
context 'with a file not blocked for read/write' do
|
126
125
|
before do
|
127
126
|
expect(TCellAgent).to receive(:policy).with(
|
@@ -130,28 +129,36 @@ describe 'IO' do
|
|
130
129
|
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
131
130
|
end
|
132
131
|
|
133
|
-
|
132
|
+
after(:each) do
|
133
|
+
File.delete(@new_file_name)
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with a non-existent file' do
|
134
137
|
it 'should create the file' do
|
135
138
|
IO.binwrite(@new_file_name, '')
|
136
139
|
expect(File.exist?(@new_file_name)).to be_truthy
|
137
|
-
File.delete(@new_file_name)
|
138
140
|
end
|
141
|
+
|
139
142
|
it 'should write to the file' do
|
140
143
|
expect(IO.binwrite(@new_file_name, @file_contents)).to eq @file_length
|
141
|
-
File.delete(@new_file_name)
|
142
144
|
end
|
143
|
-
end
|
144
|
-
context 'with a nonexistent filename and string and offset' do
|
145
|
-
it 'should write to the file at the offset value 5' do
|
146
|
-
expect(TCellAgent).to receive(:policy).with(
|
147
|
-
TCellAgent::PolicyTypes::LFI
|
148
|
-
).and_return(@local_files_policy, @local_files_policy)
|
149
|
-
expect(@local_files_policy).to receive(:block_file_access?).and_return(false, false)
|
150
145
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
146
|
+
context 'using offset, perm' do
|
147
|
+
after :each do
|
148
|
+
expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('444')
|
149
|
+
|
150
|
+
expect(TCellAgent).to receive(:policy).with(
|
151
|
+
TCellAgent::PolicyTypes::LFI
|
152
|
+
).and_return(@local_files_policy)
|
153
|
+
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
154
|
+
expect(File.open(@new_file_name).read).to eq @new_file_contents_offset_bytes
|
155
|
+
end
|
156
|
+
|
157
|
+
test_ruby2_ruby3_keywords(IO,
|
158
|
+
'binwrite',
|
159
|
+
[NEW_FILE_NAME, 'OFFSET', 5],
|
160
|
+
{ perm: 0o444 },
|
161
|
+
6)
|
155
162
|
end
|
156
163
|
end
|
157
164
|
end
|
@@ -163,19 +170,10 @@ describe 'IO' do
|
|
163
170
|
expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
|
164
171
|
end
|
165
172
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
end.to raise_error(IOError)
|
171
|
-
end
|
172
|
-
end
|
173
|
-
context 'with a nonexistent filename and a string and an offset' do
|
174
|
-
it 'should not be able to write to the file' do
|
175
|
-
expect do
|
176
|
-
IO.binwrite(@new_file_name, @file_contents)
|
177
|
-
end.to raise_error(IOError)
|
178
|
-
end
|
173
|
+
it 'should not be able to create and write to a file' do
|
174
|
+
expect do
|
175
|
+
IO.binwrite(@new_file_name, @file_contents)
|
176
|
+
end.to raise_error(IOError)
|
179
177
|
end
|
180
178
|
end
|
181
179
|
end
|
@@ -196,20 +194,18 @@ describe 'IO' do
|
|
196
194
|
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
197
195
|
end
|
198
196
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
expect(result).to eq @file_contents
|
204
|
-
end
|
197
|
+
it 'should be able to read the file' do
|
198
|
+
result = ''
|
199
|
+
IO.foreach(@filename) { |line| result << line }
|
200
|
+
expect(result).to eq @file_contents
|
205
201
|
end
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
end
|
202
|
+
|
203
|
+
it 'should split each line to a max length of 16' do
|
204
|
+
result = ''
|
205
|
+
IO.foreach(@filename, 16) { |line| result << line }
|
206
|
+
expect(result).to eq @file_contents
|
212
207
|
end
|
208
|
+
|
213
209
|
context 'with a filename and sep' do
|
214
210
|
# TODO: no documentation on how to use sep
|
215
211
|
end
|
@@ -225,14 +221,18 @@ describe 'IO' do
|
|
225
221
|
expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
|
226
222
|
end
|
227
223
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
224
|
+
it 'returns an IOError' do
|
225
|
+
expect do
|
226
|
+
result = ''
|
227
|
+
IO.foreach(@filename) { |line| result << line }
|
228
|
+
end.to raise_error(IOError)
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'returns an IOError if it is non-existent' do
|
232
|
+
expect do
|
233
|
+
result = ''
|
234
|
+
IO.foreach('/tmp/bad-file-name') { |line| result << line }
|
235
|
+
end.to raise_error(IOError)
|
236
236
|
end
|
237
237
|
end
|
238
238
|
end
|
@@ -260,27 +260,22 @@ describe 'IO' do
|
|
260
260
|
end
|
261
261
|
end
|
262
262
|
|
263
|
-
it '
|
263
|
+
it 'executes OS commands', :skip_before do
|
264
264
|
result = IO.read('|echo test')
|
265
265
|
expect(result).to eq "test\n"
|
266
266
|
end
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
end
|
272
|
-
end
|
273
|
-
context 'with a filename and a length of 20' do
|
274
|
-
it 'should read 20 bytes of the file' do
|
275
|
-
result = IO.read(@filename, 20)
|
276
|
-
expect(result).to eq @file_contents[0..19]
|
277
|
-
end
|
267
|
+
|
268
|
+
it 'returns the file contents' do
|
269
|
+
result = IO.read(@filename)
|
270
|
+
expect(result).to eq @file_contents
|
278
271
|
end
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
272
|
+
|
273
|
+
context 'using length, offset, mode' do
|
274
|
+
test_ruby2_ruby3_keywords(IO,
|
275
|
+
'read',
|
276
|
+
[get_test_resource_path('lfi_sample_file.txt'), 20, 5],
|
277
|
+
{ mode: 'rb' },
|
278
|
+
FILE_CONTENTS[5..24])
|
284
279
|
end
|
285
280
|
end
|
286
281
|
context 'with a file blocked for read/write' do
|
@@ -295,30 +290,24 @@ describe 'IO' do
|
|
295
290
|
end
|
296
291
|
end
|
297
292
|
|
298
|
-
it '
|
293
|
+
it 'executes OS commands', :skip_before do
|
299
294
|
result = IO.read('|echo test')
|
300
295
|
expect(result).to eq "test\n"
|
301
296
|
end
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
end.to raise_error(IOError)
|
307
|
-
end
|
297
|
+
it 'receeive an IOError' do
|
298
|
+
expect do
|
299
|
+
IO.read(@filename)
|
300
|
+
end.to raise_error(IOError)
|
308
301
|
end
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
end.to raise_error(IOError)
|
314
|
-
end
|
302
|
+
it 'receeive an IOError' do
|
303
|
+
expect do
|
304
|
+
IO.read(@filename, 20)
|
305
|
+
end.to raise_error(IOError)
|
315
306
|
end
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
end.to raise_error(IOError)
|
321
|
-
end
|
307
|
+
it 'receeive an IOError' do
|
308
|
+
expect do
|
309
|
+
IO.read(@filename, 20, 5)
|
310
|
+
end.to raise_error(IOError)
|
322
311
|
end
|
323
312
|
end
|
324
313
|
end
|
@@ -346,21 +335,30 @@ describe 'IO' do
|
|
346
335
|
end
|
347
336
|
end
|
348
337
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
expect(result[0] + result[1]).to eq @file_contents
|
353
|
-
end
|
338
|
+
it 'reads the file normally' do
|
339
|
+
result = IO.readlines(@filename)
|
340
|
+
expect(result[0] + result[1]).to eq @file_contents
|
354
341
|
end
|
355
|
-
|
356
|
-
|
342
|
+
|
343
|
+
context 'using limit, separator' do
|
344
|
+
it 'splits the file and splits it into 5 char chunks' do
|
357
345
|
exp_result = ['This ', 'is li', 'ne on', "e.\n", 'This ', 'is li', 'ne tw', "o.\n"]
|
358
346
|
result = IO.readlines(@filename, 5)
|
359
347
|
expect(result).to eq exp_result
|
360
348
|
end
|
361
|
-
|
362
|
-
|
363
|
-
|
349
|
+
|
350
|
+
it 'splits the file based on the sep and limit' do
|
351
|
+
exp_result = ['This ', 'is ', 'line ', "one.\n", 'This ', 'is ', 'line ', "two.\n"]
|
352
|
+
result = IO.readlines(@filename, ' ', 5)
|
353
|
+
expect(result).to eq exp_result
|
354
|
+
end
|
355
|
+
|
356
|
+
test_ruby2_ruby3_keywords(IO,
|
357
|
+
'readlines',
|
358
|
+
[get_test_resource_path('lfi_sample_file.txt'), ' ', 5],
|
359
|
+
{ chomp: true },
|
360
|
+
['This', 'is', 'line', "one.\n", 'This', 'is', 'line', "two.\n"],
|
361
|
+
'2.4.0')
|
364
362
|
end
|
365
363
|
end
|
366
364
|
context 'with a file blocked for read/write' do
|
@@ -379,12 +377,11 @@ describe 'IO' do
|
|
379
377
|
result = IO.readlines('|echo test')[0]
|
380
378
|
expect(result).to eq "test\n"
|
381
379
|
end
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
end
|
380
|
+
|
381
|
+
it 'should not be able to read the file' do
|
382
|
+
expect do
|
383
|
+
IO.readlines(@filename)
|
384
|
+
end.to raise_error(IOError)
|
388
385
|
end
|
389
386
|
end
|
390
387
|
end
|
@@ -403,16 +400,7 @@ describe 'IO' do
|
|
403
400
|
end.to raise_error(Errno::ENOENT)
|
404
401
|
end
|
405
402
|
end
|
406
|
-
|
407
|
-
context 'with mode r' do
|
408
|
-
it 'should raise an error' do
|
409
|
-
end
|
410
|
-
end
|
411
|
-
context 'with mode w' do
|
412
|
-
it 'should return an integer' do
|
413
|
-
end
|
414
|
-
end
|
415
|
-
end
|
403
|
+
|
416
404
|
context 'with a file not blocked for read/write' do
|
417
405
|
before do
|
418
406
|
expect(TCellAgent).to receive(:policy).with(
|
@@ -421,27 +409,27 @@ describe 'IO' do
|
|
421
409
|
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
422
410
|
end
|
423
411
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
expect(fd).to be_a(Integer)
|
428
|
-
end
|
429
|
-
it 'should open the file for read' do
|
430
|
-
fd = IO.sysopen(@filename)
|
431
|
-
expect(IO.new(fd).read).to eq @file_contents
|
432
|
-
end
|
412
|
+
it 'returns an integer' do
|
413
|
+
fd = IO.sysopen(@filename)
|
414
|
+
expect(fd).to be_a(Integer)
|
433
415
|
end
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
416
|
+
it 'opens the file for read' do
|
417
|
+
fd = IO.sysopen(@filename)
|
418
|
+
expect(IO.new(fd).read).to eq @file_contents
|
419
|
+
end
|
420
|
+
it 'uses the mode when set' do
|
421
|
+
fd = IO.sysopen(@new_file_name, 'w')
|
422
|
+
expect(fd).to be_a(Integer)
|
423
|
+
|
424
|
+
file = IO.new(fd, 'w')
|
425
|
+
file.puts @file_contents
|
426
|
+
file.rewind
|
427
|
+
end
|
428
|
+
it 'should open the file for write' do
|
429
|
+
fd = IO.sysopen(@new_file_name, 'w')
|
430
|
+
file = IO.new(fd, 'w')
|
431
|
+
file.puts @file_contents
|
432
|
+
file.rewind
|
445
433
|
end
|
446
434
|
end
|
447
435
|
context 'with a file blocked for read/write' do
|
@@ -452,19 +440,16 @@ describe 'IO' do
|
|
452
440
|
expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
|
453
441
|
end
|
454
442
|
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
end.to raise_error(IOError)
|
460
|
-
end
|
443
|
+
it 'should not be able to open the file for read' do
|
444
|
+
expect do
|
445
|
+
IO.sysopen(@filename)
|
446
|
+
end.to raise_error(IOError)
|
461
447
|
end
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
end
|
448
|
+
|
449
|
+
it 'should not be able to open the file for read' do
|
450
|
+
expect do
|
451
|
+
IO.sysopen(@filename, 'r')
|
452
|
+
end.to raise_error(IOError)
|
468
453
|
end
|
469
454
|
end
|
470
455
|
end
|
@@ -491,48 +476,49 @@ describe 'IO' do
|
|
491
476
|
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
492
477
|
end
|
493
478
|
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
479
|
+
after :each do
|
480
|
+
File.delete(@new_file_name)
|
481
|
+
end
|
482
|
+
it 'creates the file' do
|
483
|
+
IO.write(@new_file_name, @file_contents)
|
484
|
+
expect(File.exist?(@new_file_name)).to be_truthy
|
485
|
+
end
|
486
|
+
it 'writes to the file' do
|
487
|
+
expect(TCellAgent).to receive(:policy).with(
|
488
|
+
TCellAgent::PolicyTypes::LFI
|
489
|
+
).and_return(@local_files_policy)
|
490
|
+
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
505
491
|
|
506
|
-
|
507
|
-
|
508
|
-
File.delete(@new_file_name)
|
509
|
-
end
|
492
|
+
IO.write(@new_file_name, @file_contents)
|
493
|
+
expect(File.open(@new_file_name).read).to eq @file_contents
|
510
494
|
end
|
511
|
-
context 'with a filename that does exist' do
|
512
|
-
it 'should overwrite the file' do
|
513
|
-
expect(TCellAgent).to receive(:policy).with(
|
514
|
-
TCellAgent::PolicyTypes::LFI
|
515
|
-
).and_return(@local_files_policy)
|
516
|
-
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
517
495
|
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
496
|
+
it 'writes over the file' do
|
497
|
+
expect(TCellAgent).to receive(:policy).with(
|
498
|
+
TCellAgent::PolicyTypes::LFI
|
499
|
+
).and_return(@local_files_policy)
|
500
|
+
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
501
|
+
|
502
|
+
IO.write(@new_file_name, @file_contents)
|
503
|
+
expect(File.open(@new_file_name).read).to eq @file_contents
|
522
504
|
end
|
523
|
-
|
524
|
-
|
505
|
+
|
506
|
+
context 'using offset, perm' do
|
507
|
+
after :each do
|
508
|
+
expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('444')
|
509
|
+
|
525
510
|
expect(TCellAgent).to receive(:policy).with(
|
526
511
|
TCellAgent::PolicyTypes::LFI
|
527
|
-
).and_return(@local_files_policy
|
528
|
-
expect(@local_files_policy).to receive(:block_file_access?).and_return(false
|
529
|
-
|
530
|
-
exp_results = @file_contents.dup
|
531
|
-
exp_results[1..6] = 'OFFSET'
|
532
|
-
IO.write(@new_file_name, @file_contents)
|
533
|
-
IO.write(@new_file_name, 'OFFSET', 1)
|
534
|
-
expect(IO.read(@new_file_name)).to eq exp_results
|
512
|
+
).and_return(@local_files_policy)
|
513
|
+
expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
|
514
|
+
expect(File.open(@new_file_name).read).to eq @new_file_contents_offset_bytes
|
535
515
|
end
|
516
|
+
|
517
|
+
test_ruby2_ruby3_keywords(IO,
|
518
|
+
'write',
|
519
|
+
[NEW_FILE_NAME, 'OFFSET', 5],
|
520
|
+
{ perm: 0o444 },
|
521
|
+
6)
|
536
522
|
end
|
537
523
|
end
|
538
524
|
context 'with a file blocked for read/write' do
|
@@ -543,20 +529,18 @@ describe 'IO' do
|
|
543
529
|
expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
|
544
530
|
end
|
545
531
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
end.to raise_error(IOError)
|
551
|
-
end
|
532
|
+
it 'raises an IOError' do
|
533
|
+
expect do
|
534
|
+
IO.write(@new_file_name, '')
|
535
|
+
end.to raise_error(IOError)
|
552
536
|
end
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
end.to raise_error(IOError)
|
558
|
-
end
|
537
|
+
it 'should not be able to create and write to the file' do
|
538
|
+
expect do
|
539
|
+
IO.write(@filename, @file_contents)
|
540
|
+
end.to raise_error(IOError)
|
559
541
|
end
|
560
542
|
end
|
561
543
|
end
|
562
544
|
end
|
545
|
+
|
546
|
+
# rubocop:enable Style/HashSyntax
|