ruby_smb 3.0.5 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -3
  3. data/.github/workflows/verify.yml +1 -1
  4. data/.simplecov +1 -1
  5. data/CONTRIBUTING.md +28 -3
  6. data/README.md +8 -0
  7. data/examples/pwsh_service.rb +112 -0
  8. data/lib/ruby_smb/client/encryption.rb +16 -4
  9. data/lib/ruby_smb/client/negotiation.rb +10 -8
  10. data/lib/ruby_smb/dcerpc/request.rb +2 -0
  11. data/lib/ruby_smb/dcerpc/svcctl/create_service_w_request.rb +35 -0
  12. data/lib/ruby_smb/dcerpc/svcctl/create_service_w_response.rb +24 -0
  13. data/lib/ruby_smb/dcerpc/svcctl/delete_service_request.rb +21 -0
  14. data/lib/ruby_smb/dcerpc/svcctl/delete_service_response.rb +21 -0
  15. data/lib/ruby_smb/dcerpc/svcctl.rb +66 -5
  16. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +1 -1
  17. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +1 -1
  18. data/lib/ruby_smb/dcerpc/winreg.rb +1 -1
  19. data/lib/ruby_smb/fscc/file_information.rb +4 -0
  20. data/lib/ruby_smb/gss/provider/ntlm.rb +4 -0
  21. data/lib/ruby_smb/server/server_client/encryption.rb +66 -0
  22. data/lib/ruby_smb/server/server_client/negotiation.rb +14 -3
  23. data/lib/ruby_smb/server/server_client/session_setup.rb +18 -3
  24. data/lib/ruby_smb/server/server_client/share_io.rb +17 -0
  25. data/lib/ruby_smb/server/server_client/tree_connect.rb +40 -3
  26. data/lib/ruby_smb/server/server_client.rb +147 -37
  27. data/lib/ruby_smb/server/share/provider/disk/file_system.rb +28 -0
  28. data/lib/ruby_smb/server/share/provider/disk/processor/close.rb +42 -0
  29. data/lib/ruby_smb/server/share/provider/disk/processor/create.rb +143 -0
  30. data/lib/ruby_smb/server/share/provider/disk/processor/query.rb +359 -0
  31. data/lib/ruby_smb/server/share/provider/disk/processor/read.rb +69 -0
  32. data/lib/ruby_smb/server/share/provider/disk/processor.rb +159 -0
  33. data/lib/ruby_smb/server/share/provider/disk.rb +4 -416
  34. data/lib/ruby_smb/server/share/provider/pipe.rb +2 -2
  35. data/lib/ruby_smb/server/share/provider/processor.rb +16 -0
  36. data/lib/ruby_smb/signing.rb +18 -4
  37. data/lib/ruby_smb/smb1/bit_field/directory_access_mask.rb +1 -1
  38. data/lib/ruby_smb/smb1/bit_field/file_access_mask.rb +1 -1
  39. data/lib/ruby_smb/smb1/commands.rb +1 -0
  40. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +11 -1
  41. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +1 -1
  42. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +5 -4
  43. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +12 -4
  44. data/lib/ruby_smb/smb1/packet/trans2/data_block.rb +9 -1
  45. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +52 -51
  46. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +37 -37
  47. data/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_both_directory_info.rb +48 -0
  48. data/lib/ruby_smb/smb1/packet/trans2/find_information_level.rb +28 -15
  49. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +51 -51
  50. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +36 -36
  51. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +40 -39
  52. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +40 -40
  53. data/lib/ruby_smb/smb1/packet/trans2/query_file_information_request.rb +60 -0
  54. data/lib/ruby_smb/smb1/packet/trans2/query_file_information_response.rb +59 -0
  55. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_attribute_info.rb +31 -0
  56. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level.rb +40 -0
  57. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request.rb +46 -0
  58. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_response.rb +59 -0
  59. data/lib/ruby_smb/smb1/packet/trans2/query_information_level/query_file_basic_info.rb +23 -0
  60. data/lib/ruby_smb/smb1/packet/trans2/query_information_level/query_file_standard_info.rb +22 -0
  61. data/lib/ruby_smb/smb1/packet/trans2/query_information_level.rb +62 -0
  62. data/lib/ruby_smb/smb1/packet/trans2/query_path_information_request.rb +65 -0
  63. data/lib/ruby_smb/smb1/packet/trans2/query_path_information_response.rb +59 -0
  64. data/lib/ruby_smb/smb1/packet/trans2/request.rb +24 -8
  65. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +4 -4
  66. data/lib/ruby_smb/smb1/packet/trans2/response.rb +29 -20
  67. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +42 -42
  68. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +23 -23
  69. data/lib/ruby_smb/smb1/packet/trans2/subcommands.rb +23 -5
  70. data/lib/ruby_smb/smb1/packet/trans2.rb +4 -0
  71. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +4 -1
  72. data/lib/ruby_smb/smb2/bit_field/directory_access_mask.rb +1 -1
  73. data/lib/ruby_smb/smb2/bit_field/file_access_mask.rb +1 -1
  74. data/lib/ruby_smb/smb2/negotiate_context.rb +10 -1
  75. data/lib/ruby_smb/smb2/packet/transform_header.rb +7 -7
  76. data/lib/ruby_smb/smb2.rb +1 -0
  77. data/lib/ruby_smb/version.rb +1 -1
  78. data/ruby_smb.gemspec +1 -1
  79. data/spec/lib/ruby_smb/client_spec.rb +31 -8
  80. data/spec/lib/ruby_smb/dcerpc/svcctl/create_service_w_request_spec.rb +143 -0
  81. data/spec/lib/ruby_smb/dcerpc/svcctl/create_service_w_response_spec.rb +45 -0
  82. data/spec/lib/ruby_smb/dcerpc/svcctl/delete_service_request_spec.rb +29 -0
  83. data/spec/lib/ruby_smb/dcerpc/svcctl/delete_service_response_spec.rb +29 -0
  84. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +8 -8
  85. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +1 -1
  86. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +1 -1
  87. data/spec/lib/ruby_smb/smb1/bit_field/directory_access_mask_spec.rb +4 -4
  88. data/spec/lib/ruby_smb/smb1/bit_field/file_access_mask_spec.rb +4 -4
  89. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_request_spec.rb +2 -2
  90. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +36 -2
  91. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_request_spec.rb +2 -2
  92. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +35 -1
  93. data/spec/lib/ruby_smb/smb1/packet/trans2/query_file_information_request_spec.rb +74 -0
  94. data/spec/lib/ruby_smb/smb1/packet/trans2/query_file_information_response_spec.rb +96 -0
  95. data/spec/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request_spec.rb +62 -0
  96. data/spec/lib/ruby_smb/smb1/packet/trans2/query_fs_information_response_spec.rb +88 -0
  97. data/spec/lib/ruby_smb/smb1/packet/trans2/query_path_information_request_spec.rb +79 -0
  98. data/spec/lib/ruby_smb/smb1/packet/trans2/query_path_information_response_spec.rb +96 -0
  99. data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +2 -2
  100. data/spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb +3 -3
  101. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb +3 -2
  102. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +7 -2
  103. data/spec/lib/ruby_smb/smb1/tree_spec.rb +3 -3
  104. data/spec/lib/ruby_smb/smb2/bit_field/directory_access_mask_spec.rb +4 -4
  105. data/spec/lib/ruby_smb/smb2/bit_field/file_access_mask_spec.rb +4 -4
  106. data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +2 -2
  107. data/spec/spec_helper.rb +2 -3
  108. data.tar.gz.sig +0 -0
  109. metadata +48 -4
  110. metadata.gz.sig +1 -2
