Class: Net::SSH::Buffer

### Home Classes Methods

### In Files

- lib/net/ssh/buffer.rb

### Parent

Object

### Methods

- ::from
- ::new
- #==
- #append
- #available
- #clear!
- #consume!
- #empty?
- #eof?
- #length
- #read
- #read!
- #read_bignum
- #read_bool
- #read_buffer
- #read_byte
- #read_int64
- #read_key
- #read_keyblob
- #read_long
- #read_string
- #read_to
- #remainder_as_buffer
- #reset!
- #to_s
- #write
- #write_bignum
- #write_bool
- #write_byte
- #write_int64
- #write_key
- #write_long
- #write_string

### Files

- README.rdoc

### Class/Module Index

Quicksearch

- Net
- Net::SSH
- Net::SSH::Authentication
- Net::SSH::Authentication::Agent
- Net::SSH::Authentication::Agent::Comment
- Net::SSH::Authentication::AgentError
- Net::SSH::Authentication::AgentNotAvailable
- Net::SSH::Authentication::Constants
- Net::SSH::Authentication::DisallowedMethod
- Net::SSH::Authentication::KeyManager
- Net::SSH::Authentication::KeyManagerError
- Net::SSH::Authentication::Methods
- Net::SSH::Authentication::Methods::Abstract
- Net::SSH::Authentication::Methods::Hostbased
- Net::SSH::Authentication::Methods::KeyboardInteractive
- Net::SSH::Authentication::Methods::None
- Net::SSH::Authentication::Methods::Password
- Net::SSH::Authentication::Methods::Publickey
- Net::SSH::Authentication::Session
- Net::SSH::AuthenticationFailed
- Net::SSH::Buffer
- Net::SSH::ChannelOpenFailed
- Net::SSH::ChannelRequestFailed
- Net::SSH::Compat
- Net::SSH::Config
- Net::SSH::Connection
- Net::SSH::Connection::Channel
- Net::SSH::Connection::Constants
- Net::SSH::Connection::Session
- Net::SSH::Connection::Session::NilChannel
- Net::SSH::Connection::Term
- Net::SSH::ConnectionTimeout
- Net::SSH::Disconnect
- Net::SSH::Exception
- Net::SSH::HostKeyError
- Net::SSH::HostKeyMismatch
- Net::SSH::HostKeyUnknown
- Net::SSH::KeyFactory
- Net::SSH::KnownHosts
- Net::SSH::Loggable
- Net::SSH::Packet
- Net::SSH::PromptMethods
- Net::SSH::PromptMethods::Clear
- Net::SSH::PromptMethods::Highline
- Net::SSH::PromptMethods::Termios
- Net::SSH::Proxy
- Net::SSH::Proxy::Command
- Net::SSH::Proxy::ConnectError
- Net::SSH::Proxy::Error
- Net::SSH::Proxy::HTTP
- Net::SSH::Proxy::SOCKS4
- Net::SSH::Proxy::SOCKS5
- Net::SSH::Proxy::UnauthorizedError
- Net::SSH::Test
- Net::SSH::Test::Channel
- Net::SSH::Test::Extensions
- Net::SSH::Test::Extensions::BufferedIo
- Net::SSH::Test::Extensions::Channel
- Net::SSH::Test::Extensions::IO
- Net::SSH::Test::Extensions::IO::ClassMethods
- Net::SSH::Test::Extensions::PacketStream
- Net::SSH::Test::Kex
- Net::SSH::Test::LocalPacket
- Net::SSH::Test::Packet
- Net::SSH::Test::RemotePacket
- Net::SSH::Test::Script
- Net::SSH::Test::Socket
- Net::SSH::Transport
- Net::SSH::Transport::Algorithms
- Net::SSH::Transport::CTR
- Net::SSH::Transport::CipherFactory
- Net::SSH::Transport::Constants
- Net::SSH::Transport::HMAC
- Net::SSH::Transport::HMAC::Abstract
- Net::SSH::Transport::HMAC::MD5
- Net::SSH::Transport::HMAC::MD5_96
- Net::SSH::Transport::HMAC::None
- Net::SSH::Transport::HMAC::RIPEMD160
- Net::SSH::Transport::HMAC::SHA1
- Net::SSH::Transport::HMAC::SHA1_96
- Net::SSH::Transport::HMAC::SHA2_256
- Net::SSH::Transport::HMAC::SHA2_256_96
- Net::SSH::Transport::HMAC::SHA2_512
- Net::SSH::Transport::HMAC::SHA2_512_96
- Net::SSH::Transport::IdentityCipher
- Net::SSH::Transport::Kex
- Net::SSH::Transport::Kex::DiffieHellmanGroup14SHA1
- Net::SSH::Transport::Kex::DiffieHellmanGroup1SHA1
- Net::SSH::Transport::Kex::DiffieHellmanGroupExchangeSHA1
- Net::SSH::Transport::Kex::DiffieHellmanGroupExchangeSHA256
- Net::SSH::Transport::Kex::EcdhSHA2NistP256
- Net::SSH::Transport::Kex::EcdhSHA2NistP384
- Net::SSH::Transport::Kex::EcdhSHA2NistP521
- Net::SSH::Transport::KeyExpander
- Net::SSH::Transport::PacketStream
- Net::SSH::Transport::ServerVersion
- Net::SSH::Transport::Session
- Net::SSH::Transport::State
- Net::SSH::Verifiers
- Net::SSH::Verifiers::Lenient
- Net::SSH::Verifiers::Null
- Net::SSH::Verifiers::Secure
- Net::SSH::Verifiers::Strict
- Net::SSH::Version
- OpenSSL
- OpenSSL::BN
- OpenSSL::PKey
- OpenSSL::PKey::DH
- OpenSSL::PKey::DSA
- OpenSSL::PKey::EC
- OpenSSL::PKey::OpenSSL
- OpenSSL::PKey::OpenSSL::PKey
- OpenSSL::PKey::OpenSSL::PKey::OpenSSL
- OpenSSL::PKey::OpenSSL::PKey::OpenSSL::PKey
- OpenSSL::PKey::OpenSSL::PKey::OpenSSL::PKey::ECError
- OpenSSL::PKey::PKey
- OpenSSL::PKey::RSA
- String

