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,23 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module PrintSystem
|
4
|
+
|
5
|
+
# [3.1.4.4.2 RpcEnumPrinterDrivers (Opnum 10)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/857d00ac-3682-4a0d-86ca-3d3c372e5e4a)
|
6
|
+
class RpcEnumPrinterDriversResponse < BinData::Record
|
7
|
+
attr_reader :opnum
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
def initialize_instance
|
12
|
+
super
|
13
|
+
@opnum = RPC_ENUM_PRINTER_DRIVERS
|
14
|
+
end
|
15
|
+
|
16
|
+
rprn_byte_array_ptr :p_drivers
|
17
|
+
ndr_uint32 :pcb_needed
|
18
|
+
ndr_uint32 :pc_returned
|
19
|
+
ndr_uint32 :error_status
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module PrintSystem
|
4
|
+
|
5
|
+
# [3.1.4.4.4 RpcGetPrinterDriverDirectory (Opnum 12)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/9df11cf4-4098-4852-ad72-d1f75a82bffe)
|
6
|
+
class RpcGetPrinterDriverDirectoryRequest < BinData::Record
|
7
|
+
attr_reader :opnum
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
def initialize_instance
|
12
|
+
super
|
13
|
+
@opnum = RPC_GET_PRINTER_DRIVER_DIRECTORY
|
14
|
+
end
|
15
|
+
|
16
|
+
ndr_wide_stringz_ptr :p_name
|
17
|
+
ndr_wide_stringz_ptr :p_environment
|
18
|
+
ndr_uint32 :level
|
19
|
+
rprn_byte_array_ptr :p_driver_directory
|
20
|
+
ndr_uint32 :cb_buf
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module PrintSystem
|
4
|
+
|
5
|
+
# [3.1.4.4.4 RpcGetPrinterDriverDirectory (Opnum 12)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/9df11cf4-4098-4852-ad72-d1f75a82bffe)
|
6
|
+
class RpcGetPrinterDriverDirectoryResponse < BinData::Record
|
7
|
+
attr_reader :opnum
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
def initialize_instance
|
12
|
+
super
|
13
|
+
@opnum = RPC_GET_PRINTER_DRIVER_DIRECTORY
|
14
|
+
end
|
15
|
+
|
16
|
+
rprn_byte_array_ptr :p_driver_directory
|
17
|
+
ndr_uint32 :pcb_needed
|
18
|
+
ndr_uint32 :error_status
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module PrintSystem
|
4
|
+
|
5
|
+
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/848b8334-134a-4d02-aea4-03b673d6c515
|
6
|
+
UUID = '12345678-1234-abcd-ef00-0123456789ab'.freeze
|
7
|
+
VER_MAJOR = 1
|
8
|
+
VER_MINOR = 0
|
9
|
+
|
10
|
+
# Operation numbers
|
11
|
+
RPC_ENUM_PRINTER_DRIVERS = 10
|
12
|
+
RPC_GET_PRINTER_DRIVER_DIRECTORY = 12
|
13
|
+
RPC_ADD_PRINTER_DRIVER_EX = 89
|
14
|
+
|
15
|
+
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/b96cc497-59e5-4510-ab04-5484993b259b
|
16
|
+
APD_STRICT_UPGRADE = 0x00000001
|
17
|
+
APD_STRICT_DOWNGRADE = 0x00000002
|
18
|
+
APD_COPY_ALL_FILES = 0x00000004
|
19
|
+
APD_COPY_NEW_FILES = 0x00000008
|
20
|
+
APD_COPY_FROM_DIRECTORY = 0x00000010
|
21
|
+
APD_DONT_COPY_FILES_TO_CLUSTER = 0x00001000
|
22
|
+
APD_COPY_TO_ALL_SPOOLERS = 0x00002000
|
23
|
+
APD_INSTALL_WARNED_DRIVER = 0x00008000
|
24
|
+
APD_RETURN_BLOCKING_STATUS_CODE = 0x00010000
|
25
|
+
|
26
|
+
# [2.2.1.5.2 DRIVER_INFO_2](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/39bbfc30-8768-4cd4-9930-434857e2c2a2)
|
27
|
+
class DriverInfo2 < RubySMB::Dcerpc::Ndr::NdrStruct
|
28
|
+
default_parameter byte_align: 4
|
29
|
+
endian :little
|
30
|
+
|
31
|
+
ndr_uint32 :c_version
|
32
|
+
ndr_wide_stringz_ptr :p_name
|
33
|
+
ndr_wide_stringz_ptr :p_environment
|
34
|
+
ndr_wide_stringz_ptr :p_driver_path
|
35
|
+
ndr_wide_stringz_ptr :p_data_file
|
36
|
+
ndr_wide_stringz_ptr :p_config_file
|
37
|
+
end
|
38
|
+
|
39
|
+
class PDriverInfo2 < DriverInfo2
|
40
|
+
extend RubySMB::Dcerpc::Ndr::PointerClassPlugin
|
41
|
+
end
|
42
|
+
|
43
|
+
# [2.2.1.2.3 DRIVER_CONTAINER](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/3a3f9cf7-8ec4-4921-b1f6-86cf8d139bc2)
|
44
|
+
class DriverContainer < RubySMB::Dcerpc::Ndr::NdrStruct
|
45
|
+
default_parameter byte_align: 4
|
46
|
+
endian :little
|
47
|
+
|
48
|
+
ndr_uint32 :level, check_value: -> { [2].include?(value) }
|
49
|
+
ndr_uint32 :tag
|
50
|
+
choice :driver_info, selection: :level, byte_align: 4 do
|
51
|
+
p_driver_info2 2
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# for RpcEnumPrinterDrivers and RpcGetPrinterDriverDirectory `BYTE*` fields
|
56
|
+
class RprnByteArrayPtr < RubySMB::Dcerpc::Ndr::NdrConfArray
|
57
|
+
default_parameters type: :ndr_uint8
|
58
|
+
extend RubySMB::Dcerpc::Ndr::PointerClassPlugin
|
59
|
+
end
|
60
|
+
|
61
|
+
require 'ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_request'
|
62
|
+
require 'ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_response'
|
63
|
+
require 'ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_request'
|
64
|
+
require 'ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_response'
|
65
|
+
require 'ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_request'
|
66
|
+
require 'ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_response'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/ruby_smb/dcerpc.rb
CHANGED
@@ -50,8 +50,8 @@ module RubySMB
|
|
50
50
|
require 'ruby_smb/dcerpc/rpc_auth3'
|
51
51
|
require 'ruby_smb/dcerpc/bind'
|
52
52
|
require 'ruby_smb/dcerpc/bind_ack'
|
53
|
-
|
54
|
-
|
53
|
+
require 'ruby_smb/dcerpc/print_system'
|
54
|
+
require 'ruby_smb/dcerpc/encrypting_file_system'
|
55
55
|
|
56
56
|
# Bind to the remote server interface endpoint.
|
57
57
|
#
|
@@ -4,7 +4,26 @@ module RubySMB
|
|
4
4
|
module Field
|
5
5
|
# Represents an NTStatus code as defined in
|
6
6
|
# [2.3.1 NTSTATUS values](https://msdn.microsoft.com/en-us/library/cc704588.aspx)
|
7
|
-
class NtStatus < BinData::
|
7
|
+
class NtStatus < BinData::Primitive
|
8
|
+
endian :little
|
9
|
+
uint32 :val
|
10
|
+
|
11
|
+
def get
|
12
|
+
val.to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
def set(value)
|
16
|
+
case value
|
17
|
+
when WindowsError::ErrorCode
|
18
|
+
set(value.value)
|
19
|
+
when Integer
|
20
|
+
self.val = value
|
21
|
+
else
|
22
|
+
self.val = value.to_i
|
23
|
+
end
|
24
|
+
val
|
25
|
+
end
|
26
|
+
|
8
27
|
# Returns a meaningful error code parsed from the numeric value
|
9
28
|
#
|
10
29
|
# @return [WindowsError::ErrorCode] the ErrorCode object for this code
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Fscc
|
3
|
+
module FileInformation
|
4
|
+
# The FileEaInformation Class as defined in
|
5
|
+
# [2.4.12 FileEaInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/db6cf109-ead8-441a-b29e-cb2032778b0f)
|
6
|
+
class FileEaInformation < BinData::Record
|
7
|
+
CLASS_LEVEL = FileInformation::FILE_EA_INFORMATION
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
uint32 :ea_size, label: 'Extended Attributes Size'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Fscc
|
3
|
+
module FileInformation
|
4
|
+
# The FileNetworkOpenInformation Class as defined in
|
5
|
+
# [2.4.29 FileNetworkOpenInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/26d261db-58d1-4513-a548-074448cbb146)
|
6
|
+
class FileNetworkOpenInformation < BinData::Record
|
7
|
+
CLASS_LEVEL = FileInformation::FILE_NETWORK_OPEN_INFORMATION
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
file_time :create_time, label: 'Create Time'
|
12
|
+
file_time :last_access, label: 'Last Accessed Time'
|
13
|
+
file_time :last_write, label: 'Last Write Time'
|
14
|
+
file_time :last_change, label: 'Last Modified Time'
|
15
|
+
int64 :allocation_size, label: 'Allocated Size'
|
16
|
+
int64 :end_of_file, label: 'End of File'
|
17
|
+
file_attributes :file_attributes, label: 'File Attributes'
|
18
|
+
uint32 :reserved, label: 'Reserved Space'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Fscc
|
3
|
+
module FileInformation
|
4
|
+
# The FileStreamInformation
|
5
|
+
# [2.4.43 FileStreamInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/f8762be6-3ab9-411e-a7d6-5cc68f70c78d)
|
6
|
+
class FileStreamInformation < BinData::Record
|
7
|
+
endian :little
|
8
|
+
uint32 :next_entry_offset, label: 'Next Entry Offset'
|
9
|
+
uint32 :stream_name_length, label: 'Stream Name Length', initial_value: -> { stream_name.do_num_bytes }
|
10
|
+
int64 :stream_size, label: 'Stream Size'
|
11
|
+
int64 :stream_allocation_size, label: 'Stream Allocation Size'
|
12
|
+
string16 :stream_name, label: 'Stream Name', read_length: -> { stream_name_length }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -17,6 +17,10 @@ module RubySMB
|
|
17
17
|
# contents of a directory.
|
18
18
|
FILE_BOTH_DIRECTORY_INFORMATION = 0x03
|
19
19
|
|
20
|
+
# Information class used to query for the size of the extended attributes
|
21
|
+
# (EA) for a file.
|
22
|
+
FILE_EA_INFORMATION = 0x07
|
23
|
+
|
20
24
|
# Information class used to rename a file.
|
21
25
|
FILE_RENAME_INFORMATION = 0x0A
|
22
26
|
|
@@ -27,6 +31,14 @@ module RubySMB
|
|
27
31
|
# Information class used to mark a file for deletion.
|
28
32
|
FILE_DISPOSITION_INFORMATION = 0x0D
|
29
33
|
|
34
|
+
# Information class used to enumerate the data streams of a file or a
|
35
|
+
# directory.
|
36
|
+
FILE_STREAM_INFORMATION = 0x16
|
37
|
+
|
38
|
+
# This information class is used to query for information that is commonly
|
39
|
+
# needed when a file is opened across a network.
|
40
|
+
FILE_NETWORK_OPEN_INFORMATION = 0x22
|
41
|
+
|
30
42
|
# Information class used in directory enumeration to return detailed
|
31
43
|
# information (with extended attributes size, short names and file ID)
|
32
44
|
# about the contents of a directory.
|
@@ -38,6 +50,13 @@ module RubySMB
|
|
38
50
|
FILE_ID_FULL_DIRECTORY_INFORMATION = 0x26
|
39
51
|
|
40
52
|
|
53
|
+
# This information class is used to query the normalized name of a file. A
|
54
|
+
# normalized name is an absolute pathname where each short name component
|
55
|
+
# has been replaced with the corresponding long name component, and each
|
56
|
+
# name component uses the exact letter casing stored on disk.
|
57
|
+
FILE_NORMALIZED_NAME_INFORMATION = 0x30
|
58
|
+
|
59
|
+
|
41
60
|
# These Information Classes can be used by SMB1 using the pass-through
|
42
61
|
# Information Levels when available on the server (CAP_INFOLEVEL_PASSTHRU
|
43
62
|
# capability flag in an SMB_COM_NEGOTIATE server response). The constant
|
@@ -46,6 +65,13 @@ module RubySMB
|
|
46
65
|
# [2.2.2.3.5 Pass-through Information Level Codes](https://msdn.microsoft.com/en-us/library/ff470158.aspx)
|
47
66
|
SMB_INFO_PASSTHROUGH = 0x03e8
|
48
67
|
|
68
|
+
# The FILE_NAME_INFORMATION type as defined in
|
69
|
+
# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/20406fb1-605f-4629-ba9a-c67ee25f23d2
|
70
|
+
class FileNameInformation < BinData::Record
|
71
|
+
endian :little
|
72
|
+
uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
|
73
|
+
string16 :file_name, label: 'File Name', read_length: -> { file_name_length }
|
74
|
+
end
|
49
75
|
|
50
76
|
require 'ruby_smb/fscc/file_information/file_directory_information'
|
51
77
|
require 'ruby_smb/fscc/file_information/file_full_directory_information'
|
@@ -55,6 +81,9 @@ module RubySMB
|
|
55
81
|
require 'ruby_smb/fscc/file_information/file_id_both_directory_information'
|
56
82
|
require 'ruby_smb/fscc/file_information/file_names_information'
|
57
83
|
require 'ruby_smb/fscc/file_information/file_rename_information'
|
84
|
+
require 'ruby_smb/fscc/file_information/file_network_open_information'
|
85
|
+
require 'ruby_smb/fscc/file_information/file_ea_information'
|
86
|
+
require 'ruby_smb/fscc/file_information/file_stream_information'
|
58
87
|
end
|
59
88
|
end
|
60
89
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Fscc
|
3
|
+
module FileSystemInformation
|
4
|
+
# The FileFsAttributeInformation
|
5
|
+
# [2.5.1 FileFsAttributeInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ebc7e6e5-4650-4e54-b17c-cf60f6fbeeaa)
|
6
|
+
class FileFsAttributeInformation < BinData::Record
|
7
|
+
CLASS_LEVEL = FileSystemInformation::FILE_FS_ATTRIBUTE_INFORMATION
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
struct :file_system_attributes, label: 'File System Attributes' do
|
11
|
+
bit1 :file_supports_reparse_points, label: 'FS Supports Reparse Points'
|
12
|
+
bit1 :file_supports_sparse_files, label: 'FS Supports Sparse Files'
|
13
|
+
bit1 :file_volume_quotas, label: 'FS Supports Quotas'
|
14
|
+
bit1 :file_file_compression, label: 'FS Supports File Compression'
|
15
|
+
bit1 :file_persistent_acls, label: 'FS Supports Persistent ACLs'
|
16
|
+
bit1 :file_unicode_on_disk, label: 'FS Supports Unicode Names'
|
17
|
+
bit1 :file_case_preserved_names, label: 'FS Preserves Name Casing'
|
18
|
+
bit1 :file_case_sensitive_search, label: 'FS Supports Case-Sensitive Searching'
|
19
|
+
# byte boundary
|
20
|
+
bit1 :file_volume_is_compressed, label: 'FS Is Compressed'
|
21
|
+
bit6 :reserved0
|
22
|
+
bit1 :file_supports_remote_storage, label: 'FS Supports Remote Storage'
|
23
|
+
# byte boundary
|
24
|
+
bit1 :file_supports_extended_attributes, label: 'FS Supports Persistent Extended Attributes'
|
25
|
+
bit1 :file_supports_hard_links, label: 'FS Supports Hard Links'
|
26
|
+
bit1 :file_supports_transactions, label: 'FS Supports Transactions'
|
27
|
+
bit1 :file_sequential_write_once, label: 'FS Is Write Once'
|
28
|
+
bit1 :file_read_only_volume, label: 'FS Is Read-Only'
|
29
|
+
bit1 :file_named_streams, label: 'FS Supports Named Streams'
|
30
|
+
bit1 :file_supports_encryption, label: 'FS Supports Encryption'
|
31
|
+
bit1 :file_supports_object_ids, label: 'FS Supports Object IDs'
|
32
|
+
# byte boundary
|
33
|
+
bit3 :reserved1
|
34
|
+
bit1 :file_supports_sparse_vdl, label: 'FS Supports Sparse VDL'
|
35
|
+
bit1 :file_supports_block_refcounting, label: 'FS Supports Block Reference Counting'
|
36
|
+
bit1 :file_supports_integrity_streams, label: 'FS Supports Integrity Streams'
|
37
|
+
bit1 :file_supports_usn_journal, label: 'FS Supports USN Change Journal'
|
38
|
+
bit1 :file_supports_open_by_file_id, label: 'FS Supports Open By File ID'
|
39
|
+
end
|
40
|
+
int32 :maximum_component_name_length, label: 'Maximum Component Name Length'
|
41
|
+
uint32 :file_system_name_length, label: 'File System Name Length', initial_value: -> { file_system_name.do_num_bytes }
|
42
|
+
string16 :file_system_name, label: 'File System Name', read_length: -> { file_system_name_length }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Fscc
|
3
|
+
module FileSystemInformation
|
4
|
+
# The FileFsVolumeInformation
|
5
|
+
# [2.5.9 FileFsVolumeInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/bf691378-c34e-4a13-976e-404ea1a87738)
|
6
|
+
class FileFsVolumeInformation < BinData::Record
|
7
|
+
CLASS_LEVEL = FileSystemInformation::FILE_FS_VOLUME_INFORMATION
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
file_time :volume_creation_time, label: 'Volume Creation Time'
|
11
|
+
uint32 :volume_serial_number, label: 'Volume Serial Number'
|
12
|
+
uint32 :volume_label_length, label: 'Volume Label Length', initial_value: -> { volume_label.do_num_bytes }
|
13
|
+
uint8 :supports_objects, label: 'Supports Objects'
|
14
|
+
uint8 :reserved, label: 'Reserved'
|
15
|
+
string16 :volume_label, label: 'Volume Label', read_length: -> { volume_label_length }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Fscc
|
3
|
+
# Namespace and constant values for File System Information Classes, as defined in
|
4
|
+
# [2.5 File System Information Classes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ee12042a-9352-46e3-9f67-c094b75fe6c3)
|
5
|
+
module FileSystemInformation
|
6
|
+
FILE_FS_VOLUME_INFORMATION = 1
|
7
|
+
FILE_FS_LABEL_INFORMATION = 2
|
8
|
+
FILE_FS_SIZE_INFORMATION = 3
|
9
|
+
FILE_FS_DEVICE_INFORMATION = 4
|
10
|
+
FILE_FS_ATTRIBUTE_INFORMATION = 5
|
11
|
+
FILE_FS_CONTROL_INFORMATION = 6
|
12
|
+
FILE_FS_FULL_SIZE_INFORMATION = 7
|
13
|
+
FILE_FS_OBJECT_ID_INFORMATION = 8
|
14
|
+
FILE_FS_DRIVER_PATH_INFORMATION = 9
|
15
|
+
FILE_FS_VOLUME_FLAGS_INFORMATION = 10
|
16
|
+
FILE_FS_SECTOR_SIZE_INFORMATION = 11
|
17
|
+
|
18
|
+
require 'ruby_smb/fscc/file_system_information/file_fs_attribute_information'
|
19
|
+
require 'ruby_smb/fscc/file_system_information/file_fs_volume_information'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/ruby_smb/fscc.rb
CHANGED
@@ -43,6 +43,8 @@ module RubySMB
|
|
43
43
|
begin
|
44
44
|
super(val)
|
45
45
|
rescue IOError => e
|
46
|
+
# $stderr.puts "#{e.class}: #{e.message}"
|
47
|
+
# $stderr.puts e.backtrace.join("\n")
|
46
48
|
case self.to_s
|
47
49
|
when /EmptyPacket|ErrorPacket/
|
48
50
|
raise RubySMB::Error::InvalidPacket, 'Not a valid SMB packet'
|
@@ -68,6 +70,10 @@ module RubySMB
|
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
73
|
+
def self.from_hex(val)
|
74
|
+
self.read(val.scan(/../).map { |x| x.hex.chr }.join)
|
75
|
+
end
|
76
|
+
|
71
77
|
def status_code
|
72
78
|
value = -1
|
73
79
|
smb_version = packet_smb_version
|
@@ -50,7 +50,8 @@ module RubySMB
|
|
50
50
|
|
51
51
|
begin
|
52
52
|
gss_api = OpenSSL::ASN1.decode(request_buffer)
|
53
|
-
rescue OpenSSL::ASN1::ASN1Error
|
53
|
+
rescue OpenSSL::ASN1::ASN1Error => e
|
54
|
+
logger.error("Failed to parse the ASN1-encoded authentication request (#{e.message})")
|
54
55
|
return
|
55
56
|
end
|
56
57
|
|
@@ -114,11 +115,16 @@ module RubySMB
|
|
114
115
|
return WindowsError::NTStatus::STATUS_LOGON_FAILURE
|
115
116
|
end
|
116
117
|
|
118
|
+
dbg_string = "#{type3_msg.domain.encode(''.encoding)}\\#{type3_msg.user.encode(''.encoding)}"
|
119
|
+
logger.debug("NTLM authentication request received for #{dbg_string}")
|
117
120
|
account = @provider.get_account(
|
118
121
|
type3_msg.user,
|
119
122
|
domain: type3_msg.domain
|
120
123
|
)
|
121
|
-
|
124
|
+
if account.nil?
|
125
|
+
logger.info("NTLM authentication request failed for #{dbg_string} (no account)")
|
126
|
+
return WindowsError::NTStatus::STATUS_LOGON_FAILURE
|
127
|
+
end
|
122
128
|
|
123
129
|
matches = false
|
124
130
|
case type3_msg.ntlm_version
|
@@ -159,8 +165,12 @@ module RubySMB
|
|
159
165
|
raise NotImplementedError, "authentication via ntlm version #{type3_msg.ntlm_version} is not supported"
|
160
166
|
end
|
161
167
|
|
162
|
-
|
168
|
+
unless matches
|
169
|
+
logger.info("NTLM authentication request failed for #{dbg_string} (bad password)")
|
170
|
+
return WindowsError::NTStatus::STATUS_LOGON_FAILURE
|
171
|
+
end
|
163
172
|
|
173
|
+
logger.info("NTLM authentication request succeeded for #{dbg_string}")
|
164
174
|
WindowsError::NTStatus::STATUS_SUCCESS
|
165
175
|
end
|
166
176
|
|
@@ -73,7 +73,6 @@ module RubySMB
|
|
73
73
|
response.data_block.server_guid = @server.guid
|
74
74
|
response.data_block.security_blob = process_gss.buffer
|
75
75
|
|
76
|
-
@state = :session_setup
|
77
76
|
@dialect = dialect
|
78
77
|
response
|
79
78
|
end
|
@@ -146,7 +145,6 @@ module RubySMB
|
|
146
145
|
update_preauth_hash(response)
|
147
146
|
end
|
148
147
|
|
149
|
-
@state = :session_setup
|
150
148
|
@dialect = dialect
|
151
149
|
response
|
152
150
|
end
|
@@ -2,39 +2,26 @@ module RubySMB
|
|
2
2
|
class Server
|
3
3
|
class ServerClient
|
4
4
|
module SessionSetup
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def handle_session_setup(raw_request)
|
11
|
-
response = nil
|
12
|
-
|
13
|
-
case metadialect.order
|
14
|
-
when Dialect::ORDER_SMB1
|
15
|
-
request = SMB1::Packet::SessionSetupRequest.read(raw_request)
|
16
|
-
response = do_session_setup_smb1(request)
|
17
|
-
when Dialect::ORDER_SMB2
|
18
|
-
request = SMB2::Packet::SessionSetupRequest.read(raw_request)
|
19
|
-
response = do_session_setup_smb2(request)
|
20
|
-
end
|
21
|
-
|
22
|
-
if response.nil?
|
23
|
-
disconnect!
|
5
|
+
def do_session_setup_smb1(request, session)
|
6
|
+
session_id = request.smb_header.uid
|
7
|
+
if session_id == 0
|
8
|
+
session_id = rand(1..0x10000)
|
9
|
+
session = @session_table[session_id] = Server::Session.new(session_id)
|
24
10
|
else
|
25
|
-
|
11
|
+
session = @session_table[session_id]
|
12
|
+
if session.nil?
|
13
|
+
response = SMB1::Packet::EmptyPacket.new
|
14
|
+
response.smb_header.nt_status = SMBError::STATUS_SMB_BAD_UID
|
15
|
+
return response
|
16
|
+
end
|
26
17
|
end
|
27
18
|
|
28
|
-
nil
|
29
|
-
end
|
30
|
-
|
31
|
-
def do_session_setup_smb1(request)
|
32
19
|
gss_result = process_gss(request.data_block.security_blob)
|
33
20
|
return if gss_result.nil?
|
34
21
|
|
35
22
|
response = SMB1::Packet::SessionSetupResponse.new
|
36
23
|
response.smb_header.pid_low = request.smb_header.pid_low
|
37
|
-
response.smb_header.uid =
|
24
|
+
response.smb_header.uid = session_id
|
38
25
|
response.smb_header.mid = request.smb_header.mid
|
39
26
|
response.smb_header.nt_status = gss_result.nt_status.value
|
40
27
|
response.smb_header.flags.reply = true
|
@@ -46,14 +33,28 @@ module RubySMB
|
|
46
33
|
end
|
47
34
|
|
48
35
|
if gss_result.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
|
49
|
-
|
50
|
-
|
36
|
+
session.state = :valid
|
37
|
+
session.user_id = gss_result.identity
|
38
|
+
session.key = @gss_authenticator.session_key
|
51
39
|
end
|
52
40
|
|
53
41
|
response
|
54
42
|
end
|
55
43
|
|
56
|
-
def do_session_setup_smb2(request)
|
44
|
+
def do_session_setup_smb2(request, session)
|
45
|
+
session_id = request.smb2_header.session_id
|
46
|
+
if session_id == 0
|
47
|
+
session_id = rand(1..0xfffffffe)
|
48
|
+
session = @session_table[session_id] = Session.new(session_id)
|
49
|
+
else
|
50
|
+
session = @session_table[session_id]
|
51
|
+
if session.nil?
|
52
|
+
response = SMB2::Packet::ErrorPacket.new
|
53
|
+
response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_USER_SESSION_DELETED
|
54
|
+
return response
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
57
58
|
gss_result = process_gss(request.buffer)
|
58
59
|
return if gss_result.nil?
|
59
60
|
|
@@ -61,20 +62,30 @@ module RubySMB
|
|
61
62
|
response.smb2_header.nt_status = gss_result.nt_status.value
|
62
63
|
response.smb2_header.credits = 1
|
63
64
|
response.smb2_header.message_id = request.smb2_header.message_id
|
64
|
-
response.smb2_header.session_id =
|
65
|
+
response.smb2_header.session_id = session_id
|
65
66
|
response.buffer = gss_result.buffer
|
66
67
|
|
67
68
|
update_preauth_hash(request) if @dialect == '0x0311'
|
68
69
|
if gss_result.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
response.smb2_header.credits = 32
|
71
|
+
session.state = :valid
|
72
|
+
session.user_id = gss_result.identity
|
73
|
+
session.key = @gss_authenticator.session_key
|
74
|
+
session.signing_required = request.security_mode.signing_required == 1
|
72
75
|
elsif gss_result.nt_status == WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED && @dialect == '0x0311'
|
73
76
|
update_preauth_hash(response)
|
74
77
|
end
|
75
78
|
|
76
79
|
response
|
77
80
|
end
|
81
|
+
|
82
|
+
def do_logoff_smb2(request, session)
|
83
|
+
session = @session_table.delete(session.id)
|
84
|
+
session.logoff!
|
85
|
+
|
86
|
+
response = SMB2::Packet::LogoffResponse.new
|
87
|
+
response
|
88
|
+
end
|
78
89
|
end
|
79
90
|
end
|
80
91
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RubySMB
|
2
|
+
class Server
|
3
|
+
class ServerClient
|
4
|
+
module ShareIO
|
5
|
+
def proxy_share_io_smb2(request, session)
|
6
|
+
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/9a639360-87be-4d49-a1dd-4c6be0c020bd
|
7
|
+
share_processor = session.tree_connect_table[request.smb2_header.tree_id]
|
8
|
+
if share_processor.nil?
|
9
|
+
response = SMB2::Packet::ErrorPacket.new
|
10
|
+
response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NETWORK_NAME_DELETED
|
11
|
+
return response
|
12
|
+
end
|
13
|
+
|
14
|
+
logger.debug("Received #{SMB2::Commands.name(request.smb2_header.command)} request for share: #{share_processor.provider.name}")
|
15
|
+
share_processor.send(__callee__, request)
|
16
|
+
end
|
17
|
+
|
18
|
+
alias :do_close_smb2 :proxy_share_io_smb2
|
19
|
+
alias :do_create_smb2 :proxy_share_io_smb2
|
20
|
+
alias :do_ioctl_smb2 :proxy_share_io_smb2
|
21
|
+
alias :do_query_directory_smb2 :proxy_share_io_smb2
|
22
|
+
alias :do_query_info_smb2 :proxy_share_io_smb2
|
23
|
+
alias :do_read_smb2 :proxy_share_io_smb2
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|