Class Net::SSH::Transport::State
In: lib/net/ssh/transport/state.rb
lib/net/ssh/transport/state.rb
Parent: Object

Encapsulates state information about one end of an SSH connection. Such state includes the packet sequence number, the algorithms in use, how many packets and blocks have been processed since the last reset, and so forth. This class will never be instantiated directly, but is used as part of the internal state of the PacketStream module.

Methods

Attributes

blocks  [R]  The number of data blocks processed since the last call to reset!
blocks  [R]  The number of data blocks processed since the last call to reset!
cipher  [R]  The cipher algorithm in use for this socket endpoint.
cipher  [R]  The cipher algorithm in use for this socket endpoint.
compression  [R]  The compression algorithm in use for this endpoint.
compression  [R]  The compression algorithm in use for this endpoint.
compression_level  [R]  The compression level to use when compressing data (or nil, for the default).
compression_level  [R]  The compression level to use when compressing data (or nil, for the default).
hmac  [R]  The hmac algorithm in use for this endpoint.
hmac  [R]  The hmac algorithm in use for this endpoint.
max_blocks  [RW]  The maximum number of blocks that this endpoint wants to process before needing a rekey.
max_blocks  [RW]  The maximum number of blocks that this endpoint wants to process before needing a rekey.
max_packets  [RW]  The maximum number of packets that this endpoint wants to process before needing a rekey.
max_packets  [RW]  The maximum number of packets that this endpoint wants to process before needing a rekey.
packets  [R]  The number of packets processed since the last call to reset!
packets  [R]  The number of packets processed since the last call to reset!
rekey_limit  [RW]  The user-specified maximum number of bytes that this endpoint ought to process before needing a rekey.
rekey_limit  [RW]  The user-specified maximum number of bytes that this endpoint ought to process before needing a rekey.
role  [R]  The role that this state plays (either :client or :server)
role  [R]  The role that this state plays (either :client or :server)
sequence_number  [R]  The next packet sequence number for this socket endpoint.
sequence_number  [R]  The next packet sequence number for this socket endpoint.
socket  [R]  The socket object that owns this state object.
socket  [R]  The socket object that owns this state object.

Public Class methods

Creates a new state object, belonging to the given socket. Initializes the algorithms to "none".

[Source]

    # File lib/net/ssh/transport/state.rb, line 54
54:     def initialize(socket, role)
55:       @socket = socket
56:       @role = role
57:       @sequence_number = @packets = @blocks = 0
58:       @cipher = CipherFactory.get("none")
59:       @hmac = HMAC.get("none")
60:       @compression = nil
61:       @compressor = @decompressor = nil
62:       @next_iv = ""
63:     end

Creates a new state object, belonging to the given socket. Initializes the algorithms to "none".

[Source]

    # File lib/net/ssh/transport/state.rb, line 54
54:     def initialize(socket, role)
55:       @socket = socket
56:       @role = role
57:       @sequence_number = @packets = @blocks = 0
58:       @cipher = CipherFactory.get("none")
59:       @hmac = HMAC.get("none")
60:       @compression = nil
61:       @compressor = @decompressor = nil
62:       @next_iv = ""
63:     end

Public Instance methods

Closes any the compressor and/or decompressor objects that have been instantiated.

[Source]

     # File lib/net/ssh/transport/state.rb, line 162
162:     def cleanup
163:       if @compressor
164:         @compressor.finish if !@compressor.finished?
165:         @compressor.close
166:       end
167: 
168:       if @decompressor
169:         # we call reset here so that we don't get warnings when we try to
170:         # close the decompressor
171:         @decompressor.reset
172:         @decompressor.close
173:       end
174: 
175:       @compressor = @decompressor = nil
176:     end

Closes any the compressor and/or decompressor objects that have been instantiated.

[Source]

     # File lib/net/ssh/transport/state.rb, line 162
