##// END OF EJS Templates
cull Session digest history...
MinRK -
Show More
@@ -28,6 +28,7 b' import hmac'
28 import logging
28 import logging
29 import os
29 import os
30 import pprint
30 import pprint
31 import random
31 import uuid
32 import uuid
32 from datetime import datetime
33 from datetime import datetime
33
34
@@ -310,8 +311,16 b' class Session(Configurable):'
310 self.auth = hmac.HMAC(new)
311 self.auth = hmac.HMAC(new)
311 else:
312 else:
312 self.auth = None
313 self.auth = None
314
313 auth = Instance(hmac.HMAC)
315 auth = Instance(hmac.HMAC)
316
314 digest_history = Set()
317 digest_history = Set()
318 digest_history_size = Integer(2**16, config=True,
319 help="""The maximum number of digests to remember.
320
321 The digest history will be culled when it exceeds this value.
322 """
323 )
315
324
316 keyfile = Unicode('', config=True,
325 keyfile = Unicode('', config=True,
317 help="""path to file containing execution key.""")
326 help="""path to file containing execution key.""")
@@ -699,6 +708,30 b' class Session(Configurable):'
699 idents, msg_list = msg_list[:idx], msg_list[idx+1:]
708 idents, msg_list = msg_list[:idx], msg_list[idx+1:]
700 return [m.bytes for m in idents], msg_list
709 return [m.bytes for m in idents], msg_list
701
710
711 def _add_digest(self, signature):
712 """add a digest to history to protect against replay attacks"""
713 if self.digest_history_size == 0:
714 # no history, never add digests
715 return
716
717 self.digest_history.add(signature)
718 if len(self.digest_history) > self.digest_history_size:
719 # threshold reached, cull 10%
720 self._cull_digest_history()
721
722 def _cull_digest_history(self):
723 """cull the digest history
724
725 Removes a randomly selected 10% of the digest history
726 """
727 current = len(self.digest_history)
728 n_to_cull = max(int(current // 10), current - self.digest_history_size)
729 if n_to_cull >= current:
730 self.digest_history = set()
731 return
732 to_cull = random.sample(self.digest_history, n_to_cull)
733 self.digest_history.difference_update(to_cull)
734
702 def unserialize(self, msg_list, content=True, copy=True):
735 def unserialize(self, msg_list, content=True, copy=True):
703 """Unserialize a msg_list to a nested message dict.
736 """Unserialize a msg_list to a nested message dict.
704
737
@@ -734,8 +767,8 b' class Session(Configurable):'
734 if not signature:
767 if not signature:
735 raise ValueError("Unsigned Message")
768 raise ValueError("Unsigned Message")
736 if signature in self.digest_history:
769 if signature in self.digest_history:
737 raise ValueError("Duplicate Signature: %r"%signature)
770 raise ValueError("Duplicate Signature: %r" % signature)
738 self.digest_history.add(signature)
771 self._add_digest(signature)
739 check = self.sign(msg_list[1:5])
772 check = self.sign(msg_list[1:5])
740 if not signature == check:
773 if not signature == check:
741 raise ValueError("Invalid Signature: %r" % signature)
774 raise ValueError("Invalid Signature: %r" % signature)
@@ -204,4 +204,22 b' class TestSession(SessionTestCase):'
204 self.assertEqual(session.bsession, session.session.encode('ascii'))
204 self.assertEqual(session.bsession, session.session.encode('ascii'))
205 self.assertEqual(b'stuff', session.bsession)
205 self.assertEqual(b'stuff', session.bsession)
206
206
207 def test_zero_digest_history(self):
208 session = ss.Session(digest_history_size=0)
209 for i in range(11):
210 session._add_digest(uuid.uuid4().bytes)
211 self.assertEqual(len(session.digest_history), 0)
212
213 def test_cull_digest_history(self):
214 session = ss.Session(digest_history_size=100)
215 for i in range(100):
216 session._add_digest(uuid.uuid4().bytes)
217 self.assertTrue(len(session.digest_history) == 100)
218 session._add_digest(uuid.uuid4().bytes)
219 self.assertTrue(len(session.digest_history) == 91)
220 for i in range(9):
221 session._add_digest(uuid.uuid4().bytes)
222 self.assertTrue(len(session.digest_history) == 100)
223 session._add_digest(uuid.uuid4().bytes)
224 self.assertTrue(len(session.digest_history) == 91)
207
225
General Comments 0
You need to be logged in to leave comments. Login now