summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2005-05-14 06:21:36 +0000
committerRobey Pointer <robey@lag.net>2005-05-14 06:21:36 +0000
commitcb5aa0671bfeafacd225de350db3f4e7a049e7bc (patch)
tree45deb2d66250b8e9329c075f5efff623572d1333
parent366f216e3f4792da0f619e6aeff84a91230c2527 (diff)
[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
-rw-r--r--paramiko/packet.py13
-rw-r--r--paramiko/transport.py12
2 files changed, 20 insertions, 5 deletions
diff --git a/paramiko/packet.py b/paramiko/packet.py
index bf4cdb44..2fdc163d 100644
--- a/paramiko/packet.py
+++ b/paramiko/packet.py
@@ -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
diff --git a/paramiko/transport.py b/paramiko/transport.py
index b436847c..dc0632ac 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -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