summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES1
-rw-r--r--README2
-rw-r--r--docs/install.rst8
-rw-r--r--docs/lib/passlib.hash.bcrypt.rst2
-rw-r--r--docs/new_app_quickstart.rst2
-rw-r--r--passlib/handlers/bcrypt.py22
-rw-r--r--passlib/tests/test_drivers.py8
7 files changed, 30 insertions, 15 deletions
diff --git a/CHANGES b/CHANGES
index c24de8e..be30f6e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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`.
diff --git a/README b/README
index 271d34d..ac28f40 100644
--- a/README
+++ b/README
@@ -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
#=========================================================