[Zope-Checkins] CVS: ZODB3/ZEO/zrpc - smac.py:1.38.6.3
Jeremy Hylton
jeremy at zope.com
Fri Sep 19 15:47:56 EDT 2003
Update of /cvs-repository/ZODB3/ZEO/zrpc
In directory cvs.zope.org:/tmp/cvs-serv32190
Modified Files:
Tag: Zope-2_7-branch
smac.py
Log Message:
Split single HMAC object into two: one for sends, one for receives.
I couldn't come up with a simple test that failed before this change,
although I expect it is possible. Would be good to do that
eventually.
=== ZODB3/ZEO/zrpc/smac.py 1.38.6.2 => 1.38.6.3 ===
--- ZODB3/ZEO/zrpc/smac.py:1.38.6.2 Fri Sep 19 15:01:28 2003
+++ ZODB3/ZEO/zrpc/smac.py Fri Sep 19 15:47:56 2003
@@ -96,12 +96,33 @@
self.__output_lock = threading.Lock() # Protects __output
self.__output = []
self.__closed = 0
- self.__hmac = None
+ # Each side of the connection sends and receives messages. A
+ # MAC is generated for each message and depends on each
+ # previous MAC; the state of the MAC generator depends on the
+ # history of operations it has performed. So the MACs must be
+ # generated in the same order they are verified.
+
+ # Each side is guaranteed to receive messages in the order
+ # they are sent, but there is no ordering constraint between
+ # message sends and receives. If the two sides are A and B
+ # and message An indicates the nth message sent by A, then
+ # A1 A2 B1 B2 and A1 B1 B2 A2 are both legitimate total
+ # orderings of the messages.
+
+ # As a result, there must be seperate MAC generators for each
+ # side of the connection. If not, the generator state would
+ # be different after A1 A2 B1 B2 than it would be after
+ # A1 B1 B2 A2; if the generator state was different, the MAC
+ # could not be verified.
+ self.__hmac_send = None
+ self.__hmac_recv = None
+
self.__super_init(sock, map)
def setSessionKey(self, sesskey):
log("set session key %r" % sesskey)
- self.__hmac = hmac.HMAC(sesskey, digestmod=sha)
+ self.__hmac_send = hmac.HMAC(sesskey, digestmod=sha)
+ self.__hmac_recv = hmac.HMAC(sesskey, digestmod=sha)
def get_addr(self):
return self.addr
@@ -160,7 +181,7 @@
if has_mac:
msg_size ^= MAC_BIT
msg_size += 20
- elif self.__hmac:
+ elif self.__hmac_send:
raise ValueError("Received message without MAC")
state = 1
else:
@@ -179,9 +200,9 @@
if has_mac:
mac = msg[:20]
msg = msg[20:]
- if self.__hmac:
- self.__hmac.update(msg)
- _mac = self.__hmac.digest()
+ if self.__hmac_recv:
+ self.__hmac_recv.update(msg)
+ _mac = self.__hmac_recv.digest()
if mac != _mac:
raise ValueError("MAC failed: %r != %r"
% (_mac, mac))
@@ -247,8 +268,9 @@
def message_output(self, message):
if __debug__:
if self._debug:
- log("message_output %d bytes: %s" %
- (len(message), short_repr(message)),
+ log("message_output %d bytes: %s hmac=%d" %
+ (len(message), short_repr(message),
+ self.__hmac_send and 1 or 0),
level=zLOG.TRACE)
if self.__closed:
@@ -257,10 +279,10 @@
self.__output_lock.acquire()
try:
# do two separate appends to avoid copying the message string
- if self.__hmac:
+ if self.__hmac_send:
self.__output.append(struct.pack(">I", len(message) | MAC_BIT))
- self.__hmac.update(message)
- self.__output.append(self.__hmac.digest())
+ self.__hmac_send.update(message)
+ self.__output.append(self.__hmac_send.digest())
else:
self.__output.append(struct.pack(">I", len(message)))
if len(message) <= SEND_SIZE:
More information about the Zope-Checkins
mailing list