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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +1 -2
- data/lib/ruby_smb/client/authentication.rb +1 -1
- data/lib/ruby_smb/client/echo.rb +36 -0
- data/lib/ruby_smb/client/tree_connect.rb +1 -1
- data/lib/ruby_smb/client.rb +17 -0
- data/lib/ruby_smb/dispatcher/socket.rb +21 -14
- data/lib/ruby_smb/error.rb +3 -0
- data/lib/ruby_smb/field/ea_info_array.rb +58 -0
- data/lib/ruby_smb/field/extended_attribute_flag.rb +10 -0
- data/lib/ruby_smb/field/file_full_ea_info.rb +15 -0
- data/lib/ruby_smb/field/security_descriptor.rb +42 -0
- data/lib/ruby_smb/field/smb_fea.rb +14 -0
- data/lib/ruby_smb/field/smb_fea_list.rb +13 -0
- data/lib/ruby_smb/field/utime.rb +54 -0
- data/lib/ruby_smb/field.rb +7 -0
- data/lib/ruby_smb/generic_packet.rb +8 -4
- data/lib/ruby_smb/impersonation_levels.rb +22 -0
- data/lib/ruby_smb/smb1/bit_field/create_options.rb +38 -0
- data/lib/ruby_smb/smb1/bit_field/file_access_mask.rb +1 -1
- data/lib/ruby_smb/smb1/bit_field/open2_access_mode.rb +42 -0
- data/lib/ruby_smb/smb1/bit_field/open2_flags.rb +18 -0
- data/lib/ruby_smb/smb1/bit_field/open2_open_mode.rb +17 -0
- data/lib/ruby_smb/smb1/bit_field/share_access.rb +20 -0
- data/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes.rb +35 -0
- data/lib/ruby_smb/smb1/bit_field/smb_file_attributes.rb +26 -0
- data/lib/ruby_smb/smb1/bit_field/smb_nmpipe_status.rb +19 -0
- data/lib/ruby_smb/smb1/bit_field/trans2_flags.rb +15 -0
- data/lib/ruby_smb/smb1/bit_field.rb +9 -0
- data/lib/ruby_smb/smb1/commands.rb +10 -6
- data/lib/ruby_smb/smb1/create_actions.rb +22 -0
- data/lib/ruby_smb/smb1/dispositions.rb +36 -0
- data/lib/ruby_smb/smb1/oplock_levels.rb +19 -0
- data/lib/ruby_smb/smb1/packet/echo_request.rb +30 -0
- data/lib/ruby_smb/smb1/packet/echo_response.rb +31 -0
- data/lib/ruby_smb/smb1/packet/empty_packet.rb +14 -0
- data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +85 -0
- data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +61 -0
- data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +47 -0
- data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +44 -0
- data/lib/ruby_smb/smb1/packet/nt_trans/subcommands.rb +11 -0
- data/lib/ruby_smb/smb1/packet/nt_trans.rb +16 -0
- data/lib/ruby_smb/smb1/packet/trans2/data_block.rb +32 -0
- data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +60 -0
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +65 -0
- data/lib/ruby_smb/smb1/packet/trans2/request.rb +52 -0
- data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +39 -0
- data/lib/ruby_smb/smb1/packet/trans2/response.rb +48 -0
- data/lib/ruby_smb/smb1/packet/trans2/subcommands.rb +12 -0
- data/lib/ruby_smb/smb1/packet/trans2.rb +18 -0
- data/lib/ruby_smb/smb1/packet.rb +5 -1
- data/lib/ruby_smb/smb1.rb +3 -0
- data/lib/ruby_smb/smb2/bit_field/{share_capabailities.rb → share_capabilities.rb} +0 -0
- data/lib/ruby_smb/smb2/bit_field/{smb2_capabailities.rb → smb2_capabilities.rb} +0 -0
- data/lib/ruby_smb/smb2/bit_field.rb +2 -2
- data/lib/ruby_smb/smb2/packet/echo_request.rb +21 -0
- data/lib/ruby_smb/smb2/packet/echo_response.rb +22 -0
- data/lib/ruby_smb/smb2/packet.rb +2 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/ruby_smb.gemspec +2 -0
- data/spec/lib/ruby_smb/client_spec.rb +46 -0
- data/spec/lib/ruby_smb/field/ea_info_array_spec.rb +51 -0
- data/spec/lib/ruby_smb/field/extended_attribute_flag_spec.rb +16 -0
- data/spec/lib/ruby_smb/field/file_full_ea_info_spec.rb +35 -0
- data/spec/lib/ruby_smb/field/security_descriptor.rb +194 -0
- data/spec/lib/ruby_smb/field/smb_fea_list_spec.rb +38 -0
- data/spec/lib/ruby_smb/field/smb_fea_spec.rb +27 -0
- data/spec/lib/ruby_smb/field/utime_spec.rb +59 -0
- data/spec/lib/ruby_smb/smb1/bit_field/create_options_spec.rb +181 -0
- data/spec/lib/ruby_smb/smb1/bit_field/open2_access_mode_spec.rb +81 -0
- data/spec/lib/ruby_smb/smb1/bit_field/open2_flags_spec.rb +62 -0
- data/spec/lib/ruby_smb/smb1/bit_field/open2_open_mode_spec.rb +27 -0
- data/spec/lib/ruby_smb/smb1/bit_field/share_access_spec.rb +38 -0
- data/spec/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes_spec.rb +144 -0
- data/spec/lib/ruby_smb/smb1/bit_field/smb_file_attributes_spec.rb +113 -0
- data/spec/lib/ruby_smb/smb1/bit_field/smb_nmpipe_status_spec.rb +53 -0
- data/spec/lib/ruby_smb/smb1/bit_field/trans2_flags_spec.rb +28 -0
- data/spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb +44 -0
- data/spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb +44 -0
- data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_request_spec.rb +194 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_response_spec.rb +124 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/request_spec.rb +91 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/response_spec.rb +75 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_request_spec.rb +112 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +107 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/request_secondary_spec.rb +77 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +98 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb +88 -0
- data/spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +104 -7
- metadata.gz.sig +0 -0
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e599cfd32ed2eef3ec64db3aeef90291f419a8cd
|
4
|
+
data.tar.gz: 31069aa5863e82e9a681300863f22aa8d3fa9a00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bacd65cd70045c29a402f6d81b9002ff63797203963929e96175466416700a73bbf761bd274902985e6bb0c901124b90740c3accb30d19b14e99e438eda6704a
|
7
|
+
data.tar.gz: b022e98f38ec3e9962b14dc2428f454405eb367205f0a32844a747988818d7c87732162cd1aa0581ad4ae2e93d09329ee76fc43a776df2fbe0f8556501f79c48
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
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::
|
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::
|
25
|
+
response = RubySMB::SMB1::Packet::EmptyPacket.read(raw_response)
|
26
26
|
end
|
27
27
|
smb1_tree_from_response(share, response)
|
28
28
|
end
|
data/lib/ruby_smb/client.rb
CHANGED
@@ -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
|
-
|
31
|
-
bytes_written
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
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
|
data/lib/ruby_smb/error.rb
CHANGED
@@ -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
|
data/lib/ruby_smb/field.rb
CHANGED
@@ -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
|
-
|
42
|
+
value = self.smb_header.nt_status.value
|
42
43
|
when 'SMB2'
|
43
|
-
|
44
|
-
|
45
|
-
|
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: '
|
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
|