ruby_smb 3.0.6 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4dd0be012c18ad4e243cbfa2948fc620448766612b2f33be278583981fa2cf90
4
- data.tar.gz: '07309ce54e701f2c3654a9cdbc8b3eff9d42d54451321e6e17a49d46ae4ce162'
3
+ metadata.gz: 498d32e1eeed4cb410f03dfdc5ea1b23dd5506d89e387a3533494b9f73294ffa
4
+ data.tar.gz: 838a864709be049725a3978de10d71a0cf9eb75e91d00468cdee07fc5e614250
5
5
  SHA512:
6
- metadata.gz: ee506f05e67f8fa1a61b0d0f05470b41e20c5972c9c9584e8fe8069352a2cd09704b66d42856fb1330a93def276525b0d50047e93b981479c064c36f35f8298a
7
- data.tar.gz: 78c37f1157393e17c51a6de7ff55fb25206e84f68740c958c406c36432ca90bc572716670640b9153a3ff66247dfcbeae8f4305f3c17cd91af64e8a4fc092894
6
+ metadata.gz: e60651395300c2f7bc88049e7572a2b5376646615da08a1978d8e71afe694ca2f32396e124cbda71cc203811ff8df0241aa072f58aeffa8265498789cab7696f
7
+ data.tar.gz: e9d3bd5ffb781a01e4382d8f0f2327cd384d4be520a394fbf00336fbc23b9913fae58b380c05c1782c320364edd8ac5e729639091c0f54b32208469972810705
checksums.yaml.gz.sig CHANGED
Binary file
@@ -10,6 +10,7 @@ Encoding.default_internal = 'UTF-8' if Encoding.default_internal.nil?
10
10
 