@@ -12,6 +12,7 @@ module RubySMB
12
12
  SMB_COM_NEGOTIATE = 0x72
13
13
  SMB_COM_SESSION_SETUP_ANDX = 0x73
14
14
  SMB_COM_LOGOFF = 0x74
15
+ SMB_COM_LOGOFF_ANDX = 0x74
15
16
  SMB_COM_TREE_CONNECT = 0x75
16
17
  SMB_COM_NT_TRANSACT = 0xA0
17
18
  SMB_COM_NT_TRANSACT_SECONDARY = 0xA1
@@ -47,7 +47,17 @@ module RubySMB
47
47
 
48
48
  # Represents the specific layout of the DataBlock for a {NtCreateAndxRequest} Packet.
49
49
  class DataBlock < RubySMB::SMB1::DataBlock
50
- string :file_name, label: 'File Name'
50
+ uint8 :pad, label: 'Pad', onlyif: :has_padding?
51
+ choice :file_name, selection: -> { parent.smb_header.flags2.unicode } do
52
+ stringz 0
53
+ stringz16 1
54
+ end
55
+
56
+ # This method checks if the optional pad field is present.
57
+ def has_padding?
58
+ parent.smb_header.flags2.unicode == 1 && pad.abs_offset % 2 == 1
59
+ end
60
+ private :has_padding?
51
61
  end
