ruby_smb 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
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