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.
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. |
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. |
Creates a new state object, belonging to the given socket. Initializes the algorithms to "none".
# File lib/net/ssh/transport/state.rb, line 51 51: def initialize(socket) 52: @socket = socket 53: @sequence_number = @packets = @blocks = 0 54: @cipher = CipherFactory.get("none") 55: @hmac = HMAC.get("none") 56: @compression = nil 57: @compressor = @decompressor = nil 58: end
Creates a new state object, belonging to the given socket. Initializes the algorithms to "none".
# File lib/net/ssh/transport/state.rb, line 51 51: def initialize(socket) 52: @socket = socket 53: @sequence_number = @packets = @blocks = 0 54: @cipher = CipherFactory.get("none") 55: @hmac = HMAC.get("none") 56: @compression = nil 57: @compressor = @decompressor = nil 58: end
Closes any the compressor and/or decompressor objects that have been instantiated.
# File lib/net/ssh/transport/state.rb, line 145 145: def cleanup 146: if @compressor 147: @compressor.finish if !@compressor.finished? 148: @compressor.close 149: end 150: 151: if @decompressor 152: # we call reset here so that we don't get warnings when we try to 153: # close the decompressor 154: @decompressor.reset 155: @decompressor.close 156: end 157: 158: @compressor = @decompressor = nil 159: end
Closes any the compressor and/or decompressor objects that have been instantiated.
# File lib/net/ssh/transport/state.rb, line 145 145: def cleanup 146: if @compressor 147: @compressor.finish if !@compressor.finished? 148: @compressor.close 149: end 150: 151: if @decompressor 152: # we call reset here so that we don't get warnings when we try to 153: # close the decompressor 154: @decompressor.reset 155: @decompressor.close 156: end 157: 158: @compressor = @decompressor = nil 159: 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.
# File lib/net/ssh/transport/state.rb, line 99 99: def compress(data) 100: data = data.to_s 101: return data unless compression? 102: compressor.deflate(data, Zlib::SYNC_FLUSH) 103: 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.
# File lib/net/ssh/transport/state.rb, line 99 99: def compress(data) 100: data = data.to_s 101: return data unless compression? 102: compressor.deflate(data, Zlib::SYNC_FLUSH) 103: 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.
# File lib/net/ssh/transport/state.rb, line 93 93: def compression? 94: compression == :standard || (compression == :delayed && socket.hints[:authenticated]) 95: 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.
# File lib/net/ssh/transport/state.rb, line 93 93: def compression? 94: compression == :standard || (compression == :delayed && socket.hints[:authenticated]) 95: end
The compressor object to use when compressing data. This takes into account the desired compression level.
# File lib/net/ssh/transport/state.rb, line 80 80: def compressor 81: @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION) 82: end
The compressor object to use when compressing data. This takes into account the desired compression level.
# File lib/net/ssh/transport/state.rb, line 80 80: def compressor 81: @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION) 82: 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.
# File lib/net/ssh/transport/state.rb, line 107 107: def decompress(data) 108: data = data.to_s 109: return data unless compression? 110: decompressor.inflate(data) 111: 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.
# File lib/net/ssh/transport/state.rb, line 107 107: def decompress(data) 108: data = data.to_s 109: return data unless compression? 110: decompressor.inflate(data) 111: end
The decompressor object to use when decompressing data.
# File lib/net/ssh/transport/state.rb, line 85 85: def decompressor 86: @decompressor ||= Zlib::Inflate.new(nil) 87: end
The decompressor object to use when decompressing data.
# File lib/net/ssh/transport/state.rb, line 85 85: def decompressor 86: @decompressor ||= Zlib::Inflate.new(nil) 87: 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.
# File lib/net/ssh/transport/state.rb, line 72 72: def increment(packet_length) 73: @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF 74: @packets += 1 75: @blocks += (packet_length + 4) / cipher.block_size 76: 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.
# File lib/net/ssh/transport/state.rb, line 72 72: def increment(packet_length) 73: @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF 74: @packets += 1 75: @blocks += (packet_length + 4) / cipher.block_size 76: 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.
# File lib/net/ssh/transport/state.rb, line 164 164: def needs_rekey? 165: max_packets && packets > max_packets || 166: max_blocks && blocks > max_blocks 167: 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.
# File lib/net/ssh/transport/state.rb, line 164 164: def needs_rekey? 165: max_packets && packets > max_packets || 166: max_blocks && blocks > max_blocks 167: 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.
# File lib/net/ssh/transport/state.rb, line 116 116: def reset! 117: @packets = @blocks = 0 118: 119: @max_packets ||= 1 << 31 120: 121: if max_blocks.nil? 122: # cargo-culted from openssh. the idea is that "the 2^(blocksize*2) 123: # limit is too expensive for 3DES, blowfish, etc., so enforce a 1GB 124: # limit for small blocksizes." 125: 126: if cipher.block_size >= 16 127: @max_blocks = 1 << (cipher.block_size * 2) 128: else 129: @max_blocks = (1 << 30) / cipher.block_size 130: end 131: 132: # if a limit on the # of bytes has been given, convert that into a 133: # minimum number of blocks processed. 134: 135: if rekey_limit 136: @max_blocks = [@max_blocks, rekey_limit / cipher.block_size].min 137: end 138: end 139: 140: cleanup 141: 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.
# File lib/net/ssh/transport/state.rb, line 116 116: def reset! 117: @packets = @blocks = 0 118: 119: @max_packets ||= 1 << 31 120: 121: if max_blocks.nil? 122: # cargo-culted from openssh. the idea is that "the 2^(blocksize*2) 123: # limit is too expensive for 3DES, blowfish, etc., so enforce a 1GB 124: # limit for small blocksizes." 125: 126: if cipher.block_size >= 16 127: @max_blocks = 1 << (cipher.block_size * 2) 128: else 129: @max_blocks = (1 << 30) / cipher.block_size 130: end 131: 132: # if a limit on the # of bytes has been given, convert that into a 133: # minimum number of blocks processed. 134: 135: if rekey_limit 136: @max_blocks = [@max_blocks, rekey_limit / cipher.block_size].min 137: end 138: end 139: 140: cleanup 141: end
A convenience method for quickly setting multiple values in a single command.
# File lib/net/ssh/transport/state.rb, line 62 62: def set(values) 63: values.each do |key, value| 64: instance_variable_set("@#{key}", value) 65: end 66: reset! 67: end