ruby_smb 3.0.6 → 3.1.2

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 (140) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/examples/file_server.rb +8 -1
  4. data/examples/virtual_file_server.rb +143 -0
  5. data/lib/ruby_smb/client/encryption.rb +16 -4
  6. data/lib/ruby_smb/client/negotiation.rb +10 -8
  7. data/lib/ruby_smb/fscc/file_information/file_access_information.rb +15 -0
  8. data/lib/ruby_smb/fscc/file_information/file_alignment_information.rb +45 -0
  9. data/lib/ruby_smb/fscc/file_information/file_all_information.rb +23 -0
  10. data/lib/ruby_smb/fscc/file_information/file_basic_information.rb +20 -0
  11. data/lib/ruby_smb/fscc/file_information/file_both_directory_information.rb +3 -3
  12. data/lib/ruby_smb/fscc/file_information/file_directory_information.rb +3 -3
  13. data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +1 -0
  14. data/lib/ruby_smb/fscc/file_information/file_full_directory_information.rb +3 -3
  15. data/lib/ruby_smb/fscc/file_information/file_id_both_directory_information.rb +3 -3
  16. data/lib/ruby_smb/fscc/file_information/file_id_full_directory_information.rb +3 -3
  17. data/lib/ruby_smb/fscc/file_information/file_internal_information.rb +15 -0
  18. data/lib/ruby_smb/fscc/file_information/file_mode_information.rb +29 -0
  19. data/lib/ruby_smb/fscc/file_information/file_name_information.rb +16 -0
  20. data/lib/ruby_smb/fscc/file_information/file_names_information.rb +1 -1
  21. data/lib/ruby_smb/fscc/file_information/file_normalized_name_information.rb +16 -0
  22. data/lib/ruby_smb/fscc/file_information/file_position_information.rb +15 -0
  23. data/lib/ruby_smb/fscc/file_information/file_rename_information.rb +1 -1
  24. data/lib/ruby_smb/fscc/file_information/file_standard_information.rb +20 -0
  25. data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +3 -0
  26. data/lib/ruby_smb/fscc/file_information.rb +43 -6
  27. data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +1 -0
  28. data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +1 -0
  29. data/lib/ruby_smb/fscc/file_system_information.rb +4 -0
  30. data/lib/ruby_smb/gss/provider/ntlm.rb +20 -3
  31. data/lib/ruby_smb/gss/provider.rb +10 -1
  32. data/lib/ruby_smb/server/server_client/encryption.rb +66 -0
  33. data/lib/ruby_smb/server/server_client/negotiation.rb +14 -3
  34. data/lib/ruby_smb/server/server_client/session_setup.rb +21 -4
  35. data/lib/ruby_smb/server/server_client/share_io.rb +17 -0
  36. data/lib/ruby_smb/server/server_client/tree_connect.rb +40 -3
  37. data/lib/ruby_smb/server/server_client.rb +156 -38
  38. data/lib/ruby_smb/server/session.rb +5 -1
  39. data/lib/ruby_smb/server/share/provider/disk/file_system.rb +28 -0
  40. data/lib/ruby_smb/server/share/provider/disk/processor/close.rb +46 -0
  41. data/lib/ruby_smb/server/share/provider/disk/processor/create.rb +143 -0
  42. data/lib/ruby_smb/server/share/provider/disk/processor/query.rb +359 -0
  43. data/lib/ruby_smb/server/share/provider/disk/processor/read.rb +70 -0
  44. data/lib/ruby_smb/server/share/provider/disk/processor.rb +223 -0
  45. data/lib/ruby_smb/server/share/provider/disk.rb +12 -418
  46. data/lib/ruby_smb/server/share/provider/pipe.rb +2 -2
  47. data/lib/ruby_smb/server/share/provider/processor.rb +16 -0
  48. data/lib/ruby_smb/server/share/provider/virtual_disk/virtual_file.rb +85 -0
  49. data/lib/ruby_smb/server/share/provider/virtual_disk/virtual_pathname.rb +196 -0
  50. data/lib/ruby_smb/server/share/provider/virtual_disk/virtual_stat.rb +175 -0
  51. data/lib/ruby_smb/server/share/provider/virtual_disk.rb +116 -0
  52. data/lib/ruby_smb/server/share/provider.rb +1 -0
  53. data/lib/ruby_smb/server.rb +13 -3
  54. data/lib/ruby_smb/signing.rb +18 -4
  55. data/lib/ruby_smb/smb1/commands.rb +1 -0
  56. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +11 -1
  57. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +1 -1
  58. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +5 -4
  59. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +12 -4
  60. data/lib/ruby_smb/smb1/packet/trans2/data_block.rb +9 -1
  61. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +52 -51
  62. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +37 -37
  63. data/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_both_directory_info.rb +48 -0
  64. data/lib/ruby_smb/smb1/packet/trans2/find_information_level.rb +28 -15
  65. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +51 -51
  66. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +36 -36
  67. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +40 -39
  68. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +40 -40
  69. data/lib/ruby_smb/smb1/packet/trans2/query_file_information_request.rb +60 -0
  70. data/lib/ruby_smb/smb1/packet/trans2/query_file_information_response.rb +59 -0
  71. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_attribute_info.rb +31 -0
  72. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level.rb +40 -0
  73. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request.rb +46 -0
  74. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_response.rb +59 -0
  75. data/lib/ruby_smb/smb1/packet/trans2/query_information_level/query_file_basic_info.rb +23 -0
  76. data/lib/ruby_smb/smb1/packet/trans2/query_information_level/query_file_standard_info.rb +22 -0
  77. data/lib/ruby_smb/smb1/packet/trans2/query_information_level.rb +62 -0
  78. data/lib/ruby_smb/smb1/packet/trans2/query_path_information_request.rb +65 -0
  79. data/lib/ruby_smb/smb1/packet/trans2/query_path_information_response.rb +59 -0
  80. data/lib/ruby_smb/smb1/packet/trans2/request.rb +24 -8
  81. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +4 -4
  82. data/lib/ruby_smb/smb1/packet/trans2/response.rb +29 -20
  83. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +42 -42
  84. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +23 -23
  85. data/lib/ruby_smb/smb1/packet/trans2/subcommands.rb +23 -5
  86. data/lib/ruby_smb/smb1/packet/trans2.rb +4 -0
  87. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +4 -1
  88. data/lib/ruby_smb/smb2/negotiate_context.rb +10 -1
  89. data/lib/ruby_smb/smb2/packet/transform_header.rb +7 -7
  90. data/lib/ruby_smb/smb2/tree.rb +1 -0
  91. data/lib/ruby_smb/smb2.rb +1 -0
  92. data/lib/ruby_smb/version.rb +1 -1
  93. data/spec/lib/ruby_smb/client_spec.rb +31 -8
  94. data/spec/lib/ruby_smb/fscc/file_information/file_access_information_spec.rb +21 -0
  95. data/spec/lib/ruby_smb/fscc/file_information/file_alignment_information_spec.rb +21 -0
  96. data/spec/lib/ruby_smb/fscc/file_information/file_all_information_spec.rb +61 -0
  97. data/spec/lib/ruby_smb/fscc/file_information/file_basic_information_spec.rb +41 -0
  98. data/spec/lib/ruby_smb/fscc/file_information/file_both_directory_information_spec.rb +59 -10
  99. data/spec/lib/ruby_smb/fscc/file_information/file_directory_information_spec.rb +30 -12
  100. data/spec/lib/ruby_smb/fscc/file_information/file_ea_information_spec.rb +21 -0
  101. data/spec/lib/ruby_smb/fscc/file_information/file_full_directory_information_spec.rb +30 -12
  102. data/spec/lib/ruby_smb/fscc/file_information/file_id_both_directory_information_spec.rb +63 -10
  103. data/spec/lib/ruby_smb/fscc/file_information/file_id_full_directory_information_spec.rb +30 -12
  104. data/spec/lib/ruby_smb/fscc/file_information/file_internal_information_spec.rb +21 -0
  105. data/spec/lib/ruby_smb/fscc/file_information/file_mode_information_spec.rb +21 -0
  106. data/spec/lib/ruby_smb/fscc/file_information/file_name_information_spec.rb +44 -0
  107. data/spec/lib/ruby_smb/fscc/file_information/file_names_information_spec.rb +30 -12
  108. data/spec/lib/ruby_smb/fscc/file_information/file_network_open_information_spec.rb +51 -0
  109. data/spec/lib/ruby_smb/fscc/file_information/file_normalized_name_information_spec.rb +44 -0
  110. data/spec/lib/ruby_smb/fscc/file_information/file_position_information_spec.rb +21 -0
  111. data/spec/lib/ruby_smb/fscc/file_information/file_rename_information_spec.rb +1 -1
  112. data/spec/lib/ruby_smb/fscc/file_information/file_standard_information_spec.rb +41 -0
  113. data/spec/lib/ruby_smb/fscc/file_information/file_stream_information_spec.rb +51 -0
  114. data/spec/lib/ruby_smb/fscc/file_information_spec.rb +14 -0
  115. data/spec/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information_spec.rb +46 -0
  116. data/spec/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information_spec.rb +51 -0
  117. data/spec/lib/ruby_smb/fscc/file_system_information_spec.rb +14 -0
  118. data/spec/lib/ruby_smb/server/server_client_spec.rb +15 -0
  119. data/spec/lib/ruby_smb/server/share/provider/virtual_disk/virtual_pathname_spec.rb +581 -0
  120. data/spec/lib/ruby_smb/server/share/provider/virtual_disk/virtual_stat_spec.rb +207 -0
  121. data/spec/lib/ruby_smb/server/share/provider/virtual_disk_spec.rb +122 -0
  122. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_request_spec.rb +2 -2
  123. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +36 -2
  124. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_request_spec.rb +2 -2
  125. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +35 -1
  126. data/spec/lib/ruby_smb/smb1/packet/trans2/query_file_information_request_spec.rb +74 -0
  127. data/spec/lib/ruby_smb/smb1/packet/trans2/query_file_information_response_spec.rb +96 -0
  128. data/spec/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request_spec.rb +62 -0
  129. data/spec/lib/ruby_smb/smb1/packet/trans2/query_fs_information_response_spec.rb +88 -0
  130. data/spec/lib/ruby_smb/smb1/packet/trans2/query_path_information_request_spec.rb +79 -0
  131. data/spec/lib/ruby_smb/smb1/packet/trans2/query_path_information_response_spec.rb +96 -0
  132. data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +2 -2
  133. data/spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb +3 -3
  134. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb +3 -2
  135. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +7 -2
  136. data/spec/lib/ruby_smb/smb1/tree_spec.rb +3 -3
  137. data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +2 -2
  138. data.tar.gz.sig +0 -0
  139. metadata +88 -2
  140. metadata.gz.sig +0 -0