11
11
  options = {
12
12
  allow_anonymous: true,
13
+ allow_guests: false,
13
14
  domain: nil,
14
15
  username: 'RubySMB',
15
16
  password: 'password',
@@ -39,6 +40,9 @@ OptionParser.new do |opts|
39
40
  opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
40
41
  options[:smbv3] = smbv3
41
42
  end
43
+ opts.on("--[no-]guests", "Allow guest accounts (default: #{options[:allow_guests]})") do |allow_guests|
44
+ options[:allow_guests] = allow_guests
45
+ end
42
46
  opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
43
47
  if username.include?('\\')
44
48
  options[:domain], options[:username] = username.split('\\', 2)
@@ -51,7 +55,10 @@ OptionParser.new do |opts|
51
55
  end
52
56
  end.parse!
53
57
 
54
- ntlm_provider = RubySMB::Gss::Provider::NTLM.new(allow_anonymous: options[:allow_anonymous])
58
+ ntlm_provider = RubySMB::Gss::Provider::NTLM.new(
59
+ allow_anonymous: options[:allow_anonymous],
60
+ allow_guests: options[:allow_guests]
61
+ )
55
62
  ntlm_provider.put_account(options[:username], options[:password], domain: options[:domain]) # password can also be an NTLM hash
56
63
 
57
64
  server = RubySMB::Server.new(
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'optparse'
5
+ require 'ruby_smb'
6
+ require 'ruby_smb/gss/provider/ntlm'
7
+
8
+ # we just need *a* default encoding to handle the strings from the NTLM messages
9
+ Encoding.default_internal = 'UTF-8' if Encoding.default_internal.nil?
10
+
11
+ # see: https://en.wikipedia.org/wiki/Magic_8-ball#Possible_answers
12
+ MAGIC_8_BALL_ANSWERS = [
13
+ 'It is certain.',
14
+ 'It is decidedly so.',
15
+ 'Without a doubt.',
16
+ 'Yes definitely.',
17
+ 'You may rely on it.',
18
+ 'As I see it, yes.',
19
+ 'Most likely.',
20
+ 'Outlook good.',
21
+ 'Yes.',
22
+ 'Signs point to yes.',
23
+ 'Reply hazy, try again.',
24
+ 'Ask again later.',
25
+ 'Better not tell you now.',
26
+ 'Cannot predict now.',
27
+ 'Concentrate and ask again.',
28
+ 'Don\'t count on it.',
29
+ 'My reply is no.',
30
+ 'My sources say no.',
31
+ 'Outlook not so good.',
32
+ 'Very doubtful'
33
+ ]
34
+
35
+ options = {
36
+ allow_anonymous: true,
37
+ domain: nil,
38
+ username: 'RubySMB',
39
+ password: 'password',
40
+ share_name: 'home',
41
+ smbv1: true,
42
+ smbv2: true,
43
+ smbv3: true
44
+ }
45
+ OptionParser.new do |opts|
46
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
47
+ opts.on("--share SHARE", "The share name (default: #{options[:share_name]})") do |share|
48
+ options[:share_name] = share
49
+ end
50
+ opts.on("--[no-]anonymous", "Allow anonymous access (default: #{options[:allow_anonymous]})") do |allow_anonymous|
51
+ options[:allow_anonymous] = allow_anonymous
52
+ end
53
+ opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
54
+ options[:smbv1] = smbv1
55
+ end
56
+ opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
57
+ options[:smbv2] = smbv2
58
+ end
59
+ opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
60
+ options[:smbv3] = smbv3
61
+ end
62
+ opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
63
+ if username.include?('\\')
64
+ options[:domain], options[:username] = username.split('\\', 2)
65
+ else
66
+ options[:username] = username
67
+ end
68
+ end
69
+ opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
70
+ options[:password] = password
71
+ end
72
+ opts.on("--virtual-content CONTENT", "The virtual share contents") do |virtual_content|
73
+ options[:virtual_content] = virtual_content
74
+ end
75
+ opts.on("--virtual-name NAME", "The virtual share file name") do |virtual_name|
76
+ options[:virtual_name] = virtual_name
77
+ end
78
+ opts.on("--virtual-type TYPE", "The virtual share type") do |virtual_type|
79
+ options[:virtual_type] = virtual_type
80
+ end
81
+ end.parse!
82
+
83
+ ntlm_provider = RubySMB::Gss::Provider::NTLM.new(allow_anonymous: options[:allow_anonymous])
84
+ ntlm_provider.put_account(options[:username], options[:password], domain: options[:domain]) # password can also be an NTLM hash
85
+
86
+ server = RubySMB::Server.new(
87
+ gss_provider: ntlm_provider,
88
+ logger: :stdout
89
+ )
90
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB1 } unless options[:smbv1]
91
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB2 } unless options[:smbv2]
92
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB3 } unless options[:smbv3]
93
+
94
+ if server.dialects.empty?
95
+ puts "at least one version must be enabled"
96
+ exit false
97
+ end
98
+
99
+ virtual_disk = RubySMB::Server::Share::Provider::VirtualDisk.new(options[:share_name])
100
+
101
+ # greeting is a static text file
102
+ virtual_disk.add_static_file('greeting', 'Hello World!')
103
+
104
+ # self is this example file, it's read when it's added and its #stat object is copied over
105
+ virtual_disk.add_static_file('self/static', File.open(__FILE__))
106
+
107
+ # self is this example file, it's mapped in using a real Pathname object
108
+ virtual_disk.add_mapped_file('self/mapped', Pathname.new(File.expand_path(__FILE__)))
109
+
110
+ # magic_8_ball is a dynamic file that is generated each time it is open
111
+ virtual_disk.add_dynamic_file('magic_8_ball') do
112
+ MAGIC_8_BALL_ANSWERS.sample
113
+ end
114
+
115
+ if options[:virtual_content] && options[:virtual_name] && options[:virtual_type]
116
+ case options[:virtual_type].downcase
117
+ when 'static'
118
+ # for static, content is left as is
119
+ virtual_disk.add_static_file(options[:virtual_name], options[:virtual_content])
120
+ when 'mapped'
121
+ # for mapped, content is a file path
122
+ virtual_disk.add_mapped_file(options[:virtual_name], Pathname.new(File.expand_path(options[:virtual_content])))
123
+ when 'dynamic'
124
+ # for dynamic, content is a file path
125
+ virtual_disk.add_dynamic_file(options[:virtual_name]) do
126
+ File.read(options[:virtual_content])
127
+ end
128
+ else
129
+ puts "virtual type: #{options[:virtual_type]}, must be one of static, mapped, or dynamic"
130
+ exit false
131
+ end
132
+ elsif options[:virtual_content] || options[:virtual_name] || options[:virtual_type]
133
+ puts 'the --virtual-* flags are only used when all are specified'
134
+ exit false
135
+ end
136
+
137
+ server.add_share(virtual_disk)
138
+ puts "server is running"
139
+ server.run do |server_client|
140
+ puts "received connection"
141
+ true
142
+ end
143
+
@@ -4,18 +4,24 @@ module RubySMB
4
4
  module Encryption
