ruby_smb 3.0.6 → 3.1.2

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.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/examples/file_server.rb +8 -1
  4. data/examples/virtual_file_server.rb +143 -0
  5. data/lib/ruby_smb/client/encryption.rb +16 -4
  6. data/lib/ruby_smb/client/negotiation.rb +10 -8
  7. data/lib/ruby_smb/fscc/file_information/file_access_information.rb +15 -0
  8. data/lib/ruby_smb/fscc/file_information/file_alignment_information.rb +45 -0
  9. data/lib/ruby_smb/fscc/file_information/file_all_information.rb +23 -0
  10. data/lib/ruby_smb/fscc/file_information/file_basic_information.rb +20 -0
  11. data/lib/ruby_smb/fscc/file_information/file_both_directory_information.rb +3 -3
  12. data/lib/ruby_smb/fscc/file_information/file_directory_information.rb +3 -3
  13. data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +1 -0
  14. data/lib/ruby_smb/fscc/file_information/file_full_directory_information.rb +3 -3
  15. data/lib/ruby_smb/fscc/file_information/file_id_both_directory_information.rb +3 -3
  16. data/lib/ruby_smb/fscc/file_information/file_id_full_directory_information.rb +3 -3
  17. data/lib/ruby_smb/fscc/file_information/file_internal_information.rb +15 -0
  18. data/lib/ruby_smb/fscc/file_information/file_mode_information.rb +29 -0
  19. data/lib/ruby_smb/fscc/file_information/file_name_information.rb +16 -0
  20. data/lib/ruby_smb/fscc/file_information/file_names_information.rb +1 -1
  21. data/lib/ruby_smb/fscc/file_information/file_normalized_name_information.rb +16 -0
  22. data/lib/ruby_smb/fscc/file_information/file_position_information.rb +15 -0
  23. data/lib/ruby_smb/fscc/file_information/file_rename_information.rb +1 -1
  24. data/lib/ruby_smb/fscc/file_information/file_standard_information.rb +20 -0
  25. data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +3 -0
  26. data/lib/ruby_smb/fscc/file_information.rb +43 -6
  27. data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +1 -0
  28. data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +1 -0
  29. data/lib/ruby_smb/fscc/file_system_information.rb +4 -0
  30. data/lib/ruby_smb/gss/provider/ntlm.rb +20 -3
  31. data/lib/ruby_smb/gss/provider.rb +10 -1
  32. data/lib/ruby_smb/server/server_client/encryption.rb +66 -0
  33. data/lib/ruby_smb/server/server_client/negotiation.rb +14 -3
  34. data/lib/ruby_smb/server/server_client/session_setup.rb +21 -4
  35. data/lib/ruby_smb/server/server_client/share_io.rb +17 -0
  36. data/lib/ruby_smb/server/server_client/tree_connect.rb +40 -3
  37. data/lib/ruby_smb/server/server_client.rb +156 -38
  38. data/lib/ruby_smb/server/session.rb +5 -1
  39. data/lib/ruby_smb/server/share/provider/disk/file_system.rb +28 -0
  40. data/lib/ruby_smb/server/share/provider/disk/processor/close.rb +46 -0
  41. data/lib/ruby_smb/server/share/provider/disk/processor/create.rb +143 -0
  42. data/lib/ruby_smb/server/share/provider/disk/processor/query.rb +359 -0
  43. data/lib/ruby_smb/server/share/provider/disk/processor/read.rb +70 -0
  44. data/lib/ruby_smb/server/share/provider/disk/processor.rb +223 -0
  45. data/lib/ruby_smb/server/share/provider/disk.rb +12 -418
  46. data/lib/ruby_smb/server/share/provider/pipe.rb +2 -2
  47. data/lib/ruby_smb/server/share/provider/processor.rb +16 -0
  48. data/lib/ruby_smb/server/share/provider/virtual_disk/virtual_file.rb +85 -0
  49. data/lib/ruby_smb/server/share/provider/virtual_disk/virtual_pathname.rb +196 -0
  50. data/lib/ruby_smb/server/share/provider/virtual_disk/virtual_stat.rb +175 -0
  51. data/lib/ruby_smb/server/share/provider/virtual_disk.rb +116 -0
  52. data/lib/ruby_smb/server/share/provider.rb +1 -0
  53. data/lib/ruby_smb/server.rb +13 -3
  54. data/lib/ruby_smb/signing.rb +18 -4
  55. data/lib/ruby_smb/smb1/commands.rb +1 -0
  56. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +11 -1
  57. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +1 -1
  58. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +5 -4
  59. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +12 -4
  60. data/lib/ruby_smb/smb1/packet/trans2/data_block.rb +9 -1
  61. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +52 -51
  62. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +37 -37
  63. data/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_both_directory_info.rb +48 -0
  64. data/lib/ruby_smb/smb1/packet/trans2/find_information_level.rb +28 -15
  65. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +51 -51
  66. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +36 -36
  67. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +40 -39
  68. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +40 -40
  69. data/lib/ruby_smb/smb1/packet/trans2/query_file_information_request.rb +60 -0
  70. data/lib/ruby_smb/smb1/packet/trans2/query_file_information_response.rb +59 -0
  71. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_attribute_info.rb +31 -0
  72. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level.rb +40 -0
  73. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request.rb +46 -0
  74. data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_response.rb +59 -0
  75. data/lib/ruby_smb/smb1/packet/trans2/query_information_level/query_file_basic_info.rb +23 -0
  76. data/lib/ruby_smb/smb1/packet/trans2/query_information_level/query_file_standard_info.rb +22 -0
  77. data/lib/ruby_smb/smb1/packet/trans2/query_information_level.rb +62 -0
  78. data/lib/ruby_smb/smb1/packet/trans2/query_path_information_request.rb +65 -0
  79. data/lib/ruby_smb/smb1/packet/trans2/query_path_information_response.rb +59 -0
  80. data/lib/ruby_smb/smb1/packet/trans2/request.rb +24 -8
  81. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +4 -4
  82. data/lib/ruby_smb/smb1/packet/trans2/response.rb +29 -20
  83. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +42 -42
  84. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +23 -23
  85. data/lib/ruby_smb/smb1/packet/trans2/subcommands.rb +23 -5
  86. data/lib/ruby_smb/smb1/packet/trans2.rb +4 -0
  87. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +4 -1
  88. data/lib/ruby_smb/smb2/negotiate_context.rb +10 -1
  89. data/lib/ruby_smb/smb2/packet/transform_header.rb +7 -7
  90. data/lib/ruby_smb/smb2/tree.rb +1 -0
  91. data/lib/ruby_smb/smb2.rb +1 -0
  92. data/lib/ruby_smb/version.rb +1 -1
  93. data/spec/lib/ruby_smb/client_spec.rb +31 -8
  94. data/spec/lib/ruby_smb/fscc/file_information/file_access_information_spec.rb +21 -0
  95. data/spec/lib/ruby_smb/fscc/file_information/file_alignment_information_spec.rb +21 -0
  96. data/spec/lib/ruby_smb/fscc/file_information/file_all_information_spec.rb +61 -0
  97. data/spec/lib/ruby_smb/fscc/file_information/file_basic_information_spec.rb +41 -0
  98. data/spec/lib/ruby_smb/fscc/file_information/file_both_directory_information_spec.rb +59 -10
  99. data/spec/lib/ruby_smb/fscc/file_information/file_directory_information_spec.rb +30 -12
  100. data/spec/lib/ruby_smb/fscc/file_information/file_ea_information_spec.rb +21 -0
  101. data/spec/lib/ruby_smb/fscc/file_information/file_full_directory_information_spec.rb +30 -12
  102. data/spec/lib/ruby_smb/fscc/file_information/file_id_both_directory_information_spec.rb +63 -10
  103. data/spec/lib/ruby_smb/fscc/file_information/file_id_full_directory_information_spec.rb +30 -12
  104. data/spec/lib/ruby_smb/fscc/file_information/file_internal_information_spec.rb +21 -0
  105. data/spec/lib/ruby_smb/fscc/file_information/file_mode_information_spec.rb +21 -0
  106. data/spec/lib/ruby_smb/fscc/file_information/file_name_information_spec.rb +44 -0
  107. data/spec/lib/ruby_smb/fscc/file_information/file_names_information_spec.rb +30 -12
  108. data/spec/lib/ruby_smb/fscc/file_information/file_network_open_information_spec.rb +51 -0
  109. data/spec/lib/ruby_smb/fscc/file_information/file_normalized_name_information_spec.rb +44 -0
  110. data/spec/lib/ruby_smb/fscc/file_information/file_position_information_spec.rb +21 -0
  111. data/spec/lib/ruby_smb/fscc/file_information/file_rename_information_spec.rb +1 -1
  112. data/spec/lib/ruby_smb/fscc/file_information/file_standard_information_spec.rb +41 -0
  113. data/spec/lib/ruby_smb/fscc/file_information/file_stream_information_spec.rb +51 -0
  114. data/spec/lib/ruby_smb/fscc/file_information_spec.rb +14 -0
  115. data/spec/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information_spec.rb +46 -0
  116. data/spec/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information_spec.rb +51 -0
  117. data/spec/lib/ruby_smb/fscc/file_system_information_spec.rb +14 -0
  118. data/spec/lib/ruby_smb/server/server_client_spec.rb +15 -0
  119. data/spec/lib/ruby_smb/server/share/provider/virtual_disk/virtual_pathname_spec.rb +581 -0
  120. data/spec/lib/ruby_smb/server/share/provider/virtual_disk/virtual_stat_spec.rb +207 -0
  121. data/spec/lib/ruby_smb/server/share/provider/virtual_disk_spec.rb +122 -0
  122. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_request_spec.rb +2 -2
  123. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +36 -2
  124. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_request_spec.rb +2 -2
  125. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +35 -1
  126. data/spec/lib/ruby_smb/smb1/packet/trans2/query_file_information_request_spec.rb +74 -0
  127. data/spec/lib/ruby_smb/smb1/packet/trans2/query_file_information_response_spec.rb +96 -0
  128. data/spec/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request_spec.rb +62 -0
  129. data/spec/lib/ruby_smb/smb1/packet/trans2/query_fs_information_response_spec.rb +88 -0
  130. data/spec/lib/ruby_smb/smb1/packet/trans2/query_path_information_request_spec.rb +79 -0
  131. data/spec/lib/ruby_smb/smb1/packet/trans2/query_path_information_response_spec.rb +96 -0
  132. data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +2 -2
  133. data/spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb +3 -3
  134. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb +3 -2
  135. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +7 -2
  136. data/spec/lib/ruby_smb/smb1/tree_spec.rb +3 -3
  137. data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +2 -2
  138. data.tar.gz.sig +0 -0
  139. metadata +88 -2
  140. metadata.gz.sig +0 -0
