ruby_smb 0.0.12 → 0.0.13

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 (97) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -2
  3. data/lib/ruby_smb/client/authentication.rb +1 -1
  4. data/lib/ruby_smb/client/echo.rb +36 -0
  5. data/lib/ruby_smb/client/tree_connect.rb +1 -1
  6. data/lib/ruby_smb/client.rb +17 -0
  7. data/lib/ruby_smb/dispatcher/socket.rb +21 -14
  8. data/lib/ruby_smb/error.rb +3 -0
  9. data/lib/ruby_smb/field/ea_info_array.rb +58 -0
  10. data/lib/ruby_smb/field/extended_attribute_flag.rb +10 -0
  11. data/lib/ruby_smb/field/file_full_ea_info.rb +15 -0
  12. data/lib/ruby_smb/field/security_descriptor.rb +42 -0
  13. data/lib/ruby_smb/field/smb_fea.rb +14 -0
  14. data/lib/ruby_smb/field/smb_fea_list.rb +13 -0
  15. data/lib/ruby_smb/field/utime.rb +54 -0
  16. data/lib/ruby_smb/field.rb +7 -0
  17. data/lib/ruby_smb/generic_packet.rb +8 -4
  18. data/lib/ruby_smb/impersonation_levels.rb +22 -0
  19. data/lib/ruby_smb/smb1/bit_field/create_options.rb +38 -0
  20. data/lib/ruby_smb/smb1/bit_field/file_access_mask.rb +1 -1
  21. data/lib/ruby_smb/smb1/bit_field/open2_access_mode.rb +42 -0
  22. data/lib/ruby_smb/smb1/bit_field/open2_flags.rb +18 -0
  23. data/lib/ruby_smb/smb1/bit_field/open2_open_mode.rb +17 -0
  24. data/lib/ruby_smb/smb1/bit_field/share_access.rb +20 -0
  25. data/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes.rb +35 -0
  26. data/lib/ruby_smb/smb1/bit_field/smb_file_attributes.rb +26 -0
  27. data/lib/ruby_smb/smb1/bit_field/smb_nmpipe_status.rb +19 -0
  28. data/lib/ruby_smb/smb1/bit_field/trans2_flags.rb +15 -0
  29. data/lib/ruby_smb/smb1/bit_field.rb +9 -0
  30. data/lib/ruby_smb/smb1/commands.rb +10 -6
  31. data/lib/ruby_smb/smb1/create_actions.rb +22 -0
  32. data/lib/ruby_smb/smb1/dispositions.rb +36 -0
  33. data/lib/ruby_smb/smb1/oplock_levels.rb +19 -0
  34. data/lib/ruby_smb/smb1/packet/echo_request.rb +30 -0
  35. data/lib/ruby_smb/smb1/packet/echo_response.rb +31 -0
  36. data/lib/ruby_smb/smb1/packet/empty_packet.rb +14 -0
  37. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +85 -0
  38. data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +61 -0
  39. data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +47 -0
  40. data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +44 -0
  41. data/lib/ruby_smb/smb1/packet/nt_trans/subcommands.rb +11 -0
  42. data/lib/ruby_smb/smb1/packet/nt_trans.rb +16 -0
  43. data/lib/ruby_smb/smb1/packet/trans2/data_block.rb +32 -0
  44. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +60 -0
  45. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +65 -0
  46. data/lib/ruby_smb/smb1/packet/trans2/request.rb +52 -0
  47. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +39 -0
  48. data/lib/ruby_smb/smb1/packet/trans2/response.rb +48 -0
  49. data/lib/ruby_smb/smb1/packet/trans2/subcommands.rb +12 -0
  50. data/lib/ruby_smb/smb1/packet/trans2.rb +18 -0
  51. data/lib/ruby_smb/smb1/packet.rb +5 -1
  52. data/lib/ruby_smb/smb1.rb +3 -0
  53. data/lib/ruby_smb/smb2/bit_field/{share_capabailities.rb → share_capabilities.rb} +0 -0
  54. data/lib/ruby_smb/smb2/bit_field/{smb2_capabailities.rb → smb2_capabilities.rb} +0 -0
  55. data/lib/ruby_smb/smb2/bit_field.rb +2 -2
  56. data/lib/ruby_smb/smb2/packet/echo_request.rb +21 -0
  57. data/lib/ruby_smb/smb2/packet/echo_response.rb +22 -0
  58. data/lib/ruby_smb/smb2/packet.rb +2 -0
  59. data/lib/ruby_smb/version.rb +1 -1
  60. data/ruby_smb.gemspec +2 -0
  61. data/spec/lib/ruby_smb/client_spec.rb +46 -0
  62. data/spec/lib/ruby_smb/field/ea_info_array_spec.rb +51 -0
  63. data/spec/lib/ruby_smb/field/extended_attribute_flag_spec.rb +16 -0
  64. data/spec/lib/ruby_smb/field/file_full_ea_info_spec.rb +35 -0
  65. data/spec/lib/ruby_smb/field/security_descriptor.rb +194 -0
  66. data/spec/lib/ruby_smb/field/smb_fea_list_spec.rb +38 -0
  67. data/spec/lib/ruby_smb/field/smb_fea_spec.rb +27 -0
  68. data/spec/lib/ruby_smb/field/utime_spec.rb +59 -0
  69. data/spec/lib/ruby_smb/smb1/bit_field/create_options_spec.rb +181 -0
  70. data/spec/lib/ruby_smb/smb1/bit_field/open2_access_mode_spec.rb +81 -0
  71. data/spec/lib/ruby_smb/smb1/bit_field/open2_flags_spec.rb +62 -0
  72. data/spec/lib/ruby_smb/smb1/bit_field/open2_open_mode_spec.rb +27 -0
  73. data/spec/lib/ruby_smb/smb1/bit_field/share_access_spec.rb +38 -0
  74. data/spec/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes_spec.rb +144 -0
  75. data/spec/lib/ruby_smb/smb1/bit_field/smb_file_attributes_spec.rb +113 -0
  76. data/spec/lib/ruby_smb/smb1/bit_field/smb_nmpipe_status_spec.rb +53 -0
  77. data/spec/lib/ruby_smb/smb1/bit_field/trans2_flags_spec.rb +28 -0
  78. data/spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb +44 -0
  79. data/spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb +44 -0
  80. data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +1 -1
  81. data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_request_spec.rb +194 -0
  82. data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_response_spec.rb +124 -0
  83. data/spec/lib/ruby_smb/smb1/packet/nt_trans/request_spec.rb +91 -0
  84. data/spec/lib/ruby_smb/smb1/packet/nt_trans/response_spec.rb +75 -0
  85. data/spec/lib/ruby_smb/smb1/packet/trans2/open2_request_spec.rb +112 -0
  86. data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +107 -0
  87. data/spec/lib/ruby_smb/smb1/packet/trans2/request_secondary_spec.rb +77 -0
  88. data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +98 -0
  89. data/spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb +88 -0
  90. data/spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb +30 -0
  91. data/spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb +30 -0
  92. data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +1 -1
  93. data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +1 -1
  94. data.tar.gz.sig +0 -0
  95. metadata +104 -7
  96. metadata.gz.sig +0 -0
  97. data/lib/ruby_smb/smb1/packet/error_packet.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: feeacf1f58c3116642f6235922092fe0bf6e20d1
