lib/net/ssh/buffer.rb in net-ssh-4.0.0.alpha4 vs lib/net/ssh/buffer.rb in net-ssh-4.0.0.beta1

- old
+ new

@@ -1,8 +1,10 @@ require 'net/ssh/ruby_compat' require 'net/ssh/transport/openssl' +require 'net/ssh/authentication/ed25519_loader' + module Net; module SSH # Net::SSH::Buffer is a flexible class for building and parsing binary # data packets. It provides a stream-like interface for sequentially # reading data items from the buffer, as well as a useful helper method @@ -32,10 +34,11 @@ # * :raw => write the next value verbatim (#write) # * :int64 => write an 8-byte integer (#write_int64) # * :long => write a 4-byte integer (#write_long) # * :byte => write a single byte (#write_byte) # * :string => write a 4-byte length followed by character data (#write_string) + # * :mstring => same as string, but caller cannot resuse the string, avoids potential duplication (#write_moved) # * :bool => write a single byte, interpreted as a boolean (#write_bool) # * :bignum => write an SSH-encoded bignum (#write_bignum) # * :key => write an SSH-encoded key value (#write_key) # # Any of these, except for :raw, accepts an Array argument, to make it @@ -180,11 +183,11 @@ def read!(count=nil) data = read(count) consume! data end - + # Return the next 8 bytes as a 64-bit integer (in network byte order). # Returns nil if there are less than 8 bytes remaining to be read in the # buffer. def read_int64 hi = read_long or return nil @@ -254,12 +257,12 @@ key = OpenSSL::PKey::RSA.new key.e = read_bignum key.n = read_bignum when /^ssh-ed25519$/ - key = ED25519::PubKey.read_keyblob(self) - + Net::SSH::Authentication::ED25519Loader.raiseUnlessLoaded("unsupported key type `#{type}'") + key = Net::SSH::Authentication::ED25519::PubKey.read_keyblob(self) when /^ecdsa\-sha2\-(\w*)$/ unless defined?(OpenSSL::PKey::EC) raise NotImplementedError, "unsupported key type `#{type}'" else begin @@ -282,14 +285,21 @@ end # Writes the given data literally into the string. Does not alter the # read position. Returns the buffer object. def write(*data) - data.each { |datum| @content << datum } + data.each { |datum| @content << datum.dup.force_encoding('BINARY') } self end + # Optimized version of write where the caller gives up ownership of string + # to the method. This way we can mutate the string. + def write_moved(string) + @content << string.force_encoding('BINARY') + self + end + # Writes each argument to the buffer as a network-byte-order-encoded # 64-bit integer (8 bytes). Does not alter the read position. Returns the # buffer object. def write_int64(*n) n.each do |i| @@ -321,9 +331,22 @@ def write_string(*text) text.each do |string| s = string.to_s write_long(s.bytesize) write(s) + end + self + end + + # Writes each argument to the buffer as an SSH2-encoded string. Each + # string is prefixed by its length, encoded as a 4-byte long integer. + # Does not alter the read position. Returns the buffer object. + # Might alter arguments see write_moved + def write_mstring(*text) + text.each do |string| + s = string.to_s + write_long(s.bytesize) + write_moved(s) end self end # Writes each argument to the buffer as a (C-style) boolean, with 1