summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2012-01-02 14:21:15 -0500
committerEli Collins <elic@assurancetechnologies.com>2012-01-02 14:21:15 -0500
commitf7a33447fec5219842c15eef560ca067f4ec06c3 (patch)
treee160357659e4383013cddebc294c0cf1d2441783
parent3b56bcca1021a069507e37caa9f74aceba8e1dd7 (diff)
downloadpasslib-f7a33447fec5219842c15eef560ca067f4ec06c3.tar.gz
context tweaks:
* _generate_rounds disables if 'rounds' specified in policy settings for hash. * KeyError will now be thrown if policy specifies setting not supported by handler. * set stacklevel for rounds bound warning so it matches where encrypt() was called.
-rw-r--r--passlib/context.py21
-rw-r--r--passlib/tests/test_context.py3
2 files changed, 16 insertions, 8 deletions
diff --git a/passlib/context.py b/passlib/context.py
index 1d81b12..03cfc7b 100644
--- a/passlib/context.py
+++ b/passlib/context.py
@@ -812,7 +812,7 @@ class _CryptRecord(object):
self.handler = handler
self.category = category
self._compile_rounds(min_rounds, max_rounds, default_rounds,
- vary_rounds)
+ vary_rounds, 'rounds' in settings)
self._compile_encrypt(settings)
self._compile_verify(min_verify_time)
self._compile_deprecation(deprecated)
@@ -841,7 +841,7 @@ class _CryptRecord(object):
#================================================================
# rounds generation & limits - used by encrypt & deprecation code
#================================================================
- def _compile_rounds(self, mn, mx, df, vr):
+ def _compile_rounds(self, mn, mx, df, vr, fixed):
"parse options and compile efficient generate_rounds function"
handler = self.handler
if 'rounds' not in handler.setting_kwds:
@@ -927,7 +927,7 @@ class _CryptRecord(object):
#----------------------------------------------------
# setup rounds generation function
#----------------------------------------------------
- if df is None:
+ if df is None or fixed:
self._generate_rounds = None
self._has_rounds = self._has_rounds_bounds
elif vr:
@@ -967,10 +967,13 @@ class _CryptRecord(object):
def _compile_encrypt(self, settings):
handler = self.handler
skeys = handler.setting_kwds
- self._settings = dict((k,v) for k,v in iteritems(settings)
- if k in skeys)
+ for key in settings:
+ if key not in skeys:
+ raise KeyError("keyword not supported by %s handler: %r" %
+ (handler.name, key))
+ self._settings = settings
- if not (self._settings or self._has_rounds):
+ if not (settings or self._has_rounds):
# bypass prepare settings entirely.
self.genconfig = handler.genconfig
self.encrypt = handler.encrypt
@@ -1000,15 +1003,17 @@ class _CryptRecord(object):
kwds['rounds'] = gen()
elif self._has_rounds_bounds:
# XXX: should this raise an error instead of warning ?
+ # NOTE: stackdepth=4 is so that error matches
+ # where ctx.encrypt() was called by application code.
mn = self._min_rounds
if mn is not None and rounds < mn:
warn("%s requires rounds >= %d, increasing value from %d" %
- (self._ident, mn, rounds), PasslibPolicyWarning)
+ (self._ident, mn, rounds), PasslibPolicyWarning, 4)
rounds = mn
mx = self._max_rounds
if mx and rounds > mx:
warn("%s requires rounds <= %d, decreasing value from %d" %
- (self._ident, mx, rounds), PasslibPolicyWarning)
+ (self._ident, mx, rounds), PasslibPolicyWarning, 4)
rounds = mx
kwds['rounds'] = rounds
diff --git a/passlib/tests/test_context.py b/passlib/tests/test_context.py
index 25d1d40..a6f9f60 100644
--- a/passlib/tests/test_context.py
+++ b/passlib/tests/test_context.py
@@ -603,6 +603,9 @@ class CryptContextTest(TestCase):
'$3$$00000000000000000000000000000000',
)
+ # unsupported hash settings should be rejected
+ self.assertRaises(KeyError, cc.replace, md5_crypt__ident="NT")
+
def test_10_02_genconfig_rounds_limits(self):
"test genconfig() policy rounds limits"
cc = CryptContext(policy=None,