52
62
 
53
63
  smb_header :smb_header
@@ -57,7 +57,7 @@ module RubySMB
57
57
  end
58
58
  end
59
59
 
60
- # The Trans2 Data Blcok for this particular Subcommand
60
+ # The Trans2 Data Block for this particular Subcommand
61
61
  class Trans2Data < BinData::Record
62
62
  security_descriptor :security_descriptor
63
63
  file_full_ea_info :extended_attributes
@@ -22,13 +22,14 @@ module RubySMB
22
22
 
23
23
  # Represents the specific layout of the DataBlock for a {ReadAndxResponse} Packet.
24
24
  class DataBlock < RubySMB::SMB1::DataBlock
25
- uint8 :pad, label: 'Pad', onlyif: -> { has_padding? }
25
+ uint8 :pad, label: 'Pad', onlyif: :has_padding?
26
26
  string :data, label: 'Data', read_length: -> { parent.parameter_block.data_length }
27
27
 
28
- # This method checks if the optional pad field is present in the response.
28
+ # This method checks if the optional pad field is present.
29
29
  def has_padding?
30
- return false if byte_count.zero?
31
- return true if byte_count - parent.parameter_block.data_length == 1
30
+ bc = byte_count.clear? ? 0 : byte_count # work around infinite recursion
31
+ return false if bc == 0
32
+ return true if bc - parent.parameter_block.data_length == 1
32
33
  false
33
34
  end
34
35
  private :has_padding?
@@ -23,9 +23,17 @@ module RubySMB
23
23
  # for the security blob, you must null-terminate the {native_os} and {native_lan_man} fields
24
24
  # yourself if you set them away from their defaults.
25
25
  class DataBlock < RubySMB::SMB1::DataBlock
26
- string :security_blob, label: 'Security Blob (GSS-API)', length: -> { parent.parameter_block.security_blob_length }
27
- string :native_os, label: 'Native OS', initial_value: "Windows 7 Ultimate N 7601 Service Pack 1\x00"
28
- string :native_lan_man, label: 'Native LAN Manager', initial_value: "Windows 7 Ultimate N 6.1\x00"
26
+ string :security_blob, label: 'Security Blob (GSS-API)', read_length: -> { parent.parameter_block.security_blob_length }
27
+ uint8 :pad1, label: 'Pad 1', onlyif: -> { parent.smb_header.flags2.unicode == 1 && pad1.abs_offset % 2 == 1 }
28
+ choice :native_os, label: 'Native OS', selection: -> { parent.smb_header.flags2.unicode } do
29
+ stringz 0, initial_value: 'Windows 7 Ultimate N 7601 Service Pack 1'
30
+ stringz16 1, initial_value: 'Windows 7 Ultimate N 7601 Service Pack 1'.encode('utf-16le')
31
+ end
32
+ uint8 :pad2, label: 'Pad 2', onlyif: -> { parent.smb_header.flags2.unicode == 1 && pad2.abs_offset % 2 == 1 }
33
+ choice :native_lan_man, label: 'Native LAN Manager', selection: -> { parent.smb_header.flags2.unicode } do
34
+ stringz 0, initial_value: 'Windows 7 Ultimate N 6.1'
35
+ stringz16 1, initial_value: 'Windows 7 Ultimate N 6.1'.encode('utf-16le')
36
+ end
29
37
  end
30
38
 
31
39
  smb_header :smb_header
@@ -34,7 +42,7 @@ module RubySMB
34
42
 
35
43
  # Takes an NTLM Type 1 Message and creates the GSS Security Blob
36
44
  # for it and sets it in the {RubySMB::SMB1::Packet::SessionSetupRequest::DataBlock#security_blob}
37
- # field. It also automaticaly sets the length in
45
+ # field. It also automatically sets the length in
38
46
  # {RubySMB::SMB1::Packet::SessionSetupRequest::ParameterBlock#security_blob_length}
39
47
  #
40
48
  # @param type1_message [String] the serialized Type 1 NTLM message
@@ -35,13 +35,21 @@ module RubySMB
35
35
  # Determines the correct length for the padding in front of