4
- data.tar.gz: 7297da083b1e96ae1285fa5108dd8681b2bf7afe
3
+ metadata.gz: e599cfd32ed2eef3ec64db3aeef90291f419a8cd
4
+ data.tar.gz: 31069aa5863e82e9a681300863f22aa8d3fa9a00
5
5
  SHA512:
6
- metadata.gz: 1c77ee63edd56e399c014b16a11536009a4bad9d0db2e5bbe77d0be8918157a5520030ee98d87dfb410381e467ad282f3c93c2f4b4f9ddb809967fbbeadec86f
7
- data.tar.gz: 76111bb45b72c3f817206e946ba226aa030247f957604361b96821c0c3975c8e4e8b9c29cd5f26b81a5f27d1c5095064ebe48c958197d6eaf3e99238a3a7cc5d
6
+ metadata.gz: bacd65cd70045c29a402f6d81b9002ff63797203963929e96175466416700a73bbf761bd274902985e6bb0c901124b90740c3accb30d19b14e99e438eda6704a
7
+ data.tar.gz: b022e98f38ec3e9962b14dc2428f454405eb367205f0a32844a747988818d7c87732162cd1aa0581ad4ae2e93d09329ee76fc43a776df2fbe0f8556501f79c48
checksums.yaml.gz.sig CHANGED
@@ -1,2 +1 @@
1
- wD�����$�>�օ6���*Aq����R^�q���AB=N���xs5 �O�V�T�-苲 �mon��}i�����+�f��������~��9�)���b3�
2
- e� F"> E��U��IQ�;�$����ท�ϐ%���JE���@�U�.���֏��PH<��ÕF���S�v�F����9?hz�_I��^�� BH�/&��d�ٕvLu��) 4����8�of�ǝ�Œ����"�[2��}�t�Zy�ftf�U���Xփ
1
+ lzK3�->�wU�N+jGC
@@ -92,7 +92,7 @@ module RubySMB
92
92
  begin