@@ -25,22 +25,38 @@ module RubySMB
25
25
  uint8 :setup_count, label: 'Setup Count', initial_value: -> { setup.length }
26
26
  uint8 :reserved3, label: 'Reserved Space', initial_value: 0x00
27
27
 
28
- array :setup, type: :uint16, initial_length: 0
28
+ array :setup, type: :uint16, initial_length: :setup_count
29
29
  end
30
30
 
31
31
  # The {RubySMB::SMB1::DataBlock} specific to this packet type.
32
32
  class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
33
- uint8 :name, label: 'Name', initial_value: 0x00
34
- string :pad1, length: -> { pad1_length }
35
- string :trans2_parameters, label: 'Trans2 Parameters'
36
- string :pad2, length: -> { pad2_length }
37
- string :trans2_data, label: 'Trans2 Data'
33
+ uint8 :name, label: 'Name', initial_value: 0x00
34
+ string :pad1, length: -> { pad1_length }
35
+ string :trans2_parameters, label: 'Trans2 Parameters'
36
+ string :pad2, length: -> { pad2_length }
37
+ string :trans2_data, label: 'Trans2 Data'
38
38
  end
39
39
 
40
+ require 'ruby_smb/smb1/packet/trans2/find_first2_request'
41
+ require 'ruby_smb/smb1/packet/trans2/find_next2_request'
42
+ require 'ruby_smb/smb1/packet/trans2/open2_request'
43
+ require 'ruby_smb/smb1/packet/trans2/query_file_information_request'
44
+ require 'ruby_smb/smb1/packet/trans2/query_path_information_request'
45
+ require 'ruby_smb/smb1/packet/trans2/set_file_information_request'
46
+ require 'ruby_smb/smb1/packet/trans2/query_fs_information_request'
47
+
40
48
  smb_header :smb_header