36
36
  # #trans2_data. It should always force a 4-byte alignment.
37
37
  def pad2_length
38
- if enable_padding
38
+ if enable_padding && (trans2_data.num_bytes > 0 || (!byte_count.clear? && offset_of(pad2) - byte_count.num_bytes < byte_count))
39
39
  offset = (trans2_parameters.abs_offset + trans2_parameters.length) % 4
40
40
  (4 - offset) % 4
41
41
  else
42
42
  0
43
43
  end
44
44
  end
45
+
46
+ # Some structures use an opaque buffer in trans2_data. Calculate its
47
+ # size here.
48
+ def buffer_read_length
49
+ return 0 if byte_count.clear?
50
+
51
+ byte_count + byte_count.num_bytes - offset_of(trans2_data)
52
+ end
45
53
  end
46
54
  end
47
55
  end
@@ -2,70 +2,71 @@ module RubySMB
2
2
  module SMB1
3
3
  module Packet
4
4
  module Trans2
5
- # A Trans2 FIND_FIRST2 Request Packet as defined in
6
- # [2.2.6.2.1](https://msdn.microsoft.com/en-us/library/ee441987.aspx)
7
- class FindFirst2Request < RubySMB::GenericPacket
8
- COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
9
-
10
- class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
11
- end
5
+ # The Trans2 Parameter Block for this particular Subcommand
6
+ class FindFirst2RequestTrans2Parameters < BinData::Record
7
+ endian :little
12
8
 
13
- # The Trans2 Parameter Block for this particular Subcommand
14
- class Trans2Parameters < BinData::Record
15
- endian :little
16
- smb_file_attributes :search_attributes, label: 'File Attributes'
17
- uint16 :search_count, label: 'Search Count'
9
+ smb_file_attributes :search_attributes, label: 'File Attributes'
10
+ uint16 :search_count, label: 'Search Count'
18
11
 
19
- struct :flags do
20
- bit3 :reserved, label: 'Reserved Space'
21
- bit1 :backup, label: 'With Backup Intent'
22
- bit1 :continue, label: 'Continue From Last'
23
- bit1 :resume_keys, label: 'Return Resume Keys'
24
- bit1 :close_eos, label: 'Close at End of Search'
25
- bit1 :close, label: 'Close Search After This Request'
12
+ struct :flags do
13
+ bit3 :reserved, label: 'Reserved Space'
14
+ bit1 :backup, label: 'With Backup Intent'
15
+ bit1 :continue, label: 'Continue From Last'
16
+ bit1 :resume_keys, label: 'Return Resume Keys'
17
+ bit1 :close_eos, label: 'Close at End of Search'
18
+ bit1 :close, label: 'Close Search After This Request'
26
19
 
27
- bit8 :reserved2, label: 'Reserved Space'
28
- end
20
+ bit8 :reserved2, label: 'Reserved Space'
21
+ end
29
22
 
30
- uint16 :information_level, label: 'Information Level'
31
- uint32 :storage_type, label: 'Search Storage type'
23
+ uint16 :information_level, label: 'Information Level'
24
+ uint32 :storage_type, label: 'Search Storage type'
32
25
 
33
- choice :filename, :copy_on_change => true, selection: -> { self.smb_header.flags2.unicode } do
34
- stringz16 1, label: 'FileName'
35
- stringz 0, label: 'FileName'
36
- end
26
+ choice :filename, :copy_on_change => true, selection: -> { self.smb_header.flags2.unicode } do
27
+ stringz16 1, label: 'FileName'
28
+ stringz 0, label: 'FileName'
29
+ end
37
30
 
38
- # Returns the length of the Trans2Parameters struct
39
- # in number of bytes
40
- def length
41
- do_num_bytes
42
- end
31
+ # Returns the length of the Trans2Parameters struct
32
+ # in number of bytes
33
+ def length
34
+ do_num_bytes
43
35
  end
36
+ end
44
37
 
45
- # The Trans2 Data Blcok for this particular Subcommand
46
- class Trans2Data < BinData::Record
47
- smb_gea_list :extended_attribute_list, label: 'Get Extended Attribute List',
48
- onlyif: -> { parent.trans2_parameters.information_level == FindInformationLevel::SMB_INFO_QUERY_EAS_FROM_LIST}
38
+ # The Trans2 Data Block for this particular Subcommand
39
+ class FindFirst2RequestTrans2Data < BinData::Record
40
+ smb_gea_list :extended_attribute_list, label: 'Get Extended Attribute List',
41
+ onlyif: -> { parent.trans2_parameters.information_level == FindInformationLevel::SMB_INFO_QUERY_EAS_FROM_LIST}
49
42
 
