tcell_agent 1.1.12 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +5 -5
  2. data/bin/tcell_agent +26 -14
  3. data/lib/tcell_agent.rb +16 -10
  4. data/lib/tcell_agent/agent.rb +78 -97
  5. data/lib/tcell_agent/agent/route_manager.rb +0 -16
  6. data/lib/tcell_agent/agent/static_agent.rb +9 -30
  7. data/lib/tcell_agent/authlogic.rb +3 -6
  8. data/lib/tcell_agent/config/unknown_options.rb +4 -8
  9. data/lib/tcell_agent/configuration.rb +38 -119
  10. data/lib/tcell_agent/devise.rb +25 -27
  11. data/lib/tcell_agent/hooks/login_fraud.rb +30 -33
  12. data/lib/tcell_agent/instrument_servers.rb +25 -0
  13. data/lib/tcell_agent/instrumentation.rb +12 -10
  14. data/lib/tcell_agent/instrumentation/cmdi.rb +19 -15
  15. data/lib/tcell_agent/instrumentation/lfi.rb +73 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
  17. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +123 -0
  18. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +159 -0
  19. data/lib/tcell_agent/logger.rb +50 -114
  20. data/lib/tcell_agent/patches.rb +6 -7
  21. data/lib/tcell_agent/policies/appfirewall_policy.rb +26 -0
  22. data/lib/tcell_agent/policies/command_injection_policy.rb +28 -0
  23. data/lib/tcell_agent/policies/dataloss_policy.rb +44 -44
  24. data/lib/tcell_agent/policies/headers_policy.rb +25 -0
  25. data/lib/tcell_agent/policies/http_redirect_policy.rb +13 -79
  26. data/lib/tcell_agent/policies/js_agent_policy.rb +27 -0
  27. data/lib/tcell_agent/policies/local_file_access.rb +28 -0
  28. data/lib/tcell_agent/policies/login_policy.rb +43 -0
  29. data/lib/tcell_agent/policies/patches_policy.rb +27 -0
  30. data/lib/tcell_agent/policies/policies_manager.rb +68 -0
  31. data/lib/tcell_agent/policies/policy_polling.rb +58 -0
  32. data/lib/tcell_agent/policies/policy_types.rb +14 -0
  33. data/lib/tcell_agent/policies/system_enablements.rb +27 -0
  34. data/lib/tcell_agent/rails/auth/authlogic.rb +43 -68
  35. data/lib/tcell_agent/rails/auth/devise.rb +20 -23
  36. data/lib/tcell_agent/rails/auth/doorkeeper.rb +63 -74
  37. data/lib/tcell_agent/rails/csrf_exception.rb +2 -2
  38. data/lib/tcell_agent/rails/dlp.rb +25 -15
  39. data/lib/tcell_agent/rails/dlp_handler.rb +1 -2
  40. data/lib/tcell_agent/rails/js_agent_insert.rb +12 -13
  41. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +4 -25
  42. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -12
  43. data/lib/tcell_agent/rails/middleware/global_middleware.rb +0 -1
  44. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +14 -34
  45. data/lib/tcell_agent/rails/on_start.rb +32 -31
  46. data/lib/tcell_agent/rails/routes.rb +7 -6
  47. data/lib/tcell_agent/rails/routes/grape.rb +1 -3
  48. data/lib/tcell_agent/rails/routes/route_id.rb +3 -1
  49. data/lib/tcell_agent/rails/settings_reporter.rb +23 -36
  50. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +12 -0
  51. data/lib/tcell_agent/rails/tcell_body_proxy.rb +6 -4
  52. data/lib/tcell_agent/rust/agent_config.rb +49 -0
  53. data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.2.so → libtcellagent-4.14.0.dylib} +0 -0
  54. data/lib/tcell_agent/rust/libtcellagent-4.14.0.so +0 -0
  55. data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-alpine-4.14.0.so} +0 -0
  56. data/lib/tcell_agent/rust/models.rb +0 -55
  57. data/lib/tcell_agent/rust/native_agent.rb +531 -0
  58. data/lib/tcell_agent/rust/native_agent_response.rb +42 -0
  59. data/lib/tcell_agent/rust/native_library.rb +68 -0
  60. data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
  61. data/lib/tcell_agent/sensor_events/agent_setting_event.rb +12 -0
  62. data/lib/tcell_agent/sensor_events/{app_config.rb → app_config_setting_event.rb} +0 -6
  63. data/lib/tcell_agent/sensor_events/dlp.rb +2 -6
  64. data/lib/tcell_agent/sensor_events/sensor.rb +0 -62
  65. data/lib/tcell_agent/sensor_events/server_agent.rb +13 -18
  66. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -108
  67. data/lib/tcell_agent/sensor_events/util/utils.rb +0 -2
  68. data/lib/tcell_agent/servers/passenger.rb +1 -28
  69. data/lib/tcell_agent/servers/puma.rb +3 -21
  70. data/lib/tcell_agent/servers/rails_server.rb +1 -1
  71. data/lib/tcell_agent/servers/thin.rb +2 -2
  72. data/lib/tcell_agent/servers/unicorn.rb +19 -80
  73. data/lib/tcell_agent/servers/webrick.rb +1 -1
  74. data/lib/tcell_agent/settings_reporter.rb +24 -24
  75. data/lib/tcell_agent/sinatra.rb +14 -16
  76. data/lib/tcell_agent/tcell_context.rb +40 -14
  77. data/lib/tcell_agent/utils/headers.rb +14 -0
  78. data/lib/tcell_agent/version.rb +1 -1
  79. data/spec/lib/tcell_agent/cmdi_spec.rb +0 -585
  80. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -18
  81. data/spec/lib/tcell_agent/configuration_spec.rb +4 -140
  82. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +46 -173
  83. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +504 -0
  84. data/spec/lib/tcell_agent/instrumentation/cmdi/kernel_cmdi_spec.rb +435 -0
  85. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +326 -0
  86. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +556 -0
  87. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +249 -0
  88. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +105 -0
  89. data/spec/lib/tcell_agent/patches_spec.rb +25 -43
  90. data/spec/lib/tcell_agent/policies/appfirewall_policy_spec.rb +183 -0
  91. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +57 -0
  92. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +84 -773
  93. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +161 -0
  94. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +9 -9
  95. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +243 -198
  96. data/spec/lib/tcell_agent/policies/js_agent_policy_spec.rb +75 -0
  97. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +165 -33
  98. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +84 -277
  99. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +104 -0
  100. data/spec/lib/tcell_agent/policies/policy_polling_spec.rb +6 -0
  101. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +56 -0
  102. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +9 -18
  103. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +13 -30
  104. data/spec/lib/tcell_agent/rails/logger_spec.rb +27 -7
  105. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +17 -12
  106. data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +14 -14
  107. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +0 -35
  108. data/spec/lib/tcell_agent/settings_reporter_spec.rb +127 -153
  109. data/spec/spec_helper.rb +1 -1
  110. data/spec/support/builders.rb +104 -0
  111. data/spec/support/force_logger_mocking.rb +38 -0
  112. data/spec/support/resources/lfi_sample_file.txt +2 -0
  113. data/spec/support/static_agent_overrides.rb +0 -15
  114. metadata +63 -74
  115. data/lib/tcell_agent/agent/event_processor.rb +0 -326
  116. data/lib/tcell_agent/agent/fork_pipe_manager.rb +0 -113
  117. data/lib/tcell_agent/agent/policy_manager.rb +0 -219
  118. data/lib/tcell_agent/agent/policy_types.rb +0 -30
  119. data/lib/tcell_agent/api.rb +0 -91
  120. data/lib/tcell_agent/appsensor/injections_reporter.rb +0 -24
  121. data/lib/tcell_agent/config/child_process_events.rb +0 -8
  122. data/lib/tcell_agent/instrumentation/cmdi/backtick.rb +0 -10
  123. data/lib/tcell_agent/instrumentation/cmdi/exec.rb +0 -14
  124. data/lib/tcell_agent/instrumentation/cmdi/popen.rb +0 -28
  125. data/lib/tcell_agent/instrumentation/cmdi/spawn.rb +0 -11
  126. data/lib/tcell_agent/instrumentation/cmdi/system.rb +0 -11
  127. data/lib/tcell_agent/policies/http_tx_policy.rb +0 -60
  128. data/lib/tcell_agent/policies/login_fraud_policy.rb +0 -45
  129. data/lib/tcell_agent/policies/rust_policies.rb +0 -110
  130. data/lib/tcell_agent/rails.rb +0 -40
  131. data/lib/tcell_agent/rust/libtcellagent-1.3.2.dylib +0 -0
  132. data/lib/tcell_agent/rust/tcellagent-1.3.2.dll +0 -0
  133. data/lib/tcell_agent/rust/whisperer.rb +0 -308
  134. data/lib/tcell_agent/sensor_events/appsensor_event.rb +0 -52
  135. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +0 -45
  136. data/lib/tcell_agent/sensor_events/command_injection.rb +0 -75
  137. data/lib/tcell_agent/sensor_events/honeytokens.rb +0 -16
  138. data/lib/tcell_agent/sensor_events/login_fraud.rb +0 -60
  139. data/lib/tcell_agent/sensor_events/metrics.rb +0 -123
  140. data/lib/tcell_agent/sensor_events/patches.rb +0 -21
  141. data/lib/tcell_agent/start_background_thread.rb +0 -55
  142. data/lib/tcell_agent/system_info.rb +0 -11
  143. data/lib/tcell_agent/utils/io.rb +0 -38
  144. data/lib/tcell_agent/utils/passwords.rb +0 -28
  145. data/lib/tcell_agent/utils/queue_with_timeout.rb +0 -142
  146. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +0 -100
  147. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +0 -535
  148. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +0 -133
  149. data/spec/lib/tcell_agent/api/api_spec.rb +0 -39
  150. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +0 -187
  151. data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
  152. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
  153. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
  154. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
  155. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
  156. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
  157. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
  158. data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
  159. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
  160. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
  161. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
  162. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
  163. data/spec/lib/tcell_agent/utils/passwords_spec.rb +0 -143