93
93
  packet = RubySMB::SMB1::Packet::SessionSetupResponse.read(raw_response)
94
94
  rescue
95
- packet = RubySMB::SMB1::Packet::ErrorPacket.read(raw_response)
95
+ packet = RubySMB::SMB1::Packet::EmptyPacket.read(raw_response)
96
96
  end
97
97
 
98
98
  unless packet.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_SESSION_SETUP
@@ -0,0 +1,36 @@
1
+ module RubySMB
2
+ class Client
3
+
4
+ # Contains the methods for doing ECHO commands
5
+ module Echo
6
+
7
+ # Sends an ECHO request packet and returns the
8
+ # last response packet.
9
+ #
10
+ # @param echo [Integer] the number of times the server should echo (ignored in SMB2)
11
+ # @param data [String] the data the server should echo back (ignored in SMB2)
12
+ # @return [RubySMB::SMB1::Packet::EchoResponse] the last Echo Response packet received
13
+ def smb1_echo(count: 1, data: '')
14
+ request = RubySMB::SMB2::Packet::EchoRequest.new
15
+ request.parameter_block.echo_count = count
16
+ request.data_block.data = data
17
+ raw_response = send_recv(request)
18
+ (count - 1).times do
19
+ raw_response = dispatcher.recv_packet
20
+ end
21
+ RubySMB::SMB1::Packet::EchoResponse.read(raw_response)
22
+ end
23
+
24
+
25
+ # Sends an ECHO request packet and returns the
26
+ # response packet.
27
+ #
28
+ # @return [RubySMB::SMB2::Packet::EchoResponse]
29
+ def smb2_echo
30
+ request = RubySMB::SMB2::Packet::EchoRequest.new
31
+ raw_response = send_recv(request)
32
+ RubySMB::SMB2::Packet::EchoResponse.read(raw_response)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -22,7 +22,7 @@ module RubySMB
22
22
  begin
23
23
  response = RubySMB::SMB1::Packet::TreeConnectResponse.read(raw_response)
24
24
  rescue EOFError
25
- response = RubySMB::SMB1::Packet::ErrorPacket.read(raw_response)
25
+ response = RubySMB::SMB1::Packet::EmptyPacket.read(raw_response)
26
26
  end
27
27
  smb1_tree_from_response(share, response)
28
28
  end
@@ -7,11 +7,13 @@ module RubySMB
7
7
  require 'ruby_smb/client/authentication'
8
8
  require 'ruby_smb/client/signing'
9
9
  require 'ruby_smb/client/tree_connect'
10
+ require 'ruby_smb/client/echo'
10
11
 
11
12
  include RubySMB::Client::Negotiation
12
13
  include RubySMB::Client::Authentication
13
14
  include RubySMB::Client::Signing
14
15
  include RubySMB::Client::TreeConnect
16
+ include RubySMB::Client::Echo
15
17
 
16
18
  # The Default SMB1 Dialect string used in an SMB1 Negotiate Request
17
19
  SMB1_DIALECT_SMB1_DEFAULT = "NT LM 0.12"
@@ -131,6 +133,21 @@ module RubySMB
131
133
  dispatcher.tcp_socket.close
132
134
  end
133
135
 
136
+ # Sends an Echo request to the server and returns the
137
+ # NTStatus of the last response packet received.
138
+ #
139
+ # @param echo [Integer] the number of times the server should echo (ignored in SMB2)
140
+ # @param data [String] the data the server should echo back (ignored in SMB2)
141
+ # @return [WindowsError::ErrorCode] the NTStatus of the last response received
142
+ def echo(count: 1, data: '' )
143
+ if smb2
144
+ response = smb2_echo
145
+ else
146
+ response = smb1_echo(count:count, data:data)
147
+ end
148
+ response.status_code
149
+ end
150
+
134
151
  # Sets the message id field in an SMB2 packet's
135
152
  # header to the one tracked by the client. It then increments
136
153
  # the counter on the client.
@@ -27,10 +27,13 @@ class RubySMB::Dispatcher::Socket < RubySMB::Dispatcher::Base
27
27
  def send_packet(packet)
28
28
  data = nbss(packet) + packet.to_binary_s
29
29
  bytes_written = 0
