tcell_agent 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/bin/tcell_agent +6 -11
- data/lib/tcell_agent/agent.rb +18 -13
- data/lib/tcell_agent/config_initializer.rb +0 -4
- data/lib/tcell_agent/configuration.rb +4 -4
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrumentation.rb +14 -6
- data/lib/tcell_agent/instrumentation/cmdi.rb +32 -0
- data/lib/tcell_agent/instrumentation/lfi.rb +55 -9
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
- data/lib/tcell_agent/logger.rb +2 -2
- data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
- data/lib/tcell_agent/policies/headers_policy.rb +2 -2
- data/lib/tcell_agent/policies/patches_policy.rb +8 -4
- data/lib/tcell_agent/policies/policies_manager.rb +1 -0
- data/lib/tcell_agent/policies/policy_polling.rb +4 -3
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +1 -0
- data/lib/tcell_agent/rails/better_ip.rb +7 -19
- data/lib/tcell_agent/rails/dlp.rb +48 -48
- data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
- data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
- data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -5
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
- data/lib/tcell_agent/rails/routes/grape.rb +2 -1
- data/lib/tcell_agent/rails/settings_reporter.rb +0 -8
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -6
- data/lib/tcell_agent/routes/table.rb +3 -0
- data/lib/tcell_agent/rust/agent_config.rb +9 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-6.2.1.so → libtcellagent-alpine.so} +0 -0
- data/lib/tcell_agent/rust/{tcellagent-6.2.1.dll → libtcellagent-x64.dll} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-6.2.1.dylib → libtcellagent.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-6.2.1.so → libtcellagent.so} +0 -0
- data/lib/tcell_agent/rust/native_agent.rb +48 -58
- data/lib/tcell_agent/rust/native_library.rb +7 -10
- data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
- data/lib/tcell_agent/servers/puma.rb +25 -8
- data/lib/tcell_agent/servers/rack_puma_handler.rb +13 -3
- data/lib/tcell_agent/servers/webrick.rb +13 -3
- data/lib/tcell_agent/settings_reporter.rb +0 -14
- data/lib/tcell_agent/sinatra.rb +1 -0
- data/lib/tcell_agent/tcell_context.rb +15 -6
- data/lib/tcell_agent/utils/headers.rb +0 -1
- data/lib/tcell_agent/utils/strings.rb +2 -2
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/cruby_spec_helper.rb +26 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
- data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
- data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +207 -223
- data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +89 -70
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +73 -0
- data/spec/lib/tcell_agent/patches_spec.rb +2 -1
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
- data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +14 -8
- data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -16
- data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
- data/spec/spec_helper.rb +3 -1
- data/spec/support/builders.rb +2 -1
- data/spec/support/server_mocks/puma_mock.rb +4 -0
- data/spec/support/shared_spec.rb +29 -0
- data/tcell_agent.gemspec +14 -14
- metadata +23 -19
- data/Rakefile +0 -18
- data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
- data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -131
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -102
|
@@ -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
|