@@ -0,0 +1,556 @@
1
+ require 'spec_helper'
2
+ require 'securerandom'
3
+
4
+ describe 'IO' do
5
+ before do
6
+ native_agent = double('native_agent')
7
+ @local_files_policy = TCellAgent::Policies::LocalFileInclusion.new(
8
+ native_agent, {}
9
+ )
10
+ @cmdi_policy = TCellAgent::Policies::CommandInjectionPolicy.new(
11
+ native_agent, {}
12
+ )
13
+ end
14
+
15
+ before(:all) do
16
+ @filename = get_test_resource_path('lfi_sample_file.txt')
17
+ @file_contents = "This is line one.\nThis is line two.\n"
18
+ @file_length = @file_contents.length
19
+
20
+ @new_file_name = '/tmp/' + SecureRandom.uuid
21
+ @new_file_contents_offset = "This OFFSETe one.\nThis is line two.\n"
22
+ end
23
+
24
+ describe '.binread' do
25
+ context 'empty path' do
26
+ it 'should raise an error' do
27
+ expect do
28
+ IO.binread
29
+ end.to raise_error(ArgumentError)
30
+ expect do
31
+ IO.binread(nil)
32
+ end.to raise_error(TypeError)
33
+ expect do
34
+ IO.binread('')
35
+ end.to raise_error(Errno::ENOENT)
36
+ end
37
+ end
38
+ context 'with a file not blocked for read/write' do
39
+ before do |test|
40
+ unless test.metadata[:skip_before]
41
+ expect(TCellAgent).to receive(:policy).with(
42
+ TCellAgent::PolicyTypes::LFI
43
+ ).and_return(@local_files_policy)
44
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
45
+ end
46
+ end
47
+
48
+ it 'should still be able to execute OS commands', :skip_before do
49
+ result = IO.binread('|echo test')
50
+ expect(result).to eq "test\n"
51
+ end
52
+ context 'with a filename' do
53
+ it 'should still be able to read file' do
54
+ result = IO.binread(@filename)
55
+ expect(result).to eq @file_contents
56
+ end
57
+ end
58
+ context 'with a filename and a length of 20' do
59
+ it 'should read 20 bytes of the file' do
60
+ result = IO.binread(@filename, 20)
61
+ expect(result).to eq @file_contents[0..19]
62
+ end
63
+ end
64
+ context 'with a filename and a length of 20 and an offset of 5' do
65
+ it 'should read 20 bytes starting from the 5th byte' do
66
+ result = IO.binread(@filename, 20, 5)
67
+ expect(result).to eq @file_contents[5..24]
68
+ end
69
+ end
70
+ end
71
+ context 'with a file blocked for read/write' do
72
+ before do |test|
73
+ unless test.metadata[:skip_before]
74
+ expect(TCellAgent).to receive(:policy).with(
75
+ TCellAgent::PolicyTypes::LFI
76
+ ).and_return(@local_files_policy)
77
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
78
+ end
79
+ end
80
+
81
+ it 'should still be able to execute OS commands', :skip_before do
82
+ result = IO.binread('|echo test')
83
+ expect(result).to eq "test\n"
84
+ end
85
+ context 'with a filename' do
86
+ it 'should not be able to read the file' do
87
+ expect do
88
+ IO.binread(@filename)
89
+ end.to raise_error(IOError)
90
+ end
91
+ end
92
+ context 'with a filename and a length of 20' do
93
+ it 'should not be able to read the file' do
94
+ expect do
95
+ IO.binread(@filename, 20)
96
+ end.to raise_error(IOError)
97
+ end
98
+ end
99
+ context 'with a filename and a length of 20 and an offset of 5' do
100
+ it 'should not be able to read the file' do
101
+ expect do
102
+ IO.binread(@filename, 20, 5)
103
+ end.to raise_error(IOError)
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ describe '.binwrite' do
110
+ context 'empty path' do
111
+ it 'should raise an error' do
112
+ expect do
113
+ IO.binwrite
114
+ end.to raise_error(ArgumentError)
115
+ expect do
116
+ IO.binwrite(nil)
117
+ end.to raise_error(ArgumentError)
118
+ expect do
119
+ IO.binwrite('')
120
+ end.to raise_error(ArgumentError)
121
+ end
122
+ end
123
+ context 'with a file not blocked for read/write' do
124
+ before do
125
+ expect(TCellAgent).to receive(:policy).with(
126
+ TCellAgent::PolicyTypes::LFI
127
+ ).and_return(@local_files_policy)
128
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
129
+ end
130
+
131
+ context 'with a nonexistent filename and string' do
132
+ it 'should create the file' do
133
+ IO.binwrite(@new_file_name, '')
134
+ expect(File.exist?(@new_file_name)).to be_truthy
135
+ File.delete(@new_file_name)
136
+ end
137
+ it 'should write to the file' do
138
+ expect(IO.binwrite(@new_file_name, @file_contents)).to eq @file_length
139
+ File.delete(@new_file_name)
140
+ end
141
+ end
142
+ context 'with a nonexistent filename and string and offset' do
143
+ it 'should write to the file at the offset value 5' do
144
+ expect(TCellAgent).to receive(:policy).with(
145
+ TCellAgent::PolicyTypes::LFI
146
+ ).and_return(@local_files_policy, @local_files_policy)
147
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false, false)
148
+
149
+ IO.binwrite(@new_file_name, @file_contents)
150
+ IO.binwrite(@new_file_name, 'OFFSET', 5)
151
+ expect(IO.binread(@new_file_name)).to eq @new_file_contents_offset
152
+ File.delete(@new_file_name)
153
+ end
154
+ end
155
+ end
156
+ context 'with a file blocked for read or write' do
157
+ before do
158
+ expect(TCellAgent).to receive(:policy).with(
159
+ TCellAgent::PolicyTypes::LFI
160
+ ).and_return(@local_files_policy)
161
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
162
+ end
163
+
164
+ context 'with a nonexistent filename and a string' do
165
+ it 'should not be able to write to the file' do
166
+ expect do
167
+ IO.binwrite(@new_file_name, @file_contents)
168
+ end.to raise_error(IOError)
169
+ end
170
+ end
171
+ context 'with a nonexistent filename and a string and an offset' do
172
+ it 'should not be able to write to the file' do
173
+ expect do
174
+ IO.binwrite(@new_file_name, @file_contents)
175
+ end.to raise_error(IOError)
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ describe '.foreach' do
182
+ context 'empty path' do
183
+ it 'should raise an error' do
184
+ expect do
185
+ IO.foreach('') { pass }
186
+ end.to raise_error(Errno::ENOENT)
187
+ end
188
+ end
189
+ context 'with a file not blocked for read/write' do
190
+ before do
191
+ expect(TCellAgent).to receive(:policy).with(
192
+ TCellAgent::PolicyTypes::LFI
193
+ ).and_return(@local_files_policy)
194
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
195
+ end
196
+
197
+ context 'with a filename' do
198
+ it 'should be able to read the file' do
199
+ result = ''
200
+ IO.foreach(@filename) { |line| result << line }
201
+ expect(result).to eq @file_contents
202
+ end
203
+ end
204
+ context 'with a filename and a limit 16' do
205
+ it 'should split each line to a max length of 16' do
206
+ result = ''
207
+ IO.foreach(@filename, 16) { |line| result << line }
208
+ expect(result).to eq @file_contents
209
+ end
210
+ end
211
+ context 'with a filename and sep' do
212
+ # TODO: no documentation on how to use sep
213
+ end
214
+ context 'with a filename and sep and limit' do
215
+ # TODO: no documentation on how to use sep and limit
216
+ end
217
+ end
218
+ context 'with a file blocked for read or write' do
219
+ before do
220
+ expect(TCellAgent).to receive(:policy).with(
221
+ TCellAgent::PolicyTypes::LFI
222
+ ).and_return(@local_files_policy)
223
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
224
+ end
225
+
226
+ context 'with a filename' do
227
+ it 'should not be able to read the file' do
228
+ expect do
229
+ result = ''
230
+ IO.foreach(@filename) { |line| result << line }
231
+ expect(result).to eq @file_contents
232
+ end.to raise_error(IOError)
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ describe '.read' do
239
+ context 'empty path' do
240
+ it 'should raise an error' do
241
+ expect do
242
+ IO.read
243
+ end.to raise_error(ArgumentError)
244
+ expect do
245
+ IO.read('')
246
+ end.to raise_error(Errno::ENOENT)
247
+ end
248
+ end
249
+ context 'with a file not blocked for read/write' do
250
+ before do |test|
251
+ unless test.metadata[:skip_before]
252
+ expect(TCellAgent).to receive(:policy).with(
253
+ TCellAgent::PolicyTypes::LFI
254
+ ).and_return(@local_files_policy)
255
+
256
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
257
+ end
258
+ end
259
+
260
+ it 'should still be able to execute OS commands', :skip_before do
261
+ result = IO.read('|echo test')
262
+ expect(result).to eq "test\n"
263
+ end
264
+ context 'with a filename' do
265
+ it 'should read the file' do
266
+ result = IO.read(@filename)
267
+ expect(result).to eq @file_contents
268
+ end
269
+ end
270
+ context 'with a filename and a length of 20' do
271
+ it 'should read 20 bytes of the file' do
272
+ result = IO.read(@filename, 20)
273
+ expect(result).to eq @file_contents[0..19]
274
+ end
275
+ end
276
+ context 'with a filename and a length of 20 and an offset of 5' do
277
+ it 'should read 20 bytes starting from the 5th byte' do
278
+ result = IO.read(@filename, 20, 5)
279
+ expect(result).to eq @file_contents[5..24]
280
+ end
281
+ end
282
+ end
283
+ context 'with a file blocked for read/write' do
284
+ before do |test|
285
+ unless test.metadata[:skip_before]
286
+ expect(TCellAgent).to receive(:policy).with(
287
+ TCellAgent::PolicyTypes::LFI
288
+ ).and_return(@local_files_policy)
289
+
290
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
291
+ end
292
+ end
293
+
294
+ it 'should still be able to execute OS commands', :skip_before do
295
+ result = IO.read('|echo test')
296
+ expect(result).to eq "test\n"
297
+ end
298
+ context 'with a filename' do
299
+ it 'should not be able to read the file' do
300
+ expect do
301
+ IO.read(@filename)
302
+ end.to raise_error(IOError)
303
+ end
304
+ end
305
+ context 'with a filename and a length 20' do
306
+ it 'should not be able to read the file' do
307
+ expect do
308
+ IO.read(@filename, 20)
309
+ end.to raise_error(IOError)
310
+ end
311
+ end
312
+ context 'with a filename and a length and an offset 5' do
313
+ it 'should not be able to read the file' do
314
+ expect do
315
+ IO.read(@filename, 20, 5)
316
+ end.to raise_error(IOError)
317
+ end
318
+ end
319
+ end
320
+ end
321
+
322
+ describe '.readlines' do
323
+ context 'empty path' do
324
+ it 'should raise an error' do
325
+ expect do
326
+ IO.readlines
327
+ end.to raise_error(ArgumentError)
328
+ expect do
329
+ IO.readlines('')
330
+ end.to raise_error(Errno::ENOENT)
331
+ end
332
+ end
333
+ context 'with a file not blocked for read/write' do
334
+ before do |test|
335
+ unless test.metadata[:skip_before]
336
+ expect(TCellAgent).to receive(:policy).with(
337
+ TCellAgent::PolicyTypes::LFI
338
+ ).and_return(@local_files_policy)
339
+
340
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
341
+ end
342
+ end
343
+
344
+ context 'with a filename' do
345
+ it 'should read the file' do
346
+ result = IO.readlines(@filename)
347
+ expect(result[0] + result[1]).to eq @file_contents
348
+ end
349
+ end
350
+ context 'with a filename and a limit 20' do
351
+ it 'should read 20 bytes of the file' do
352
+ exp_result = ['This ', 'is li', 'ne on', "e.\n", 'This ', 'is li', 'ne tw', "o.\n"]
353
+ result = IO.readlines(@filename, 5)
354
+ expect(result).to eq exp_result
355
+ end
356
+ end
357
+ context 'with a filename and a limit of 20 and sep' do
358
+ # TODO
359
+ end
360
+ end
361
+ context 'with a file blocked for read/write' do
362
+ before do |test|
363
+ unless test.metadata[:skip_before]
364
+ expect(TCellAgent).to receive(:policy).with(
365
+ TCellAgent::PolicyTypes::LFI
366
+ ).and_return(@local_files_policy)
367
+
368
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
369
+ end
370
+ end
371
+
372
+ it 'should still be able to execute OS commands', :skip_before do
373
+ result = IO.readlines('|echo test')[0]
374
+ expect(result).to eq "test\n"
375
+ end
376
+ context 'with a filename' do
377
+ it 'should not be able to read the file' do
378
+ expect do
379
+ IO.readlines(@filename)
380
+ end.to raise_error(IOError)
381
+ end
382
+ end
383
+ end
384
+ end
385
+
386
+ describe '.sysopen' do
387
+ context 'empty path' do
388
+ it 'should raise an error' do
389
+ expect do
390
+ IO.sysopen
391
+ end.to raise_error(ArgumentError)
392
+ expect do
393
+ IO.sysopen(nil)
394
+ end.to raise_error(TypeError)
395
+ expect do
396
+ IO.sysopen('')
397
+ end.to raise_error(Errno::ENOENT)
398
+ end
399
+ end
400
+ context 'with a nonexistent file' do
401
+ context 'with mode r' do
402
+ it 'should raise an error' do
403
+ end
404
+ end
405
+ context 'with mode w' do
406
+ it 'should return an integer' do
407
+ end
408
+ end
409
+ end
410
+ context 'with a file not blocked for read/write' do
411
+ before do
412
+ expect(TCellAgent).to receive(:policy).with(
413
+ TCellAgent::PolicyTypes::LFI
414
+ ).and_return(@local_files_policy)
415
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
416
+ end
417
+
418
+ context 'with a filename' do
419
+ it 'should return an integer' do
420
+ fd = IO.sysopen(@filename)
421
+ expect(fd).to be_a(Integer)
422
+ end
423
+ it 'should open the file for read' do
424
+ fd = IO.sysopen(@filename)
425
+ expect(IO.new(fd).read).to eq @file_contents
426
+ end
427
+ end
428
+ context 'with a filename and mode w' do
429
+ it 'should return an integer' do
430
+ fd = IO.sysopen(@new_file_name, 'w')
431
+ expect(fd).to be_a(Integer)
432
+ end
433
+ it 'should open the file for write' do
434
+ fd = IO.sysopen(@new_file_name, 'w')
435
+ file = IO.new(fd, 'w')
436
+ file.puts @file_contents
437
+ file.rewind
438
+ end
439
+ end
440
+ end
441
+ context 'with a file blocked for read/write' do
442
+ before do
443
+ expect(TCellAgent).to receive(:policy).with(
444
+ TCellAgent::PolicyTypes::LFI
445
+ ).and_return(@local_files_policy)
446
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
447
+ end
448
+
449
+ context 'with a filename' do
450
+ it 'should not be able to open the file for read' do
451
+ expect do
452
+ IO.sysopen(@filename)
453
+ end.to raise_error(IOError)
454
+ end
455
+ end
456
+ context 'with a filename and mode' do
457
+ it 'should not be able to open the file for read' do
458
+ expect do
459
+ IO.sysopen(@filename, 'r')
460
+ end.to raise_error(IOError)
461
+ end
462
+ end
463
+ end
464
+ end
465
+
466
+ describe '.write' do
467
+ context 'empty path' do
468
+ it 'should raise an error' do
469
+ expect do
470
+ IO.write
471
+ end.to raise_error(ArgumentError)
472
+ expect do
473
+ IO.write(nil)
474
+ end.to raise_error(ArgumentError)
475
+ expect do
476
+ IO.write('')
477
+ end.to raise_error(ArgumentError)
478
+ end
479
+ end
480
+ context 'with a file not blocked for read/write' do
481
+ before do
482
+ expect(TCellAgent).to receive(:policy).with(
483
+ TCellAgent::PolicyTypes::LFI
484
+ ).and_return(@local_files_policy)
485
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
486
+ end
487
+
488
+ context 'with a filename that doe not exist' do
489
+ it 'should create the file' do
490
+ IO.write(@new_file_name, @file_contents)
491
+ expect(File.exist?(@new_file_name)).to be_truthy
492
+ File.delete(@new_file_name)
493
+ end
494
+ it 'should write to the file' do
495
+ expect(TCellAgent).to receive(:policy).with(
496
+ TCellAgent::PolicyTypes::LFI
497
+ ).and_return(@local_files_policy)
498
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
499
+
500
+ IO.write(@new_file_name, @file_contents)
501
+ expect(IO.read(@new_file_name)).to eq @file_contents
502
+ File.delete(@new_file_name)
503
+ end
504
+ end
505
+ context 'with a filename that does exist' do
506
+ it 'should overwrite the file' do
507
+ expect(TCellAgent).to receive(:policy).with(
508
+ TCellAgent::PolicyTypes::LFI
509
+ ).and_return(@local_files_policy)
510
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
511
+
512
+ IO.write(@new_file_name, @file_contents)
513
+ expect(IO.read(@new_file_name)).to eq @file_contents
514
+ File.delete(@new_file_name)
515
+ end
516
+ end
517
+ context 'with a filename that does exist and an offset 5' do
518
+ it 'should overwrite the file starting at the offset value' do
519
+ expect(TCellAgent).to receive(:policy).with(
520
+ TCellAgent::PolicyTypes::LFI
521
+ ).and_return(@local_files_policy, @local_files_policy)
522
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false, false)
523
+
524
+ exp_results = @file_contents.dup
525
+ exp_results[1..6] = 'OFFSET'
526
+ IO.write(@new_file_name, @file_contents)
527
+ IO.write(@new_file_name, 'OFFSET', 1)
528
+ expect(IO.read(@new_file_name)).to eq exp_results
529
+ end
530
+ end
531
+ end
532
+ context 'with a file blocked for read/write' do
533
+ before do
534
+ expect(TCellAgent).to receive(:policy).with(
535
+ TCellAgent::PolicyTypes::LFI
536
+ ).and_return(@local_files_policy)
537
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(true)
538
+ end
539
+
540
+ context 'with a filename that does not exist' do
541
+ it 'should not be able to write to the file' do
542
+ expect do
543
+ IO.write(@new_file_name, '')
544
+ end.to raise_error(IOError)
545
+ end
546
+ end
547
+ context 'with a filename that does exist' do
548
+ it 'should not be able to write to the file' do
549
+ expect do
550
+ IO.write(@filename, @file_contents)
551
+ end.to raise_error(IOError)
552
+ end
553
+ end
554
+ end
555
+ end
556
+ end