50
- # Returns the length of the Trans2Data struct
51
- # in number of bytes
52
- def length
53
- do_num_bytes
54
- end
43
+ # Returns the length of the Trans2Data struct
44
+ # in number of bytes
45
+ def length
46
+ do_num_bytes
55
47
  end
48
+ end
49
+
50
+ # The {RubySMB::SMB1::DataBlock} specific to this packet type.
51
+ class FindFirst2RequestDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
52
+ uint8 :name, label: 'Name', initial_value: 0x00
53
+ string :pad1, length: -> { pad1_length }
54
+ find_first2_request_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
55
+ string :pad2, length: -> { pad2_length }
56
+ find_first2_request_trans2_data :trans2_data, label: 'Trans2 Data'
57
+ end
56
58
 
57
- # The {RubySMB::SMB1::DataBlock} specific to this packet type.
58
- class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
59
- uint8 :name, label: 'Name', initial_value: 0x00
60
- string :pad1, length: -> { pad1_length }
61
- trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
62
- string :pad2, length: -> { pad2_length }
63
- trans2_data :trans2_data, label: 'Trans2 Data'
59
+ # A Trans2 FIND_FIRST2 Request Packet as defined in
60
+ # [2.2.6.2.1](https://msdn.microsoft.com/en-us/library/ee441987.aspx)
61
+ class FindFirst2Request < RubySMB::GenericPacket
62
+ COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
63
+
64
+ class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
64
65
  end
65
66
 
66
- smb_header :smb_header
67
- parameter_block :parameter_block
68
- data_block :data_block
67
+ smb_header :smb_header
68
+ parameter_block :parameter_block
69
+ find_first2_request_data_block :data_block
69
70
 
70
71
  def initialize_instance
71
72
  super
@@ -2,53 +2,53 @@ module RubySMB
2
2
  module SMB1
3
3
  module Packet
4
4
  module Trans2
5
- # This class represents an SMB1 Trans2 FIND_FIRST2 Response Packet as defined in
6
- # [2.2.6.2.2 Response](https://msdn.microsoft.com/en-us/library/ee441704.aspx)
7
- class FindFirst2Response < RubySMB::GenericPacket
8
- COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
5
+ # The Trans2 Parameter Block for this particular Subcommand
6
+ class FindFirst2ResponseTrans2Parameters < BinData::Record
7
+ endian :little
9
8
 
10
- class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Response::ParameterBlock
11
- end
9
+ uint16 :sid, label: 'Search ID'
10
+ uint16 :search_count, label: 'Search Count'
11
+ uint16 :eos, label: 'End of Search'
12
+ uint16 :ea_error_offset, label: 'Offset to EA Error'
13
+ uint16 :last_name_offset, label: 'Last Name Offset'
12
14
 
13
- # The Trans2 Parameter Block for this particular Subcommand
14
- class Trans2Parameters < BinData::Record
15
- endian :little
15
+ # Returns the length of the Trans2Parameters struct
16
+ # in number of bytes
17
+ def length
18
+ do_num_bytes
19
+ end
20
+ end
16
21
 
17
- uint16 :sid, label: 'Search ID'
18
- uint16 :search_count, label: 'Search Count'
19
- uint16 :eos, label: 'End of Search'
20
- uint16 :ea_error_offset, label: 'Offset to EA Error'
21
- uint16 :last_name_offset, label: 'Last Name Offset'
22
+ # The Trans2 Data Block for this particular Subcommand
23
+ class FindFirst2ResponseTrans2Data < BinData::Record
24
+ string :buffer, label: 'Results Buffer', read_length: :buffer_read_length
22
25
 
23
- # Returns the length of the Trans2Parameters struct
24
- # in number of bytes
25
- def length
26
- do_num_bytes
27
- end
26
+ # Returns the length of the Trans2Data struct
27
+ # in number of bytes
28
+ def length
29
+ do_num_bytes
28
30
  end
31
+ end
29
32
 
