ruby_smb 2.0.13 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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 +11 -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/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 +3 -2
- 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
|