No matching classes.

# Net::SSH::Buffer

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 for building binary packets given a signature.

Writing to a buffer always appends to the end, regardless of where the read cursor is. Reading, on the other hand, always begins at the first byte of the buffer and increments the read cursor, with subsequent reads taking up where the last left off.

As a consumer of the Net::SSH library, you will rarely come into contact with these buffer objects directly, but it could happen. Also, if you are ever implementing a protocol on top of SSH (e.g. SFTP), this buffer class can be quite handy.

### Attributes

content[R]

exposes the raw content of the buffer

position[RW]

the current position of the pointer in the buffer

### Public Class Methods

from(*args) click to toggle source

This is a convenience method for creating and populating a new buffer from a single command. The arguments must be even in length, with the first of each pair of arguments being a symbol naming the type of the data that follows. If the type is :raw, the value is written directly to the hash.

    b = Buffer.from(:byte, 1, :string, "hello", :raw, "\1\2\3\4")
    #-> "\1\0\0\0\5hello\1\2\3\4"

The supported data types are:

- :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)

- :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 easier to write multiple values of the same type in a briefer manner.

    # File lib/net/ssh/buffer.rb, line 43
    def self.from(*args)
      raise ArgumentError, "odd number of arguments given" unless args.length % 2 == 0

      buffer = new
      0.step(args.length-1, 2) do |index|
        type = args[index]
        value = args[index+1]
        if type == :raw
          buffer.append(value.to_s)
        elsif Array === value
          buffer.send("write_#{type}", *value)
        else
          buffer.send("write_#{type}", value)
        end
      end

      buffer
    end

new(content="") click to toggle source

Creates a new buffer, initialized to the given content. The position is initialized to the beginning of the buffer.

    # File lib/net/ssh/buffer.rb, line 70
    def initialize(content="")
      @content = content.to_s
      @position = 0
    end

### Public Instance Methods

==(buffer) click to toggle source

Compares the contents of the two buffers, returning `true` only if they are identical in size and content.

    # File lib/net/ssh/buffer.rb, line 93
    def ==(buffer)
      to_s == buffer.to_s
    end

append(text) click to toggle source

Appends the given text to the end of the buffer. Does not alter the read position. Returns the buffer object itself.

    # File lib/net/ssh/buffer.rb, line 142
    def append(text)
      @content << text
      self
    end

available() click to toggle source

Returns the number of bytes available to be read (e.g., how many bytes remain between the current position and the end of the buffer).

    # File lib/net/ssh/buffer.rb, line 82
    def available
      length - position
    end

clear!() click to toggle source

