summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Stufft <donald@stufft.io>2015-06-11 09:23:01 -0400
committerDonald Stufft <donald@stufft.io>2015-06-11 09:23:01 -0400
commit51ebadb34d22d25c10c5e54d4dada46b88c3829b (patch)
treeb14a815d477d7f24eebbad6be2b038b21693da7e
parentf3280bda0a560fbf4d401bd8edf89b974a97b39c (diff)
downloadpy-bcrypt-git-51ebadb34d22d25c10c5e54d4dada46b88c3829b.tar.gz
Migrate to using CFFI 1.0
* Move everything under src/ to ensure we test against the installed library. * Create a build_bcrypt.py script which will build _bcrypt.so. * Refactor to utilize the new _bcrypt.so instead of implicit compile.
-rw-r--r--MANIFEST.in3
-rw-r--r--bcrypt/__init__.py150
-rw-r--r--setup.py55
-rw-r--r--src/bcrypt/__about__.py (renamed from bcrypt/__about__.py)0
-rw-r--r--src/bcrypt/__init__.py65
-rw-r--r--src/build_bcrypt.py47
-rw-r--r--src/crypt_blowfish-1.3/LINKS (renamed from bcrypt/crypt_blowfish-1.3/LINKS)0
-rw-r--r--src/crypt_blowfish-1.3/Makefile (renamed from bcrypt/crypt_blowfish-1.3/Makefile)0
-rw-r--r--src/crypt_blowfish-1.3/PERFORMANCE (renamed from bcrypt/crypt_blowfish-1.3/PERFORMANCE)0
-rw-r--r--src/crypt_blowfish-1.3/README (renamed from bcrypt/crypt_blowfish-1.3/README)0
-rw-r--r--src/crypt_blowfish-1.3/crypt.3 (renamed from bcrypt/crypt_blowfish-1.3/crypt.3)0
-rw-r--r--src/crypt_blowfish-1.3/crypt.h (renamed from bcrypt/crypt_blowfish-1.3/crypt.h)0
-rw-r--r--src/crypt_blowfish-1.3/crypt_blowfish.c (renamed from bcrypt/crypt_blowfish-1.3/crypt_blowfish.c)0
-rw-r--r--src/crypt_blowfish-1.3/crypt_blowfish.h (renamed from bcrypt/crypt_blowfish-1.3/crypt_blowfish.h)0
-rw-r--r--src/crypt_blowfish-1.3/crypt_gensalt.c (renamed from bcrypt/crypt_blowfish-1.3/crypt_gensalt.c)0
-rw-r--r--src/crypt_blowfish-1.3/crypt_gensalt.h (renamed from bcrypt/crypt_blowfish-1.3/crypt_gensalt.h)0
-rw-r--r--src/crypt_blowfish-1.3/glibc-2.1.3-crypt.diff (renamed from bcrypt/crypt_blowfish-1.3/glibc-2.1.3-crypt.diff)0
-rw-r--r--src/crypt_blowfish-1.3/glibc-2.14-crypt.diff (renamed from bcrypt/crypt_blowfish-1.3/glibc-2.14-crypt.diff)0
-rw-r--r--src/crypt_blowfish-1.3/glibc-2.3.6-crypt.diff (renamed from bcrypt/crypt_blowfish-1.3/glibc-2.3.6-crypt.diff)0
-rw-r--r--src/crypt_blowfish-1.3/ow-crypt.h (renamed from bcrypt/crypt_blowfish-1.3/ow-crypt.h)0
-rw-r--r--src/crypt_blowfish-1.3/wrapper.c (renamed from bcrypt/crypt_blowfish-1.3/wrapper.c)0
-rw-r--r--src/crypt_blowfish-1.3/x86.S (renamed from bcrypt/crypt_blowfish-1.3/x86.S)0
-rw-r--r--tests/test_bcrypt.py5
23 files changed, 127 insertions, 198 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
index 521c312..ea1c0a0 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,3 @@
include LICENSE README.rst
-recursive-include bcrypt/crypt_blowfish-1.3 *
+include src/build_bcrypt.py
+recursive-include src/crypt_blowfish-1.3 *
diff --git a/bcrypt/__init__.py b/bcrypt/__init__.py
deleted file mode 100644
index 29a4701..0000000
--- a/bcrypt/__init__.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Author:: Donald Stufft (<donald@stufft.io>)
-# Copyright:: Copyright (c) 2013 Donald Stufft
-# License:: Apache License, Version 2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from __future__ import absolute_import
-from __future__ import division
-
-import binascii
-import os
-import sys
-import threading
-
-from cffi import FFI
-from cffi.verifier import Verifier
-
-import six
-
-from .__about__ import (
- __author__, __copyright__, __email__, __license__, __summary__, __title__,
- __uri__, __version__,
-)
-
-
-__all__ = [
- "__title__", "__summary__", "__uri__", "__version__", "__author__",
- "__email__", "__license__", "__copyright__",
- "gensalt", "hashpw",
-]
-
-
-def _create_modulename(cdef_sources, source, sys_version):
- """
- This is the same as CFFI's create modulename except we don't include the
- CFFI version.
- """
- key = '\x00'.join([sys_version[:3], source, cdef_sources])
- key = key.encode('utf-8')
- k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff)
- k1 = k1.lstrip('0x').rstrip('L')
- k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff)
- k2 = k2.lstrip('0').rstrip('L')
- return '_bcrypt_cffi_{0}{1}'.format(k1, k2)
-
-
-def _compile_module(*args, **kwargs):
- raise RuntimeError(
- "Attempted implicit compile of a cffi module. All cffi modules should "
- "be pre-compiled at installation time."
- )
-
-
-class LazyLibrary(object):
- def __init__(self, ffi):
- self._ffi = ffi
- self._lib = None
- self._lock = threading.Lock()
-
- def __getattr__(self, name):
- if self._lib is None:
- with self._lock:
- # We no cover this because this guard is here just to protect
- # against concurrent loads of this library. This is pretty
- # hard to test and the logic is simple and should hold fine
- # without testing (famous last words).
- if self._lib is None: # pragma: no cover
- self._lib = self._ffi.verifier.load_library()
-
- return getattr(self._lib, name)
-
-
-_crypt_blowfish_dir = "crypt_blowfish-1.3"
-_bundled_dir = os.path.join(os.path.dirname(__file__), _crypt_blowfish_dir)
-
-
-CDEF = """
- char *crypt_gensalt_rn(const char *prefix, unsigned long count,
- const char *input, int size, char *output, int output_size);
-
- char *crypt_rn(const char *key, const char *setting, void *data, int size);
-"""
-
-SOURCE = """
- #include "ow-crypt.h"
-"""
-
-_ffi = FFI()
-_ffi.cdef(CDEF)
-_ffi.verifier = Verifier(
- _ffi,
- SOURCE,
- sources=[
- str(os.path.join(_bundled_dir, "crypt_blowfish.c")),
- str(os.path.join(_bundled_dir, "crypt_gensalt.c")),
- str(os.path.join(_bundled_dir, "wrapper.c")),
- # How can we get distutils to work with a .S file?
- # Set bcrypt/crypt_blowfish-1.3/crypt_blowfish.c#57 back to 1 if we
- # get ASM loaded.
- # str(os.path.join(_bundled_dir, "x86.S")),
- ],
- include_dirs=[str(_bundled_dir)],
- modulename=_create_modulename(CDEF, SOURCE, sys.version),
-)
-
-# Patch the Verifier() instance to prevent CFFI from compiling the module
-_ffi.verifier.compile_module = _compile_module
-_ffi.verifier._compile_module = _compile_module
-
-
-_bcrypt_lib = LazyLibrary(_ffi)
-
-
-def gensalt(rounds=12):
- salt = os.urandom(16)
- output = _ffi.new("unsigned char[]", 30)
-
- retval = _bcrypt_lib.crypt_gensalt_rn(
- b"$2a$", rounds, salt, len(salt), output, len(output),
- )
-
- if not retval:
- raise ValueError("Invalid rounds")
-
- return _ffi.string(output)
-
-
-def hashpw(password, salt):
- if isinstance(password, six.text_type) or isinstance(salt, six.text_type):
- raise TypeError("Unicode-objects must be encoded before hashing")
-
- if b"\x00" in password:
- raise ValueError("password may not contain NUL bytes")
-
- hashed = _ffi.new("unsigned char[]", 128)
- retval = _bcrypt_lib.crypt_rn(password, salt, hashed, len(hashed))
-
- if not retval:
- raise ValueError("Invalid salt")
-
- return _ffi.string(hashed)
diff --git a/setup.py b/setup.py
index 370a753..f635d94 100644
--- a/setup.py
+++ b/setup.py
@@ -7,48 +7,21 @@ from setuptools.command.install import install
from setuptools.command.test import test
-CFFI_DEPENDENCY = "cffi>=0.8"
+CFFI_DEPENDENCY = "cffi>=1.1"
SIX_DEPENDENCY = "six>=1.4.1"
+CFFI_MODULES = [
+ "src/build_bcrypt.py:ffi",
+]
+
+
# Manually extract the __about__
__about__ = {}
-with open("bcrypt/__about__.py") as fp:
+with open("src/bcrypt/__about__.py") as fp:
exec(fp.read(), __about__)
-def get_ext_modules():
- from bcrypt import _ffi
- return [_ffi.verifier.get_extension()]
-
-
-class CFFIBuild(build):
- """
- This class exists, instead of just providing ``ext_modules=[...]`` directly
- in ``setup()`` because importing cryptography requires we have several
- packages installed first.
-
- By doing the imports here we ensure that packages listed in
- ``setup_requires`` are already installed.
- """
-
- def finalize_options(self):
- self.distribution.ext_modules = get_ext_modules()
- build.finalize_options(self)
-
-
-class CFFIInstall(install):
- """
- As a consequence of CFFIBuild and it's late addition of ext_modules, we
- need the equivalent for the ``install`` command to install into platlib
- install-dir rather than purelib.
- """
-
- def finalize_options(self):
- self.distribution.ext_modules = get_ext_modules()
- install.finalize_options(self)
-
-
class PyTest(test):
def finalize_options(self):
test.finalize_options(self)
@@ -159,12 +132,11 @@ def keywords_with_side_effects(argv):
}
else:
return {
- "setup_requires": [CFFI_DEPENDENCY, SIX_DEPENDENCY],
+ "setup_requires": [CFFI_DEPENDENCY],
"cmdclass": {
- "build": CFFIBuild,
- "install": CFFIInstall,
"test": PyTest,
- }
+ },
+ "cffi_modules": CFFI_MODULES,
}
@@ -231,14 +203,11 @@ setup(
"pytest",
],
+ package_dir={"": "src"},
packages=[
"bcrypt",
],
- package_data={
- "bcrypt": ["crypt_blowfish-1.3/*"],
- },
-
zip_safe=False,
classifiers=[
@@ -252,5 +221,7 @@ setup(
"Programming Language :: Python :: 3.3",
],
+ ext_package="bcrypt",
+
**keywords_with_side_effects(sys.argv)
)
diff --git a/bcrypt/__about__.py b/src/bcrypt/__about__.py
index d526fe7..d526fe7 100644
--- a/bcrypt/__about__.py
+++ b/src/bcrypt/__about__.py
diff --git a/src/bcrypt/__init__.py b/src/bcrypt/__init__.py
new file mode 100644
index 0000000..10f860b
--- /dev/null
+++ b/src/bcrypt/__init__.py
@@ -0,0 +1,65 @@
+# Author:: Donald Stufft (<donald@stufft.io>)
+# Copyright:: Copyright (c) 2013 Donald Stufft
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from __future__ import absolute_import
+from __future__ import division
+
+import os
+
+import six
+
+from bcrypt import _bcrypt
+
+from .__about__ import (
+ __author__, __copyright__, __email__, __license__, __summary__, __title__,
+ __uri__, __version__,
+)
+
+
+__all__ = [
+ "__title__", "__summary__", "__uri__", "__version__", "__author__",
+ "__email__", "__license__", "__copyright__",
+ "gensalt", "hashpw",
+]
+
+
+def gensalt(rounds=12):
+ salt = os.urandom(16)
+ output = _bcrypt.ffi.new("unsigned char[]", 30)
+
+ retval = _bcrypt.lib.crypt_gensalt_rn(
+ b"$2a$", rounds, salt, len(salt), output, len(output),
+ )
+
+ if not retval:
+ raise ValueError("Invalid rounds")
+
+ return _bcrypt.ffi.string(output)
+
+
+def hashpw(password, salt):
+ if isinstance(password, six.text_type) or isinstance(salt, six.text_type):
+ raise TypeError("Unicode-objects must be encoded before hashing")
+
+ if b"\x00" in password:
+ raise ValueError("password may not contain NUL bytes")
+
+ hashed = _bcrypt.ffi.new("unsigned char[]", 128)
+ retval = _bcrypt.lib.crypt_rn(password, salt, hashed, len(hashed))
+
+ if not retval:
+ raise ValueError("Invalid salt")
+
+ return _bcrypt.ffi.string(hashed)
diff --git a/src/build_bcrypt.py b/src/build_bcrypt.py
new file mode 100644
index 0000000..b468c08
--- /dev/null
+++ b/src/build_bcrypt.py
@@ -0,0 +1,47 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os.path
+
+from cffi import FFI
+
+
+BLOWFISH_DIR = os.path.join(os.path.dirname(__file__), "crypt_blowfish-1.3")
+
+
+ffi = FFI()
+
+ffi.cdef(
+ """
+ char *crypt_gensalt_rn(const char *prefix, unsigned long count,
+ const char *input, int size, char *output, int output_size);
+
+ char *crypt_rn(const char *key, const char *setting, void *data, int size);
+ """
+)
+
+ffi.set_source(
+ "_bcrypt",
+ """
+ #include "ow-crypt.h"
+ """,
+ sources=[
+ os.path.join(BLOWFISH_DIR, "crypt_blowfish.c"),
+ os.path.join(BLOWFISH_DIR, "crypt_gensalt.c"),
+ os.path.join(BLOWFISH_DIR, "wrapper.c"),
+ # How can we get distutils to work with a .S file?
+ # Set bcrypt/crypt_blowfish-1.3/crypt_blowfish.c#57 back to 1 if we
+ # get ASM loaded.
+ # os.path.join(BLOWFISH_DIR, "x86.S"),
+ ],
+ include_dirs=[BLOWFISH_DIR],
+)
diff --git a/bcrypt/crypt_blowfish-1.3/LINKS b/src/crypt_blowfish-1.3/LINKS
index a6cb7e1..a6cb7e1 100644
--- a/bcrypt/crypt_blowfish-1.3/LINKS
+++ b/src/crypt_blowfish-1.3/LINKS
diff --git a/bcrypt/crypt_blowfish-1.3/Makefile b/src/crypt_blowfish-1.3/Makefile
index c162adc..c162adc 100644
--- a/bcrypt/crypt_blowfish-1.3/Makefile
+++ b/src/crypt_blowfish-1.3/Makefile
diff --git a/bcrypt/crypt_blowfish-1.3/PERFORMANCE b/src/crypt_blowfish-1.3/PERFORMANCE
index 9d6fe4e..9d6fe4e 100644
--- a/bcrypt/crypt_blowfish-1.3/PERFORMANCE
+++ b/src/crypt_blowfish-1.3/PERFORMANCE
diff --git a/bcrypt/crypt_blowfish-1.3/README b/src/crypt_blowfish-1.3/README
index e95da23..e95da23 100644
--- a/bcrypt/crypt_blowfish-1.3/README
+++ b/src/crypt_blowfish-1.3/README
diff --git a/bcrypt/crypt_blowfish-1.3/crypt.3 b/src/crypt_blowfish-1.3/crypt.3
index b4c0895..b4c0895 100644
--- a/bcrypt/crypt_blowfish-1.3/crypt.3
+++ b/src/crypt_blowfish-1.3/crypt.3
diff --git a/bcrypt/crypt_blowfish-1.3/crypt.h b/src/crypt_blowfish-1.3/crypt.h
index 12e6705..12e6705 100644
--- a/bcrypt/crypt_blowfish-1.3/crypt.h
+++ b/src/crypt_blowfish-1.3/crypt.h
diff --git a/bcrypt/crypt_blowfish-1.3/crypt_blowfish.c b/src/crypt_blowfish-1.3/crypt_blowfish.c
index 488a920..488a920 100644
--- a/bcrypt/crypt_blowfish-1.3/crypt_blowfish.c
+++ b/src/crypt_blowfish-1.3/crypt_blowfish.c
diff --git a/bcrypt/crypt_blowfish-1.3/crypt_blowfish.h b/src/crypt_blowfish-1.3/crypt_blowfish.h
index 2ee0d8c..2ee0d8c 100644
--- a/bcrypt/crypt_blowfish-1.3/crypt_blowfish.h
+++ b/src/crypt_blowfish-1.3/crypt_blowfish.h
diff --git a/bcrypt/crypt_blowfish-1.3/crypt_gensalt.c b/src/crypt_blowfish-1.3/crypt_gensalt.c
index 73c15a1..73c15a1 100644
--- a/bcrypt/crypt_blowfish-1.3/crypt_gensalt.c
+++ b/src/crypt_blowfish-1.3/crypt_gensalt.c
diff --git a/bcrypt/crypt_blowfish-1.3/crypt_gensalt.h b/src/crypt_blowfish-1.3/crypt_gensalt.h
index 457bbfe..457bbfe 100644
--- a/bcrypt/crypt_blowfish-1.3/crypt_gensalt.h
+++ b/src/crypt_blowfish-1.3/crypt_gensalt.h
diff --git a/bcrypt/crypt_blowfish-1.3/glibc-2.1.3-crypt.diff b/src/crypt_blowfish-1.3/glibc-2.1.3-crypt.diff
index 415e5b4..415e5b4 100644
--- a/bcrypt/crypt_blowfish-1.3/glibc-2.1.3-crypt.diff
+++ b/src/crypt_blowfish-1.3/glibc-2.1.3-crypt.diff
diff --git a/bcrypt/crypt_blowfish-1.3/glibc-2.14-crypt.diff b/src/crypt_blowfish-1.3/glibc-2.14-crypt.diff
index bacd12e..bacd12e 100644
--- a/bcrypt/crypt_blowfish-1.3/glibc-2.14-crypt.diff
+++ b/src/crypt_blowfish-1.3/glibc-2.14-crypt.diff
diff --git a/bcrypt/crypt_blowfish-1.3/glibc-2.3.6-crypt.diff b/src/crypt_blowfish-1.3/glibc-2.3.6-crypt.diff
index 4471054..4471054 100644
--- a/bcrypt/crypt_blowfish-1.3/glibc-2.3.6-crypt.diff
+++ b/src/crypt_blowfish-1.3/glibc-2.3.6-crypt.diff
diff --git a/bcrypt/crypt_blowfish-1.3/ow-crypt.h b/src/crypt_blowfish-1.3/ow-crypt.h
index 2e48794..2e48794 100644
--- a/bcrypt/crypt_blowfish-1.3/ow-crypt.h
+++ b/src/crypt_blowfish-1.3/ow-crypt.h
diff --git a/bcrypt/crypt_blowfish-1.3/wrapper.c b/src/crypt_blowfish-1.3/wrapper.c
index 1e49c90..1e49c90 100644
--- a/bcrypt/crypt_blowfish-1.3/wrapper.c
+++ b/src/crypt_blowfish-1.3/wrapper.c
diff --git a/bcrypt/crypt_blowfish-1.3/x86.S b/src/crypt_blowfish-1.3/x86.S
index b0f1cd2..b0f1cd2 100644
--- a/bcrypt/crypt_blowfish-1.3/x86.S
+++ b/src/crypt_blowfish-1.3/x86.S
diff --git a/tests/test_bcrypt.py b/tests/test_bcrypt.py
index 5793811..c91a62e 100644
--- a/tests/test_bcrypt.py
+++ b/tests/test_bcrypt.py
@@ -7,11 +7,6 @@ import six
import bcrypt
-def test_raise_implicit_compile():
- with pytest.raises(RuntimeError):
- bcrypt._compile_module()
-
-
def test_gensalt_basic(monkeypatch):
monkeypatch.setattr(os, "urandom", lambda n: b"0000000000000000")
assert bcrypt.gensalt() == b"$2a$12$KB.uKB.uKB.uKB.uKB.uK."