ruby_smb 1.0.3 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.travis.yml +3 -2
  5. data/Gemfile +6 -2
  6. data/README.md +35 -47
  7. data/examples/enum_registry_key.rb +28 -0
  8. data/examples/enum_registry_values.rb +30 -0
  9. data/examples/negotiate.rb +51 -8
  10. data/examples/pipes.rb +2 -1
  11. data/examples/read_file_encryption.rb +56 -0
  12. data/examples/read_registry_key_value.rb +32 -0
  13. data/lib/ruby_smb.rb +4 -1
  14. data/lib/ruby_smb/client.rb +233 -22
  15. data/lib/ruby_smb/client/authentication.rb +70 -33
  16. data/lib/ruby_smb/client/echo.rb +20 -2
  17. data/lib/ruby_smb/client/encryption.rb +62 -0
  18. data/lib/ruby_smb/client/negotiation.rb +172 -24
  19. data/lib/ruby_smb/client/signing.rb +19 -0
  20. data/lib/ruby_smb/client/tree_connect.rb +24 -18
  21. data/lib/ruby_smb/client/utils.rb +8 -7
  22. data/lib/ruby_smb/client/winreg.rb +46 -0
  23. data/lib/ruby_smb/crypto.rb +30 -0
  24. data/lib/ruby_smb/dcerpc.rb +38 -0
  25. data/lib/ruby_smb/dcerpc/bind.rb +2 -2
  26. data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
  27. data/lib/ruby_smb/dcerpc/error.rb +3 -0
  28. data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
  29. data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
  30. data/lib/ruby_smb/dcerpc/request.rb +28 -9
  31. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -0
  32. data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
  33. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
  34. data/lib/ruby_smb/dcerpc/winreg.rb +340 -0
  35. data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
  36. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
  37. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
  38. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
  39. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
  40. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
  41. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
  42. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
  43. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
  44. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
  45. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
  46. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
  47. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +39 -0
  48. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
  49. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
  50. data/lib/ruby_smb/dispatcher/socket.rb +4 -3
  51. data/lib/ruby_smb/error.rb +68 -2
  52. data/lib/ruby_smb/generic_packet.rb +33 -4
  53. data/lib/ruby_smb/smb1/commands.rb +1 -1
  54. data/lib/ruby_smb/smb1/file.rb +66 -15
  55. data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
  56. data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
  57. data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
  58. data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
  59. data/lib/ruby_smb/smb1/packet/empty_packet.rb +10 -1
  60. data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
  61. data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
  62. data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
  63. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
  64. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
  65. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
  66. data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
  67. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
  68. data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
  69. data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
  70. data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
  71. data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
  72. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
  73. data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
  74. data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +3 -2
  75. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
  76. data/lib/ruby_smb/smb1/packet/session_setup_response.rb +3 -2
  77. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
  78. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
  79. data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
  80. data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
  81. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
  82. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
  83. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
  84. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
  85. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
  86. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
  87. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
  88. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
  89. data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
  90. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
  91. data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
  92. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
  93. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
  94. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
  95. data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
  96. data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
  97. data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
  98. data/lib/ruby_smb/smb1/packet/write_andx_request.rb +3 -6
  99. data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
  100. data/lib/ruby_smb/smb1/pipe.rb +87 -6
  101. data/lib/ruby_smb/smb1/tree.rb +50 -3
  102. data/lib/ruby_smb/smb2/bit_field/session_flags.rb +2 -1
  103. data/lib/ruby_smb/smb2/bit_field/share_flags.rb +6 -4
  104. data/lib/ruby_smb/smb2/file.rb +103 -25
  105. data/lib/ruby_smb/smb2/negotiate_context.rb +108 -0
  106. data/lib/ruby_smb/smb2/packet.rb +2 -0
  107. data/lib/ruby_smb/smb2/packet/close_request.rb +2 -4
  108. data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
  109. data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +41 -0
  110. data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
  111. data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
  112. data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
  113. data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
  114. data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -3
  115. data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
  116. data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
  117. data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
  118. data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
  119. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +51 -17
  120. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +52 -5
  121. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
  122. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
  123. data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
  124. data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
  125. data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
  126. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
  127. data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
  128. data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
  129. data/lib/ruby_smb/smb2/packet/transform_header.rb +84 -0
  130. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +93 -10
  131. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +10 -22
  132. data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
  133. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
  134. data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
  135. data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
  136. data/lib/ruby_smb/smb2/pipe.rb +86 -12
  137. data/lib/ruby_smb/smb2/smb2_header.rb +1 -1
  138. data/lib/ruby_smb/smb2/tree.rb +65 -21
  139. data/lib/ruby_smb/version.rb +1 -1
  140. data/ruby_smb.gemspec +5 -3
  141. data/spec/lib/ruby_smb/client_spec.rb +1612 -108
  142. data/spec/lib/ruby_smb/crypto_spec.rb +25 -0
  143. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
  144. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
  145. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +410 -0
  146. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
  147. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -0
  148. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
  149. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
  150. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
  151. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
  152. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +108 -0
  153. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
  154. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
  155. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
  156. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
  157. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
  158. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +90 -0
  159. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
  160. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +39 -0
  161. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
  162. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
  163. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +150 -0
  164. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
  165. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
  166. data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
  167. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +2 -2
  168. data/spec/lib/ruby_smb/error_spec.rb +59 -0
  169. data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
  170. data/spec/lib/ruby_smb/smb1/file_spec.rb +191 -2
  171. data/spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb +68 -0
  172. data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +2 -2
  173. data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +2 -2
  174. data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +2 -2
  175. data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +1 -1
  176. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +11 -2
  177. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
  178. data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
  179. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +272 -149
  180. data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
  181. data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +9 -0
  182. data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +27 -0
  183. data/spec/lib/ruby_smb/smb2/file_spec.rb +323 -6
  184. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +332 -0
  185. data/spec/lib/ruby_smb/smb2/packet/compression_transform_header_spec.rb +108 -0
  186. data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +78 -0
  187. data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +138 -3
  188. data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +120 -2
  189. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +8 -0
  190. data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +220 -0
  191. data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +339 -9
  192. data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +3 -22
  193. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +286 -149
  194. data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +2 -2
  195. data/spec/lib/ruby_smb/smb2/tree_spec.rb +261 -2
  196. metadata +191 -83
  197. metadata.gz.sig +0 -0
  198. data/lib/ruby_smb/smb1/dcerpc.rb +0 -67
  199. data/lib/ruby_smb/smb2/dcerpc.rb +0 -70
  200. data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +0 -37