162:     def cleanup
163:       if @compressor
164:         @compressor.finish if !@compressor.finished?
165:         @compressor.close
166:       end
167: 
168:       if @decompressor
169:         # we call reset here so that we don't get warnings when we try to
170:         # close the decompressor
171:         @decompressor.reset
172:         @decompressor.close
173:       end
174: 
175:       @compressor = @decompressor = nil
176:     end

Compresses the data. If no compression is in effect, this will just return the data unmodified, otherwise it uses compressor to compress the data.

[Source]

     # File lib/net/ssh/transport/state.rb, line 116
116:     def compress(data)
117:       data = data.to_s
118:       return data unless compression?
119:       compressor.deflate(data, Zlib::SYNC_FLUSH)
120:     end

Compresses the data. If no compression is in effect, this will just return the data unmodified, otherwise it uses compressor to compress the data.

[Source]

     # File lib/net/ssh/transport/state.rb, line 116
116:     def compress(data)
117:       data = data.to_s
118:       return data unless compression?
119:       compressor.deflate(data, Zlib::SYNC_FLUSH)
120:     end

Returns true if data compression/decompression is enabled. This will return true if :standard compression is selected, or if :delayed compression is selected and the :authenticated hint has been received by the socket.

[Source]

     # File lib/net/ssh/transport/state.rb, line 110
110:     def compression?
111:       compression == :standard || (compression == :delayed && socket.hints[:authenticated])
112:     end

Returns true if data compression/decompression is enabled. This will return true if :standard compression is selected, or if :delayed compression is selected and the :authenticated hint has been received by the socket.

[Source]

     # File lib/net/ssh/transport/state.rb, line 110
110:     def compression?
111:       compression == :standard || (compression == :delayed && socket.hints[:authenticated])
112:     end

The compressor object to use when compressing data. This takes into account the desired compression level.

[Source]

    # File lib/net/ssh/transport/state.rb, line 97
97:     def compressor
98:       @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION)
99:     end

The compressor object to use when compressing data. This takes into account the desired compression level.

[Source]

    # File lib/net/ssh/transport/state.rb, line 97
97:     def compressor
98:       @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION)
99:     end

Deompresses the data. If no compression is in effect, this will just return the data unmodified, otherwise it uses decompressor to decompress the data.

[Source]

     # File lib/net/ssh/transport/state.rb, line 124
124:     def decompress(data)
125:       data = data.to_s
126:       return data unless compression?
127:       decompressor.inflate(data)
128:     end

Deompresses the data. If no compression is in effect, this will just return the data unmodified, otherwise it uses decompressor to decompress the data.

[Source]

     # File lib/net/ssh/transport/state.rb, line 124
124:     def decompress(data)
125:       data = data.to_s
126:       return data unless compression?
127:       decompressor.inflate(data)
128:     end

The decompressor object to use when decompressing data.

[Source]

     # File lib/net/ssh/transport/state.rb, line 102
102:     def decompressor
103:       @decompressor ||= Zlib::Inflate.new(nil)
104:     end

The decompressor object to use when decompressing data.

[Source]

     # File lib/net/ssh/transport/state.rb, line 102
102:     def decompressor
103:       @decompressor ||= Zlib::Inflate.new(nil)
104:     end

[Source]

    # File lib/net/ssh/transport/state.rb, line 80
80:     def final_cipher
81:       result = cipher.final
82:       update_next_iv(role == :client ? result : "", true)
83:       return result
84:     end

[Source]

    # File lib/net/ssh/transport/state.rb, line 80
80:     def final_cipher
81:       result = cipher.final
82:       update_next_iv(role == :client ? result : "", true)
83:       return result
84:     end

Increments the counters. The sequence number is incremented (and remapped so it always fits in a 32-bit integer). The number of packets and blocks are also incremented.

[Source]

    # File lib/net/ssh/transport/state.rb, line 89
89:     def increment(packet_length)
90:       @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF
91:       @packets += 1
92:       @blocks += (packet_length + 4) / cipher.block_size
93:     end

Increments the counters. The sequence number is incremented (and remapped so it always fits in a 32-bit integer). The number of packets and blocks are also incremented.

[Source]

    # File lib/net/ssh/transport/state.rb, line 89
