diff options
| author | Eli Collins <elic@assurancetechnologies.com> | 2012-01-02 14:21:15 -0500 |
|---|---|---|
| committer | Eli Collins <elic@assurancetechnologies.com> | 2012-01-02 14:21:15 -0500 |
| commit | f7a33447fec5219842c15eef560ca067f4ec06c3 (patch) | |
| tree | e160357659e4383013cddebc294c0cf1d2441783 | |
| parent | 3b56bcca1021a069507e37caa9f74aceba8e1dd7 (diff) | |
| download | passlib-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.py | 21 | ||||
| -rw-r--r-- | passlib/tests/test_context.py | 3 |
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, |
