diff options
| -rw-r--r-- | CHANGES | 1 | ||||
| -rw-r--r-- | README | 2 | ||||
| -rw-r--r-- | docs/install.rst | 8 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.bcrypt.rst | 2 | ||||
| -rw-r--r-- | docs/new_app_quickstart.rst | 2 | ||||
| -rw-r--r-- | passlib/handlers/bcrypt.py | 22 | ||||
| -rw-r--r-- | passlib/tests/test_drivers.py | 8 |
7 files changed, 30 insertions, 15 deletions
@@ -6,6 +6,7 @@ Release History **1.5** (NOT YET RELEASED) + * added support for using BCryptor as bcrypt backend * added quickstart guide to documentation * removed deprecated parts of :mod:`passlib.utils.handlers`. @@ -17,7 +17,7 @@ The latest documentation can be found online at `<http://packages.python.org/pas Requirements ============ * Python 2.5 - 2.7 -* PyBCrypt (optional; required only if bcrypt support is needed) +* PyBCrypt or BCryptor (optional; required only if bcrypt support is needed) * M2Crypto (optional; accelerates PBKDF2-based hashes) Installation diff --git a/docs/install.rst b/docs/install.rst index ff267cb..d7529a5 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -13,12 +13,14 @@ Requirements Passlib is pure-python, and should support all available Python implementations and platforms. -* `py-bcrypt <http://www.mindrot.org/projects/py-bcrypt/>`_ (optional) +* `py-bcrypt <http://www.mindrot.org/projects/py-bcrypt/>`_ or + `bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_ (optional) - If installed, pybcrypt will be used to support the BCrypt hash algorithm. + If either 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`. This includes pretty much all non-BSD systems. + via stdlib's :mod:`!crypt` (which includes pretty much all non-BSD systems). * `M2Crypto <http://chandlerproject.org/bin/view/Projects/MeTooCrypto>`_ (optional) diff --git a/docs/lib/passlib.hash.bcrypt.rst b/docs/lib/passlib.hash.bcrypt.rst index 905b90e..efa2098 100644 --- a/docs/lib/passlib.hash.bcrypt.rst +++ b/docs/lib/passlib.hash.bcrypt.rst @@ -11,7 +11,7 @@ password hash for many systems (notably BSD), and has no known weaknesses. .. note:: - It is strongly recommended to install PyBcrypt if this algorithm + It is strongly recommended to install PyBcrypt or BCryptor if this algorithm is going to be used. Usage diff --git a/docs/new_app_quickstart.rst b/docs/new_app_quickstart.rst index f446b34..c7309da 100644 --- a/docs/new_app_quickstart.rst +++ b/docs/new_app_quickstart.rst @@ -81,7 +81,7 @@ of simultaneous logon attempts (eg web apps). For BCrypt support on non-BSD systems, Passlib requires a C-extension module - provided by the external pybcrypt package. + provided by the external pybcrypt or bcryptor packages. SHA512-Crypt ------------ diff --git a/passlib/handlers/bcrypt.py b/passlib/handlers/bcrypt.py index 7cd4dbb..ae0ab1f 100644 --- a/passlib/handlers/bcrypt.py +++ b/passlib/handlers/bcrypt.py @@ -20,6 +20,10 @@ try: from bcrypt import hashpw as pybcrypt_hashpw except ImportError: #pragma: no cover - though should run whole suite w/o pybcrypt installed pybcrypt_hashpw = None +try: + from bcryptor.engine import Engine as bcryptor_engine +except ImportError: #pragma: no cover - though should run whole suite w/o bcryptor installed + bcryptor_engine = None #libs from passlib.utils import os_crypt, classproperty, handlers as uh, h64 @@ -54,10 +58,11 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh. Typically you want to leave this alone, and let it default to ``2a``, but it can be set to ``2`` to use the older version of BCrypt. - It will use the first available of two possible backends: + It will use the first available of three possible backends: * `py-bcrypt <http://www.mindrot.org/projects/py-bcrypt/>`_, if installed. - * stdlib :func:`crypt()`, if the host OS supports BCrypt. + * `bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_, if installed. + * stdlib :func:`crypt()`, if the host OS supports BCrypt (eg BSD). You can see which backend is in use by calling the :meth:`get_backend()` method. """ @@ -119,13 +124,17 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh. #========================================================= #primary interface #========================================================= - backends = ("pybcrypt", "os_crypt") + backends = ("pybcrypt", "bcryptor", "os_crypt") @classproperty def _has_backend_pybcrypt(cls): return pybcrypt_hashpw is not None @classproperty + def _has_backend_bcryptor(cls): + return bcryptor_engine is not None + + @classproperty def _has_backend_os_crypt(cls): return ( os_crypt is not None @@ -139,7 +148,7 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh. @classmethod def _no_backends_msg(cls): - return "no BCrypt backends available - please install pybcrypt for BCrypt support" + return "no BCrypt backends available - please install pybcrypt or bcryptor for BCrypt support" def _calc_checksum_os_crypt(self, secret): if isinstance(secret, unicode): @@ -151,6 +160,11 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh. secret = secret.encode("utf-8") return pybcrypt_hashpw(secret, self.to_string())[-31:] + def _calc_checksum_bcryptor(self, secret): + if isinstance(secret, unicode): + secret = secret.encode("utf-8") + return bcryptor_engine(False).hash_key(secret, self.to_string())[-31:] + #========================================================= #eoc #========================================================= diff --git a/passlib/tests/test_drivers.py b/passlib/tests/test_drivers.py index a3289c5..9c7e11a 100644 --- a/passlib/tests/test_drivers.py +++ b/passlib/tests/test_drivers.py @@ -87,7 +87,7 @@ class BCryptTest(HandlerCase): bcrypt.set_backend(orig) bcrypt_mod.os_crypt = orig -bcrypt._no_backends_msg() +bcrypt._no_backends_msg() #call this for coverage purposes try: bcrypt.get_backend() @@ -95,12 +95,10 @@ except EnvironmentError: #no bcrypt backends available! BCryptTest = None -#NOTE: pybcrypt backend will be chosen as primary if possible, so just check for os crypt and builtin +#NOTE: pybcrypt backend will be chosen as primary if possible, so just check for bcryptor, os crypt +BCryptor_BCryptTest = create_backend_case(BCryptTest, "bcryptor") OsCrypt_BCryptTest = create_backend_case(BCryptTest, "os_crypt") -###this one's unusuablly slow, don't test it unless user asks for it. -##Builtin_BCryptTest = create_backend_case(BCryptTest, "builtin") if enable_option("slow") else None - #========================================================= #bigcrypt #========================================================= |
