[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:
Robey Pointer 2005-05-14 06:21:36 +00:00
parent 366f216e3f
commit cb5aa0671b
2 changed files with 20 additions and 5 deletions

View File

@ -46,6 +46,7 @@ class Packetizer (object):
self.__closed = False self.__closed = False
self.__dump_packets = False self.__dump_packets = False
self.__need_rekey = False self.__need_rekey = False
self.__init_count = 0
# used for noticing when to re-key: # used for noticing when to re-key:
self.__sent_bytes = 0 self.__sent_bytes = 0
@ -100,6 +101,10 @@ class Packetizer (object):
self.__mac_key_out = mac_key self.__mac_key_out = mac_key
self.__sent_bytes = 0 self.__sent_bytes = 0
self.__sent_packets = 0 self.__sent_packets = 0
# 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 self.__need_rekey = False
def set_inbound_cipher(self, block_engine, block_size, mac_engine, mac_size, mac_key): def set_inbound_cipher(self, block_engine, block_size, mac_engine, mac_size, mac_key):
@ -114,6 +119,10 @@ class Packetizer (object):
self.__received_bytes = 0 self.__received_bytes = 0
self.__received_packets = 0 self.__received_packets = 0
self.__received_packets_overflow = 0 self.__received_packets_overflow = 0
# 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 self.__need_rekey = False
def close(self): def close(self):

View File

@ -227,6 +227,7 @@ class BaseTransport (threading.Thread):
self.expected_packet = 0 self.expected_packet = 0
self.active = False self.active = False
self.initial_kex_done = False self.initial_kex_done = False
self.in_kex = False
self.lock = threading.Lock() # synchronization (always higher level than write_lock) self.lock = threading.Lock() # synchronization (always higher level than write_lock)
self.channels = { } # (id -> Channel) self.channels = { } # (id -> Channel)
self.channel_events = { } # (id -> Event) self.channel_events = { } # (id -> Event)
@ -860,7 +861,7 @@ class BaseTransport (threading.Thread):
def _send_message(self, data): def _send_message(self, data):
self.packetizer.send_message(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() self._send_kex_init()
def _send_user_message(self, data): def _send_user_message(self, data):
@ -933,7 +934,7 @@ class BaseTransport (threading.Thread):
self.expected_packet = MSG_KEXINIT self.expected_packet = MSG_KEXINIT
while self.active: while self.active:
if self.packetizer.need_rekey(): if self.packetizer.need_rekey() and not self.in_kex:
self._send_kex_init() self._send_kex_init()
ptype, m = self.packetizer.read_message() ptype, m = self.packetizer.read_message()
if ptype == MSG_IGNORE: if ptype == MSG_IGNORE:
@ -1050,6 +1051,7 @@ class BaseTransport (threading.Thread):
kind of key negotiation we support. kind of key negotiation we support.
""" """
self.clear_to_send.clear() self.clear_to_send.clear()
self.in_kex = True
if self.server_mode: if self.server_mode:
if (self._modulus_pack is None) and ('diffie-hellman-group-exchange-sha1' in self._preferred_kex): 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 # 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('none')
m.add('') m.add('')
m.add('') m.add('')
m.add_boolean(0) m.add_boolean(False)
m.add_int(0) m.add_int(0)
# save a copy for later (needed to compute a hash) # save a copy for later (needed to compute a hash)
self.local_kex_init = str(m) self.local_kex_init = str(m)
@ -1212,6 +1214,8 @@ class BaseTransport (threading.Thread):
else: else:
mac_key = self._compute_key('E', mac_engine.digest_size) mac_key = self._compute_key('E', mac_engine.digest_size)
self.packetizer.set_outbound_cipher(engine, block_size, mac_engine, mac_size, mac_key) 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 # we always expect to receive NEWKEYS now
self.expected_packet = MSG_NEWKEYS self.expected_packet = MSG_NEWKEYS
@ -1228,6 +1232,8 @@ class BaseTransport (threading.Thread):
if self.completion_event != None: if self.completion_event != None:
self.completion_event.set() self.completion_event.set()
# it's now okay to send data again (if this was a re-key) # 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() self.clear_to_send.set()
return return