30
- while bytes_written < data.size
31
- bytes_written += @tcp_socket.write(data[bytes_written..-1])
30
+ begin
31
+ while bytes_written < data.size
32
+ bytes_written += @tcp_socket.write(data[bytes_written..-1])
33
+ end
34
+ rescue IOError => e
35
+ raise RubySMB::Error::CommunicationError, "An error occured writing to the Socket"
32
36
  end
33
-
34
37
  nil
35
38
  end
36
39
 
@@ -40,17 +43,21 @@ class RubySMB::Dispatcher::Socket < RubySMB::Dispatcher::Base
40
43
  # @return [String]
41
44
  # @todo should return SMB2::Packet
42
45
  def recv_packet
43
- IO.select([@tcp_socket])
44
- nbss_header = @tcp_socket.read(4) # Length of NBSS header. TODO: remove to a constant
45
- if nbss_header.nil?
46
- raise ::RubySMB::Error::NetBiosSessionService, 'NBSS Header is missing'
47
- else
48
- length = nbss_header.unpack('N').first
49
- end
50
- IO.select([@tcp_socket])
51
- data = @tcp_socket.read(length)
52
- data << @tcp_socket.read(length - data.length) while data.length < length
46
+ begin
47
+ IO.select([@tcp_socket])
48
+ nbss_header = @tcp_socket.read(4) # Length of NBSS header. TODO: remove to a constant
49
+ if nbss_header.nil?
50
+ raise ::RubySMB::Error::NetBiosSessionService, 'NBSS Header is missing'
51
+ else
52
+ length = nbss_header.unpack('N').first
53
+ end
54
+ IO.select([@tcp_socket])
55
+ data = @tcp_socket.read(length)
56
+ data << @tcp_socket.read(length - data.length) while data.length < length
53
57
 
54
- data
58
+ data
59
+ rescue Errno::EINVAL, TypeError => e
60
+ raise RubySMB::Error::CommunicationError, "An error occured reading from the Socket"
61
+ end
55
62
  end
56
63
  end
@@ -14,4 +14,7 @@ module RubySMB::Error
14
14
 
15
15
  # Raised when a response packet has a NTStatus code that was unexpected.
16
16
  class UnexpectedStatusCode < StandardError; end
17
+
18
+ # Raised when an error occurs with the underlying socket.
19
+ class CommunicationError < StandardError; end
17
20
  end