@@ -0,0 +1,332 @@
1
+ RSpec.describe RubySMB::SMB2::PreauthIntegrityCapabilities do
2
+ subject(:capability) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :hash_algorithm_count }
5
+ it { is_expected.to respond_to :salt_length }
6
+ it { is_expected.to respond_to :hash_algorithms }
7
+ it { is_expected.to respond_to :salt }
8
+
9
+ it 'is little endian' do
10
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
11
+ end
12
+
13
+ describe '#hash_algorithm_count' do
14
+ it 'is a 16-bit unsigned integer' do
15
+ expect(capability.hash_algorithm_count).to be_a BinData::Uint16le
16
+ end
17
+
18
+ it 'is set to the #hash_algorithms array size' do
19
+ array = [1, 2, 3]
20
+ capability.hash_algorithms = array
21
+ expect(capability.hash_algorithm_count).to eq(array.size)
22
+ end
23
+ end
24
+
25
+ describe '#salt_length' do
26
+ it 'is a 16-bit unsigned integer' do
27
+ expect(capability.salt_length).to be_a BinData::Uint16le
28
+ end
29
+
30
+ it 'is set to the #salt string size' do
31
+ salt = 'my_random_salt'
32
+ capability.salt = salt
33
+ expect(capability.salt_length).to eq(salt.size)
34
+ end
35
+ end
36
+
37
+ describe '#hash_algorithms' do
38
+ it 'is a BinData Array' do
39
+ expect(capability.hash_algorithms).to be_a BinData::Array
40
+ end
41
+
42
+ it 'has #hash_algorithm_count elements' do
43
+ capability.hash_algorithm_count = 3
44
+ expect(capability.hash_algorithms.size).to eq 3
45
+ end
46
+ end
47
+
48
+ describe '#salt' do
49
+ it 'is a string' do
50
+ expect(capability.salt).to be_a BinData::String
51
+ end
52
+
53
+ it 'should read #salt_length bytes' do
54
+ salt = 'my_random_salt'
55
+ capability.salt_length = 5
56
+ expect(capability.salt.read(salt)).to eq(salt[0,5])
57
+ end
58
+ end
59
+
60
+ it 'reads binary data as expected' do
61
+ data = described_class.new(
62
+ hash_algorithms: [described_class::SHA_512],
63
+ salt: 'test salt'
64
+ )
65
+ expect(described_class.read(data.to_binary_s)).to eq(data)
66
+ end
67
+ end
68
+
69
+ RSpec.describe RubySMB::SMB2::EncryptionCapabilities do
70
+ subject(:capability) { described_class.new }
71
+
72
+ it { is_expected.to respond_to :cipher_count }
73
+ it { is_expected.to respond_to :ciphers }
74
+
75
+ it 'is little endian' do
76
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
77
+ end
78
+
79
+ describe '#cipher_count' do
80
+ it 'is a 16-bit unsigned integer' do
81
+ expect(capability.cipher_count).to be_a BinData::Uint16le
82
+ end
83
+
84
+ it 'is set to the #ciphers array size' do
85
+ array = [1, 2, 3]
86
+ capability.ciphers = array
87
+ expect(capability.cipher_count).to eq(array.size)
88
+ end
89
+ end
90
+
91
+ describe '#ciphers' do
92
+ it 'is a BinData Array' do
93
+ expect(capability.ciphers).to be_a BinData::Array
94
+ end
95
+
96
+ it 'has #cipher_count elements' do
97
+ capability.cipher_count = 3
98
+ expect(capability.ciphers.size).to eq 3
99
+ end
100
+ end
101
+
102
+ it 'reads binary data as expected' do
103
+ data = described_class.new(
104
+ ciphers: [described_class::AES_128_CCM, described_class::AES_128_GCM]
105
+ )
106
+ expect(described_class.read(data.to_binary_s)).to eq(data)
107
+ end
108
+ end
109
+
110
+ RSpec.describe RubySMB::SMB2::CompressionCapabilities do
111
+ subject(:capability) { described_class.new }
112
+
113
+ it { is_expected.to respond_to :compression_algorithm_count }
114
+ it { is_expected.to respond_to :padding }
115
+ it { is_expected.to respond_to :flags }
116
+ it { is_expected.to respond_to :compression_algorithms }
117
+
118
+ it 'is little endian' do
119
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
120
+ end
121
+
122
+ describe '#compression_algorithm_count' do
123
+ it 'is a 16-bit unsigned integer' do
124
+ expect(capability.compression_algorithm_count).to be_a BinData::Uint16le
125
+ end
126
+
127
+ it 'is set to the #compression_algorithms array size' do
128
+ array = [1, 2, 3]
129
+ capability.compression_algorithms = array
130
+ expect(capability.compression_algorithm_count).to eq(array.size)
131
+ end
132
+ end
133
+
134
+ describe '#padding' do
135
+ it 'is a 16-bit unsigned integer' do
136
+ expect(capability.padding).to be_a BinData::Uint16le
137
+ end
138
+ end
139
+
140
+ describe '#flags' do
141
+ it 'is a 32-bit unsigned integer' do
142
+ expect(capability.flags).to be_a BinData::Uint32le
143
+ end
144
+ end
145
+
146
+ describe '#compression_algorithms' do
147
+ it 'is a BinData Array' do
148
+ expect(capability.compression_algorithms).to be_a BinData::Array
149
+ end
150
+
151
+ it 'has #compression_algorithm_count elements' do
152
+ capability.compression_algorithm_count = 3
153
+ expect(capability.compression_algorithms.size).to eq 3
154
+ end
155
+ end
156
+
157
+ it 'reads binary data as expected' do
158
+ data = described_class.new(
159
+ compression_algorithms: [described_class::LZNT1, described_class::LZ77]
160
+ )
161
+ expect(described_class.read(data.to_binary_s)).to eq(data)
162
+ end
163
+ end
164
+
165
+ RSpec.describe RubySMB::SMB2::NetnameNegotiateContextId do
166
+ subject(:capability) { described_class.new }
167
+
168
+ it { is_expected.to respond_to :net_name }
169
+
170
+ it 'is little endian' do
171
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
172
+ end
173
+
174
+ describe '#net_name' do
175
+ it 'is a unicode string' do
176
+ expect(capability.net_name).to be_a RubySMB::Field::Stringz16
177
+ end
178
+ end
179
+
180
+ it 'reads binary data as expected' do
181
+ data = described_class.new(
182
+ net_name: 'netname test'
183
+ )
184
+ expect(described_class.read(data.to_binary_s)).to eq(data)
185
+ end
186
+ end
187
+
188
+ RSpec.describe RubySMB::SMB2::NegotiateContext do
189
+ class FakePacket < BinData::Record
190
+ endian :little
191
+ string :garbage
192
+ negotiate_context :nc
193
+ end
194
+
195
+ let(:test_packet) do
196
+ packet = FakePacket.new
197
+ packet.nc.context_type = described_class::SMB2_PREAUTH_INTEGRITY_CAPABILITIES
198
+ packet
199
+ end
200
+ subject(:negotiate_context) { described_class.new }
201
+
202
+ it { is_expected.to respond_to :pad }
203
+ it { is_expected.to respond_to :context_type }
204
+ it { is_expected.to respond_to :data_length }
205
+ it { is_expected.to respond_to :reserved }
206
+ it { is_expected.to respond_to :data }
207
+
208
+ it 'is little endian' do
209
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
210
+ end
211
+
212
+ describe '#pad' do
213
+ it 'is a string' do
214
+ expect(negotiate_context.pad).to be_a BinData::String
215
+ end
216
+
217
+ it 'should keep the #context_type 8-byte aligned' do
218
+ test_packet.garbage = 'foo'
219
+ expect(test_packet.nc.context_type.abs_offset % 8).to eq(0)
220
+ end
221
+ end
222
+
223
+ describe '#context_type ' do
224
+ it 'is a 16-bit unsigned integer' do
225
+ expect(negotiate_context.context_type).to be_a BinData::Uint16le
226
+ end
227
+ end
228
+
229
+ describe '#data_length' do
230
+ it 'is a 16-bit unsigned integer' do
231
+ expect(negotiate_context.data_length).to be_a BinData::Uint16le
232
+ end
233
+
234
+ it 'should give the #data field length in bytes' do
235
+ expect(described_class.new(context_type: described_class::SMB2_ENCRYPTION_CAPABILITIES).data_length)
236
+ .to eq(RubySMB::SMB2::EncryptionCapabilities.new.num_bytes)
237
+ end
238
+ end
239
+
240
+ describe '#data' do
241
+ it 'is a BinData choice field' do
242
+ expect(negotiate_context.data).to be_a BinData::Choice
243
+ end
244
+
245
+ context 'with a SMB2_PREAUTH_INTEGRITY_CAPABILITIES context type' do
246
+ it 'selects the PreauthIntegrityCapabilities structure' do
247
+ expect(described_class.new(context_type: described_class::SMB2_PREAUTH_INTEGRITY_CAPABILITIES).data)
248
+ .to eq(RubySMB::SMB2::PreauthIntegrityCapabilities.new)
249
+ end
250
+ end
251
+
252
+ context 'with a SMB2_ENCRYPTION_CAPABILITIES context type' do
253
+ it 'selects the PreauthIntegrityCapabilities structure' do
254
+ expect(described_class.new(context_type: described_class::SMB2_ENCRYPTION_CAPABILITIES).data)
255
+ .to eq(RubySMB::SMB2::EncryptionCapabilities.new)
256
+ end
257
+ end
258
+
259
+ context 'with a SMB2_COMPRESSION_CAPABILITIES context type' do
260
+ it 'selects the PreauthIntegrityCapabilities structure' do
261
+ expect(described_class.new(context_type: described_class::SMB2_COMPRESSION_CAPABILITIES).data)
262
+ .to eq(RubySMB::SMB2::CompressionCapabilities.new)
263
+ end
264
+ end
265
+
266
+ context 'with a SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context type' do
267
+ it 'selects the PreauthIntegrityCapabilities structure' do
268
+ expect(described_class.new(context_type: described_class::SMB2_NETNAME_NEGOTIATE_CONTEXT_ID).data)
269
+ .to eq(RubySMB::SMB2::NetnameNegotiateContextId.new)
270
+ end
271
+ end
272
+ end
273
+
274
+ describe '#pad_length' do
275
+ it 'returns 0 when #context_type is already 8-byte aligned' do
276
+ expect(test_packet.nc.pad_length).to eq(0)
277
+ end
278
+
279
+ it 'returns 2 when #context_type is only 2-byte aligned' do
280
+ test_packet.garbage = 'align' + 'A'
281
+ expect(test_packet.nc.pad_length).to eq(2)
282
+ end
283
+ end
284
+
285
+ context 'with a SMB2_PREAUTH_INTEGRITY_CAPABILITIES context type' do
286
+ it 'reads binary data as expected' do
287
+ data = described_class.new(
288
+ context_type: described_class::SMB2_PREAUTH_INTEGRITY_CAPABILITIES
289
+ )
290
+ data.data.hash_algorithms << RubySMB::SMB2::PreauthIntegrityCapabilities::SHA_512
291
+ data.data.salt = 'test salt'
292
+ expect(described_class.read(data.to_binary_s)).to eq(data)
293
+ end
294
+ end
295
+
296
+ context 'with a SMB2_ENCRYPTION_CAPABILITIES context type' do
297
+ it 'reads binary data as expected' do
298
+ data = described_class.new(
299
+ context_type: described_class::SMB2_ENCRYPTION_CAPABILITIES
300
+ )
301
+ data.data.ciphers = [
302
+ RubySMB::SMB2::EncryptionCapabilities::AES_128_CCM,
303
+ RubySMB::SMB2::EncryptionCapabilities::AES_128_GCM
304
+ ]
305
+ expect(described_class.read(data.to_binary_s)).to eq(data)
306
+ end
307
+ end
308
+
309
+ context 'with a SMB2_COMPRESSION_CAPABILITIES context type' do
310
+ it 'reads binary data as expected' do
311
+ data = described_class.new(
312
+ context_type: described_class::SMB2_COMPRESSION_CAPABILITIES
313
+ )
314
+ data.data.compression_algorithms = [
315
+ RubySMB::SMB2::CompressionCapabilities::LZNT1,
316
+ RubySMB::SMB2::CompressionCapabilities::LZ77
317
+ ]
318
+ expect(described_class.read(data.to_binary_s)).to eq(data)
319
+ end
320
+ end
321
+
322
+ context 'with a SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context type' do
323
+ it 'reads binary data as expected' do
324
+ data = described_class.new(
325
+ context_type: described_class::SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
326
+ )
327
+ data.data.net_name = 'netname test'
328
+ expect(described_class.read(data.to_binary_s)).to eq(data)
329
+ end
330
+ end
331
+ end
332
+
@@ -0,0 +1,108 @@
1
+ RSpec.describe RubySMB::SMB2::Packet::CompressionTransformHeader do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :protocol }
5
+ it { is_expected.to respond_to :original_compressed_segment_size }
6
+ it { is_expected.to respond_to :compression_algorithm }
7
+ it { is_expected.to respond_to :flags }
8
+ it { is_expected.to respond_to :offset }
9
+
10
+ it 'is little endian' do
11
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
12
+ end
13
+
14
+ describe '#protocol' do
15
+ it 'is a 32-bit field' do
16
+ expect(packet.protocol).to be_a BinData::Bit32
17
+ end
18
+
19
+ it 'is initialized with the value 0xFC534D42' do
20
+ expect(packet.protocol).to eq(0xFC534D42)
21
+ end
22
+ end
23
+
24
+ describe '#original_compressed_segment_size ' do
25
+ it 'is a 32-bit unsigned integer' do
26
+ expect(packet.original_compressed_segment_size).to be_a BinData::Uint32le
27
+ end
28
+ end
29
+
30
+ describe '#compression_algorithm ' do
31
+ it 'is a 16-bit unsigned integer' do
32
+ expect(packet.compression_algorithm).to be_a BinData::Uint16le
33
+ end
34
+ end
35
+
36
+ describe '#flags ' do
37
+ it 'is a 16-bit unsigned integer' do
38
+ expect(packet.flags).to be_a BinData::Uint16le
39
+ end
40
+ end
41
+
42
+ describe '#offset' do
43
+ it 'is a 32-bit unsigned integer' do
44
+ expect(packet.offset).to be_a BinData::Uint32le
45
+ end
46
+ end
47
+
48
+ it 'reads binary data as expected' do
49
+ data = described_class.new
50
+ expect(described_class.read(data.to_binary_s)).to eq(data)
51
+ end
52
+ end
53
+
54
+ RSpec.describe RubySMB::SMB2::Packet::Smb2CompressionPayloadHeader do
55
+ subject(:packet) { described_class.new }
56
+
57
+ it { is_expected.to respond_to :algorithm_id }
58
+ it { is_expected.to respond_to :payload_length }
59
+
60
+ it 'is little endian' do
61
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
62
+ end
63
+
64
+ describe '#algorithm_id ' do
65
+ it 'is a 16-bit unsigned integer' do
66
+ expect(packet.algorithm_id).to be_a BinData::Uint16le
67
+ end
68
+ end
69
+
70
+ describe '#payload_length' do
71
+ it 'is a 32-bit unsigned integer' do
72
+ expect(packet.payload_length).to be_a BinData::Uint32le
73
+ end
74
+ end
75
+
76
+ it 'reads binary data as expected' do
77
+ data = described_class.new
78
+ expect(described_class.read(data.to_binary_s)).to eq(data)
79
+ end
80
+ end
81
+
82
+ RSpec.describe RubySMB::SMB2::Packet::Smb2CompressionPatternPayloadV1 do
83
+ subject(:packet) { described_class.new }
84
+
85
+ it { is_expected.to respond_to :pattern }
86
+ it { is_expected.to respond_to :repetitions }
87
+
88
+ it 'is little endian' do
89
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
90
+ end
91
+
92
+ describe '#pattern' do
93
+ it 'is a 8-bit unsigned integer' do
94
+ expect(packet.pattern).to be_a BinData::Uint8
95
+ end
96
+ end
97
+
98
+ describe '#repetitions' do
99
+ it 'is a 32-bit unsigned integer' do
100
+ expect(packet.repetitions).to be_a BinData::Uint32le
101
+ end
102
+ end
103
+
104
+ it 'reads binary data as expected' do
105
+ data = described_class.new
106
+ expect(described_class.read(data.to_binary_s)).to eq(data)
107
+ end
108
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::SMB2::Packet::ErrorPacket do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :smb2_header }
7
+ it { is_expected.to respond_to :structure_size }
8
+ it { is_expected.to respond_to :error_data }
9
+
10
+ describe '#smb2_header' do
11
+ subject(:header) { packet.smb2_header }
12
+
13
+ it 'is a standard SMB2 Header' do
14
+ expect(header).to be_a RubySMB::SMB2::SMB2Header
15
+ end
16
+ end
17
+
18
+ describe '#structure_size' do
19
+ it 'should be a 16-bit unsigned integer' do
20
+ expect(packet.structure_size).to be_a BinData::Uint16le
21
+ end
22
+
23
+ it 'should be 9 by default' do
24
+ expect(packet.structure_size).to eq 9
25
+ end
26
+ end
27
+
28
+ describe '#error_context_count' do
29
+ it 'should be a 8-bit unsigned integer' do
30
+ expect(packet.error_context_count).to be_a BinData::Uint8
31
+ end
32
+ end
33
+
34
+ describe '#byte_count' do
35
+ it 'should be a 32-bit unsigned integer' do
36
+ expect(packet.byte_count).to be_a BinData::Uint32le
37
+ end
38
+ end
39
+
40
+ describe '#error_data' do
41
+ it 'should be a String' do
42
+ expect(packet.error_data).to be_a BinData::String
43
+ end
44
+
45
+ it 'should read #byte_count bytes' do
46
+ packet.error_data = 'test'
47
+ packet.byte_count = 3
48
+ expect(described_class.read(packet.to_binary_s).error_data.size).to eq 3
49
+ end
50
+ end
51
+
52
+ describe '#valid?' do
53
+ before :example do
54
+ packet.original_command = RubySMB::SMB2::Commands::LOGOFF
55
+ packet.smb2_header.command = RubySMB::SMB2::Commands::LOGOFF
56
+ end
57
+
58
+ it 'returns true if the packet protocol ID and header command are valid' do
59
+ expect(packet).to be_valid
60
+ end
61
+
62
+ it 'returns false if the packet protocol ID is wrong' do
63
+ packet.smb2_header.protocol = RubySMB::SMB1::SMB_PROTOCOL_ID
64
+ expect(packet).to_not be_valid
65
+ end
66
+
67
+ it 'returns false if the packet header command is wrong' do
68
+ packet.smb2_header.command = RubySMB::SMB2::Commands::NEGOTIATE
69
+ expect(packet).to_not be_valid
70
+ end
71
+
72
+ it 'returns false if the packet #structure_size is wrong' do
73
+ packet.structure_size = 10
74
+ expect(packet).to_not be_valid
75
+ end
76
+ end
77
+ end
78
+