@@ -0,0 +1,207 @@
1
+ RSpec.describe RubySMB::Server::Share::Provider::VirtualDisk::VirtualStat do
2
+ subject(:virtual_stat) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :atime }
5
+ it { is_expected.to respond_to :blksize }
6
+ it { is_expected.to respond_to :blockdev? }
7
+ it { is_expected.to respond_to :blocks }
8
+ it { is_expected.to respond_to :chardev? }
9
+ it { is_expected.to respond_to :ctime }
10
+ it { is_expected.to respond_to :dev }
11
+ it { is_expected.to respond_to :directory? }
12
+ it { is_expected.to respond_to :executable? }
13
+ it { is_expected.to respond_to :file? }
14
+ it { is_expected.to respond_to :ftype }
15
+ it { is_expected.to respond_to :gid }
16
+ it { is_expected.to respond_to :grpowned? }
17
+ it { is_expected.to respond_to :ino }
18
+ it { is_expected.to respond_to :mode }
19
+ it { is_expected.to respond_to :mtime }
20
+ it { is_expected.to respond_to :nlink }
21
+ it { is_expected.to respond_to :owned? }
22
+ it { is_expected.to respond_to :pipe? }
23
+ it { is_expected.to respond_to :readable? }
24
+ it { is_expected.to respond_to :setgid? }
25
+ it { is_expected.to respond_to :setuid? }
26
+ it { is_expected.to respond_to :size }
27
+ it { is_expected.to respond_to :socket? }
28
+ it { is_expected.to respond_to :sticky? }
29
+ it { is_expected.to respond_to :symlink? }
30
+ it { is_expected.to respond_to :uid }
31
+ it { is_expected.to respond_to :world_readable? }
32
+ it { is_expected.to respond_to :world_writable? }
33
+ it { is_expected.to respond_to :writable? }
34
+ it { is_expected.to respond_to :zero? }
35
+
36
+ describe '#initialize' do
37
+ it 'defaults to being a directory' do
38
+ expect(virtual_stat.directory?).to be true
39
+ end
40
+
41
+ it 'throws an exception when it is both a file and a directory' do
42
+ expect { described_class.new(directory?: true, file?: true) }.to raise_error(ArgumentError)
43
+ end
44
+
45
+ it 'throws an exception when it is neither a file or a directory' do
46
+ expect { described_class.new(directory?: false, file?: false) }.to raise_error(ArgumentError)
47
+ end
48
+
49
+ it 'is a directory when it is a directory' do
50
+ expect(described_class.new(directory?: true).directory?).to be true
51
+ end
52
+
53
+ it 'is a directory when not a file' do
54
+ expect(described_class.new(file?: false).directory?).to be true
55
+ end
56
+
57
+ it 'is a file when it is a file' do
58
+ expect(described_class.new(file?: true).file?).to be true
59
+ end
60
+
61
+ it 'is a file when not a directory' do
62
+ expect(described_class.new(directory?: false).file?).to be true
63
+ end
64
+ end
65
+
66
+ describe '#atime' do
67
+ it 'is expected to default to now' do
68
+ now = Time.now
69
+ expect(Time).to receive(:now).and_return(now)
70
+ expect(virtual_stat.atime).to eq now
71
+ end
72
+ end
73
+
74
+ describe '#ctime' do
75
+ it 'is expected to default to now' do
76
+ now = Time.now
77
+ expect(Time).to receive(:now).and_return(now)
78
+ expect(virtual_stat.ctime).to eq now
79
+ end
80
+ end
81
+
82
+ describe '#mtime' do
83
+ it 'is expected to default to now' do
84
+ now = Time.now
85
+ expect(Time).to receive(:now).and_return(now)
86
+ expect(virtual_stat.mtime).to eq now
87
+ end
88
+ end
89
+
90
+ describe '#birthtime' do
91
+ it 'is expected to default to now' do
92
+ now = Time.now
93
+ expect(Time).to receive(:now).and_return(now)
94
+ expect(virtual_stat.birthtime).to eq now
95
+ end
96
+ end
97
+
98
+ describe '#uid' do
99
+ it 'is expected to default to the current process uid' do
100
+ expect(virtual_stat.uid).to eq Process.uid
101
+ end
102
+ end
103
+
104
+ describe '#owned?' do
105
+ it 'is expected to return true when uid is this process' do
106
+ expect(virtual_stat).to receive(:uid).and_return(Process.uid)
107
+ expect(virtual_stat.owned?).to be true
108
+ end
109
+
110
+ it 'is expected to return false when uid is not this process' do
111
+ expect(virtual_stat).to receive(:uid)
112
+ expect(virtual_stat.owned?).to be false
113
+ end
114
+ end
115
+
116
+ describe '#gid' do
117
+ it 'is expected to default to the current process gid' do
118
+ expect(virtual_stat.gid).to eq Process.gid
119
+ end
120
+ end
121
+
122
+ describe '#grpowned?' do
123
+ it 'is expected to return true when gid is this process' do
124
+ expect(virtual_stat).to receive(:gid).and_return(Process.gid)
125
+ expect(virtual_stat.grpowned?).to be true
126
+ end
127
+
128
+ it 'is expected to return false when gid is not this process' do
129
+ expect(virtual_stat).to receive(:gid)
130
+ expect(virtual_stat.grpowned?).to be false
131
+ end
132
+ end
133
+
134
+ describe '#readable?' do
135
+ it 'is expected to readable by default' do
136
+ expect(virtual_stat.readable?).to be true
137
+ end
138
+ end
139
+
140
+ describe '#writable?' do
141
+ it 'is expected to writable by default' do
142
+ expect(virtual_stat.writable?).to be true
143
+ end
144
+ end
145
+
146
+ describe '#ftype' do
147
+ it 'is expected to be a String' do
148
+ expect(virtual_stat.ftype).to be_a String
149
+ end
150
+ end
151
+
152
+ # test each and every permission represented by the 12 possible bits
153
+ (0..12).each.map { |bit| (1 << bit) & 0o7777 }.each do |mode|
154
+ context "when mode is 0o#{mode.to_s(8).rjust(4, '0')}" do
155
+ before(:each) { expect(virtual_stat).to receive(:mode).at_least(:once).and_return(mode) }
156
+
157
+ describe '#executable?' do
158
+ it 'is correct' do
159
+ expect(virtual_stat.executable?).to eq mode & 0o111 != 0
160
+ end
161
+ end
162
+
163
+ describe '#readable?' do
164
+ it 'is correct' do
165
+ expect(virtual_stat.readable?).to eq mode & 0o444 != 0
166
+ end
167
+ end
168
+
169
+ describe '#setgid?' do
170
+ it 'is correct' do
171
+ expect(virtual_stat.setgid?).to eq mode & 0o2000 != 0
172
+ end
173
+ end
174
+
175
+ describe '#setuid?' do
176
+ it 'is correct' do
177
+ expect(virtual_stat.setuid?).to eq mode & 0o4000 != 0
178
+ end
179
+ end
180
+
181
+ describe '#sticky?' do
182
+ it 'is correct' do
183
+ expect(virtual_stat.sticky?).to eq mode & 0o1000 != 0
184
+ end
185
+ end
186
+
187
+ describe '#world_readable?' do
188
+ it 'is correct' do
189
+ expect(virtual_stat.world_readable?).to eq mode & 0o004 != 0
190
+ end
191
+ end
192
+
193
+ describe '#world_writable?' do
194
+ it 'is correct' do
195
+ expect(virtual_stat.world_writable?).to eq mode & 0o002 != 0
196
+ end
197
+ end
198
+
199
+ describe '#writable?' do
200
+ it 'is correct' do
201
+ expect(virtual_stat.writable?).to eq mode & 0o222 != 0
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
207
+
@@ -0,0 +1,122 @@
1
+ RSpec.describe RubySMB::Server::Share::Provider::VirtualDisk do
2
+ let(:name) { 'vdisk' }
3
+ subject(:virtual_disk) { described_class.new(name) }
4
+
5
+ it { is_expected.to respond_to :name }
6
+ it { is_expected.to respond_to :path }
7
+ it { is_expected.to respond_to :type }
8
+ context 'it provides the basic Hash methods' do
9
+ it { is_expected.to respond_to :[] }
10
+ it { is_expected.to respond_to :each }
11
+ it { is_expected.to respond_to :each_key }
12
+ it { is_expected.to respond_to :each_value }
13
+ it { is_expected.to respond_to :keys }
14
+ it { is_expected.to respond_to :length }
15
+ it { is_expected.to respond_to :values }
16
+ end
17
+
18
+ describe '#add' do
19
+ let(:path) { '/path' }
20
+
21
+ it 'does not throw an exception if the stat object is not a file' do
22
+ stat = RubySMB::Server::Share::Provider::VirtualDisk::VirtualStat.new(file?: false)
23
+ vp = RubySMB::Server::Share::Provider::VirtualDisk::VirtualPathname.new({}, path, stat: stat)
24
+ expect { virtual_disk.add(vp) }.not_to raise_error
25
+ end
26
+
27
+ it 'throws an exception if the path is not absolute' do
28
+ vp = RubySMB::Server::Share::Provider::VirtualDisk::VirtualPathname.new({}, path[1..])
29
+ expect { virtual_disk.add(vp) }.to raise_error(ArgumentError)
30
+ end
31
+
32
+ it 'automatically creates parent directories' do
33
+ expect(virtual_disk.length).to eq 1 # starts with just the root folder
34
+ expect(RubySMB::Server::Share::Provider::VirtualDisk::VirtualPathname).to receive(:new).exactly(3).times.and_call_original
35
+ virtual_disk.add(RubySMB::Server::Share::Provider::VirtualDisk::VirtualPathname.new({}, File.join(path, 'sub', 'dir')))
36
+ expect(virtual_disk.length).to eq 4 # ends with the added item and 2 parent folders
37
+ end
38
+ end
39
+
40
+ describe '#add_dynamic_file' do
41
+ let(:path) { 'path' }
42
+ let(:content) { 'Hello World!' }
43
+ let(:block) { Proc.new { content } }
44
+
45
+ before(:each) { allow(virtual_disk).to receive(:add) }
46
+
47
+ it 'normalizes the path argument' do
48
+ expect(RubySMB::Server::Share::Provider::VirtualDisk::VirtualDynamicFile).to receive(:new).with(virtual_disk, File::SEPARATOR + path, stat: nil, &block)
49
+ virtual_disk.add_dynamic_file(path + '/dir/..', &block)
50
+ end
51
+
52
+ it 'initializes a new VirtualDynamicFile instance' do
53
+ expect(RubySMB::Server::Share::Provider::VirtualDisk::VirtualDynamicFile).to receive(:new)
54
+ virtual_disk.add_dynamic_file(path, &block)
55
+ end
56
+
57
+ it 'adds the mapped file' do
58
+ expect(virtual_disk).to receive(:add)
59
+ expect(virtual_disk.add_dynamic_file(path, &block))
60
+ end
61
+
62
+ it 'throws an exception if the stat object is not a file' do
63
+ stat = RubySMB::Server::Share::Provider::VirtualDisk::VirtualStat.new(file?: false)
64
+ expect { virtual_disk.add_dynamic_file(path, stat: stat, &block) }. to raise_error(ArgumentError)
65
+ end
66
+ end
67
+
68
+ describe '#add_mapped_file' do
69
+ let(:path) { 'path' }
70
+ let(:mapped_path) { 'mapped_path' }
71
+
72
+ before(:each) { allow(virtual_disk).to receive(:add) }
73
+
74
+ it 'normalizes the path argument' do
75
+ expect(RubySMB::Server::Share::Provider::VirtualDisk::VirtualMappedFile).to receive(:new).with(virtual_disk, File::SEPARATOR + path, mapped_path)
76
+ virtual_disk.add_mapped_file(path + '/dir/..', mapped_path)
77
+ end
78
+
79
+ it 'initializes a new VirtualMappedFile instance' do
80
+ expect(RubySMB::Server::Share::Provider::VirtualDisk::VirtualMappedFile).to receive(:new)
81
+ virtual_disk.add_mapped_file(path, mapped_path)
82
+ end
83
+
84
+ it 'adds the mapped file' do
85
+ expect(virtual_disk).to receive(:add)
86
+ expect(virtual_disk.add_mapped_file(path, mapped_path))
87
+ end
88
+
89
+ it 'throws an exception if the stat object is not a file' do
90
+ stat = RubySMB::Server::Share::Provider::VirtualDisk::VirtualStat.new(file?: false)
91
+ expect { virtual_disk.add_mapped_file(path, mapped_path, stat: stat) }. to raise_error(ArgumentError)
92
+ end
93
+ end
94
+
95
+ describe '#add_static_file' do
96
+ let(:path) { 'path' }
97
+ let(:content) { 'Hello World!' }
98
+
99
+ before(:each) { allow(virtual_disk).to receive(:add) }
100
+
101
+ it 'normalizes the path argument' do
102
+ expect(RubySMB::Server::Share::Provider::VirtualDisk::VirtualStaticFile).to receive(:new).with(virtual_disk, File::SEPARATOR + path, content, stat: nil)
103
+ virtual_disk.add_static_file(path + '/dir/..', content)
104
+ end
105
+
106
+ it 'initializes a new VirtualStaticFile instance' do
107
+ expect(RubySMB::Server::Share::Provider::VirtualDisk::VirtualStaticFile).to receive(:new)
108
+ virtual_disk.add_static_file(path, content)
109
+ end
110
+
111
+ it 'adds the mapped file' do
112
+ expect(virtual_disk).to receive(:add)
113
+ expect(virtual_disk.add_static_file(path, content))
114
+ end
115
+
116
+ it 'throws an exception if the stat object is not a file' do
117
+ stat = RubySMB::Server::Share::Provider::VirtualDisk::VirtualStat.new(file?: false)
118
+ expect { virtual_disk.add_static_file(path, content, stat: stat) }.to raise_error(ArgumentError)
119
+ end
120
+ end
121
+ end
122
+
@@ -26,7 +26,7 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindFirst2Request do
26
26
  expect(parameter_block).to be_a RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