41
49
  parameter_block :parameter_block
42
- data_block :data_block
43
-
50
+ choice :data_block, selection: -> { parameter_block.setup.first || :default } do
51
+ open2_request_data_block Subcommands::OPEN2
52
+ find_first2_request_data_block Subcommands::FIND_FIRST2
53
+ find_next2_request_data_block Subcommands::FIND_NEXT2
54
+ query_file_information_request_data_block Subcommands::QUERY_FILE_INFORMATION
55
+ query_path_information_request_data_block Subcommands::QUERY_PATH_INFORMATION
56
+ set_file_information_request_data_block Subcommands::SET_FILE_INFORMATION
57
+ query_fs_information_request_data_block Subcommands::QUERY_FS_INFORMATION
58
+ data_block :default
59
+ end
44
60
  end
45
61
  end
46
62
  end
@@ -9,7 +9,7 @@ module RubySMB
9
9
 
10
10
  # The {RubySMB::SMB1::ParameterBlock} specific to this packet type.
11
11
  class ParameterBlock < RubySMB::SMB1::ParameterBlock
12
- uint16 :total_parameter_count, label: 'Total Parameter Count(bytes)'
12
+ uint16 :total_parameter_count, label: 'Total Parameter Count(bytes)'
13
13
  uint16 :total_data_count, label: 'Total Data Count(bytes)'
14
14
  uint16 :parameter_count, label: 'Parameter Count(bytes)', initial_value: -> { parent.data_block.trans2_parameters.length }
15
15
  uint16 :parameter_offset, label: 'Parameter Offset', initial_value: -> { parent.data_block.trans2_parameters.abs_offset }
@@ -24,9 +24,9 @@ module RubySMB
24
24
  class DataBlock < RubySMB::SMB1::Packet::Trans2::Request::DataBlock
25
25
  end
26
26
 
27
- smb_header :smb_header
28
- parameter_block :parameter_block
29
- data_block :data_block
27
+ smb_header :smb_header
28
+ parameter_block :parameter_block
29
+ data_block :data_block
30
30
 
31
31
  end
32
32
  end
@@ -9,32 +9,41 @@ module RubySMB
9
9
 
10
10
  # The {RubySMB::SMB1::ParameterBlock} specific to this packet type.
11
11
  class ParameterBlock < RubySMB::SMB1::ParameterBlock
12
- uint16 :total_parameter_count, label: 'Total Parameter Count(bytes)'
13
- uint16 :total_data_count, label: 'Total Data Count(bytes)'
14
- uint16 :reserved, label: 'Reserved Space', initial_value: 0x00
15
- uint16 :parameter_count, label: 'Parameter Count(bytes)', initial_value: -> { parent.data_block.trans2_parameters.length }
16
- uint16 :parameter_offset, label: 'Parameter Offset', initial_value: -> { parent.data_block.trans2_parameters.abs_offset }
17
- uint16 :parameter_displacement, label: 'Parameter Displacement'
18
- uint16 :data_count, label: 'Data Count(bytes)', initial_value: -> { parent.data_block.trans2_data.length }
19
- uint16 :data_offset, label: 'Data Offset', initial_value: -> { parent.data_block.trans2_data.abs_offset }
20
- uint16 :data_displacement, label: 'Data Displacement'
21
- uint8 :setup_count, label: 'Setup Count', initial_value: -> { setup.length }
22
- uint8 :reserved2, label: 'Reserved Space', initial_value: 0x00
12
+ uint16 :total_parameter_count, label: 'Total Parameter Count(bytes)'
13
+ uint16 :total_data_count, label: 'Total Data Count(bytes)'
14
+ uint16 :reserved, label: 'Reserved Space', initial_value: 0x00
15
+ uint16 :parameter_count, label: 'Parameter Count(bytes)', initial_value: -> { parent.data_block.trans2_parameters.length }
16
+ uint16 :parameter_offset, label: 'Parameter Offset', initial_value: -> { parent.data_block.trans2_parameters.abs_offset }
17
+ uint16 :parameter_displacement, label: 'Parameter Displacement'
18
+ uint16 :data_count, label: 'Data Count(bytes)', initial_value: -> { parent.data_block.trans2_data.length }
19
+ uint16 :data_offset, label: 'Data Offset', initial_value: -> { parent.data_block.trans2_data.abs_offset }
20
+ uint16 :data_displacement, label: 'Data Displacement'
21
+ uint8 :setup_count, label: 'Setup Count', initial_value: -> { setup.length }
22
+ uint8 :reserved2, label: 'Reserved Space', initial_value: 0x00
23
23
 