@@ -0,0 +1,58 @@
1
+ module RubySMB
2
+ module Field
3
+ # Convenience class that extend the normal {BinData::Array} for use
4
+ # with {RubySMB::Field::FileFullEaInfo}. This array will automatically
5
+ # updates the {RubySMB::Field::FileFullEaInfo#next_entry_offset} of
6
+ # each element in the array.
7
+ class EaInfoArray < BinData::Array
8
+
9
+ # Overrides the method from {BinData::Array} to
10
+ # call #update_offsets
11
+ # @raise [ArgumentError] if the inserted element is not a {RubySMB::Field::FileFullEaInfo}
12
+ def []=(index, value)
13
+ unless value.is_a? RubySMB::Field::FileFullEaInfo
14
+ raise ArgumentError, "This array can only contain RubySMB::Field::FileFullEaInfo objects"
15
+ end
16
+ retval = super(index,value)
17
+ update_offsets
18
+ retval
19
+ end
20
+
21
+ # Overrides the insert method in {BinData::Array} to
22
+ # call #update_offsets.
23
+ #
24
+ # @param index [Integer] the index to insert into the array at
25
+ # @param objs [Array<Object>] the objects to be inserted
26
+ # @raise [ArgumentError] if the inserted element is not a {RubySMB::Field::FileFullEaInfo}
27
+ # @return [self]
28
+ def insert(index, *objs)
29
+ objs.each do |x|
30
+ unless x.is_a? RubySMB::Field::FileFullEaInfo
31
+ raise ArgumentError, "This array can only contain RubySMB::Field::FileFullEaInfo objects"
32
+ end
33
+ end
34
+ super(index, *objs)
35
+ update_offsets
36
+ end
37
+
38
+ # Iterates through all of the elements in the array and
39
+ # dynamically updates all of the next_record_offset fields
40
+ # to properly reflect the chain.
41
+ #
42
+ # @return [self]
43
+ def update_offsets
44
+ self.each do |element|
45
+ if element == self.last
46
+ # If this is the end of our array, the offset must be 0
47
+ element.next_entry_offset = 0
48
+ else
49
+ # If there is an element after this one, set the offset
50
+ element.next_entry_offset = element.do_num_bytes
51
+ end
52
+ end
53
+ self
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,10 @@
1
+ module RubySMB
2
+ module Field
3
+ # Representation of the ExtendedAttributeFlag bit-field as defined in
4
+ # [2.2.1.2.2 SMB_FEA](https://msdn.microsoft.com/en-us/library/ee915515.aspx)
5
+ class ExtendedAttributeFlag < BinData::Record
6
+ bit1 :file_need_ea, label: 'EA Required'
7
+ bit7 :reserved, label: 'Reserved Space'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ module RubySMB
2
+ module Field
3
+ # Class representing a FillFullEaInformation structure as defined in
4
+ # [2.4.15 FileFullEaInformation](https://msdn.microsoft.com/en-us/library/cc232069.aspx)
5
+ class FileFullEaInfo < BinData::Record
6
+ endian :little
7
+ uint32 :next_entry_offset, label: 'Next Entry Offset'
8
+ extended_attribute_flag :flags
9
+ uint8 :ea_name_length, label: 'EA Name Length', value: lambda { ea_name.do_num_bytes }
10
+ uint8 :ea_value_length, label: 'EA Value Length', value: lambda { ea_value.do_num_bytes }
11
+ string :ea_name, label: 'EA Name'
12
+ string :ea_value, label: 'EA Value'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,42 @@
1
+ module RubySMB
2
+ module Field
3
+ # Class representing a SECURITY_DESCRIPTOR as defined in
4
+ # [2.4.6 SECURITY_DESCRIPTOR](https://msdn.microsoft.com/en-us/library/cc230366.aspx)
5
+ class SecurityDescriptor < BinData::Record
6
+ endian :little
7
+ uint8 :revision, label: 'Revision', initial_value: 0x01
8
+ uint8 :sbz1, label: 'Resource Manager Control Bits'
9
+
10
+ struct :control do
11
+ endian :little
12
+ bit1 :dacl_computed_inheritance, label: 'DACL Computed Inheritance'
13
+ bit1 :sacl_computed_inheritance, label: 'SACL Computed Inheritance'
14
+ bit1 :dacl_auto_inherited, label: 'DACL Auto-Inherited'
15
+ bit1 :sacl_auto_inherited, label: 'SACL Auto-Inherited'
16
+ bit1 :dacl_protected, label: 'DACL Protected'
17
+ bit1 :sacl_protected, label: 'SACL Protected'
18
+ bit1 :rm_control_valid, label: 'RM Control Valid'
19
+ bit1 :self_relative, label: 'Self-Relative Format', initial_value: 0x01
20
+ # Byte Boundary
21
+ bit1 :owner_defaulted, label: 'Owner Defaulted'
22
+ bit1 :group_defaulted, label: 'Group Defaulted'
23
+ bit1 :dacl_present, label: 'DACL Present'
24
+ bit1 :dacl_defaulted, label: 'DACL Defaulted'
25
+ bit1 :sacl_present, label: 'SACL Present'
26
+ bit1 :sacl_defaulted, label: 'SACL Defaulted'
27
+ bit1 :server_security, label: 'Server Security'
28
+ bit1 :dacl_trusted, label: 'DACL Trusted'
29
+ end
30
+
31
+ uint32 :offset_owner, label: 'Offset Owner', value: lambda { owner_sid.rel_offset }
32
+ uint32 :offset_group, label: 'Offset Group', value: lambda { group_sid.rel_offset }
33
+ uint32 :offset_sacl, label: 'Offset SACL', value: lambda { sacl.rel_offset }
34
+ uint32 :offset_dacl, label: 'Offset DACL', value: lambda { dacl.rel_offset }
35
+
36
+ string :owner_sid, label: 'Owner SID'
37
+ string :group_sid, label: 'Group SID'
38
+ string :sacl, label: 'SACL'
39
+ string :dacl, label: 'DACL'
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,14 @@
1
+ module RubySMB
2
+ module Field
3
+ # Class representing an SMB File Extended Attribute as defined in
4
+ # [2.2.1.2.2 SMB_FEA](https://msdn.microsoft.com/en-us/library/ee915515.aspx)
5
+ class SmbFea < BinData::Record
6
+ endian :little
7
+ extended_attribute_flag :ea_flag, label: 'Extended Attribute Flag'
8
+ uint8 :attribute_name_length, label: 'Attribute Name Length', value: lambda { attribute_name.length}
9
+ uint16 :attribute_value_length, label: 'Attribute Value Length', value: lambda { attribute_value.length}
10
+ string :attribute_name, label: 'Attribute Name'
11
+ string :attribute_value, label: 'Attribute Value'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module RubySMB
2
+ module Field
3
+ # Class representing an SMB File Extended Attribute List as defined in
4
+ # [2.2.1.2.2.1 SMB_FEA_LIST](https://msdn.microsoft.com/en-us/library/ff359296.aspx)
5
+ class SmbFeaList < BinData::Record
6
+ endian :little
7
+ uint32 :size_of_list, label: 'Size of List in Bytes', value: lambda { fea_list.do_num_bytes }
8
+ array :fea_list, initial_length: 0 do
9
+ smb_fea
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,54 @@
1
+ module RubySMB
2
+ module Field
3
+
4
+ # Conveneince class for dealing with 32-bit unsigned UTIME
5
+ # fields in SMB, as defined in
6
+ # [2.2.1.4.3 UTIME](https://msdn.microsoft.com/en-us/library/ee441907.aspx)
7
+ class Utime < BinData::Primitive
8
+ endian :little
9
+ uint32 :val
10
+
11
+ # Gets the value of the field
12
+ #
13
+ # @return [BinData::Bit32] the 64-bit value of the field
14
+ def get
15
+ val
16
+ end
17
+
18
+ # Sets the value of the field from a DateTime,Time,Fixnum, or object
19
+ # that can be converted to an integer. Any other
20
+ # parameter passed in will be assumed to already be correct.
21
+ #
22
+ # @param value [DateTime,Time,Fixnum,#to_i] the value to set
23
+ # @return
24
+ def set(value)
25
+ case value
26
+ when DateTime
27
+ set(value.to_time)
28
+ when Time
29
+ set(value.to_i)
30
+ when Fixnum
31
+ self.val = value
32
+ else
33
+ self.val = value.to_i
34
+ end
35
+ val
36
+ end
37
+
38
+ # Returns the value of the field as a {DateTime}
39
+ #
40
+ # @return [DateTime] the {DateTime} representation of the current value
41
+ def to_datetime
42
+ time = to_time
43
+ time.to_datetime
44
+ end
45
+
46
+ # Returns the value of the field as a {Time}
47
+ #
48
+ # @return [Time] the {Time} representation of the current value
49
+ def to_time
50
+ Time.at val
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,7 +1,14 @@
1
1
  module RubySMB