27
27
  end
28
28
 
29
- it 'should have the setup set to the OPEN2 subcommand' do
29
+ it 'should have the setup set to the FIND_FIRST2 subcommand' do
30
30
  expect(parameter_block.setup).to include RubySMB::SMB1::Packet::Trans2::Subcommands::FIND_FIRST2
31
31
  end
32
32
  end
@@ -47,7 +47,7 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindFirst2Request do
47
47
  end
48
48
 
49
49
  it 'should keep #trans2_data 4-byte aligned' do
50
- expect(data_block.trans2_data.abs_offset % 4).to eq 0
50
+ expect(data_block.trans2_data.abs_offset % 4).to eq 0 if data_block.trans2_data.num_bytes != 0
51
51
  end
52
52
 
53
53
  describe '#trans2_parameters' do
@@ -24,7 +24,7 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindFirst2Response do
24
24
  describe '#parameter_block' do
25
25
  subject(:parameter_block) { packet.parameter_block }
26
26
 
27
- it 'should have the setup set to the OPEN2 subcommand' do
27
+ it 'should have the setup set to the FIND_FIRST2 subcommand' do
28
28
  expect(parameter_block.setup).to include RubySMB::SMB1::Packet::Trans2::Subcommands::FIND_FIRST2
29
29
  end