24
- array :setup, type: :uint16, initial_length: 0
24
+ array :setup, type: :uint16, initial_length: :setup_count
25
25
  end
26
26
 
27
- # The {RubySMB::SMB1::DataBlock} specific to this packet type.
28
- class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
29
- string :pad1, length: -> { pad1_length }
30
- string :trans2_parameters, label: 'Trans2 Parameters'
31
- string :pad2, length: -> { pad2_length }
32
- string :trans2_data, label: 'Trans2 Data'
33
- end
27
+ require 'ruby_smb/smb1/packet/trans2/find_first2_response'
28
+ require 'ruby_smb/smb1/packet/trans2/find_next2_response'
29
+ require 'ruby_smb/smb1/packet/trans2/open2_response'
30
+ require 'ruby_smb/smb1/packet/trans2/query_file_information_response'
31
+ require 'ruby_smb/smb1/packet/trans2/query_path_information_response'
32
+ require 'ruby_smb/smb1/packet/trans2/set_file_information_response'
33
+ require 'ruby_smb/smb1/packet/trans2/query_fs_information_response'
34
34
 
35
35
  smb_header :smb_header
36
36
  parameter_block :parameter_block
37
- data_block :data_block
37
+ choice :data_block, selection: -> { parameter_block.setup.first || :default } do
38
+ open2_response_data_block Subcommands::OPEN2
39
+ find_first2_response_data_block Subcommands::FIND_FIRST2
40
+ find_next2_response_data_block Subcommands::FIND_NEXT2
41
+ query_file_information_response_data_block Subcommands::QUERY_FILE_INFORMATION
42
+ query_path_information_response_data_block Subcommands::QUERY_PATH_INFORMATION
43
+ set_file_information_response_data_block Subcommands::SET_FILE_INFORMATION
44
+ query_fs_information_response_data_block Subcommands::QUERY_FS_INFORMATION
45
+ data_block :default
46
+ end
38
47
 
39
48
  def initialize_instance
40
49
  super
@@ -2,59 +2,59 @@ module RubySMB
2
2
  module SMB1
3
3
  module Packet
4
4
  module Trans2
5
- # A Trans2 SET_FILE_INFORMATION Request Packet as defined in
6
- # [2.2.6.9.1 Request](https://msdn.microsoft.com/en-us/library/ee441527.aspx)
7
- class SetFileInformationRequest < RubySMB::GenericPacket
8
- COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
5
+ # The Trans2 Parameter Block for this particular Subcommand
6
+ class SetFileInformationRequestTrans2Parameters < BinData::Record
7
+ endian :little
9
8
 
10
- class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
11
- end
9
+ uint16 :fid, label: 'FID'
10
+ uint16 :information_level, label: 'Information Level'
11
+ uint16 :reserved, label: 'Reserved Space'
12
12
 
13
- # The Trans2 Parameter Block for this particular Subcommand
14
- class Trans2Parameters < BinData::Record
15
- endian :little
13
+ # Returns the length of the Trans2Parameters struct
14
+ # in number of bytes
15
+ def length
16
+ do_num_bytes
17
+ end
18
+ end
16
19
 
17
- uint16 :fid, label: 'FID'
18
- uint16 :information_level, label: 'Information Level'
19
- uint16 :reserved, label: 'Reserved Space'
20
+ # The Trans2 Data Block for this particular Subcommand
21
+ class SetFileInformationRequestTrans2Data < BinData::Record
22
+ include RubySMB::Fscc::FileInformation
20
23
 
21
- # Returns the length of the Trans2Parameters struct
22
- # in number of bytes
23
- def length
24
- do_num_bytes
25
- end
24
+ choice :info_level_struct, selection: -> { parent.trans2_parameters.information_level } do
25
+ # It supports new pass-through Information Level capabilities, as specified in
26
+ # [2.2.2.3.5 Pass-through Information Level Codes](https://msdn.microsoft.com/en-us/library/ff470158.aspx)
27
+ file_disposition_information (FILE_DISPOSITION_INFORMATION + SMB_INFO_PASSTHROUGH), label: 'File Disposition Information'
28
+ file_rename_information (FILE_RENAME_INFORMATION + SMB_INFO_PASSTHROUGH), label: 'File Rename Information'
26
29
  end
27
30
 
28
- # The Trans2 Data Block for this particular Subcommand
29
- class Trans2Data < BinData::Record
30
- include RubySMB::Fscc::FileInformation
31
+ # Returns the length of the Trans2Data struct
32
+ # in number of bytes
33
+ def length
34
+ do_num_bytes
35
+ end
36
+ end
31
37
 
32
- choice :info_level_struct, selection: -> { parent.trans2_parameters.information_level } do
33
- # It supports new pass-through Information Level capabilities, as specified in
34
- # [2.2.2.3.5 Pass-through Information Level Codes](https://msdn.microsoft.com/en-us/library/ff470158.aspx)
35
- file_disposition_information (FILE_DISPOSITION_INFORMATION + SMB_INFO_PASSTHROUGH), label: 'File Disposition Information'
36
- file_rename_information (FILE_RENAME_INFORMATION + SMB_INFO_PASSTHROUGH), label: 'File Rename Information'
37
- end
38
+ # The {RubySMB::SMB1::DataBlock} specific to this packet type.
39
+ class SetFileInformationRequestDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
40
+ uint8 :name, label: 'Name', initial_value: 0x00
41
+ string :pad1, length: -> { pad1_length }
42
+ set_file_information_request_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
43
+ string :pad2, length: -> { pad2_length }
44
+ set_file_information_request_trans2_data :trans2_data, label: 'Trans2 Data'
45
+ end
38
46
 