2
2
  module Field
3
3
  require 'ruby_smb/field/file_time'
4
+ require 'ruby_smb/field/utime'
4
5
  require 'ruby_smb/field/stringz16'
5
6
  require 'ruby_smb/field/nt_status'
7
+ require 'ruby_smb/field/extended_attribute_flag'
8
+ require 'ruby_smb/field/smb_fea'
9
+ require 'ruby_smb/field/smb_fea_list'
10
+ require 'ruby_smb/field/security_descriptor'
11
+ require 'ruby_smb/field/file_full_ea_info'
12
+ require 'ruby_smb/field/ea_info_array'
6
13
  end
7
14
  end
@@ -35,15 +35,19 @@ module RubySMB
35
35
  end
36
36
 
37
37
  def status_code
38
+ value = -1
38
39
  smb_version = packet_smb_version
39
40
  case smb_version
40
41
  when 'SMB1'
41
- status_code = WindowsError::NTStatus.find_by_retval(self.smb_header.nt_status.value).first
42
+ value = self.smb_header.nt_status.value
42
43
  when 'SMB2'
43
- status_code = WindowsError::NTStatus.find_by_retval(self.smb2_header.nt_status.value).first
44
- else
45
- nil
44
+ value = self.smb2_header.nt_status.value
45
+ end
46
+ status_code = WindowsError::NTStatus.find_by_retval(value).first
47
+ if status_code.nil?
48
+ status_code = WindowsError::ErrorCode.new("0x#{value.to_s(16)}", value, "Unknown 0x#{value.to_s(16)}")
46
49
  end
50
+ status_code
47
51
  end
48
52
 
49
53
  private
