ruby_smb 1.0.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +3 -2
- data/Gemfile +6 -2
- data/README.md +35 -47
- data/examples/enum_registry_key.rb +28 -0
- data/examples/enum_registry_values.rb +30 -0
- data/examples/negotiate.rb +51 -8
- data/examples/pipes.rb +2 -1
- data/examples/read_file_encryption.rb +56 -0
- data/examples/read_registry_key_value.rb +32 -0
- data/lib/ruby_smb.rb +4 -1
- data/lib/ruby_smb/client.rb +233 -22
- data/lib/ruby_smb/client/authentication.rb +70 -33
- data/lib/ruby_smb/client/echo.rb +20 -2
- data/lib/ruby_smb/client/encryption.rb +62 -0
- data/lib/ruby_smb/client/negotiation.rb +172 -24
- data/lib/ruby_smb/client/signing.rb +19 -0
- data/lib/ruby_smb/client/tree_connect.rb +24 -18
- data/lib/ruby_smb/client/utils.rb +8 -7
- data/lib/ruby_smb/client/winreg.rb +46 -0
- data/lib/ruby_smb/crypto.rb +30 -0
- data/lib/ruby_smb/dcerpc.rb +38 -0
- data/lib/ruby_smb/dcerpc/bind.rb +2 -2
- data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
- data/lib/ruby_smb/dcerpc/error.rb +3 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
- data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
- data/lib/ruby_smb/dcerpc/request.rb +28 -9
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -0
- data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +340 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
- data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
- data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +39 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
- data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
- data/lib/ruby_smb/dispatcher/socket.rb +4 -3
- data/lib/ruby_smb/error.rb +68 -2
- data/lib/ruby_smb/generic_packet.rb +33 -4
- data/lib/ruby_smb/smb1/commands.rb +1 -1
- data/lib/ruby_smb/smb1/file.rb +66 -15
- data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/empty_packet.rb +10 -1
- data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
- data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/session_setup_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
- data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/write_andx_request.rb +3 -6
- data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/pipe.rb +87 -6
- data/lib/ruby_smb/smb1/tree.rb +50 -3
- data/lib/ruby_smb/smb2/bit_field/session_flags.rb +2 -1
- data/lib/ruby_smb/smb2/bit_field/share_flags.rb +6 -4
- data/lib/ruby_smb/smb2/file.rb +103 -25
- data/lib/ruby_smb/smb2/negotiate_context.rb +108 -0
- data/lib/ruby_smb/smb2/packet.rb +2 -0
- data/lib/ruby_smb/smb2/packet/close_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +41 -0
- data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -3
- data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +51 -17
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +52 -5
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
- data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/transform_header.rb +84 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +93 -10
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +10 -22
- data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
- data/lib/ruby_smb/smb2/pipe.rb +86 -12
- data/lib/ruby_smb/smb2/smb2_header.rb +1 -1
- data/lib/ruby_smb/smb2/tree.rb +65 -21
- data/lib/ruby_smb/version.rb +1 -1
- data/ruby_smb.gemspec +5 -3
- data/spec/lib/ruby_smb/client_spec.rb +1612 -108
- data/spec/lib/ruby_smb/crypto_spec.rb +25 -0
- data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +410 -0
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +108 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +90 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +39 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +150 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
- data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +2 -2
- data/spec/lib/ruby_smb/error_spec.rb +59 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
- data/spec/lib/ruby_smb/smb1/file_spec.rb +191 -2
- data/spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb +68 -0
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +11 -2
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +272 -149
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
- data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +9 -0
- data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +27 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +323 -6
- data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +332 -0
- data/spec/lib/ruby_smb/smb2/packet/compression_transform_header_spec.rb +108 -0
- data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +78 -0
- data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +138 -3
- data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +120 -2
- data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +8 -0
- data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +220 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +339 -9
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +3 -22
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +286 -149
- data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +261 -2
- metadata +191 -83
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/dcerpc.rb +0 -67
- data/lib/ruby_smb/smb2/dcerpc.rb +0 -70
- 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
|
+
|