30
- # The Trans2 Data Blcok for this particular Subcommand
31
- class Trans2Data < BinData::Record
32
- rest :buffer, label: 'Results Buffer'
33
+ # The {RubySMB::SMB1::DataBlock} specific to this packet type.
34
+ class FindFirst2ResponseDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
35
+ string :pad1, length: -> { pad1_length }
36
+ find_first2_response_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
37
+ string :pad2, length: -> { pad2_length }
38
+ find_first2_response_trans2_data :trans2_data, label: 'Trans2 Data', length: 0
39
+ end
33
40
 
34
- # Returns the length of the Trans2Data struct
35
- # in number of bytes
36
- def length
37
- do_num_bytes
38
- end
39
- end
41
+ # This class represents an SMB1 Trans2 FIND_FIRST2 Response Packet as defined in
42
+ # [2.2.6.2.2 Response](https://msdn.microsoft.com/en-us/library/ee441704.aspx)
43
+ class FindFirst2Response < RubySMB::GenericPacket
44
+ COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
40
45
 
41
- # The {RubySMB::SMB1::DataBlock} specific to this packet type.
42
- class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
43
- string :pad1, length: -> { pad1_length }
44
- trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
45
- string :pad2, length: -> { pad2_length }
46
- trans2_data :trans2_data, label: 'Trans2 Data', length: 0
46
+ class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Response::ParameterBlock
47
47
  end
48
48
 
49
- smb_header :smb_header
50
- parameter_block :parameter_block
51
- data_block :data_block
49
+ smb_header :smb_header
50
+ parameter_block :parameter_block
51
+ find_first2_response_data_block :data_block
52
52
 
53
53
  def initialize_instance
54
54
  super
@@ -0,0 +1,48 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module Packet
4
+ module Trans2
5
+ module FindInformationLevel
6
+ # The SMB_FIND_FILE_BOTH_DIRECTORY_INFO class as defined in
7
+ # [2.2.8.1.7 SMB_FIND_FILE_BOTH_DIRECTORY_INFO](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/2aa849f4-1bc0-42bf-9c8f-d09f11fccc4c)
8
+ class FindFileBothDirectoryInfo < BinData::Record
9
+ CLASS_LEVEL = FindInformationLevel::SMB_FIND_FILE_BOTH_DIRECTORY_INFO
10
+
11
+ endian :little
12
+
13
+ uint32 :next_offset, label: 'Next Entry Offset'
14
+ uint32 :file_index, label: 'File Index'
15
+ file_time :create_time, label: 'Create Time'
16
+ file_time :last_access, label: 'Last Accessed Time'
17
+ file_time :last_write, label: 'Last Write Time'
18
+ file_time :last_change, label: 'Last Attribute Change Time'
19
+ uint64 :end_of_file, label: 'End of File'
20
+ uint64 :allocation_size, label: 'Allocated Size'
21
+ smb_ext_file_attributes :ext_file_attributes, label: 'Extended File Attributes'
22
+ uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
23
+ uint32 :ea_size, label: 'Extended Attributes Size'
24
+ uint8 :short_name_length, label: 'Short Name Length'
25
+ uint8 :reserved, label: 'Reserved'
26
+ string16 :short_name, label: 'Short Name', length: 24 # always 12 wchars / 24 bytes
27
+
28
+ choice :file_name, :copy_on_change => true, selection: -> { unicode } do
29
+ string16 true, label: 'File Name', read_length: -> { file_name_length }
30
+ stringz false, label: 'File Name', read_length: -> { file_name_length }
31
+ end
32
+
33
+ # Set unicode encoding for filename
34
+ # @!attribute [rw] unicode
35
+ # @return [Boolean]
36
+ attr_accessor :unicode
37
+
38
+ def initialize_instance
39
+ super
40
+ @unicode = false
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -7,24 +7,37 @@ module RubySMB
7
7
  # of information that a server MUST respond with for each file matching the
8
8
  # request's search criteria.
9
9
  module FindInformationLevel