39
- # Returns the length of the Trans2Data struct
40
- # in number of bytes
41
- def length
42
- do_num_bytes
43
- end
44
- end
47
+ # A Trans2 SET_FILE_INFORMATION Request Packet as defined in
48
+ # [2.2.6.9.1 Request](https://msdn.microsoft.com/en-us/library/ee441527.aspx)
49
+ class SetFileInformationRequest < RubySMB::GenericPacket
50
+ COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
45
51
 
46
- # The {RubySMB::SMB1::DataBlock} specific to this packet type.
47
- class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
48
- uint8 :name, label: 'Name', initial_value: 0x00
49
- string :pad1, length: -> { pad1_length }
50
- trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
51
- string :pad2, length: -> { pad2_length }
52
- trans2_data :trans2_data, label: 'Trans2 Data'
52
+ class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
53
53
  end
54
54
 
55
- smb_header :smb_header
56
- parameter_block :parameter_block
57
- data_block :data_block
55
+ smb_header :smb_header
56
+ parameter_block :parameter_block
57
+ set_file_information_request_data_block :data_block
58
58
 
59
59
  def initialize_instance
60
60
  super
@@ -2,6 +2,26 @@ module RubySMB
2
2
  module SMB1
3
3
  module Packet
4
4
  module Trans2
5
+ # The Trans2 Parameter Block for this particular Subcommand
6
+ class SetFileInformationResponseTrans2Parameters < BinData::Record
7
+ endian :little
8
+
9
+ uint16 :ea_error_offset, label: 'Extended Attribute Error Offset'
10
+
11
+ # Returns the length of the Trans2Parameters struct
12
+ # in number of bytes
13
+ def length
14
+ do_num_bytes
15
+ end
16
+ end
17
+
18
+ # The {RubySMB::SMB1::DataBlock} specific to this packet type.
19
+ class SetFileInformationResponseDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
20
+ string :pad1, length: -> { pad1_length }
21
+ set_file_information_response_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
22
+ # trans2_data: No data is sent by this message.
23
+ end
24
+
5
25
  # A Trans2 SET_FILE_INFORMATION Response Packet as defined in
6
26
  # [2.2.6.9.2 Response](https://msdn.microsoft.com/en-us/library/ff469853.aspx)
7
27
  class SetFileInformationResponse < RubySMB::GenericPacket
@@ -10,29 +30,9 @@ module RubySMB
10
30
  class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Response::ParameterBlock
11
31
  end
12
32
 
13
- # The Trans2 Parameter Block for this particular Subcommand
14
- class Trans2Parameters < BinData::Record
15
- endian :little
16
-
17
- uint16 :ea_error_offset, label: 'Extended Attribute Error Offset'
18
-
19
- # Returns the length of the Trans2Parameters struct
20
- # in number of bytes
21
- def length
22
- do_num_bytes
23
- end
24
- end
25
-
26
- # The {RubySMB::SMB1::DataBlock} specific to this packet type.
27
- class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
28
- string :pad1, length: -> { pad1_length }
29
- trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
30
- # trans2_data: No data is sent by this message.
31
- end
32
-
33
- smb_header :smb_header
34
- parameter_block :parameter_block
35
- data_block :data_block
33
+ smb_header :smb_header
34
+ parameter_block :parameter_block
35
+ set_file_information_response_data_block :data_block
36
36
 
37
37
  def initialize_instance
38
38
  super
@@ -2,12 +2,30 @@ module RubySMB
2
2
  module SMB1
3
3
  module Packet
4
4
  module Trans2
5
+ # Transaction2 subcommand constants as defined in
6
+ # [2.2.6 Transaction2 Subcommands](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/1cc40e02-aaea-4f33-b7b7-3a6b63906516)
5
7
  module Subcommands
6
- OPEN2 = 0x0000
7
- FIND_FIRST2 = 0x0001
8
- FIND_NEXT2 = 0x0002
9
- SET_FILE_INFORMATION = 0x0008
10
- SESSION_SETUP = 0x000E
8
+ OPEN2 = 0x0000
9
+ FIND_FIRST2 = 0x0001
10
+ FIND_NEXT2 = 0x0002
11
+ QUERY_FS_INFORMATION = 0x0003
12
+ SET_FS_INFORMATION = 0x0004
13
+ QUERY_PATH_INFORMATION = 0x0005
14
+ SET_PATH_INFORMATION = 0x0006
15
+ QUERY_FILE_INFORMATION = 0x0007
16
+ SET_FILE_INFORMATION = 0x0008
17
+ FSCTL = 0x0009
18
+ IOCTL2 = 0x000A
19
+ FIND_NOTIFY_FIRST = 0x000B
20
+ FIND_NOTIFY_NEXT = 0x000C
21
+ CREATE_DIRECTORY = 0x000D
22
+ SESSION_SETUP = 0x000E
23
+ GET_DFS_REFERRAL = 0x0010
24
+ REPORT_DFS_INCONSISTENCY = 0x0011
25
+
26
+ def self.name(value)
27
+ constants.select { |c| c.upcase == c }.find { |c| const_get(c) == value }
28
+ end
11
29
  end
12
30
  end
13
31
  end
@@ -5,6 +5,8 @@ module RubySMB
5
5
  # [2.2.4.46 SMB_COM_TRANSACTION2 (0x32)](https://msdn.microsoft.com/en-us/library/ee441652.aspx)
6
6
  module Trans2
