ruby_smb 3.0.0 → 3.0.4
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/examples/anonymous_auth.rb +29 -6
- data/examples/auth_capture.rb +28 -0
- data/examples/file_server.rb +76 -0
- data/examples/read_file.rb +51 -10
- data/examples/tree_connect.rb +49 -8
- data/lib/ruby_smb/client/authentication.rb +11 -3
- data/lib/ruby_smb/client.rb +16 -2
- data/lib/ruby_smb/create_actions.rb +21 -0
- data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_request.rb +20 -0
- data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_response.rb +20 -0
- data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_request.rb +21 -0
- data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_response.rb +21 -0
- data/lib/ruby_smb/dcerpc/encrypting_file_system.rb +44 -0
- data/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_request.rb +22 -0
- data/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_response.rb +20 -0
- data/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_response.rb +22 -0
- data/lib/ruby_smb/dcerpc/print_system.rb +69 -0
- data/lib/ruby_smb/dcerpc.rb +2 -2
- data/lib/ruby_smb/field/nt_status.rb +20 -1
- data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +14 -0
- data/lib/ruby_smb/fscc/file_information/file_network_open_information.rb +22 -0
- data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +16 -0
- data/lib/ruby_smb/fscc/file_information.rb +29 -0
- data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +46 -0
- data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +19 -0
- data/lib/ruby_smb/fscc/file_system_information.rb +22 -0
- data/lib/ruby_smb/fscc.rb +1 -0
- data/lib/ruby_smb/generic_packet.rb +6 -0
- data/lib/ruby_smb/gss/provider/authenticator.rb +4 -0
- data/lib/ruby_smb/gss/provider/ntlm.rb +13 -3
- data/lib/ruby_smb/server/server_client/negotiation.rb +0 -2
- data/lib/ruby_smb/server/server_client/session_setup.rb +43 -32
- data/lib/ruby_smb/server/server_client/share_io.rb +28 -0
- data/lib/ruby_smb/server/server_client/tree_connect.rb +60 -0
- data/lib/ruby_smb/server/server_client.rb +214 -24
- data/lib/ruby_smb/server/session.rb +71 -0
- data/lib/ruby_smb/server/share/provider/disk.rb +437 -0
- data/lib/ruby_smb/server/share/provider/pipe.rb +27 -0
- data/lib/ruby_smb/server/share/provider/processor.rb +76 -0
- data/lib/ruby_smb/server/share/provider.rb +38 -0
- data/lib/ruby_smb/server/share.rb +11 -0
- data/lib/ruby_smb/server.rb +35 -3
- data/lib/ruby_smb/signing.rb +37 -11
- data/lib/ruby_smb/smb1/commands.rb +4 -0
- data/lib/ruby_smb/smb1/tree.rb +87 -79
- data/lib/ruby_smb/smb1.rb +0 -1
- data/lib/ruby_smb/smb2/bit_field/smb2_header_flags.rb +2 -1
- data/lib/ruby_smb/smb2/commands.rb +4 -0
- data/lib/ruby_smb/smb2/create_context/request.rb +64 -0
- data/lib/ruby_smb/smb2/create_context/response.rb +62 -0
- data/lib/ruby_smb/smb2/create_context.rb +74 -22
- data/lib/ruby_smb/smb2/packet/create_request.rb +44 -11
- data/lib/ruby_smb/smb2/packet/create_response.rb +17 -3
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +1 -1
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +2 -2
- data/lib/ruby_smb/smb2/packet/query_info_request.rb +43 -0
- data/lib/ruby_smb/smb2/packet/query_info_response.rb +23 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +1 -1
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -0
- data/lib/ruby_smb/smb2/packet.rb +2 -0
- data/lib/ruby_smb/smb2/tree.rb +80 -70
- data/lib/ruby_smb/smb2.rb +11 -0
- data/lib/ruby_smb/smb_error.rb +110 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/lib/ruby_smb.rb +2 -0
- data/ruby_smb.gemspec +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +10 -0
- data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_request_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/print_system/driver_container_spec.rb +41 -0
- data/spec/lib/ruby_smb/dcerpc/print_system/driver_info2_spec.rb +64 -0
- data/spec/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_request_spec.rb +59 -0
- data/spec/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_request_spec.rb +62 -0
- data/spec/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_response_spec.rb +54 -0
- data/spec/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_request_spec.rb +62 -0
- data/spec/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_response_spec.rb +46 -0
- data/spec/lib/ruby_smb/field/nt_status_spec.rb +6 -2
- data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +4 -0
- data/spec/lib/ruby_smb/server/server_client_spec.rb +36 -53
- data/spec/lib/ruby_smb/server/session_spec.rb +38 -0
- data/spec/lib/ruby_smb/server/share/provider/disk_spec.rb +61 -0
- data/spec/lib/ruby_smb/server/share/provider/pipe_spec.rb +31 -0
- data/spec/lib/ruby_smb/server/share/provider_spec.rb +13 -0
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +3 -3
- data/spec/lib/ruby_smb/smb2/bit_field/header_flags_spec.rb +8 -2
- data/spec/lib/ruby_smb/smb2/{create_context_spec.rb → create_context/create_context_request_spec.rb} +1 -1
- data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +5 -5
- data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +9 -5
- data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +3 -2
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +3 -3
- data.tar.gz.sig +0 -0
- metadata +71 -7
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/create_actions.rb +0 -20
@@ -0,0 +1,64 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::PrintSystem::DriverInfo2 do
|
2
|
+
subject(:struct) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :c_version }
|
5
|
+
it { is_expected.to respond_to :p_name }
|
6
|
+
it { is_expected.to respond_to :p_environment }
|
7
|
+
it { is_expected.to respond_to :p_driver_path }
|
8
|
+
it { is_expected.to respond_to :p_data_file }
|
9
|
+
it { is_expected.to respond_to :p_config_file }
|
10
|
+
|
11
|
+
it 'is little endian' do
|
12
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#c_version' do
|
16
|
+
it 'is a NdrUint32' do
|
17
|
+
expect(struct.c_version).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#p_name' do
|
22
|
+
it 'is a NdrWideStringzPtr' do
|
23
|
+
expect(struct.p_name).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#p_environment' do
|
28
|
+
it 'is a NdrWideStringzPtr' do
|
29
|
+
expect(struct.p_environment).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#p_driver_path' do
|
34
|
+
it 'is a NdrWideStringzPtr' do
|
35
|
+
expect(struct.p_driver_path).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#p_data_file' do
|
40
|
+
it 'is a NdrWideStringzPtr' do
|
41
|
+
expect(struct.p_data_file).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#p_config_file' do
|
46
|
+
it 'is a NdrWideStringzPtr' do
|
47
|
+
expect(struct.p_config_file).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'reads its own binary representation and outputs the same struct' do
|
52
|
+
struct = described_class.new(
|
53
|
+
c_version: 0,
|
54
|
+
p_name: 'p_name',
|
55
|
+
p_environment: 'p_environment',
|
56
|
+
p_driver_path: 'p_driver_path',
|
57
|
+
p_data_file: 'p_data_file',
|
58
|
+
p_config_file: 'p_config_file'
|
59
|
+
)
|
60
|
+
binary = struct.to_binary_s
|
61
|
+
expect(described_class.read(binary)).to eq(struct)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::PrintSystem::RpcAddPrinterDriverExRequest do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :p_name }
|
5
|
+
it { is_expected.to respond_to :p_driver_container }
|
6
|
+
it { is_expected.to respond_to :dw_file_copy_flags }
|
7
|
+
|
8
|
+
it 'is little endian' do
|
9
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#p_name' do
|
13
|
+
it 'is a NdrWideStringzPtr' do
|
14
|
+
expect(packet.p_name).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#p_driver_container' do
|
19
|
+
it 'is a DriverContainer structure' do
|
20
|
+
expect(packet.p_driver_container).to be_a RubySMB::Dcerpc::PrintSystem::DriverContainer
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#dw_file_copy_flags' do
|
25
|
+
it 'is a NdrUint32' do
|
26
|
+
expect(packet.dw_file_copy_flags).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#initialize_instance' do
|
31
|
+
it 'sets #opnum to RPC_ADD_PRINTER_DRIVER_EX constant' do
|
32
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::PrintSystem::RPC_ADD_PRINTER_DRIVER_EX)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'reads its own binary representation and outputs the same packet' do
|
37
|
+
packet = described_class.new(
|
38
|
+
p_name: 'p_name',
|
39
|
+
p_driver_container: RubySMB::Dcerpc::PrintSystem::DriverContainer.new(
|
40
|
+
RubySMB::Dcerpc::PrintSystem::DriverContainer.new(
|
41
|
+
level: 2,
|
42
|
+
tag: 2,
|
43
|
+
driver_info: RubySMB::Dcerpc::PrintSystem::DriverInfo2.new(
|
44
|
+
c_version: 0,
|
45
|
+
p_name: 'p_name',
|
46
|
+
p_environment: 'p_environment',
|
47
|
+
p_driver_path: 'p_driver_path',
|
48
|
+
p_data_file: 'p_data_file',
|
49
|
+
p_config_file: 'p_config_file'
|
50
|
+
)
|
51
|
+
)
|
52
|
+
),
|
53
|
+
dw_file_copy_flags: 0
|
54
|
+
)
|
55
|
+
binary = packet.to_binary_s
|
56
|
+
expect(described_class.read(binary)).to eq(packet)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::PrintSystem::RpcAddPrinterDriverExResponse do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :error_status }
|
5
|
+
|
6
|
+
it 'is little endian' do
|
7
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#error_status' do
|
11
|
+
it 'is a NdrUint32' do
|
12
|
+
expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#initialize_instance' do
|
17
|
+
it 'sets #opnum to RPC_ADD_PRINTER_DRIVER_EX constant' do
|
18
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::PrintSystem::RPC_ADD_PRINTER_DRIVER_EX)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'reads its own binary representation and outputs the same packet' do
|
23
|
+
packet = described_class.new(
|
24
|
+
error_status: 0
|
25
|
+
)
|
26
|
+
binary = packet.to_binary_s
|
27
|
+
expect(described_class.read(binary)).to eq(packet)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::PrintSystem::RpcEnumPrinterDriversRequest do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :p_name }
|
5
|
+
it { is_expected.to respond_to :p_environment }
|
6
|
+
it { is_expected.to respond_to :level }
|
7
|
+
it { is_expected.to respond_to :p_drivers }
|
8
|
+
it { is_expected.to respond_to :cb_buf }
|
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 '#p_name' do
|
15
|
+
it 'is a NdrWideStringzPtr' do
|
16
|
+
expect(packet.p_name).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#p_environment' do
|
21
|
+
it 'is a NdrWideStringzPtr' do
|
22
|
+
expect(packet.p_environment).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#level' do
|
27
|
+
it 'is a NdrUint32' do
|
28
|
+
expect(packet.level).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#p_drivers' do
|
33
|
+
it 'is a RprnByteArrayPtr' do
|
34
|
+
expect(packet.p_drivers).to be_a RubySMB::Dcerpc::PrintSystem::RprnByteArrayPtr
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#cb_buf' do
|
39
|
+
it 'is a NdrUint32' do
|
40
|
+
expect(packet.cb_buf).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#initialize_instance' do
|
45
|
+
it 'sets #opnum to RPC_ENUM_PRINTER_DRIVERS constant' do
|
46
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::PrintSystem::RPC_ENUM_PRINTER_DRIVERS)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'reads its own binary representation and outputs the same packet' do
|
51
|
+
packet = described_class.new(
|
52
|
+
p_name: 'p_name',
|
53
|
+
p_environment: 'p_environment',
|
54
|
+
level: 0,
|
55
|
+
p_drivers: [0, 1, 2],
|
56
|
+
cb_buf: 0
|
57
|
+
)
|
58
|
+
binary = packet.to_binary_s
|
59
|
+
expect(described_class.read(binary)).to eq(packet)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::PrintSystem::RpcEnumPrinterDriversResponse do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :p_drivers }
|
5
|
+
it { is_expected.to respond_to :pcb_needed }
|
6
|
+
it { is_expected.to respond_to :pc_returned }
|
7
|
+
it { is_expected.to respond_to :error_status }
|
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 '#p_drivers' do
|
14
|
+
it 'is a RprnByteArrayPtr' do
|
15
|
+
expect(packet.p_drivers).to be_a RubySMB::Dcerpc::PrintSystem::RprnByteArrayPtr
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#pcb_needed' do
|
20
|
+
it 'is a NdrUint32' do
|
21
|
+
expect(packet.pcb_needed).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#pc_returned' do
|
26
|
+
it 'is a NdrUint32' do
|
27
|
+
expect(packet.pc_returned).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#error_status' do
|
32
|
+
it 'is a NdrUint32' do
|
33
|
+
expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#initialize_instance' do
|
38
|
+
it 'sets #opnum to RPC_ENUM_PRINTER_DRIVERS constant' do
|
39
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::PrintSystem::RPC_ENUM_PRINTER_DRIVERS)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'reads its own binary representation and outputs the same packet' do
|
44
|
+
packet = described_class.new(
|
45
|
+
p_drivers: [0, 1, 2],
|
46
|
+
pcb_needed: 0,
|
47
|
+
pc_returned: 0,
|
48
|
+
error_status: 0
|
49
|
+
)
|
50
|
+
binary = packet.to_binary_s
|
51
|
+
expect(described_class.read(binary)).to eq(packet)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::PrintSystem::RpcGetPrinterDriverDirectoryRequest do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :p_name }
|
5
|
+
it { is_expected.to respond_to :p_environment }
|
6
|
+
it { is_expected.to respond_to :level}
|
7
|
+
it { is_expected.to respond_to :p_driver_directory }
|
8
|
+
it { is_expected.to respond_to :cb_buf }
|
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 '#p_name' do
|
15
|
+
it 'is a NdrWideStringzPtr' do
|
16
|
+
expect(packet.p_name).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#p_environment' do
|
21
|
+
it 'is a NdrWideStringzPtr' do
|
22
|
+
expect(packet.p_environment).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#level' do
|
27
|
+
it 'is a NdrUint32' do
|
28
|
+
expect(packet.level).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#p_driver_directory' do
|
33
|
+
it 'is a RprnByteArrayPtr' do
|
34
|
+
expect(packet.p_driver_directory).to be_a RubySMB::Dcerpc::PrintSystem::RprnByteArrayPtr
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#cb_buf' do
|
39
|
+
it 'is a NdrUint32' do
|
40
|
+
expect(packet.cb_buf).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#initialize_instance' do
|
45
|
+
it 'sets #opnum to RPC_GET_PRINTER_DRIVER_DIRECTORY constant' do
|
46
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::PrintSystem::RPC_GET_PRINTER_DRIVER_DIRECTORY)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'reads its own binary representation and outputs the same packet' do
|
51
|
+
packet = described_class.new(
|
52
|
+
p_name: 'p_name',
|
53
|
+
p_environment: 'p_environment',
|
54
|
+
level: 0,
|
55
|
+
p_driver_directory: [0, 1, 2],
|
56
|
+
cb_buf: 0
|
57
|
+
)
|
58
|
+
binary = packet.to_binary_s
|
59
|
+
expect(described_class.read(binary)).to eq(packet)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::PrintSystem::RpcGetPrinterDriverDirectoryResponse do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :p_driver_directory }
|
5
|
+
it { is_expected.to respond_to :pcb_needed }
|
6
|
+
it { is_expected.to respond_to :error_status }
|
7
|
+
|
8
|
+
it 'is little endian' do
|
9
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#p_driver_directory' do
|
13
|
+
it 'is a RprnByteArrayPtr' do
|
14
|
+
expect(packet.p_driver_directory).to be_a RubySMB::Dcerpc::PrintSystem::RprnByteArrayPtr
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#pcb_needed' do
|
19
|
+
it 'is a NdrUint32' do
|
20
|
+
expect(packet.pcb_needed).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#error_status' do
|
25
|
+
it 'is a NdrUint32' do
|
26
|
+
expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#initialize_instance' do
|
31
|
+
it 'sets #opnum to RPC_GET_PRINTER_DRIVER_DIRECTORY constant' do
|
32
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::PrintSystem::RPC_GET_PRINTER_DRIVER_DIRECTORY)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'reads its own binary representation and outputs the same packet' do
|
37
|
+
packet = described_class.new(
|
38
|
+
p_driver_directory: [0, 1, 2],
|
39
|
+
pcb_needed: 0,
|
40
|
+
error_status: 0
|
41
|
+
)
|
42
|
+
binary = packet.to_binary_s
|
43
|
+
expect(described_class.read(binary)).to eq(packet)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -3,8 +3,12 @@ RSpec.describe RubySMB::Field::NtStatus do
|
|
3
3
|
|
4
4
|
it { is_expected.to respond_to :to_nt_status }
|
5
5
|
|
6
|
-
it '
|
7
|
-
expect(nt_status).to be_a BinData::Uint32le
|
6
|
+
it 'uses an internal Unsigned 32-bit little endian integer' do
|
7
|
+
expect(nt_status.val).to be_a BinData::Uint32le
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns an integer value' do
|
11
|
+
expect(nt_status.value).to be_a Integer
|
8
12
|
end
|
9
13
|
|
10
14
|
describe '#to_nt_status' do
|
@@ -13,6 +13,10 @@ RSpec.describe RubySMB::Gss::Provider::NTLM::Authenticator do
|
|
13
13
|
Net::NTLM::Message::Type2.new.response(user: username, password: '', domain: domain)
|
14
14
|
end
|
15
15
|
|
16
|
+
before(:each) do
|
17
|
+
allow(authenticator).to receive(:logger).and_return(Logger.new(IO::NULL))
|
18
|
+
end
|
19
|
+
|
16
20
|
describe '#initialize' do
|
17
21
|
it 'defaults to a null session key' do
|
18
22
|
expect(authenticator.session_key).to be_nil
|
@@ -5,33 +5,24 @@ RSpec.describe RubySMB::Server::ServerClient do
|
|
5
5
|
subject(:server_client) { described_class.new(server, dispatcher) }
|
6
6
|
|
7
7
|
it { is_expected.to respond_to :dialect }
|
8
|
-
it { is_expected.to respond_to :
|
9
|
-
it { is_expected.to respond_to :state }
|
10
|
-
it { is_expected.to respond_to :session_key }
|
8
|
+
it { is_expected.to respond_to :session_table }
|
11
9
|
|
12
10
|
describe '#disconnect!' do
|
13
11
|
it 'closes the socket' do
|
12
|
+
expect(dispatcher.tcp_socket).to receive(:closed?).with(no_args).and_return(false)
|
14
13
|
expect(dispatcher.tcp_socket).to receive(:close).with(no_args).and_return(nil)
|
15
14
|
server_client.disconnect!
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
18
|
describe '#initialize' do
|
20
|
-
it 'starts in the negotiate state' do
|
21
|
-
expect(server_client.state).to eq :negotiate
|
22
|
-
end
|
23
|
-
|
24
19
|
it 'starts without a dialect' do
|
25
20
|
expect(server_client.dialect).to be_nil
|
26
21
|
expect(server_client.metadialect).to be_nil
|
27
22
|
end
|
28
23
|
|
29
|
-
it 'starts without
|
30
|
-
expect(server_client.
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'starts without a session_key' do
|
34
|
-
expect(server_client.session_key).to be_nil
|
24
|
+
it 'starts without any sessions' do
|
25
|
+
expect(server_client.session_table).to be_empty
|
35
26
|
end
|
36
27
|
|
37
28
|
it 'creates a new authenticator instance' do
|
@@ -66,33 +57,30 @@ RSpec.describe RubySMB::Server::ServerClient do
|
|
66
57
|
before(:each) do
|
67
58
|
expect(server_client).to receive(:recv_packet).and_return(packet)
|
68
59
|
# this hook should ensure that the dispatcher loop returns after processing a single request
|
69
|
-
expect(dispatcher.tcp_socket).to receive(:closed?).and_return(true)
|
60
|
+
expect(dispatcher.tcp_socket).to receive(:closed?).with(no_args).and_return(true)
|
61
|
+
expect(server_client).to receive(:disconnect!).with(no_args).and_return(nil)
|
70
62
|
end
|
71
63
|
|
72
|
-
it 'calls #handle_negotiate when the
|
64
|
+
it 'calls #handle_negotiate when the dialect is nil' do
|
73
65
|
expect(server_client).to receive(:handle_negotiate).with(packet).and_return(nil)
|
74
|
-
server_client.instance_eval { @
|
75
|
-
server_client.run
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'calls #handle_session_setup when the state is session_setup' do
|
79
|
-
expect(server_client).to receive(:handle_session_setup).with(packet).and_return(nil)
|
80
|
-
server_client.instance_eval { @state = :session_setup }
|
66
|
+
server_client.instance_eval { @dialect = nil }
|
81
67
|
server_client.run
|
82
68
|
end
|
83
69
|
|
84
|
-
it 'calls #
|
85
|
-
expect(server_client).to receive(:
|
86
|
-
server_client.instance_eval { @
|
70
|
+
it 'calls #handle_smb when the dialect is not nil' do
|
71
|
+
expect(server_client).to receive(:handle_smb).with(packet).and_return(nil)
|
72
|
+
server_client.instance_eval { @dialect = true }
|
87
73
|
server_client.run
|
88
74
|
end
|
89
75
|
end
|
90
76
|
|
91
77
|
describe '#send_packet' do
|
92
|
-
let(:
|
78
|
+
let(:session_id) { rand(0xffffffff) }
|
79
|
+
let(:packet) { RubySMB::SMB2::Packet::SessionSetupResponse.new(smb2_header: { session_id: session_id }) }
|
93
80
|
|
94
81
|
before(:each) do
|
95
82
|
expect(dispatcher).to receive(:send_packet).with(packet).and_return(nil)
|
83
|
+
server_client.session_table[session_id] = RubySMB::Server::Session.new(session_id)
|
96
84
|
end
|
97
85
|
|
98
86
|
it 'sends a packet to the dispatcher' do
|
@@ -105,40 +93,35 @@ RSpec.describe RubySMB::Server::ServerClient do
|
|
105
93
|
server_client.instance_eval { @dialect = dialect }
|
106
94
|
end
|
107
95
|
|
108
|
-
context 'and the
|
96
|
+
context 'and the identity is anonymous' do
|
109
97
|
before(:each) do
|
110
|
-
server_client.
|
98
|
+
server_client.session_table[session_id].user_id = RubySMB::Gss::Provider::IDENTITY_ANONYMOUS
|
111
99
|
end
|
112
100
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
it 'does not sign packets' do
|
119
|
-
expect(server_client).to_not receive(:smb2_sign)
|
120
|
-
expect(server_client).to_not receive(:smb3_sign)
|
121
|
-
server_client.send_packet(packet)
|
122
|
-
end
|
101
|
+
it 'does not sign packets' do
|
102
|
+
expect(RubySMB::Signing).to_not receive(:smb2_sign)
|
103
|
+
expect(RubySMB::Signing).to_not receive(:smb3_sign)
|
104
|
+
server_client.send_packet(packet)
|
123
105
|
end
|
106
|
+
end
|
124
107
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
108
|
+
context 'and the identity is not anonymous' do
|
109
|
+
before(:each) do
|
110
|
+
server_client.session_table[session_id].user_id = 'WORKGROUP\RubySMB'
|
111
|
+
server_client.session_table[session_id].key = Random.new.bytes(16)
|
112
|
+
end
|
129
113
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
140
|
-
server_client.send_packet(packet)
|
114
|
+
it 'does sign packets' do
|
115
|
+
dialect_family = RubySMB::Dialect[dialect].family
|
116
|
+
session = server_client.session_table[session_id]
|
117
|
+
if dialect_family == RubySMB::Dialect::FAMILY_SMB2
|
118
|
+
expect(RubySMB::Signing).to receive(:smb2_sign).with(packet, session.key).and_return(packet)
|
119
|
+
expect(RubySMB::Signing).to_not receive(:smb3_sign)
|
120
|
+
elsif dialect_family == RubySMB::Dialect::FAMILY_SMB3
|
121
|
+
expect(RubySMB::Signing).to receive(:smb3_sign).with(packet, session.key, dialect, any_args).and_return(packet)
|
122
|
+
expect(RubySMB::Signing).to_not receive(:smb2_sign)
|
141
123
|
end
|
124
|
+
server_client.send_packet(packet)
|
142
125
|
end
|
143
126
|
end
|
144
127
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
RSpec.describe RubySMB::Server::Session do
|
2
|
+
let(:user_id) { 'WORKGROUP\RubySMB' }
|
3
|
+
subject(:session) { described_class.new(rand(0xffffffff), user_id: user_id) }
|
4
|
+
|
5
|
+
it { is_expected.to respond_to :id }
|
6
|
+
it { is_expected.to respond_to :key }
|
7
|
+
it { is_expected.to respond_to :signing_required }
|
8
|
+
it { is_expected.to respond_to :tree_connect_table }
|
9
|
+
it { is_expected.to respond_to :creation_time }
|
10
|
+
|
11
|
+
describe '#initialize' do
|
12
|
+
it 'starts with no signing required' do
|
13
|
+
expect(session.signing_required).to be_falsey
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'starts with no tree connections' do
|
17
|
+
expect(session.tree_connect_table).to be_empty
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'starts in the in progress state' do
|
21
|
+
expect(session.state).to be :in_progress
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#is_anonymous' do
|
26
|
+
it 'is false' do
|
27
|
+
expect(session.is_anonymous).to be_falsey
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when the identity is set to anonymous' do
|
31
|
+
let(:user_id) { RubySMB::Gss::Provider::IDENTITY_ANONYMOUS }
|
32
|
+
|
33
|
+
it 'is true' do
|
34
|
+
expect(session.is_anonymous).to be_truthy
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
RSpec.describe RubySMB::Server::Share::Provider::Disk do
|
2
|
+
let(:name) { 'share' }
|
3
|
+
let(:path) { Dir.getwd }
|
4
|
+
subject(:share_provider) { described_class.new(name, path) }
|
5
|
+
|
6
|
+
it { is_expected.to respond_to :name }
|
7
|
+
it { is_expected.to respond_to :path }
|
8
|
+
it { is_expected.to respond_to :type }
|
9
|
+
|
10
|
+
describe '#TYPE' do
|
11
|
+
it 'is TYPE_DISK' do
|
12
|
+
expect(described_class::TYPE).to eq RubySMB::Server::Share::TYPE_DISK
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#initialize' do
|
17
|
+
it 'sets the name' do
|
18
|
+
expect(share_provider.name).to eq name
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'sets the path' do
|
22
|
+
expect(share_provider.path).to be_a Pathname
|
23
|
+
expect(share_provider.path).to eq Pathname.new(path)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'sets the type correctly' do
|
27
|
+
expect(share_provider.type).to eq RubySMB::Server::Share::TYPE_DISK
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'raises an ArgumentError for an invalid path' do
|
31
|
+
# __FILE__ is not a directory so it's invalid
|
32
|
+
expect { described_class.new(name, __FILE__) }.to raise_error(ArgumentError)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
RSpec.describe RubySMB::Server::Share::Provider::Disk::Processor do
|
38
|
+
let(:session) { RubySMB::Server::Session.new(rand(0xffffffff)) }
|
39
|
+
let(:share_provider) { RubySMB::Server::Share::Provider::Disk.new('share', Dir.getwd) }
|
40
|
+
subject(:share_processor) { described_class.new(share_provider, nil, session) }
|
41
|
+
|
42
|
+
it { is_expected.to respond_to :provider }
|
43
|
+
|
44
|
+
describe '#maximal_access' do
|
45
|
+
# no path specified should be the root of the share
|
46
|
+
context 'with no path specified' do
|
47
|
+
let(:maximal_access) { share_processor.maximal_access }
|
48
|
+
it 'is a FileAccessMask' do
|
49
|
+
expect(maximal_access).to be_a RubySMB::SMB2::BitField::FileAccessMask
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'marks the data as readable' do
|
53
|
+
expect(maximal_access.read_data).to eq 1
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'marks the data attributes as readable' do
|
57
|
+
expect(maximal_access.read_attr).to eq 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|