[project @ Arch-1:robey@lag.net--2005-master-shake%paramiko--dev--1--patch-9]
oooh maybe i'll test things before checking them in next time: rekeying was a little bit overzealous. now it's careful to only rekey once and reset the counters in sync
This commit is contained in:
parent
366f216e3f
commit
cb5aa0671b
|
@ -46,6 +46,7 @@ class Packetizer (object):
|
|||
self.__closed = False
|
||||
self.__dump_packets = False
|
||||
self.__need_rekey = False
|
||||
self.__init_count = 0
|
||||
|
||||
# used for noticing when to re-key:
|
||||
self.__sent_bytes = 0
|
||||
|
@ -100,7 +101,11 @@ class Packetizer (object):
|
|||
self.__mac_key_out = mac_key
|
||||
self.__sent_bytes = 0
|
||||
self.__sent_packets = 0
|
||||
self.__need_rekey = False
|
||||
# wait until the reset happens in both directions before clearing rekey flag
|
||||
self.__init_count |= 1
|
||||
if self.__init_count == 3:
|
||||
self.__init_count = 0
|
||||
self.__need_rekey = False
|
||||
|
||||
def set_inbound_cipher(self, block_engine, block_size, mac_engine, mac_size, mac_key):
|
||||
"""
|
||||
|
@ -114,7 +119,11 @@ class Packetizer (object):
|
|||
self.__received_bytes = 0
|
||||
self.__received_packets = 0
|
||||
self.__received_packets_overflow = 0
|
||||
self.__need_rekey = False
|
||||
# wait until the reset happens in both directions before clearing rekey flag
|
||||
self.__init_count |= 2
|
||||
if self.__init_count == 3:
|
||||
self.__init_count = 0
|
||||
self.__need_rekey = False
|
||||
|
||||
def close(self):
|
||||
self.__closed = True
|
||||
|
|
|
@ -227,6 +227,7 @@ class BaseTransport (threading.Thread):
|
|||
self.expected_packet = 0
|
||||
self.active = False
|
||||
self.initial_kex_done = False
|
||||
self.in_kex = False
|
||||
self.lock = threading.Lock() # synchronization (always higher level than write_lock)
|
||||
self.channels = { } # (id -> Channel)
|
||||
self.channel_events = { } # (id -> Event)
|
||||
|
@ -860,7 +861,7 @@ class BaseTransport (threading.Thread):
|
|||
|
||||
def _send_message(self, data):
|
||||
self.packetizer.send_message(data)
|
||||
if self.packetizer.need_rekey():
|
||||
if self.packetizer.need_rekey() and not self.in_kex:
|
||||
self._send_kex_init()
|
||||
|
||||
def _send_user_message(self, data):
|
||||
|
@ -933,7 +934,7 @@ class BaseTransport (threading.Thread):
|
|||
self.expected_packet = MSG_KEXINIT
|
||||
|
||||
while self.active:
|
||||
if self.packetizer.need_rekey():
|
||||
if self.packetizer.need_rekey() and not self.in_kex:
|
||||
self._send_kex_init()
|
||||
ptype, m = self.packetizer.read_message()
|
||||
if ptype == MSG_IGNORE:
|
||||
|
@ -1050,6 +1051,7 @@ class BaseTransport (threading.Thread):
|
|||
kind of key negotiation we support.
|
||||
"""
|
||||
self.clear_to_send.clear()
|
||||
self.in_kex = True
|
||||
if self.server_mode:
|
||||
if (self._modulus_pack is None) and ('diffie-hellman-group-exchange-sha1' in self._preferred_kex):
|
||||
# can't do group-exchange if we don't have a pack of potential primes
|
||||
|
@ -1074,7 +1076,7 @@ class BaseTransport (threading.Thread):
|
|||
m.add('none')
|
||||
m.add('')
|
||||
m.add('')
|
||||
m.add_boolean(0)
|
||||
m.add_boolean(False)
|
||||
m.add_int(0)
|
||||
# save a copy for later (needed to compute a hash)
|
||||
self.local_kex_init = str(m)
|
||||
|
@ -1212,6 +1214,8 @@ class BaseTransport (threading.Thread):
|
|||
else:
|
||||
mac_key = self._compute_key('E', mac_engine.digest_size)
|
||||
self.packetizer.set_outbound_cipher(engine, block_size, mac_engine, mac_size, mac_key)
|
||||
if not self.packetizer.need_rekey():
|
||||
self.in_kex = False
|
||||
# we always expect to receive NEWKEYS now
|
||||
self.expected_packet = MSG_NEWKEYS
|
||||
|
||||
|
@ -1228,6 +1232,8 @@ class BaseTransport (threading.Thread):
|
|||
if self.completion_event != None:
|
||||
self.completion_event.set()
|
||||
# it's now okay to send data again (if this was a re-key)
|
||||
if not self.packetizer.need_rekey():
|
||||
self.in_kex = False
|
||||
self.clear_to_send.set()
|
||||
return
|
||||
|
||||
|
|
Loading…
Reference in New Issue