7
7
  require 'ruby_smb/smb1/packet/trans2/find_information_level'
8
+ require 'ruby_smb/smb1/packet/trans2/query_information_level'
9
+ require 'ruby_smb/smb1/packet/trans2/query_fs_information_level'
8
10
  require 'ruby_smb/smb1/packet/trans2/data_block'
9
11
  require 'ruby_smb/smb1/packet/trans2/subcommands'
10
12
  require 'ruby_smb/smb1/packet/trans2/request'
@@ -18,6 +20,8 @@ module RubySMB
18
20
  require 'ruby_smb/smb1/packet/trans2/find_next2_response'
19
21
  require 'ruby_smb/smb1/packet/trans2/set_file_information_request'
20
22
  require 'ruby_smb/smb1/packet/trans2/set_file_information_response'
23
+ require 'ruby_smb/smb1/packet/trans2/query_path_information_request'
24
+ require 'ruby_smb/smb1/packet/trans2/query_path_information_response'
21
25
  end
22
26
  end
23
27
  end
@@ -16,7 +16,10 @@ module RubySMB
16
16
  # The {RubySMB::SMB1::DataBlock} specific to this packet type.
17
17
  class DataBlock < RubySMB::SMB1::DataBlock
18
18
  stringz :password, label: 'Password Field', initial_value: '', length: -> { parent.parameter_block.password_length }
19
- stringz :path, label: 'Resource Path'
19
+ choice :path, selection: -> { parent.smb_header.flags2.unicode } do
20
+ stringz 0
21
+ stringz16 1
22
+ end
20
23
  stringz :service, label: 'Resource Type', initial_value: '?????'
21
24
  end
22
25
 
@@ -22,9 +22,13 @@ module RubySMB
22
22
  class EncryptionCapabilities < BinData::Record
23
23
  AES_128_CCM = 0x0001
24
24
  AES_128_GCM = 0x0002
25
+ AES_256_CCM = 0x0003
26
+ AES_256_GCM = 0x0004
25
27
  ENCRYPTION_ALGORITHM_MAP = {
26
28
  AES_128_CCM => 'AES-128-CCM',
27
- AES_128_GCM => 'AES-128-GCM'
29
+ AES_128_GCM => 'AES-128-GCM',
30
+ AES_256_CCM => 'AES-256-CCM',
31
+ AES_256_GCM => 'AES-256-GCM'
28
32
  }
29
33
 
30
34
  endian :little
@@ -99,6 +103,10 @@ module RubySMB
99
103
  SMB2_NETNAME_NEGOTIATE_CONTEXT_ID = 0x0005
100
104
  # The NegotiateContext Data field contains the transport capabilities, as specified in section 2.2.3.1.5.
101
105
  SMB2_TRANSPORT_CAPABILITIES = 0x0006
106
+ # The NegotiateContext Data field contains the RDMA transform capabilities, as specified in section 2.2.3.1.6.
107
+ SMB2_RDMA_TRANSFORM_CAPABILITIES = 0x0007
108
+ # The NegotiateContext Data field contains the signing capabilities, as specified in section 2.2.3.1.7.
109
+ SMB2_SIGNING_CAPABILITIES = 0x0008
102
110
 
103
111
  endian :little
104
112
 
@@ -112,6 +120,7 @@ module RubySMB
112
120
  compression_capabilities SMB2_COMPRESSION_CAPABILITIES, label: 'Compression Capabilities'
113
121
  netname_negotiate_context_id SMB2_NETNAME_NEGOTIATE_CONTEXT_ID, label: 'Netname Negotiate Context ID', data_length: :data_length
114
122
  transport_capabilities SMB2_TRANSPORT_CAPABILITIES, label: 'Transport Capabilities'
123
+ string :default, label: 'Unsupported Negotiating Context', read_length: :data_length
115
124
  end
116
125
 
117
126
  def pad_length
@@ -8,7 +8,7 @@ module RubySMB
8
8
  hide :reserved0
9
9
 
10
10
  endian :little
11
- bit32 :protocol, label: 'Protocol ID Field', initial_value: 0xFD534D42
11
+ bit32 :protocol, label: 'Protocol ID Field', initial_value: RubySMB::SMB2::SMB2_TRANSFORM_PROTOCOL_ID
12
12
  string :signature, label: 'Signature', length: 16
13
13
  string :nonce, label: 'Nonce', length: 16
14
14
  uint32 :original_message_size, label: 'Original Message Size'
@@ -22,13 +22,13 @@ module RubySMB
22
22
  encrypted_data = self.encrypted_data.to_ary.pack('C*')
23
23
 
24
24
  case algorithm
25
- when 'AES-128-CCM'
25
+ when 'AES-128-CCM', 'AES-256-CCM'
26
26
  cipher = OpenSSL::CCM.new('AES', key, 16)
27
27
  unencrypted_data = cipher.decrypt(encrypted_data + self.signature, self.nonce[0...11], auth_data)
28
28
  unless unencrypted_data.length > 0
29
29
  raise OpenSSL::Cipher::CipherError # raised for consistency with GCM mode
30
30
  end
31
- when 'AES-128-GCM'
31
+ when 'AES-128-GCM', 'AES-256-GCM'
32
32
  cipher = OpenSSL::Cipher.new(algorithm).decrypt
33
33
  cipher.key = key
34
34
  cipher.iv = self.nonce[0...12]
@@ -37,7 +37,7 @@ module RubySMB
37
37
  unencrypted_data = cipher.update(encrypted_data)
38
38
  cipher.final # raises OpenSSL::Cipher::CipherError on signature failure
39
39
  else
40
- raise ArgumentError.new('Invalid algorithm, must be either AES-128-CCM or AES-128-GCM')
40
+ raise ArgumentError.new('Invalid algorithm, must be one of AES-128-CCM, AES-128-GCM, AES-256-CCM, or AES-256-GCM')
41
41
  end
42
42
 
43
43
  unencrypted_data[0...self.original_message_size]
@@ -53,14 +53,14 @@ module RubySMB
53
53
  self.original_message_size.assign(unencrypted_data.length)
54
54
 
55
55
  case algorithm
56
- when 'AES-128-CCM'
56
+ when 'AES-128-CCM', 'AES-256-CCM'
57
57
  cipher = OpenSSL::CCM.new('AES', key, 16)
58
58
  random_iv = OpenSSL::Random.random_bytes(11)
59
59
  self.nonce.assign(random_iv)
60
60
  result = cipher.encrypt(unencrypted_data, random_iv, self.to_binary_s[20...52])
61
61
  encrypted_data = result[0...-16]
62
62
  auth_tag = result[-16..-1]
63
- when 'AES-128-GCM'
63
+ when 'AES-128-GCM', 'AES-256-GCM'
64
64
  cipher = OpenSSL::Cipher.new(algorithm).encrypt
65
65
  cipher.iv_len = 12
66
66
  cipher.key = key
@@ -69,7 +69,7 @@ module RubySMB
69
69
  encrypted_data = cipher.update(unencrypted_data) + cipher.final
70
70
  auth_tag = cipher.auth_tag
71
71
  else
72
- raise ArgumentError.new('Invalid algorithm, must be either AES-128-CCM or AES-128-GCM')
72
+ raise ArgumentError.new('Invalid algorithm, must be one of AES-128-CCM, AES-128-GCM, AES-256-CCM, or AES-256-GCM')
73
73
  end
74
74
 
75
75
  self.encrypted_data.assign(encrypted_data.bytes)
@@ -237,6 +237,7 @@ module RubySMB
237
237
 
238
238
  if read
239
239
  create_request.share_access.read_access = 1
240
+ create_request.desired_access.read_attr = 1
240
241
  create_request.desired_access.read_data = 1
241
242
  end
242
243
 
data/lib/ruby_smb/smb2.rb CHANGED
@@ -5,6 +5,7 @@ module RubySMB
5
5
  module SMB2
6
6
  # Protocol ID value. Translates to \xFESMB
7
7
  SMB2_PROTOCOL_ID = 0xFE534D42
8
+ SMB2_TRANSFORM_PROTOCOL_ID = 0xFD534D42
8
9
  # Wildcard revision, see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/63abf97c-0d09-47e2-88d6-6bfa552949a5
9
10
  SMB2_WILDCARD_REVISION = 0x02ff
10
11
 
@@ -1,3 +1,3 @@
1
1
  module RubySMB
2
- VERSION = '3.0.6'.freeze
2
+ VERSION = '3.1.2'.freeze
3
3
  end
@@ -962,8 +962,10 @@ RSpec.describe RubySMB::Client do
962
962
  expect(nc.length).to eq(1)
963
963
  expect(nc.first.data.ciphers).to eq(
964
964
  [
965
- RubySMB::SMB2::EncryptionCapabilities::AES_128_CCM,
966
- RubySMB::SMB2::EncryptionCapabilities::AES_128_GCM
965
+ RubySMB::SMB2::EncryptionCapabilities::AES_256_GCM,
966
+ RubySMB::SMB2::EncryptionCapabilities::AES_256_CCM,
967
+ RubySMB::SMB2::EncryptionCapabilities::AES_128_GCM,
968
+ RubySMB::SMB2::EncryptionCapabilities::AES_128_CCM
967
969
  ]
968
970
  )
969
971
  end
@@ -1277,6 +1279,9 @@ RSpec.describe RubySMB::Client do
1277
1279
  end
1278
1280
 
1279
1281
  it 'calls the backing methods' do
1282
+ request_packet = double('Request packet')
1283
+ allow(client).to receive(:negotiate_request).and_return(request_packet)
1284
+ allow(request_packet).to receive(:packet_smb_version)
1280
1285
  expect(client).to receive(:negotiate_request)
1281
1286
  expect(client).to receive(:send_recv)
1282
1287
  expect(client).to receive(:negotiate_response)
@@ -1317,14 +1322,20 @@ RSpec.describe RubySMB::Client do
1317
1322
 
1318
1323
  it 'increments the message ID' do
1319
1324
  expect(client).to receive(:smb2_message_id=).with(1)
1325
+ expect(client).to receive(:negotiate_request).twice.and_call_original
1326
+ expect(client).to receive(:parse_negotiate_response).twice do
1327
+ client.smb1 = false
1328
+ end
1320
1329
  client.negotiate
1321
1330
  end
1322
1331
 
1323
1332
  it 're-negotiates' do
1324
- expect(client).to receive(:negotiate_request).twice
1333
+ expect(client).to receive(:negotiate_request).twice.and_call_original
1325
1334
  expect(client).to receive(:send_recv).twice
1326
1335
  expect(client).to receive(:negotiate_response).twice
1327
- expect(client).to receive(:parse_negotiate_response).twice
1336
+ expect(client).to receive(:parse_negotiate_response).twice do
1337
+ client.smb1 = false
1338
+ end
1328
1339
  client.negotiate
1329
1340
  end
1330
1341
  end
@@ -2681,13 +2692,15 @@ RSpec.describe RubySMB::Client do
2681
2692
  context "with #{dialect} dialect" do
2682
2693
  before :example do
2683
2694
  client.dialect = dialect
2695
+ client.encryption_algorithm = 'AES-128-CCM'
2684
2696
  end
2685
2697
 
2686
2698
  it 'generates the client encryption key with the expected parameters' do
2687
2699
  expect(RubySMB::Crypto::KDF).to receive(:counter_mode).with(
2688
2700
  session_key,
2689
2701
  "SMB2AESCCM\x00",
2690
- "ServerIn \x00"
2702
+ "ServerIn \x00",
2703
+ {length: 128}
2691
2704
  ).and_call_original
2692
2705
  client.smb3_encrypt(data)
2693
2706
  end
@@ -2698,10 +2711,12 @@ RSpec.describe RubySMB::Client do
2698
2711
  it 'generates the client encryption key with the expected parameters' do
2699
2712
  client.preauth_integrity_hash_value = ''
2700
2713
  client.dialect = '0x0311'
2714
+ client.encryption_algorithm = 'AES-128-CCM'
2701
2715
  expect(RubySMB::Crypto::KDF).to receive(:counter_mode).with(
2702
2716
  session_key,
2703
2717
  "SMBC2SCipherKey\x00",
2704
- ''
2718
+ '',
2719
+ {length: 128}
2705
2720
  ).and_call_original
2706
2721
  client.smb3_encrypt(data)
2707
2722
  end
@@ -2723,6 +2738,7 @@ RSpec.describe RubySMB::Client do
2723
2738
 
2724
2739
  it 'generates the expected client encryption key with 0x0302 dialect' do
2725
2740
  client.dialect = '0x0302'
2741
+ client.encryption_algorithm = 'AES-128-CCM'
2726
2742
  expected_enc_key =
2727
2743
  "\xa4\xfa\x23\xc1\xb0\x65\x84\xce\x47\x08\x5b\xe0\x64\x98\xd7\x87".b
2728
2744
  client.smb3_encrypt(data)
@@ -2731,6 +2747,7 @@ RSpec.describe RubySMB::Client do
2731
2747
 
2732
2748
  it 'generates the expected client encryption key with 0x0311 dialect' do
2733
2749
  client.dialect = '0x0311'
2750
+ client.encryption_algorithm = 'AES-128-CCM'
2734
2751
  client.session_key =
2735
2752
  "\x5c\x00\x4a\x3b\xf0\xa2\x4f\x75\x4c\xb2\x74\x0a\xcf\xc4\x8e\x1a".b
2736
2753
  client.preauth_integrity_hash_value =
@@ -2765,13 +2782,15 @@ RSpec.describe RubySMB::Client do
2765
2782
  context "with #{dialect} dialect" do
2766
2783
  before :example do
2767
2784
  client.dialect = dialect
2785
+ client.encryption_algorithm = 'AES-128-CCM'
2768
2786
  end
2769
2787
 
2770
2788
  it 'generates the client encryption key with the expected parameters' do
2771
2789
  expect(RubySMB::Crypto::KDF).to receive(:counter_mode).with(
2772
2790
  session_key,
2773
2791
  "SMB2AESCCM\x00",
2774
- "ServerOut\x00"
2792
+ "ServerOut\x00",
2793
+ {length: 128}
2775
2794
  ).and_call_original
2776
2795
  client.smb3_decrypt(transform_packet)
2777
2796
  end
@@ -2782,10 +2801,12 @@ RSpec.describe RubySMB::Client do
2782
2801
  it 'generates the client encryption key with the expected parameters' do
2783
2802
  client.preauth_integrity_hash_value = ''
2784
2803
  client.dialect = '0x0311'
2804
+ client.encryption_algorithm = 'AES-128-CCM'
2785
2805
  expect(RubySMB::Crypto::KDF).to receive(:counter_mode).with(
2786
2806
  session_key,
2787
2807
  "SMBS2CCipherKey\x00",
2788
- ''
2808
+ '',
2809
+ {length: 128}
2789
2810
  ).and_call_original
2790
2811
  client.smb3_decrypt(transform_packet)
2791
2812
  end
@@ -2806,6 +2827,7 @@ RSpec.describe RubySMB::Client do
2806
2827
 
2807
2828
  it 'generates the expected server encryption key with 0x0302 dialect' do
2808
2829
  client.dialect = '0x0302'
2830
+ client.encryption_algorithm = 'AES-128-CCM'
2809
2831
  expected_enc_key =
2810
2832
  "\x65\x21\xd3\x6d\xe9\xe3\x5a\x66\x09\x61\xae\x3e\xc6\x49\x6b\xdf".b
2811
2833
  client.smb3_decrypt(transform_packet)
@@ -2814,6 +2836,7 @@ RSpec.describe RubySMB::Client do
2814
2836
 
2815
2837
  it 'generates the expected server encryption key with 0x0311 dialect' do
2816
2838
  client.dialect = '0x0311'
2839
+ client.encryption_algorithm = 'AES-128-CCM'
2817
2840
  client.session_key =
2818
2841
  "\x5c\x00\x4a\x3b\xf0\xa2\x4f\x75\x4c\xb2\x74\x0a\xcf\xc4\x8e\x1a".b
2819
2842
  client.preauth_integrity_hash_value =
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Fscc::FileInformation::FileAccessInformation do
4
+ it 'references the correct class level' do
5
+ expect(described_class).to be_const_defined(:CLASS_LEVEL)
6
+ expect(described_class::CLASS_LEVEL).to be RubySMB::Fscc::FileInformation::FILE_ACCESS_INFORMATION
7
+ end
8
+
9
+ subject(:struct) { described_class.new }
10
+
11
+ it { should respond_to :access_flags }
12
+
13
+ it 'is little endian' do
14
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
15
+ end
16
+
17
+ it 'tracks the access flags in a Uint32 field' do
18
+ expect(struct.access_flags).to be_a BinData::Uint32le
19
+ end
20
+
21
+ end