10
- # Return creation, access, and last write timestamps, size and file attributes along with the file name.
11
- SMB_INFO_STANDARD = 0x0001
12
- # Return the SMB_INFO_STANDARD data along with the size of a file's extended attributes (EAs).
13
- SMB_INFO_QUERY_EA_SIZE = 0x0002
14
- # Return the SMB_INFO_QUERY_EA_SIZE data along with a specific list of a file's EAs. The requested EAs are provided in the Trans2_Data block of the request.
15
- SMB_INFO_QUERY_EAS_FROM_LIST = 0x0003
16
- # Return 64-bit format versions of: creation, access, last write, and last attribute change timestamps; size. In addition, return extended file attributes and file name.
17
- SMB_FIND_FILE_DIRECTORY_INFO = 0x0101
18
- # Returns the SMB_FIND_FILE_DIRECTORY_INFO data along with the size of a file's EAs.
19
- SMB_FIND_FILE_FULL_DIRECTORY_INFO = 0x0102
20
- # Returns the name(s) of the file(s).
21
- SMB_FIND_FILE_NAMES_INFO = 0x0103
22
- # Returns a combination of the data from SMB_FIND_FILE_FULL_DIRECTORY_INFO and SMB_FIND_FILE_NAMES_INFO.
23
- SMB_FIND_FILE_BOTH_DIRECTORY_INFO = 0x0104
10
+ # Constants defined in
11
+ # [2.2.2.3.1 FIND Information Level Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/f5dcd594-1c46-4bc6-963f-581a4c78ea99)
12
+ # [dialect] description
24
13
 
14
+ # [LANMAN2.0] Return creation, access, and last write timestamps, size and file attributes along with the file name.
15
+ SMB_INFO_STANDARD = 0x0001 # 1
25
16
 
26
- require 'ruby_smb/smb1/packet/trans2/find_information_level/find_file_full_directory_info'
17
+ # [LANMAN2.0] Return the SMB_INFO_STANDARD data along with the size of a file's extended attributes (EAs).
18
+ SMB_INFO_QUERY_EA_SIZE = 0x0002 # 2
19
+
20
+ # [LANMAN2.0] Return the SMB_INFO_QUERY_EA_SIZE data along with a specific list of a file's EAs. The requested EAs are provided in the Trans2_Data block of the request.
21
+ SMB_INFO_QUERY_EAS_FROM_LIST = 0x0003 # 3
22
+
23
+ # [NT LANMAN] Return 64-bit format versions of: creation, access, last write, and last attribute change timestamps; size. In addition, return extended file attributes and file name.
24
+ SMB_FIND_FILE_DIRECTORY_INFO = 0x0101 # 257
25
+
26
+ # [NT LANMAN] Returns the SMB_FIND_FILE_DIRECTORY_INFO data along with the size of a file's EAs.
27
+ SMB_FIND_FILE_FULL_DIRECTORY_INFO = 0x0102 # 258
27
28
 
29
+ # [NT LANMAN] Returns the name(s) of the file(s).
30
+ SMB_FIND_FILE_NAMES_INFO = 0x0103 # 259
31
+
32
+ # [NT LANMAN] Returns a combination of the data from SMB_FIND_FILE_FULL_DIRECTORY_INFO and SMB_FIND_FILE_NAMES_INFO.
33
+ SMB_FIND_FILE_BOTH_DIRECTORY_INFO = 0x0104 # 260
34
+
35
+ def self.name(value)
36
+ constants.select { |c| c.upcase == c }.find { |c| const_get(c) == value }
37
+ end
38
+
39
+ require 'ruby_smb/smb1/packet/trans2/find_information_level/find_file_both_directory_info'
40
+ require 'ruby_smb/smb1/packet/trans2/find_information_level/find_file_full_directory_info'
28
41
  end
29
42
  end
30
43
  end
@@ -2,70 +2,70 @@ module RubySMB
2
2
  module SMB1
3
3
  module Packet
4
4
  module Trans2
5
- # A Trans2 FIND_NEXT2 Request Packet as defined in
6
- # [2.2.6.3.1 Request](https://msdn.microsoft.com/en-us/library/ee441844.aspx)
7
- class FindNext2Request < RubySMB::GenericPacket
8
- COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
5
+ # The Trans2 Parameter Block for this particular Subcommand
6
+ class FindNext2RequestTrans2Parameters < BinData::Record
7
+ endian :little
9
8
 
10
- class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
11
- end
9
+ uint16 :sid, label: 'Search ID'
10
+ uint16 :search_count, label: 'Search Count'
11
+ uint16 :information_level, label: 'Information Level'
12
+ uint32 :resume_key, label: 'Resume Key'
12
13
 
13
- # The Trans2 Parameter Block for this particular Subcommand
14
- class Trans2Parameters < BinData::Record
15
- endian :little
14
+ struct :flags do
15
+ bit3 :reserved, label: 'Reserved Space'
16
+ bit1 :backup, label: 'With Backup Intent'
17
+ bit1 :continue, label: 'Continue From Last'
18
+ bit1 :resume_keys, label: 'Return Resume Keys'
19
+ bit1 :close_eos, label: 'Close at End of Search'
20
+ bit1 :close, label: 'Close Search After This Request'
16
21
 