@@ -0,0 +1,22 @@
1
+ module RubySMB
2
+ # Contains constants for the various Impersonation levels as defined in
3
+ # [2.2.4.64.1 Request](https://msdn.microsoft.com/en-us/library/ee442175.aspx)
4
+ # See also [Impersonation Levels](https://msdn.microsoft.com/en-us/library/ms686632(v=vs.85).aspx)
5
+ module ImpersonationLevels
6
+ # The client is anonymous to the server. The server process can impersonate the client, but the impersonation
7
+ # token does not contain any information about the client. This level is only supported over the local
8
+ # interprocess communication transport. All other transports silently promote this level to identify.
9
+ SEC_ANONYMOUS = 0x00000000
10
+
11
+ # The system default level. The server can obtain the client's identity,
12
+ # and the server can impersonate the client to do ACL checks.
13
+ SEC_IDENTIFY = 0x00000001
14
+
15
+ # The server can impersonate the client's security context while acting on behalf of the client.
16
+ # The server can access local resources as the client. If the server is local, it can access
17
+ # network resources as the client. If the server is remote, it can access only resources
18
+ # that are on the same computer as the server.
19
+ SEC_IMPERSONATE = 0x00000002
20
+
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module BitField
4
+
5
+ # Represents a CreateOptions BitField as used by both the NT_CREATE_ANDX
6
+ # and the NT_TRANSACT_CREATE Requests. The definition for this field can be found at
7
+ # [2.2.4.64.1 Request](https://msdn.microsoft.com/en-us/library/ee442175.aspx)
8
+ class CreateOptions < BinData::Record
9
+ endian :little
10
+ bit1 :create_tree_connection, label: 'Create Tree Connection'
11
+ bit1 :non_directory_file, label: 'Non-Directory File'
12
+ bit1 :synchronous_io_nonalert, label: 'Synchronous IO Nonalert'
13
+ bit1 :synchronous_io_alert, label: 'Synchronous IO Alert'
14
+ bit1 :no_intermediate_buffer, label: 'No Intermediate Buffering'
15
+ bit1 :sequential_only, label: 'Sequential Only'
16
+ bit1 :write_through, label: 'Write Through'
17
+ bit1 :directory_file, label: 'Directory File'
18
+ # Byte Boundary
19
+ bit1 :no_compression, label: 'No Compression'
20
+ bit1 :open_for_backup_intent, label: 'Open For Backup Intent'
21
+ bit1 :open_by_file_id, label: 'Open by File ID'
22
+ bit1 :delete_on_close, label: 'Delete on Close'
23
+ bit1 :random_access, label: 'Random Access'
24
+ bit1 :open_for_recovery, label: 'Open for Recovery'
25
+ bit1 :no_ea_knowledge, label: 'No EA Knowledge'
26
+ bit1 :complete_if_oplocked, label: 'Complete if OPLocked'
27
+ # Byte Boundary
28
+ bit1 :open_for_free_space_query, label: 'Open for Free Space Query'
29
+ bit1 :open_no_recall, label: 'Open No Recall'
30
+ bit1 :reserved2, label: 'Reserved Space'
31
+ bit1 :reserve_opfilter, label: 'Reserve OPFilter'
32
+ bit4 :reserved, label: 'Reserved Space'
33
+ # Byte Boundary
34
+ bit8
35
+ end
36
+ end
37
+ end
38
+ end
@@ -7,7 +7,7 @@ module RubySMB
7
7
  endian :little
8
8
  bit1 :read_attr, label: 'Read Attributes'
9
9
  bit1 :delete_child, label: 'Delete Child'
10
- bit1 :execute, label: 'Traverse'
10
+ bit1 :execute, label: 'Execute'
11
11
  bit1 :write_ea, label: 'Write Extended Attributes'
12
12
  bit1 :read_ea, label: 'Read Extended Attributes'
13
13
  bit1 :append_data, label: 'Append Data'