89:     def increment(packet_length)
90:       @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF
91:       @packets += 1
92:       @blocks += (packet_length + 4) / cipher.block_size
93:     end

Returns true if the number of packets processed exceeds the maximum number of packets, or if the number of blocks processed exceeds the maximum number of blocks.

[Source]

     # File lib/net/ssh/transport/state.rb, line 181
181:     def needs_rekey?
182:       max_packets && packets > max_packets ||
183:       max_blocks && blocks > max_blocks
184:     end

Returns true if the number of packets processed exceeds the maximum number of packets, or if the number of blocks processed exceeds the maximum number of blocks.

[Source]

     # File lib/net/ssh/transport/state.rb, line 181
181:     def needs_rekey?
182:       max_packets && packets > max_packets ||
183:       max_blocks && blocks > max_blocks
184:     end

Resets the counters on the state object, but leaves the sequence_number unchanged. It also sets defaults for and recomputes the max_packets and max_blocks values.

[Source]

     # File lib/net/ssh/transport/state.rb, line 133
133:     def reset!
134:       @packets = @blocks = 0
135: 
136:       @max_packets ||= 1 << 31
137: 
138:       if max_blocks.nil?
139:         # cargo-culted from openssh. the idea is that "the 2^(blocksize*2)
140:         # limit is too expensive for 3DES, blowfish, etc., so enforce a 1GB
141:         # limit for small blocksizes."
142: 
143:         if cipher.block_size >= 16
144:           @max_blocks = 1 << (cipher.block_size * 2)
145:         else
146:           @max_blocks = (1 << 30) / cipher.block_size
147:         end
148: 
149:         # if a limit on the # of bytes has been given, convert that into a
150:         # minimum number of blocks processed.
151: 
152:         if rekey_limit
153:           @max_blocks = [@max_blocks, rekey_limit / cipher.block_size].min
154:         end
155:       end
156: 
157:       cleanup
158:     end

Resets the counters on the state object, but leaves the sequence_number unchanged. It also sets defaults for and recomputes the max_packets and max_blocks values.

[Source]

     # File lib/net/ssh/transport/state.rb, line 133
133:     def reset!
134:       @packets = @blocks = 0
135: 
136:       @max_packets ||= 1 << 31
137: 
138:       if max_blocks.nil?
139:         # cargo-culted from openssh. the idea is that "the 2^(blocksize*2)
140:         # limit is too expensive for 3DES, blowfish, etc., so enforce a 1GB
141:         # limit for small blocksizes."
142: 
143:         if cipher.block_size >= 16
144:           @max_blocks = 1 << (cipher.block_size * 2)
145:         else
146:           @max_blocks = (1 << 30) / cipher.block_size
147:         end
148: 
149:         # if a limit on the # of bytes has been given, convert that into a
150:         # minimum number of blocks processed.
151: 
152:         if rekey_limit
153:           @max_blocks = [@max_blocks, rekey_limit / cipher.block_size].min
154:         end
155:       end
156: 
157:       cleanup
158:     end

A convenience method for quickly setting multiple values in a single command.

[Source]

    # File lib/net/ssh/transport/state.rb, line 67
67:     def set(values)
68:       values.each do |key, value|
69:         instance_variable_set("@#{key}", value)
70:       end
71:       reset!
72:     end

A convenience method for quickly setting multiple values in a single command.

[Source]

    # File lib/net/ssh/transport/state.rb, line 67
67:     def set(values)
68:       values.each do |key, value|
69:         instance_variable_set("@#{key}", value)
70:       end
71:       reset!
72:     end

[Source]

    # File lib/net/ssh/transport/state.rb, line 74
74:     def update_cipher(data)
75:       result = cipher.update(data)
76:       update_next_iv(role == :client ? result : data)
77:       return result
78:     end

[Source]

    # File lib/net/ssh/transport/state.rb, line 74
74:     def update_cipher(data)
75:       result = cipher.update(data)
76:       update_next_iv(role == :client ? result : data)
77:       return result
78:     end

[Validate]