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
-
#block_size ⇒ Object
readonly
The block size for the cipher.
-
#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
Decompresses 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”.
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/net/ssh/transport/state.rb', line 58 def initialize(socket, role) @socket = socket @role = role @sequence_number = @packets = @blocks = 0 @cipher = CipherFactory.get("none") @block_size = 8 @hmac = HMAC.get("none") @compression = nil @compressor = @decompressor = nil @next_iv = String.new end |
Instance Attribute Details
#block_size ⇒ Object (readonly)
The block size for the cipher
39 40 41 |
# File 'lib/net/ssh/transport/state.rb', line 39 def block_size @block_size end |
#blocks ⇒ Object (readonly)
The number of data blocks processed since the last call to #reset!
33 34 35 |
# File 'lib/net/ssh/transport/state.rb', line 33 def blocks @blocks end |
#cipher ⇒ Object (readonly)
The cipher algorithm in use for this socket endpoint.
36 37 38 |
# File 'lib/net/ssh/transport/state.rb', line 36 def cipher @cipher end |
#compression ⇒ Object (readonly)
The compression algorithm in use for this endpoint.
24 25 26 |
# File 'lib/net/ssh/transport/state.rb', line 24 def compression @compression end |
#compression_level ⇒ Object (readonly)
The compression level to use when compressing data (or nil, for the default).
27 28 29 |
# File 'lib/net/ssh/transport/state.rb', line 27 def compression_level @compression_level end |
#hmac ⇒ Object (readonly)
The hmac algorithm in use for this endpoint.
21 22 23 |
# File 'lib/net/ssh/transport/state.rb', line 21 def hmac @hmac end |
#max_blocks ⇒ Object
The maximum number of blocks that this endpoint wants to process before needing a rekey.
50 51 52 |
# File 'lib/net/ssh/transport/state.rb', line 50 def max_blocks @max_blocks end |
#max_packets ⇒ Object
The maximum number of packets that this endpoint wants to process before needing a rekey.
46 47 48 |
# File 'lib/net/ssh/transport/state.rb', line 46 def max_packets @max_packets end |
#packets ⇒ Object (readonly)
The number of packets processed since the last call to #reset!
30 31 32 |
# File 'lib/net/ssh/transport/state.rb', line 30 def packets @packets end |
#rekey_limit ⇒ Object
The user-specified maximum number of bytes that this endpoint ought to process before needing a rekey.
54 55 56 |
# File 'lib/net/ssh/transport/state.rb', line 54 def rekey_limit @rekey_limit end |
#role ⇒ Object (readonly)
The role that this state plays (either :client or :server)
42 43 44 |
# File 'lib/net/ssh/transport/state.rb', line 42 def role @role end |
#sequence_number ⇒ Object (readonly)
The next packet sequence number for this socket endpoint.
18 19 20 |
# File 'lib/net/ssh/transport/state.rb', line 18 def sequence_number @sequence_number end |
#socket ⇒ Object (readonly)
The socket object that owns this state object.
15 16 17 |
# File 'lib/net/ssh/transport/state.rb', line 15 def socket @socket end |
Instance Method Details
#cleanup ⇒ Object
Closes any the compressor and/or decompressor objects that have been instantiated.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/net/ssh/transport/state.rb', line 168 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.
121 122 123 124 125 126 |
# File 'lib/net/ssh/transport/state.rb', line 121 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.
115 116 117 |
# File 'lib/net/ssh/transport/state.rb', line 115 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.
102 103 104 |
# File 'lib/net/ssh/transport/state.rb', line 102 def compressor @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION) end |
#decompress(data) ⇒ Object
Decompresses the data. If no compression is in effect, this will just return the data unmodified, otherwise it uses #decompressor to decompress the data.
130 131 132 133 134 135 |
# File 'lib/net/ssh/transport/state.rb', line 130 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.
107 108 109 |
# File 'lib/net/ssh/transport/state.rb', line 107 def decompressor @decompressor ||= Zlib::Inflate.new(nil) end |
#final_cipher ⇒ Object
85 86 87 88 89 |
# File 'lib/net/ssh/transport/state.rb', line 85 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.
94 95 96 97 98 |
# File 'lib/net/ssh/transport/state.rb', line 94 def increment(packet_length) @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF @packets += 1 @blocks += (packet_length + 4) / @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.
187 188 189 190 |
# File 'lib/net/ssh/transport/state.rb', line 187 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.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/net/ssh/transport/state.rb', line 140 def reset! @packets = @blocks = 0 @max_packets ||= 1 << 31 @block_size = cipher.block_size 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 @block_size >= 16 @max_blocks = 1 << (@block_size * 2) else @max_blocks = (1 << 30) / @block_size end # if a limit on the # of bytes has been given, convert that into a # minimum number of blocks processed. @max_blocks = [@max_blocks, rekey_limit / @block_size].min if rekey_limit end cleanup end |
#set(values) ⇒ Object
A convenience method for quickly setting multiple values in a single command.
72 73 74 75 76 77 |
# File 'lib/net/ssh/transport/state.rb', line 72 def set(values) values.each do |key, value| instance_variable_set("@#{key}", value) end reset! end |
#update_cipher(data) ⇒ Object
79 80 81 82 83 |
# File 'lib/net/ssh/transport/state.rb', line 79 def update_cipher(data) result = cipher.update(data) update_next_iv(role == :client ? result : data) return result end |