30
30
  end
@@ -40,7 +40,7 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindFirst2Response do
40
40
  end
41
41
 
42
42
  it 'should keep #trans2_data 4-byte aligned' do
43
- expect(data_block.trans2_data.abs_offset % 4).to eq 0
43
+ expect(data_block.trans2_data.abs_offset % 4).to eq 0 if data_block.trans2_data.num_bytes != 0
44
44
  end
45
45
 
46
46
  describe '#trans2_parameters' do
@@ -57,6 +57,40 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindFirst2Response do
57
57
  subject(:data) { data_block.trans2_data }
58
58
 
59
59
  it { is_expected.to respond_to :buffer }
60
+
61
+ describe '#buffer' do
62
+ it 'is a String field' do
63
+ expect(data.buffer).to be_a BinData::String
64
+ end
65
+ end
66
+
67
+ context 'when the buffer is empty' do
68
+ before :each do
69
+ data.buffer = ''
70
+ end
71
+
72
+ it 'should not be padded' do
73
+ expect(data_block.pad2.num_bytes).to eq 0
74
+ end
75
+
76
+ it 'should read its own binary representation' do
77
+ expect(packet.class.read(packet.to_binary_s).data_block.trans2_data.buffer).to eq ''
78
+ end
79
+ end
80
+
81
+ context 'when the buffer is not empty' do
82
+ before :each do
83
+ data.buffer = 'test'
84
+ end
85
+
86
+ it 'should be padded to a 4-byte boundary' do
87
+ expect(data_block.trans2_data.abs_offset % 4).to eq 0
88
+ end
89
+
90
+ it 'should read its own binary representation' do
91
+ expect(packet.class.read(packet.to_binary_s).data_block.trans2_data.buffer).to eq 'test'
92
+ end
93
+ end
60
94
  end
