188: def poll_next_packet
189: if @packet.nil?
190: minimum = server.block_size < 4 ? 4 : server.block_size
191: return nil if available < minimum
192: data = read_available(minimum)
193:
194:
195: @packet = Net::SSH::Buffer.new(server.update_cipher(data))
196: @packet_length = @packet.read_long
197: end
198:
199: need = @packet_length + 4 - server.block_size
200: raise Net::SSH::Exception, "padding error, need #{need} block #{server.block_size}" if need % server.block_size != 0
201:
202: return nil if available < need + server.hmac.mac_length
203:
204: if need > 0
205:
206: data = read_available(need)
207: @packet.append(server.update_cipher(data))
208: end
209:
210:
211:
212: real_hmac = read_available(server.hmac.mac_length) || ""
213:
214: @packet.append(server.final_cipher)
215: padding_length = @packet.read_byte
216:
217: payload = @packet.read(@packet_length - padding_length - 1)
218: padding = @packet.read(padding_length) if padding_length > 0
219:
220: my_computed_hmac = server.hmac.digest([server.sequence_number, @packet.content].pack("NA*"))
221: raise Net::SSH::Exception, "corrupted mac detected" if real_hmac != my_computed_hmac
222:
223:
224: payload = server.decompress(payload)
225:
226: debug { "received packet nr #{server.sequence_number} type #{payload.getbyte(0)} len #{@packet_length}" }
227:
228: server.increment(@packet_length)
229: @packet = nil
230:
231: return Packet.new(payload)
232: end