Resets the buffer, making it empty. Also, resets the read position to 0.

    # File lib/net/ssh/buffer.rb, line 116
    def clear!
      @content = ""
      @position = 0
    end

consume!(n=position) click to toggle source

Consumes n bytes from the buffer, where n is the current position unless otherwise specified. This is useful for removing data from the buffer that has previously been read, when you are expecting more data to be appended. It helps to keep the size of buffers down when they would otherwise tend to grow without bound.

Returns the buffer object itself.

    # File lib/net/ssh/buffer.rb, line 128
    def consume!(n=position)
      if n >= length
        # optimize for a fairly common case
        clear!
      elsif n > 0
        @content = @content[n..-1] || ""
        @position -= n
        @position = 0 if @position < 0
      end
      self
    end

empty?() click to toggle source

Returns `true` if the buffer contains no data (e.g., it is of zero length).

    # File lib/net/ssh/buffer.rb, line 98
    def empty?
      @content.empty?
    end

eof?() click to toggle source

Returns true if the pointer is at the end of the buffer. Subsequent reads will return nil, in this case.

    # File lib/net/ssh/buffer.rb, line 110
    def eof?
      @position >= length
    end

length() click to toggle source

Returns the length of the buffer's content.

    # File lib/net/ssh/buffer.rb, line 76
    def length
      @content.length
    end

read(count=nil) click to toggle source

Reads and returns the next `count` bytes from the buffer, starting from the read position. If `count` is `nil`, this will return all remaining text in the buffer. This method will increment the pointer.

    # File lib/net/ssh/buffer.rb, line 171
    def read(count=nil)
      count ||= length
      count = length - @position if @position + count > length
      @position += count
      @content[@position-count, count]
    end

read!(count=nil) click to toggle source

Reads (as read) and returns the given number of bytes from the buffer, and then consumes (as consume!) all data up to the new read position.

    # File lib/net/ssh/buffer.rb, line 180
    def read!(count=nil)
      data = read(count)
      consume!
      data
    end

read_bignum() click to toggle source

Read a bignum (OpenSSL::BN) from the buffer, in SSH2 format. It is essentially just a string, which is reinterpreted to be a bignum in binary format.

    # File lib/net/ssh/buffer.rb, line 228
    def read_bignum
      data = read_string
      return unless data
      OpenSSL::BN.new(data, 2)
    end

read_bool() click to toggle source

Read a single byte and convert it into a boolean, using 'C' rules (i.e., zero is false, non-zero is true).

    # File lib/net/ssh/buffer.rb, line 220
    def read_bool
      b = read_byte or return nil
      b != 0
    end

read_buffer() click to toggle source

Reads the next string from the buffer, and returns a new Buffer object that wraps it.

    # File lib/net/ssh/buffer.rb, line 277
    def read_buffer
      Buffer.new(read_string)
    end

read_byte() click to toggle source

Read and return the next byte in the buffer. Returns nil if called at the end of the buffer.

    # File lib/net/ssh/buffer.rb, line 205
    def read_byte
      b = read(1) or return nil
      b.getbyte(0)
    end

read_int64() click to toggle source

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.

    # File lib/net/ssh/buffer.rb, line 189
    def read_int64
      hi = read_long or return nil
      lo = read_long or return nil
      return (hi << 32) + lo
    end

read_key() click to toggle source

Read a key from the buffer. The key will start with a string describing its type. The remainder of the key is defined by the type that was read.

    # File lib/net/ssh/buffer.rb, line 237
    def read_key
      type = read_string
      return (type ? read_keyblob(type) : nil)
    end

read_keyblob(type) click to toggle source

Read a keyblob of the given type from the buffer, and return it as a key. Only RSA, DSA, and ECDSA keys are supported.

    # File lib/net/ssh/buffer.rb, line 244
    def read_keyblob(type)
      case type
        when "ssh-dss"
          key = OpenSSL::PKey::DSA.new
          key.p = read_bignum
          key.q = read_bignum
          key.g = read_bignum
          key.pub_key = read_bignum

        when "ssh-rsa"
          key = OpenSSL::PKey::RSA.new
          key.e = read_bignum
          key.n = read_bignum

        when /^ecdsa\-sha2\-(\w*)$/
          unless defined?(OpenSSL::PKey::EC)
            raise NotImplementedError, "unsupported key type `#{type}'"
          else
            begin
              key = OpenSSL::PKey::EC.read_keyblob($1, self)
            rescue OpenSSL::PKey::ECError
              raise NotImplementedError, "unsupported key type `#{type}'"
            end
          end
        else
          raise NotImplementedError, "unsupported key type `#{type}'"
      end

      return key
    end

