Class: Net::SSH::Transport::State
- Inherits:
-
Object
- Object
- Net::SSH::Transport::State
- Defined in:
- lib/net/ssh/transport/state.rb
Overview
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.
Instance Attribute Summary collapse
-
#blocks ⇒ Object
readonly
The number of data blocks processed since the last call to #reset!.
-
#cipher ⇒ Object
readonly
The cipher algorithm in use for this socket endpoint.
-
#compression ⇒ Object
readonly
The compression algorithm in use for this endpoint.
-
#compression_level ⇒ Object
readonly
The compression level to use when compressing data (or nil, for the default).
-
#hmac ⇒ Object
readonly
The hmac algorithm in use for this endpoint.
-
#max_blocks ⇒ Object
The maximum number of blocks that this endpoint wants to process before needing a rekey.
-
#max_packets ⇒ Object
The maximum number of packets that this endpoint wants to process before needing a rekey.
-
#packets ⇒ Object
readonly
The number of packets processed since the last call to #reset!.
-
#rekey_limit ⇒ Object
The user-specified maximum number of bytes that this endpoint ought to process before needing a rekey.
-
#role ⇒ Object
readonly
The role that this state plays (either :client or :server).
-
#sequence_number ⇒ Object
readonly
The next packet sequence number for this socket endpoint.
-
#socket ⇒ Object
readonly
The socket object that owns this state object.
Instance Method Summary collapse
-
#cleanup ⇒ Object
Closes any the compressor and/or decompressor objects that have been instantiated.
-
#compress(data) ⇒ Object
Compresses the data.
-
#compression? ⇒ Boolean
Returns true if data compression/decompression is enabled.
-
#compressor ⇒ Object
The compressor object to use when compressing data.
-
#decompress(data) ⇒ Object
Deompresses the data.
-
#decompressor ⇒ Object
The decompressor object to use when decompressing data.
- #final_cipher ⇒ Object
-
#increment(packet_length) ⇒ Object
Increments the counters.
-
#initialize(socket, role) ⇒ State
constructor
Creates a new state object, belonging to the given socket.
-
#needs_rekey? ⇒ Boolean
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.
-
#reset! ⇒ Object
Resets the counters on the state object, but leaves the sequence_number unchanged.
-
#set(values) ⇒ Object
A convenience method for quickly setting multiple values in a single command.
- #update_cipher(data) ⇒ Object
Constructor Details
#initialize(socket, role) ⇒ State
Creates a new state object, belonging to the given socket. Initializes the algorithms to “none”.
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/net/ssh/transport/state.rb', line 54 def initialize(socket, role) @socket = socket @role = role @sequence_number = @packets = @blocks = 0 @cipher = CipherFactory.get("none") @hmac = HMAC.get("none") @compression = nil @compressor = @decompressor = nil @next_iv = "" end |
Instance Attribute Details
#blocks ⇒ Object (readonly)
The number of data blocks processed since the last call to #reset!
32 33 34 |
# File 'lib/net/ssh/transport/state.rb', line 32 def blocks @blocks end |
#cipher ⇒ Object (readonly)
The cipher algorithm in use for this socket endpoint.
35 36 37 |
# File 'lib/net/ssh/transport/state.rb', line 35 def cipher @cipher end |
#compression ⇒ Object (readonly)
The compression algorithm in use for this endpoint.
23 24 25 |
# File 'lib/net/ssh/transport/state.rb', line 23 def compression @compression end |
#compression_level ⇒ Object (readonly)
The compression level to use when compressing data (or nil, for the default).
26 27 28 |
# File 'lib/net/ssh/transport/state.rb', line 26 def compression_level @compression_level end |
#hmac ⇒ Object (readonly)
The hmac algorithm in use for this endpoint.
20 21 22 |
# File 'lib/net/ssh/transport/state.rb', line 20 def hmac @hmac end |
#max_blocks ⇒ Object
The maximum number of blocks that this endpoint wants to process before needing a rekey.
46 47 48 |
# File 'lib/net/ssh/transport/state.rb', line 46 def max_blocks @max_blocks end |
#max_packets ⇒ Object
The maximum number of packets that this endpoint wants to process before needing a rekey.
42 43 44 |
# File 'lib/net/ssh/transport/state.rb', line 42 def max_packets @max_packets end |
#packets ⇒ Object (readonly)
The number of packets processed since the last call to #reset!
29 30 31 |
# File 'lib/net/ssh/transport/state.rb', line 29 def packets @packets end |
#rekey_limit ⇒ Object
The user-specified maximum number of bytes that this endpoint ought to process before needing a rekey.
50 51 52 |
# File 'lib/net/ssh/transport/state.rb', line 50 def rekey_limit @rekey_limit end |
#role ⇒ Object (readonly)
The role that this state plays (either :client or :server)
38 39 40 |
# File 'lib/net/ssh/transport/state.rb', line 38 def role @role end |
#sequence_number ⇒ Object (readonly)
The next packet sequence number for this socket endpoint.
17 18 19 |
# File 'lib/net/ssh/transport/state.rb', line 17 def sequence_number @sequence_number end |
#socket ⇒ Object (readonly)
The socket object that owns this state object.
14 15 16 |
# File 'lib/net/ssh/transport/state.rb', line 14 def socket @socket end |
Instance Method Details
#cleanup ⇒ Object
Closes any the compressor and/or decompressor objects that have been instantiated.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/net/ssh/transport/state.rb', line 162 def cleanup if @compressor @compressor.finish if !@compressor.finished? @compressor.close end if @decompressor # we call reset here so that we don't get warnings when we try to # close the decompressor @decompressor.reset @decompressor.close end @compressor = @decompressor = nil end |
#compress(data) ⇒ Object
Compresses the data. If no compression is in effect, this will just return the data unmodified, otherwise it uses #compressor to compress the data.
116 117 118 119 120 |
# File 'lib/net/ssh/transport/state.rb', line 116 def compress(data) data = data.to_s return data unless compression? compressor.deflate(data, Zlib::SYNC_FLUSH) end |
#compression? ⇒ Boolean
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.
110 111 112 |
# File 'lib/net/ssh/transport/state.rb', line 110 def compression? compression == :standard || (compression == :delayed && socket.hints[:authenticated]) end |
#compressor ⇒ Object
The compressor object to use when compressing data. This takes into account the desired compression level.
97 98 99 |
# File 'lib/net/ssh/transport/state.rb', line 97 def compressor @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION) end |
#decompress(data) ⇒ Object
Deompresses the data. If no compression is in effect, this will just return the data unmodified, otherwise it uses #decompressor to decompress the data.
124 125 126 127 128 |
# File 'lib/net/ssh/transport/state.rb', line 124 def decompress(data) data = data.to_s return data unless compression? decompressor.inflate(data) end |
#decompressor ⇒ Object
The decompressor object to use when decompressing data.
102 103 104 |
# File 'lib/net/ssh/transport/state.rb', line 102 def decompressor @decompressor ||= Zlib::Inflate.new(nil) end |
#final_cipher ⇒ Object
80 81 82 83 84 |
# File 'lib/net/ssh/transport/state.rb', line 80 def final_cipher result = cipher.final update_next_iv(role == :client ? result : "", true) return result end |
#increment(packet_length) ⇒ Object
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.
89 90 91 92 93 |
# File 'lib/net/ssh/transport/state.rb', line 89 def increment(packet_length) @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF @packets += 1 @blocks += (packet_length + 4) / cipher.block_size end |
#needs_rekey? ⇒ Boolean
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.
181 182 183 184 |
# File 'lib/net/ssh/transport/state.rb', line 181 def needs_rekey? max_packets && packets > max_packets || max_blocks && blocks > max_blocks end |
#reset! ⇒ Object
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.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/net/ssh/transport/state.rb', line 133 def reset! @packets = @blocks = 0 @max_packets ||= 1 << 31 if max_blocks.nil? # cargo-culted from openssh. the idea is that "the 2^(blocksize*2) # limit is too expensive for 3DES, blowfish, etc., so enforce a 1GB # limit for small blocksizes." if cipher.block_size >= 16 @max_blocks = 1 << (cipher.block_size * 2) else @max_blocks = (1 << 30) / cipher.block_size end # if a limit on the # of bytes has been given, convert that into a # minimum number of blocks processed. if rekey_limit @max_blocks = [@max_blocks, rekey_limit / cipher.block_size].min end end cleanup end |
#set(values) ⇒ Object
A convenience method for quickly setting multiple values in a single command.
67 68 69 70 71 72 |
# File 'lib/net/ssh/transport/state.rb', line 67 def set(values) values.each do |key, value| instance_variable_set("@#{key}", value) end reset! end |
#update_cipher(data) ⇒ Object
74 75 76 77 78 |
# File 'lib/net/ssh/transport/state.rb', line 74 def update_cipher(data) result = cipher.update(data) update_next_iv(role == :client ? result : data) return result end |