61
95
  end
62
96
 
@@ -26,7 +26,7 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindNext2Request do
26
26
  expect(parameter_block).to be_a RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
27
27
  end
28
28
 
29
- it 'should have the setup set to the OPEN2 subcommand' do
29
+ it 'should have the setup set to the FIND_NEXT2 subcommand' do
30
30
  expect(parameter_block.setup).to include RubySMB::SMB1::Packet::Trans2::Subcommands::FIND_NEXT2
31
31
  end
32
32
  end
@@ -47,7 +47,7 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindNext2Request do
47
47
  end
48
48
 
49
49
  it 'should keep #trans2_data 4-byte aligned' do
50
- expect(data_block.trans2_data.abs_offset % 4).to eq 0
50
+ expect(data_block.trans2_data.abs_offset % 4).to eq 0 if data_block.trans2_data.num_bytes != 0
51
51
  end
52
52
 
53
53
  describe '#trans2_parameters' do
@@ -24,7 +24,7 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindNext2Response do
24
24
  describe '#parameter_block' do
25
25
  subject(:parameter_block) { packet.parameter_block }
26
26
 
27
- it 'should have the setup set to the OPEN2 subcommand' do
27
+ it 'should have the setup set to the FIND_NEXT2 subcommand' do
28
28
  expect(parameter_block.setup).to include RubySMB::SMB1::Packet::Trans2::Subcommands::FIND_NEXT2