read_long() click to toggle source

Return the next four bytes as a long integer (in network byte order). Returns nil if there are less than 4 bytes remaining to be read in the buffer.

    # File lib/net/ssh/buffer.rb, line 198
    def read_long
      b = read(4) or return nil
      b.unpack("N").first
    end

read_string() click to toggle source

Read and return an SSH2-encoded string. The string starts with a long integer that describes the number of bytes remaining in the string. Returns nil if there are not enough bytes to satisfy the request.

    # File lib/net/ssh/buffer.rb, line 213
    def read_string
      length = read_long or return nil
      read(length)
    end

read_to(pattern) click to toggle source

Reads all data up to and including the given pattern, which may be a String, Fixnum, or Regexp and is interpreted exactly as String#index does. Returns nil if nothing matches. Increments the position to point immediately after the pattern, if it does match. Returns all data up to and including the text that matched the pattern.

    # File lib/net/ssh/buffer.rb, line 158
    def read_to(pattern)
      index = @content.index(pattern, @position) or return nil
      length = case pattern
        when String then pattern.length
        when Fixnum then 1
        when Regexp then $&.length
      end
      index && read(index+length)
    end

remainder_as_buffer() click to toggle source

Returns all text from the current pointer to the end of the buffer as a new Net::SSH::Buffer object.

    # File lib/net/ssh/buffer.rb, line 149
    def remainder_as_buffer
      Buffer.new(@content[@position..-1])
    end

reset!() click to toggle source

Resets the pointer to the start of the buffer. Subsequent reads will begin at position 0.

    # File lib/net/ssh/buffer.rb, line 104
    def reset!
      @position = 0
    end

to_s() click to toggle source

Returns a copy of the buffer's content.

    # File lib/net/ssh/buffer.rb, line 87
    def to_s
      (@content || "").dup
    end

write(*data) click to toggle source

Writes the given data literally into the string. Does not alter the read position. Returns the buffer object.

    # File lib/net/ssh/buffer.rb, line 283
    def write(*data)
      data.each { |datum| @content << datum }
      self
    end

write_bignum(*n) click to toggle source

Writes each argument to the buffer as a bignum (SSH2-style). No checking is done to ensure that the arguments are, in fact, bignums. Does not alter the read position. Returns the buffer object.

    # File lib/net/ssh/buffer.rb, line 338
    def write_bignum(*n)
      @content << n.map { |b| b.to_ssh }.join
      self
    end

write_bool(*b) click to toggle source

Writes each argument to the buffer as a (C-style) boolean, with 1 meaning true, and 0 meaning false. Does not alter the read position. Returns the buffer object.

    # File lib/net/ssh/buffer.rb, line 330
    def write_bool(*b)
      b.each { |v| @content << (v ? "\11"" : "\00"") }
      self
    end

write_byte(*n) click to toggle source

Writes each argument to the buffer as a byte. Does not alter the read position. Returns the buffer object.

    # File lib/net/ssh/buffer.rb, line 310
    def write_byte(*n)
      n.each { |b| @content << b.chr }
      self
    end

write_int64(*n) click to toggle source

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.

    # File lib/net/ssh/buffer.rb, line 291
    def write_int64(*n)
      n.each do |i|
        hi = (i >> 32) & 0xFFFFFFFF
        lo = i & 0xFFFFFFFF
        @content << [hi, lo].pack("N2")
      end
      self
    end

write_key(*key) click to toggle source

Writes the given arguments to the buffer as SSH2-encoded keys. Does not alter the read position. Returns the buffer object.

    # File lib/net/ssh/buffer.rb, line 345
    def write_key(*key)
      key.each { |k| append(k.to_blob) }
      self
    end

write_long(*n) click to toggle source

Writes each argument to the buffer as a network-byte-order-encoded long (4-byte) integer. Does not alter the read position. Returns the buffer object.

    # File lib/net/ssh/buffer.rb, line 303
    def write_long(*n)
      @content << n.pack("N*")
      self
    end

write_string(*text) click to toggle source

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.

    # File lib/net/ssh/buffer.rb, line 318
    def write_string(*text)
      text.each do |string|
        s = string.to_s
        write_long(s.bytesize)
        write(s)
      end
      self
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.