lib/ruby_smb/dcerpc/ndr.rb in ruby_smb-2.0.4 vs lib/ruby_smb/dcerpc/ndr.rb in ruby_smb-2.0.5
- old
+ new
@@ -5,10 +5,13 @@
# NDR Syntax
UUID = '8a885d04-1ceb-11c9-9fe8-08002b104860'
VER_MAJOR = 2
VER_MINOR = 0
+ # An NDR Enum type as defined in
+ # [Transfer Syntax NDR - Enumerated Types](https://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_02_05_01)
+ class NdrEnum < BinData::Int16le; end
# An NDR Conformant and Varying String representation as defined in
# [Transfer Syntax NDR - Conformant and Varying Strings](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_04_02)
# The string elements are Stringz16 (unicode)
class NdrString < BinData::Primitive
@@ -87,9 +90,103 @@
def set(v)
v = v.bytes if v.is_a?(self.class)
self.bytes = v.to_ary
self.max_count = self.bytes.size unless self.bytes.equal?(v)
+ end
+ end
+
+ # An NDR Uni-dimensional Fixed Array of bytes representation as defined in:
+ # [Transfer Syntax NDR - NDR Constructed Types](https://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_03_01)
+ class NdrFixedByteArray < BinData::BasePrimitive
+ optional_parameters :read_length, :length, :pad_byte, :pad_front
+ default_parameters pad_byte: 0
+ mutually_exclusive_parameters :length, :value
+
+ def initialize_shared_instance
+ if (has_parameter?(:value) || has_parameter?(:asserted_value)) && !has_parameter?(:read_length)
+ extend WarnNoReadLengthPlugin
+ end
+ super
+ end
+
+ def assign(val)
+ super(fixed_byte_array(val))
+ end
+
+ def snapshot
+ clamp_to_length(super)
+ end
+
+ class << self
+ def arg_processor
+ NdrFixedByteArrayArgProcessor.new
+ end
+ end
+
+ private
+
+ def clamp_to_length(val)
+ val = fixed_byte_array(val)
+ len = eval_parameter(:length) || val.length
+ if val.length > len
+ val = val.first(len)
+ elsif val.length < len
+ pad = eval_parameter(:pad_byte)
+ if get_parameter(:pad_front)
+ val = val.insert(0, *Array.new(len - val.length, pad))
+ else
+ val = val.fill(pad, val.length...len)
+ end
+ end
+
+ val
+ end
+
+ def fixed_byte_array(val)
+ val = val.bytes if val.is_a? String
+ val.to_ary
+ end
+
+ def read_and_return_value(io)
+ len = eval_parameter(:read_length) || eval_parameter(:length) || 0
+ io.readbytes(len)
+ end
+
+ def sensible_default
+ [ ]
+ end
+
+ def value_to_binary_string(val)
+ clamp_to_length(val).pack('C*')
+ end
+
+ class NdrFixedByteArrayArgProcessor < BinData::BaseArgProcessor
+ def sanitize_parameters!(obj_class, obj_params)
+ obj_params.must_be_integer(:length, :pad_byte)
+ obj_params.sanitize(:pad_byte) { |byte| sanitized_pad_byte(byte) }
+ end
+
+ private
+
+ def sanitized_pad_byte(byte)
+ if byte.is_a?(String)
+ raise ArgumentError, ':pad_byte must not contain more than 1 byte' if byte.bytesize > 1
+
+ byte = byte.ord
+ end
+ raise ArgumentError, ':pad_byte must be within the range of 0 - 255' unless ((byte >= 0) && (byte <= 255))
+
+ byte
+ end
+ end
+
+ # Warns when reading if :value && no :read_length
+ module WarnNoReadLengthPlugin
+ def read_and_return_value(io)
+ warn "#{debug_name} does not have a :read_length parameter - returning empty array"
+ ""
+ end
end
end
# An NDR Context Handle representation as defined in
# [IDL Data Type Declarations - Basic Type Declarations](http://pubs.opengroup.org/onlinepubs/9629399/apdxn.htm#tagcjh_34_01)