29
29
  end
30
30
  end
@@ -56,6 +56,40 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::FindNext2Response do
56
56
  subject(:data) { data_block.trans2_data }
57
57
 
58
58
  it { is_expected.to respond_to :buffer }
59
+
60
+ describe '#buffer' do
61
+ it 'is a String field' do
62
+ expect(data.buffer).to be_a BinData::String
63
+ end
64
+ end
65
+
66
+ context 'when the buffer is empty' do
67
+ before :each do
68
+ data.buffer = ''
69
+ end
70
+
71
+ it 'should not be padded' do
72
+ expect(data_block.pad2.num_bytes).to eq 0
73
+ end
74
+
75
+ it 'should read its own binary representation' do
76
+ expect(packet.class.read(packet.to_binary_s).data_block.trans2_data.buffer).to eq ''
77
+ end
78
+ end
79
+
80
+ context 'when the buffer is not empty' do
81
+ before :each do
82
+ data.buffer = 'test'
83
+ end
84
+
85
+ it 'should be padded to a 4-byte boundary' do
86
+ expect(data_block.trans2_data.abs_offset % 4).to eq 0
87
+ end
88
+
89
+ it 'should read its own binary representation' do
90
+ expect(packet.class.read(packet.to_binary_s).data_block.trans2_data.buffer).to eq 'test'
91
+ end
92
+ end
59
93
  end
