diff options
author | Eli Collins <elic@assurancetechnologies.com> | 2020-10-06 15:52:42 -0400 |
---|---|---|
committer | Eli Collins <elic@assurancetechnologies.com> | 2020-10-06 15:52:42 -0400 |
commit | 49eb92ea545e69184bbea041d979325b2c715600 (patch) | |
tree | b3644c6e07337ba326f88a02c6e79fe1aa369d43 | |
parent | 16766a60eb7794f4adee19a4c914f6b1a9f5d480 (diff) | |
download | passlib-49eb92ea545e69184bbea041d979325b2c715600.tar.gz |
passlib.hash.bcrypt: remove support for "bcryptor" backend
-rw-r--r-- | docs/install.rst | 27 | ||||
-rw-r--r-- | docs/lib/passlib.hash.bcrypt.rst | 7 | ||||
-rw-r--r-- | passlib/handlers/bcrypt.py | 43 | ||||
-rw-r--r-- | passlib/tests/test_handlers_bcrypt.py | 27 | ||||
-rw-r--r-- | passlib/tests/utils.py | 1 |
5 files changed, 13 insertions, 92 deletions
diff --git a/docs/install.rst b/docs/install.rst index 644c12c..f48af45 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -37,25 +37,12 @@ Google App Engine is supported as well. Optional Libraries ================== -* `bcrypt <https://pypi.python.org/pypi/bcrypt>`_, - `py-bcrypt <https://pypi.python.org/pypi/py-bcrypt>`_, or - `bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_ +* `bcrypt <https://pypi.python.org/pypi/bcrypt>`_ - .. rst-class:: float-right - - .. warning:: - - Support for ``py-bcrypt`` and ``bcryptor`` will be dropped in Passlib 1.8, - as these libraries are unmaintained. - - If any of these packages are installed, they will be used to provide - support for the BCrypt hash algorithm. - This is required if you want to handle BCrypt hashes, - and your OS does not provide native BCrypt support - via stdlib's :mod:`!crypt` (which includes pretty much all non-BSD systems). - - `bcrypt <https://pypi.python.org/pypi/bcrypt>`_ is currently the recommended - option -- it's actively maintained, and compatible with both CPython and PyPy. + If installed, this will be used to handle :class:~passlib.hash.bcrypt` and + :class:`~passlib.hash.bcrypt_sha256` hashes. If your system lacks :func:`crypt.crypt()` + support for bcrypt hashes, this library is *required* in order for passlib to provide + bcrypt support. Use ``pip install passlib[bcrypt]`` to get the recommended bcrypt setup. @@ -86,6 +73,10 @@ Optional Libraries If installed, this will be used to provide support for the :class:`~passlib.hash.scrypt` hash algorithm. If not installed, a MUCH slower builtin reference implementation will be used. +.. versionchanged:: 1.8 + + Dropped support for ``py-bcrypt`` and ``bcryptor`` backends. + .. versionchanged:: 1.7 Added fastpbkdf2, cryptography, argon2_cffi, argon2pure, and scrypt support. diff --git a/docs/lib/passlib.hash.bcrypt.rst b/docs/lib/passlib.hash.bcrypt.rst index 436148c..3bb5865 100644 --- a/docs/lib/passlib.hash.bcrypt.rst +++ b/docs/lib/passlib.hash.bcrypt.rst @@ -50,17 +50,10 @@ Bcrypt Backends .. rst-class:: float-center -.. warning:: - - Support for ``py-bcrypt`` and ``bcryptor`` will be dropped in Passlib 1.8, - as these libraries are unmaintained. - This class will use the first available of five possible backends: 1. `bcrypt <https://pypi.python.org/pypi/bcrypt>`_, if installed. -2. `py-bcrypt <https://pypi.python.org/pypi/py-bcrypt>`_, if installed (DEPRECATED) -3. `bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_, if installed (DEPRECATED). 4. stdlib's :func:`crypt.crypt()`, if the host OS supports BCrypt (primarily BSD-derived systems). 5. A pure-python implementation of BCrypt, built into Passlib. diff --git a/passlib/handlers/bcrypt.py b/passlib/handlers/bcrypt.py index 1c51924..c153dc4 100644 --- a/passlib/handlers/bcrypt.py +++ b/passlib/handlers/bcrypt.py @@ -20,7 +20,6 @@ from warnings import warn # site _bcrypt = None # dynamically imported by _load_backend_bcrypt() _pybcrypt = None # dynamically imported by _load_backend_pybcrypt() -_bcryptor = None # dynamically imported by _load_backend_bcryptor() # pkg _builtin_bcrypt = None # dynamically imported by _load_backend_builtin() from passlib.crypto.digest import compile_hmac @@ -291,8 +290,6 @@ class _BcryptCommon(uh.SubclassBackendMixin, uh.TruncateMixin, uh.HasManyIdents, verify = mixin_cls.verify err_types = (ValueError, uh.exc.MissingBackendError) - if _bcryptor: - err_types += (_bcryptor.engine.SaltError,) def safe_verify(secret, hash): """verify() wrapper which traps 'unknown identifier' errors""" @@ -306,7 +303,6 @@ class _BcryptCommon(uh.SubclassBackendMixin, uh.TruncateMixin, uh.HasManyIdents, # - InternalBackendError if crypt fails for unknown reason # (trapped below so we can debug it) # pybcrypt, bcrypt -- raises ValueError - # bcryptor -- raises bcryptor.engine.SaltError return NotImplemented except uh.exc.InternalBackendError: # _calc_checksum() code may also throw CryptBackendError @@ -507,7 +503,7 @@ class _BcryptCommon(uh.SubclassBackendMixin, uh.TruncateMixin, uh.HasManyIdents, cls._check_truncate_policy(secret) # NOTE: especially important to forbid NULLs for bcrypt, since many - # backends (bcryptor, bcrypt) happily accept them, and then + # backends (bcrypt) happily accept them, and then # silently truncate the password at first NULL they encounter! if _BNULL in secret: raise uh.exc.NullPasswordError(cls) @@ -656,40 +652,6 @@ class _BcryptBackend(_BcryptCommon): return hash[-31:].decode("ascii") #----------------------------------------------------------------------- -# bcryptor backend -#----------------------------------------------------------------------- -class _BcryptorBackend(_BcryptCommon): - """ - backend which uses 'bcryptor' package - """ - - @classmethod - def _load_backend_mixin(mixin_cls, name, dryrun): - # try to import bcryptor - global _bcryptor - try: - import bcryptor as _bcryptor - except ImportError: # pragma: no cover - return False - - # deprecated as of 1.7.2 - if not dryrun: - warn("Support for `bcryptor` is deprecated, and will be removed in Passlib 1.8; " - "Please use `pip install bcrypt` instead", DeprecationWarning) - - return mixin_cls._finalize_backend_mixin(name, dryrun) - - def _calc_checksum(self, secret): - # bcryptor behavior: - # py3: not supported - secret, ident = self._prepare_digest_args(secret) - config = self._get_config(ident) - hash = _bcryptor.engine.Engine(False).hash_key(secret, config) - if not hash.startswith(config) or len(hash) != len(config) + 31: - raise uh.exc.CryptBackendError(self, config, hash, source="bcryptor library") - return hash[-31:] - -#----------------------------------------------------------------------- # pybcrypt backend #----------------------------------------------------------------------- class _PyBcryptBackend(_BcryptCommon): @@ -936,7 +898,7 @@ class bcrypt(_NoBackend, _BcryptCommon): # in order to load the appropriate backend. #: list of potential backends - backends = ("bcrypt", "pybcrypt", "bcryptor", "os_crypt", "builtin") + backends = ("bcrypt", "pybcrypt", "os_crypt", "builtin") #: flag that this class's bases should be modified by SubclassBackendMixin _backend_mixin_target = True @@ -946,7 +908,6 @@ class bcrypt(_NoBackend, _BcryptCommon): None: _NoBackend, "bcrypt": _BcryptBackend, "pybcrypt": _PyBcryptBackend, - "bcryptor": _BcryptorBackend, "os_crypt": _OsCryptBackend, "builtin": _BuiltinBackend, } diff --git a/passlib/tests/test_handlers_bcrypt.py b/passlib/tests/test_handlers_bcrypt.py index 5b70a99..54a3bc1 100644 --- a/passlib/tests/test_handlers_bcrypt.py +++ b/passlib/tests/test_handlers_bcrypt.py @@ -201,7 +201,6 @@ class _bcrypt_test(HandlerCase): fuzz_verifiers = HandlerCase.fuzz_verifiers + ( "fuzz_verifier_bcrypt", "fuzz_verifier_pybcrypt", - "fuzz_verifier_bcryptor", ) def fuzz_verifier_bcrypt(self): @@ -269,28 +268,6 @@ class _bcrypt_test(HandlerCase): raise ValueError("py-bcrypt rejected hash: %r" % (hash,)) return check_pybcrypt - def fuzz_verifier_bcryptor(self): - # test against bcryptor if available - from passlib.handlers.bcrypt import IDENT_2, IDENT_2A, IDENT_2Y, IDENT_2B - from passlib.utils import to_native_str - try: - from bcryptor.engine import Engine - except ImportError: - return - def check_bcryptor(secret, hash): - """bcryptor""" - secret = to_native_str(secret, self.FuzzHashGenerator.password_encoding) - if hash.startswith((IDENT_2B, IDENT_2Y)): - hash = IDENT_2A + hash[4:] - elif hash.startswith(IDENT_2): - # bcryptor doesn't support $2$ hashes; but we can fake it - # using the $2a$ algorithm, by repeating the password until - # it's 72 chars in length. - hash = IDENT_2A + hash[3:] - if secret: - secret = repeat_string(secret, 72) - return Engine(False).hash_key(secret, hash) == hash - return check_bcryptor class FuzzHashGenerator(HandlerCase.FuzzHashGenerator): @@ -424,7 +401,7 @@ class _bcrypt_test(HandlerCase): # create test cases for specific backends bcrypt_bcrypt_test = _bcrypt_test.create_backend_case("bcrypt") bcrypt_pybcrypt_test = _bcrypt_test.create_backend_case("pybcrypt") -bcrypt_bcryptor_test = _bcrypt_test.create_backend_case("bcryptor") + class bcrypt_os_crypt_test(_bcrypt_test.create_backend_case("os_crypt")): @@ -669,7 +646,7 @@ class _bcrypt_sha256_test(HandlerCase): # create test cases for specific backends bcrypt_sha256_bcrypt_test = _bcrypt_sha256_test.create_backend_case("bcrypt") bcrypt_sha256_pybcrypt_test = _bcrypt_sha256_test.create_backend_case("pybcrypt") -bcrypt_sha256_bcryptor_test = _bcrypt_sha256_test.create_backend_case("bcryptor") + class bcrypt_sha256_os_crypt_test(_bcrypt_sha256_test.create_backend_case("os_crypt")): diff --git a/passlib/tests/utils.py b/passlib/tests/utils.py index c01decf..1880dd9 100644 --- a/passlib/tests/utils.py +++ b/passlib/tests/utils.py @@ -368,7 +368,6 @@ class TestCase(unittest.TestCase): # should be kept until then, so we test the legacy paths. warnings.filterwarnings("ignore", r"the method .*\.(encrypt|genconfig|genhash)\(\) is deprecated") warnings.filterwarnings("ignore", r"the 'vary_rounds' option is deprecated") - warnings.filterwarnings("ignore", r"Support for `(py-bcrypt|bcryptor)` is deprecated") #--------------------------------------------------------------- # tweak message formatting so longMessage mode is only enabled |