@@ -0,0 +1,42 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module BitField
4
+ # The AccessMode bit-field for an SMB1 Open2 Request as defined in
5
+ # [2.2.6.1.1 Request](https://msdn.microsoft.com/en-us/library/ee441733.aspx)
6
+ class Open2AccessMode< BinData::Record
7
+ endian :little
8
+ bit1 :reserved2, label: 'Reserved Space'
9
+ bit3 :sharing_mode, label: 'Sharing Mode'
10
+ bit1 :reserved, label: 'Reserved Space'
11
+ bit3 :access_mode, label: 'Access Mode'
12
+ # byte boundary
13
+ bit1 :reserved5, label: 'Reserved Space'
14
+ bit1 :writethrough, label: 'Writethrough mode'
15
+ bit1 :reserved4, label: 'Reserved Space'
16
+ bit1 :cache_mode, label: 'Cache Mode'
17
+ bit1 :reserved3, label: 'Reserved Space'
18
+ bit3 :reference_locality, label: 'Reference'
19
+
20
+ # Sets the #access_mode based on more human readableinput.
21
+ # Takes the symbols :r, :w, :rw, and :x to set Read, Write,
22
+ # ReadWrite, and Execute respectively.
23
+ #
24
+ # @param mode [Symbol] the access mode to set
25
+ def set_access_mode(mode=:r)
26
+ modes = [:r, :w, :rw, :x]
27
+ raise ArgumentError, "Mode must be one of #{modes.to_s}" unless modes.include? mode
28
+ case mode
29
+ when :r
30
+ self.access_mode = 0
31
+ when :w
32
+ self.access_mode = 1
33
+ when :rw
34
+ self.access_mode = 2
35
+ when :x
36
+ self.access_mode = 3
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module BitField
4
+ # The Flags bit-field for an SMB1 Open2 Request as defined in
5
+ # [2.2.6.1.1 Request](https://msdn.microsoft.com/en-us/library/ee441733.aspx)
6
+ class Open2Flags < BinData::Record
7
+ endian :little
8
+ bit4 :reserved, label: 'Reserved Space'
9
+ bit1 :req_easize, label: 'Request EA Size', initial_value: 1
10
+ bit1 :req_opbatch, label: 'Request Batch OpLock', initial_value: 0
11
+ bit1 :req_oplock, label: 'Request OpLock', initial_value: 0
12
+ bit1 :req_attrib, label: 'Request Attributes', initial_value: 1
13
+ # Byte boundary
14
+ bit8 :reserved2, label: 'Reserved Space'
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module BitField
4
+ # The OpenMode bit-field for an SMB1 Open2 Request as defined in
5
+ # [2.2.6.1.1 Request](https://msdn.microsoft.com/en-us/library/ee441733.aspx)
6
+ class Open2OpenMode< BinData::Record
7
+ endian :little
8
+ bit3 :reserved2, label: 'Reserved Space'
9
+ bit1 :create_file, label: 'Create File Options'
10
+ bit2 :reserved, label: 'Reserved Space'
11
+ bit2 :file_exists_opts, label: 'File Exists Options'
12
+ # byte boundary
13
+ bit8 :reserved5, label: 'Reserved Space'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module BitField
4
+
5
+ # Represents a ShareAccess Bit-Field as defined in
6
+ # [2.2.4.64.1 Request](https://msdn.microsoft.com/en-us/library/ee442175.aspx)
7
+ class ShareAccess < BinData::Record
8
+ endian :little
9
+ bit5 :reserved, label: 'Reserved Space'
10
+ bit1 :share_delete, label: 'Share Delete Access'
11
+ bit1 :share_write, label: 'Share Write Access'
12
+ bit1 :share_read, label: 'Share Read Access'
13
+ # Byte Boundary
14
+ bit8 :reserved2, label: 'Reserved Space'
15
+ bit8 :reserved3, label: 'Reserved Space'
16
+ bit8 :reserved4, label: 'Reserved Space'
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module BitField
4
+ # The bit-field for SMB1 Extended File Attributes as defined in
5
+ # [2.2.1.2.3 SMB_EXT_FILE_ATTR](https://msdn.microsoft.com/en-us/library/ee878573.aspx)
6
+ class SmbExtFileAttributes < BinData::Record
7
+ endian :little
8
+ bit1 :normal, label: 'Normal File'
9
+ bit1 :reserved, label: 'Reserved Space'
10
+ bit1 :archive, label: 'Archive'
11
+ bit1 :directory, label: 'Directory'
12
+ bit1 :reserved2, label: 'Reserved Space'
13
+ bit1 :system, label: 'System File'
14
+ bit1 :hidden, label: 'Hidden File'
15
+ bit1 :read_only, label: 'Read Only'
16
+ # Byte boundary
17
+ bit4 :reserved3, label: 'Reserved Space'
18
+ bit1 :compressed, label: 'Compressed File'
19
+ bit2 :reserved4, label: 'Reserved Space'
20
+ bit1 :temporary, label: 'Temporary File'
21
+ # Byte Boundary
22
+ bit8 :reserved5, label: 'Reserved Space'
23
+ # Byte Boundary
24
+ bit1 :write_through, label: 'Write through'
25
+ bit1 :reserved6, label: 'Reserved Space'
26
+ bit1 :no_buffering, label: 'Do not Buffer'
27
+ bit1 :random_access, label: 'Random Access'
28
+ bit1 :sequential_scan, label: 'Sequential Access'
29
+ bit1 :delete_on_close, label: 'Delete on close'
30
+ bit1 :backup_semantics, label: 'Backup Semantics'
31
+ bit1 :posix_semantics, label: 'POSIX Semantics'
32
+ end
33
+ end
34
+ end
35
+ end