5
5
  def smb3_encrypt(data)
6
6
  unless @client_encryption_key
7
+ raise RubySMB::Error::EncryptionError.new('The encryption algorithm has not been set') if @encryption_algorithm.nil?
8
+
9
+ key_bit_len = OpenSSL::Cipher.new(@encryption_algorithm).key_len * 8
10
+
7
11
  case @dialect
8
12
  when '0x0300', '0x0302'
9
13
  @client_encryption_key = RubySMB::Crypto::KDF.counter_mode(
10
14
  @session_key,
11
15
  "SMB2AESCCM\x00",
12
- "ServerIn \x00"
16
+ "ServerIn \x00",
17
+ length: key_bit_len
13
18
  )
14
19
  when '0x0311'
15
20
  @client_encryption_key = RubySMB::Crypto::KDF.counter_mode(
16
21
  @session_key,
17
22
  "SMBC2SCipherKey\x00",
18
- @preauth_integrity_hash_value
23
+ @preauth_integrity_hash_value,
24
+ length: key_bit_len
19
25
  )
20
26
  else
21
27
  raise RubySMB::Error::EncryptionError.new('Dialect is incompatible with SMBv3 encryption')
@@ -33,18 +39,24 @@ module RubySMB
33
39
 
34
40
  def smb3_decrypt(th)
35
41
  unless @server_encryption_key
42
+ raise RubySMB::Error::EncryptionError.new('The encryption algorithm has not been set') if @encryption_algorithm.nil?
43
+
44
+ key_bit_len = OpenSSL::Cipher.new(@encryption_algorithm).key_len * 8
45
+
36
46
  case @dialect
37
47
  when '0x0300', '0x0302'
38
48
  @server_encryption_key = RubySMB::Crypto::KDF.counter_mode(
39
49
  @session_key,
40
50
  "SMB2AESCCM\x00",
41
- "ServerOut\x00"
51
+ "ServerOut\x00",
52
+ length: key_bit_len
42
53
  )
43
54
  when '0x0311'
44
55
  @server_encryption_key = RubySMB::Crypto::KDF.counter_mode(
45
56
  @session_key,
46
57
  "SMBS2CCipherKey\x00",
47
- @preauth_integrity_hash_value
58
+ @preauth_integrity_hash_value,
59
+ length: key_bit_len
48
60
  )
49
61
  else
50
62
  raise RubySMB::Error::EncryptionError.new('Dialect is incompatible with SMBv3 decryption')
@@ -5,7 +5,7 @@ module RubySMB
5
5
  module Negotiation
6
6
  # Handles the entire SMB Multi-Protocol Negotiation from the
7
7
  # Client to the Server. It sets state on the client appropriate
8
- # to the protocol and capabilites negotiated during the exchange.
8
+ # to the protocol and capabilities negotiated during the exchange.
9
9
  # It also keeps track of the negotiated dialect.
10
10
  #
11
11
  # @return [void]
@@ -23,13 +23,13 @@ module RubySMB
23
23
  update_preauth_hash(response_packet)
24
24
  end
25
25
 
26
- # If the response contains the SMB2 wildcard revision number dialect;
27
- # it indicates that the server implements SMB 2.1 or future dialect
28
- # revisions and expects the client to send a subsequent SMB2 Negotiate
29
- # request to negotiate the actual SMB 2 Protocol revision to be used.
30
- # The wildcard revision number is sent only in response to a
26
+ # If the response contains an SMB2 dialect and the request was SMB1;
27
+ # it indicates that the server supports SMB2 and wants to upgrade the
28
+ # connection. The server expects the client to send a subsequent SMB2
29
+ # Negotiate request to negotiate the actual SMB 2 Protocol revision to
30
+ # be used. The wildcard revision number is sent only in response to a
31
31
  # multi-protocol negotiate request with the "SMB 2.???" dialect string.