60
94
  end
61
95
 
@@ -0,0 +1,74 @@
1
+ include RubySMB::Fscc::FileInformation
2
+
3
+ RSpec.describe RubySMB::SMB1::Packet::Trans2::QueryFileInformationRequest do
4
+ subject(:packet) { described_class.new }
5
+
6
+ describe '#smb_header' do
7
+ subject(:header) { packet.smb_header }
8
+
9
+ it 'is a standard SMB Header' do
10
+ expect(header).to be_a RubySMB::SMB1::SMBHeader
11
+ end
12
+
13
+ it 'should have the command set to SMB_COM_TRANSACTION2' do
14
+ expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
15
+ end
16
+
17
+ it 'should not have the response flag set' do
18
+ expect(header.flags.reply).to eq 0
19
+ end
20
+ end
21
+
22
+ describe '#parameter_block' do
23
+ subject(:parameter_block) { packet.parameter_block }
24
+
25
+ it 'is a standard ParameterBlock' do
26
+ expect(parameter_block).to be_a RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
27
+ end
28
+
29
+ it 'should have the setup set to the QUERY_FILE_INFORMATION subcommand' do
30
+ expect(parameter_block.setup).to include RubySMB::SMB1::Packet::Trans2::Subcommands::QUERY_FILE_INFORMATION
31
+ end
32
+ end
33
+
34
+ describe '#data_block' do
35
+ subject(:data_block) { packet.data_block }
36
+
37
+ it 'is a standard DataBlock' do
38
+ expect(data_block).to be_a RubySMB::SMB1::DataBlock
39
+ end
40
+
41
+ it { is_expected.to respond_to :name }
42
+ it { is_expected.to respond_to :trans2_parameters }
43
+ it { is_expected.to respond_to :trans2_data }
44
+
45
+ it 'should keep #trans2_parameters 4-byte aligned' do
46
+ expect(data_block.trans2_parameters.abs_offset % 4).to eq 0
47
+ end
48
+
49
+ it 'should keep #trans2_data 4-byte aligned' do
50
+ data_block.trans2_parameters.information_level = FILE_DISPOSITION_INFORMATION + SMB_INFO_PASSTHROUGH
51
+ expect(data_block.trans2_data.abs_offset % 4).to eq 0 if data_block.trans2_data.num_bytes != 0
52
+ end
53
+
54
+ describe '#trans2_parameters' do
55
+ subject(:parameters) { data_block.trans2_parameters }
56
+
57
+ it { is_expected.to respond_to :fid }
58
+ it { is_expected.to respond_to :information_level }
59
+
60
+ describe '#fid' do
61
+ it 'is a 16-bit field' do
62
+ expect(parameters.fid).to be_a BinData::Uint16le
63
+ end
64
+ end
65
+
66
+ describe '#information_level' do
67
+ it 'is a 16-bit field' do
68
+ expect(parameters.information_level).to be_a BinData::Uint16le
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+
@@ -0,0 +1,96 @@
1
+ RSpec.describe RubySMB::SMB1::Packet::Trans2::QueryFileInformationResponse do
2
+ subject(:packet) { described_class.new }
3
+
4
+ describe '#smb_header' do
5
+ subject(:header) { packet.smb_header }
6
+
7
+ it 'is a standard SMB Header' do
8
+ expect(header).to be_a RubySMB::SMB1::SMBHeader
9
+ end
10
+
11
+ it 'should have the command set to SMB_COM_TRANSACTION2' do
12
+ expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
13
+ end
14
+
15
+ it 'should have the response flag set' do
16
+ expect(header.flags.reply).to eq 1
17
+ end
18
+ end
19
+
20
+ describe '#parameter_block' do
21
+ subject(:parameter_block) { packet.parameter_block }
22
+
23
+ it 'should have the setup set to the QUERY_FILE_INFORMATION subcommand' do
24
+ expect(parameter_block.setup).to include RubySMB::SMB1::Packet::Trans2::Subcommands::QUERY_FILE_INFORMATION
25
+ end
26
+ end
27
+
28
+ describe '#data_block' do
29
+ subject(:data_block) { packet.data_block }
30
+
31
+ it 'is a standard DataBlock' do
32
+ expect(data_block).to be_a RubySMB::SMB1::DataBlock
33
+ end
34
+
35
+ it { is_expected.to respond_to :name }
36
+ it { is_expected.to respond_to :trans2_parameters }
37
+ it { is_expected.to respond_to :trans2_data }
38
+
39
+ it 'should keep #trans2_parameters 4-byte aligned' do
40
+ expect(data_block.trans2_parameters.abs_offset % 4).to eq 0
41
+ end
42
+
43
+ describe '#trans2_parameters' do
44
+ subject(:parameters) { data_block.trans2_parameters }
45
+
46
+ it { is_expected.to respond_to :ea_error_offset }
47
+
48
+ describe '#ea_error_offset' do
49
+ it 'is a 16-bit field' do
50
+ expect(parameters.ea_error_offset).to be_a BinData::Uint16le
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '#trans2_data' do
56
+ subject(:data) { data_block.trans2_data }
57
+
58
+ it { is_expected.to respond_to :buffer }
59
+
60
+ describe '#buffer' do
61
+ it 'is a String field' do
62
+ expect(data.buffer).to be_a BinData::String
63
+ end
64
+ end
65
+
66
+ context 'when the buffer is empty' do
67
+ before :each do
68
+ data.buffer = ''
69
+ end
70
+
71
+ it 'should not be padded' do
72
+ expect(data_block.pad2.num_bytes).to eq 0
73
+ end
74
+
75
+ it 'should read its own binary representation' do
76
+ expect(packet.class.read(packet.to_binary_s).data_block.trans2_data.buffer).to eq ''
77
+ end
78
+ end
79
+
80
+ context 'when the buffer is not empty' do
81
+ before :each do
82
+ data.buffer = 'test'
83
+ end
84
+
85
+ it 'should be padded to a 4-byte boundary' do
86
+ expect(data_block.trans2_data.abs_offset % 4).to eq 0
87
+ end
88
+
89
+ it 'should read its own binary representation' do
90
+ expect(packet.class.read(packet.to_binary_s).data_block.trans2_data.buffer).to eq 'test'
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ end