tcell_agent 1.1.12 → 2.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.
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