32
- if @dialect == '0x02ff'
32
+ if request_packet.packet_smb_version == 'SMB1' && RubySMB::Dialect[@dialect]&.order == RubySMB::Dialect::ORDER_SMB2
33
33
  self.smb2_message_id += 1
34
34
  version = negotiate
35
35
  end
@@ -265,8 +265,10 @@ module RubySMB
265
265
  nc = RubySMB::SMB2::NegotiateContext.new(
266
266
  context_type: RubySMB::SMB2::NegotiateContext::SMB2_ENCRYPTION_CAPABILITIES
267
267
  )
268
- nc.data.ciphers << RubySMB::SMB2::EncryptionCapabilities::AES_128_CCM
268
+ nc.data.ciphers << RubySMB::SMB2::EncryptionCapabilities::AES_256_GCM
269
+ nc.data.ciphers << RubySMB::SMB2::EncryptionCapabilities::AES_256_CCM
269
270
  nc.data.ciphers << RubySMB::SMB2::EncryptionCapabilities::AES_128_GCM
271
+ nc.data.ciphers << RubySMB::SMB2::EncryptionCapabilities::AES_128_CCM
270
272
  packet.add_negotiate_context(nc)
271
273
 
272
274
  nc = RubySMB::SMB2::NegotiateContext.new(
@@ -0,0 +1,15 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileAccessInformation Class as defined in
5
+ # [2.4.1 FileAccessInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/01cf43d2-deb3-40d3-a39b-9e68693d7c90)
6
+ class FileAccessInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_ACCESS_INFORMATION
8
+
9
+ endian :little
10
+
11
+ uint32 :access_flags, label: 'Access Flags'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,45 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileAlignmentInformation Class as defined in
5
+ # [2.4.3 FileAlignmentInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/9b0b9971-85aa-4651-8438-f1c4298bcb0d)
6
+ class FileAlignmentInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_ALIGNMENT_INFORMATION
8
+
9
+ # If this value is specified, there are no alignment requirements for the device.
10
+ FILE_BYTE_ALIGNMENT = 0x00000000 # 0
11
+
12
+ # If this value is specified, data MUST be aligned on a 2-byte boundary.
13
+ FILE_WORD_ALIGNMENT = 0x00000001 # 1
14
+
15
+ # If this value is specified, data MUST be aligned on a 4-byte boundary.
16
+ FILE_LONG_ALIGNMENT = 0x00000003 # 3
17
+
18
+ # If this value is specified, data MUST be aligned on an 8-byte boundary.
19
+ FILE_QUAD_ALIGNMENT = 0x00000007 # 7
20
+
21
+ # If this value is specified, data MUST be aligned on a 16-byte boundary.
22
+ FILE_OCTA_ALIGNMENT = 0X0000000F # 15
23
+
24
+ # If this value is specified, data MUST be aligned on a 32-byte boundary.
25
+ FILE_32_BYTE_ALIGNMENT = 0X0000001F # 31
26
+
27
+ # If this value is specified, data MUST be aligned on a 64-byte boundary.
28
+ FILE_64_BYTE_ALIGNMENT = 0X0000003F # 63
29
+
30
+ # If this value is specified, data MUST be aligned on a 128-byte boundary.
31
+ FILE_128_BYTE_ALIGNMENT = 0X0000007F # 127
32
+
33
+ # If this value is specified, data MUST be aligned on a 256-byte boundary.
34
+ FILE_256_BYTE_ALIGNMENT = 0X000000FF # 255
35
+
36
+ # If this value is specified, data MUST be aligned on a 512-byte boundary.
37
+ FILE_512_BYTE_ALIGNMENT = 0X000001FF # 511
38
+
39
+ endian :little
40
+
41
+ uint32 :alignment_requirement, label: 'Alignment Requirement', initial_value: FILE_BYTE_ALIGNMENT
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileAllInformation Class as defined in
5
+ # [2.4.2 FileAllInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/95f3056a-ebc1-4f5d-b938-3f68a44677a6)
6
+ class FileAllInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_ALL_INFORMATION
8
+
9
+ endian :little
10
+
11
+ file_basic_information :basic_information, label: 'Basic Information'
12
+ file_standard_information :standard_information, label: 'Standard Information'
13
+ file_internal_information :internal_information, label: 'Internal Information'
14
+ file_ea_information :ea_information, label: 'EA Information'
15
+ file_access_information :access_information, label: 'Access Information'
16
+ file_position_information :position_information, label: 'Position Information'
17
+ file_mode_information :mode_information, label: 'Mode Information'
18
+ file_alignment_information :alignment_information, label: 'Alignment Information'
19
+ file_name_information :name_information, label: 'Name Information'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileBasicInformation Class as defined in
5
+ # [2.4.7 FileBasicInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/16023025-8a78-492f-8b96-c873b042ac50)
6
+ class FileBasicInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_BASIC_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
+ file_attributes :file_attributes, label: 'File Attributes'
16
+ string :reserved, label: 'Reserved', length: 4
17
+ end
18
+ end
19
+ end
20
+ end
@@ -2,7 +2,7 @@ module RubySMB
2
2
  module Fscc
3
3
  module FileInformation
4
4
  # The FileBothDirectoryInformation Class as defined in
5
- # [2.4.8 FileBothDirectoryInformation](https://msdn.microsoft.com/en-us/library/cc232095.aspx)
5
+ # [2.4.8 FileBothDirectoryInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/270df317-9ba5-4ccb-ba00-8d22be139bc5)
6
6
  class FileBothDirectoryInformation < BinData::Record
7
7
  CLASS_LEVEL = FileInformation::FILE_BOTH_DIRECTORY_INFORMATION
8
8
 
@@ -14,8 +14,8 @@ module RubySMB
14
14
  file_time :last_access, label: 'Last Accessed Time'
15
15
  file_time :last_write, label: 'Last Write Time'
16
16
  file_time :last_change, label: 'Last Modified Time'
17
- uint64 :end_of_file, label: 'End of File'
18
- uint64 :allocation_size, label: 'Allocated Size'
17
+ int64 :end_of_file, label: 'End of File'
18
+ int64 :allocation_size, label: 'Allocated Size'
19
19
  file_attributes :file_attributes, label: 'File Attributes'
20
20
  uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
21
21
  uint32 :ea_size, label: 'Extended Attributes Size'
@@ -2,7 +2,7 @@ module RubySMB
2
2
  module Fscc
3
3
  module FileInformation
4
4
  # The FileDirectoryInformation Class as defined in
5
- # [2.4.10 FileDirectoryInformation](https://msdn.microsoft.com/en-us/library/cc232097.aspx)
5
+ # [2.4.10 FileDirectoryInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/b38bf518-9057-4c88-9ddd-5e2d3976a64b)
6
6
  class FileDirectoryInformation < BinData::Record
7
7
  CLASS_LEVEL = FileInformation::FILE_DIRECTORY_INFORMATION
8
8
 
@@ -14,8 +14,8 @@ module RubySMB
14
14
  file_time :last_access, label: 'Last Accessed Time'
15
15
  file_time :last_write, label: 'Last Write Time'
16
16
  file_time :last_change, label: 'Last Modified Time'
17
- uint64 :end_of_file, label: 'End of File'
18
- uint64 :allocation_size, label: 'Allocated Size'
17
+ int64 :end_of_file, label: 'End of File'
18
+ int64 :allocation_size, label: 'Allocated Size'
19
19
  file_attributes :file_attributes, label: 'File Attributes'
20
20
  uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
21
21
  string16 :file_name, label: 'File Name', read_length: -> { file_name_length }
@@ -7,6 +7,7 @@ module RubySMB
7
7
  CLASS_LEVEL = FileInformation::FILE_EA_INFORMATION
8
8
 
9
9
  endian :little
10
+
10
11
  uint32 :ea_size, label: 'Extended Attributes Size'
11
12
  end
12
13
  end
@@ -2,7 +2,7 @@ module RubySMB
2
2
  module Fscc
3
3
  module FileInformation
4
4
  # The FileFullDirectoryInformation Class as defined in
5
- # [2.4.14 FileFullDirectoryInformation](https://msdn.microsoft.com/en-us/library/cc232068.aspx)
5
+ # [2.4.14 FileFullDirectoryInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/e8d926d1-3a22-4654-be9c-58317a85540b)
6
6
  class FileFullDirectoryInformation < BinData::Record
7
7
  CLASS_LEVEL = FileInformation::FILE_FULL_DIRECTORY_INFORMATION
8
8
 
@@ -14,8 +14,8 @@ module RubySMB
14
14
  file_time :last_access, label: 'Last Accessed Time'
15
15
  file_time :last_write, label: 'Last Write Time'
16
16
  file_time :last_change, label: 'Last Modified Time'
17
- uint64 :end_of_file, label: 'End of File'
18
- uint64 :allocation_size, label: 'Allocated Size'
17
+ int64 :end_of_file, label: 'End of File'
18
+ int64 :allocation_size, label: 'Allocated Size'
19
19
  file_attributes :file_attributes, label: 'File Attributes'
20
20
  uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
21
21
  uint32 :ea_size, label: 'Extended Attributes Size'
@@ -14,8 +14,8 @@ module RubySMB
14
14
  file_time :last_access, label: 'Last Accessed Time'
15
15
  file_time :last_write, label: 'Last Write Time'
16
16
  file_time :last_change, label: 'Last Modified Time'
17
- uint64 :end_of_file, label: 'End of File'
18
- uint64 :allocation_size, label: 'Allocated Size'
17
+ int64 :end_of_file, label: 'End of File'
18
+ int64 :allocation_size, label: 'Allocated Size'
19
19
  file_attributes :file_attributes, label: 'File Attributes'
20
20
  uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
21
21
  uint32 :ea_size, label: 'Extended Attributes Size'
@@ -23,7 +23,7 @@ module RubySMB
23
23
  uint8 :reserved, label: 'Reserved Space'
24
24
  string16 :short_name, label: 'File Short Name', length: 24
25
25
  uint16 :reserved2, label: 'Reserved Space'
26
- uint64 :file_id, label: 'File Id'
26
+ uint64 :file_id, label: 'File ID'
27
27
  string16 :file_name, label: 'File Name', read_length: -> { file_name_length }
28
28
  end
29
29
  end
@@ -2,7 +2,7 @@ module RubySMB
2
2
  module Fscc
3
3
  module FileInformation
4
4
  # The FileIdDirectoryInformation Class as defined in
5
- # [2.4.18 FileIdFullDirectoryInformation](https://msdn.microsoft.com/en-us/library/cc232071.aspx)
5
+ # [2.4.18 FileIdFullDirectoryInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ab8e7558-899c-4be1-a7c5-3a9ae8ab76a0)
6
6
  class FileIdFullDirectoryInformation < BinData::Record
7
7
  CLASS_LEVEL = FileInformation::FILE_ID_FULL_DIRECTORY_INFORMATION
8
8
 
@@ -14,8 +14,8 @@ module RubySMB
14
14
  file_time :last_access, label: 'Last Accessed Time'
15
15
  file_time :last_write, label: 'Last Write Time'
16
16
  file_time :last_change, label: 'Last Modified Time'
17
- uint64 :end_of_file, label: 'End of File'
18
- uint64 :allocation_size, label: 'Allocated Size'
17
+ int64 :end_of_file, label: 'End of File'
18
+ int64 :allocation_size, label: 'Allocated Size'
19
19
  file_attributes :file_attributes, label: 'File Attributes'
20
20
  uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
21
21
  uint32 :ea_size, label: 'Extended Attributes Size'
@@ -0,0 +1,15 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileInternalInformation Class as defined in
5
+ # [2.4.22 FileInternalInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/7d796611-2fa5-41ac-8178-b6fea3a017b3)
6
+ class FileInternalInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_INTERNAL_INFORMATION
8
+
9
+ endian :little
10
+
11
+ uint64 :file_id, label: 'File ID'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileModeInformation Class as defined in
5
+ # [2.4.26 FileModeInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/52df7798-8330-474b-ac31-9afe8075640c)
6
+ class FileModeInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_MODE_INFORMATION
8
+
9
+ endian :little
10
+
11
+ struct :flags do
12
+ bit2 :reserved
13
+ bit1 :file_synchronous_io_nonalert, label: 'File Synchronous IO Nonalert'
14
+ bit1 :file_synchronous_io_alert, label: 'File Synchronous IO Alert'
15
+ bit1 :file_no_intermediate_buffering, label: 'File No Intermediate Buffering'
16
+ bit1 :file_sequential_only, label: 'File Sequential Only'
17
+ bit1 :file_write_through, label: 'File Write Through'
18
+ bit1 :reserved2
19
+ # byte boundary
20
+ bit3 :reserved3
21
+ bit1 :file_delete_on_close, label: 'File Delete On Close'
22
+ bit4 :reserved4
23
+ # byte boundary
24
+ bit16 :reserved5
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileNameInformation Class as defined in
5
+ # [2.4.27 FileNameInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/cb30e415-54c5-4483-a346-822ea90e1e89)
6
+ class FileNameInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_NAME_INFORMATION
8
+
9
+ endian :little
10
+
11
+ uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
12
+ string16 :file_name, label: 'File Name', read_length: -> { file_name_length }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,7 +2,7 @@ module RubySMB
2
2
  module Fscc
3
3
  module FileInformation
4
4
  # The FileNamesInformation Class as defined in
5
- # [2.4.26 FileNamesInformation](https://msdn.microsoft.com/en-us/library/cc232077.aspx)
5
+ # [2.4.28 FileNamesInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/a289f7a8-83d2-4927-8c88-b2d328dde5a5)
6
6
  class FileNamesInformation < BinData::Record
7
7
  CLASS_LEVEL = FileInformation::FILE_NAMES_INFORMATION
8
8
 
@@ -0,0 +1,16 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileNormalizedNameInformation Class as defined in
5
+ # [2.4.30 FileNormalizedNameInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/20bcadba-808c-4880-b757-4af93e41edf6)
6
+ class FileNormalizedNameInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_NORMALIZED_NAME_INFORMATION
8
+
9
+ endian :little
10
+
11
+ uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
12
+ string16 :file_name, label: 'File Name', read_length: -> { file_name_length }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FilePositionInformation Class as defined in
5
+ # [2.4.35 FilePositionInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/e3ce4a39-327e-495c-99b6-6b61606b6f16)
6
+ class FilePositionInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_POSITION_INFORMATION
8
+
9
+ endian :little
10
+
11
+ int64 :current_byte_offset, label: 'Current Byte Offset'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -4,7 +4,7 @@ module RubySMB
4
4
  # The FileRenameInformation Class as defined in
5
5
  # [2.4.34.2 FileRenameInformation](https://msdn.microsoft.com/en-us/library/cc704597.aspx)
6
6
  class FileRenameInformation < BinData::Record
7
- CLASS_LEVEL = FileInformation::FILE_ID_FULL_DIRECTORY_INFORMATION
7
+ CLASS_LEVEL = FileInformation::FILE_RENAME_INFORMATION
8
8
 
9
9
  endian :little
10
10
 
@@ -0,0 +1,20 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileStandardInformation Class as defined in
5
+ # [2.4.41 FileStandardInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/5afa7f66-619c-48f3-955f-68c4ece704ae)
6
+ class FileStandardInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_STANDARD_INFORMATION
8
+
9
+ endian :little
10
+
11
+ int64 :allocation_size, label: 'Allocation Size'
12
+ int64 :end_of_file, label: 'End of File'
13
+ uint32 :number_of_links, label: 'Number of Links'
14
+ int8 :delete_pending, label: 'Delete Pending'
15
+ int8 :directory, label: 'Directory'
16
+ string :reserved, label: 'Reserved', length: 2
17
+ end
18
+ end
19
+ end
20
+ end