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