17
- uint16 :sid, label: 'Search ID'
18
- uint16 :search_count, label: 'Search Count'
19
- uint16 :information_level, label: 'Information Level'
20
- uint32 :resume_key, label: 'Resume Key'
22
+ bit8 :reserved2, label: 'Reserved Space'
23
+ end
21
24
 
22
- struct :flags do
23
- bit3 :reserved, label: 'Reserved Space'
24
- bit1 :backup, label: 'With Backup Intent'
25
- bit1 :continue, label: 'Continue From Last'
26
- bit1 :resume_keys, label: 'Return Resume Keys'
27
- bit1 :close_eos, label: 'Close at End of Search'
28
- bit1 :close, label: 'Close Search After This Request'
25
+ choice :filename, :copy_on_change => true, selection: -> { @obj.parent.parent.parent.smb_header.flags2.unicode } do
26
+ stringz16 1, label: 'FileName'
27
+ stringz 0, label: 'FileName'
28
+ end
29
29
 
30
- bit8 :reserved2, label: 'Reserved Space'
31
- end
30
+ # Returns the length of the Trans2Parameters struct
31
+ # in number of bytes
32
+ def length
33
+ do_num_bytes
34
+ end
35
+ end
32
36
 
33
- choice :filename, :copy_on_change => true, selection: -> { @obj.parent.parent.parent.smb_header.flags2.unicode } do
34
- stringz16 1, label: 'FileName'
35
- stringz 0, label: 'FileName'
36
- end
37
+ # The Trans2 Data Block for this particular Subcommand
38
+ class FindNext2RequestTrans2Data < BinData::Record
39
+ smb_gea_list :extended_attribute_list, label: 'Get Extended Attribute List',
40
+ onlyif: -> { parent.trans2_parameters.information_level == FindInformationLevel::SMB_INFO_QUERY_EAS_FROM_LIST}
37
41
 
38
- # Returns the length of the Trans2Parameters struct
39
- # in number of bytes
40
- def length
41
- do_num_bytes
42
- end
42
+ # Returns the length of the Trans2Data struct
43
+ # in number of bytes
44
+ def length
45
+ do_num_bytes
43
46
  end
47
+ end
44
48
 
45
- # The Trans2 Data Blcok for this particular Subcommand
46
- class Trans2Data < BinData::Record
47
- smb_gea_list :extended_attribute_list, label: 'Get Extended Attribute List',
48
- onlyif: -> { parent.trans2_parameters.information_level == FindInformationLevel::SMB_INFO_QUERY_EAS_FROM_LIST}
49
+ # The {RubySMB::SMB1::DataBlock} specific to this packet type.
50
+ class FindNext2RequestDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
51
+ uint8 :name, label: 'Name', initial_value: 0x00
52
+ string :pad1, length: -> { pad1_length }
53
+ find_next2_request_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
54
+ string :pad2, length: -> { pad2_length }
55
+ find_next2_request_trans2_data :trans2_data, label: 'Trans2 Data'
56
+ end
49
57
 
50
- # Returns the length of the Trans2Data struct
51
- # in number of bytes
52
- def length
53
- do_num_bytes
54
- end
55
- end
58
+ # A Trans2 FIND_NEXT2 Request Packet as defined in
59
+ # [2.2.6.3.1 Request](https://msdn.microsoft.com/en-us/library/ee441844.aspx)
60
+ class FindNext2Request < RubySMB::GenericPacket
61
+ COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
56
62
 
57
- # The {RubySMB::SMB1::DataBlock} specific to this packet type.
58
- class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
59
- uint8 :name, label: 'Name', initial_value: 0x00
60
- string :pad1, length: -> { pad1_length }
61
- trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
62
- string :pad2, length: -> { pad2_length }
63
- trans2_data :trans2_data, label: 'Trans2 Data'
63
+ class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
64
64
  end
65
65
 
66
- smb_header :smb_header
67
- parameter_block :parameter_block
68
- data_block :data_block
66
+ smb_header :smb_header
67
+ parameter_block :parameter_block
68
+ find_next2_request_data_block :data_block
69
69
 
70
70
  def initialize_instance
71
71
  super