Skip to content

Latest commit

 

History

History
716 lines (530 loc) · 28.9 KB

CHANGES

File metadata and controls

716 lines (530 loc) · 28.9 KB

Release History

1.7 (NOT YET RELEASED)

.. todo::

    The following tasks are blocking the 1.7 release:

    * Finish the :mod:`passlib.totp` module (mainly tests & documentation)

    * Get scrypt hash implemented, or push it to later release (really want to include it)

    * Finish :mod:`passlib.pwd` -- need to finalize API and document it better.

    * Would strongly like to also add pbkdf2 & bcrypt variants which have support for an external
      "pepper" to further increase security.

    * Internal cleanups:

        * Check for additions to Django's hashers as of Django 1.7

        * Potentially reorg the utils module (particularly the crypto bits), it's getting messy.

Requirements

  • Passlib now requires Python 2.6, 2.7, or >= 3.2. Support for Python versions 2.5, 3.0, and 3.1 has been dropped (and Python 3.2 may be dropped in the next major release). Support for PyPy 1.x has also been dropped.
  • The :mod:`passlib.ext.django` extension now requires Django 1.4 or better. Django 0.9 .. 1.3 are no longer supported.

Major Changes

  • New :mod:`passlib.totp` module provides full support for TOTP & HOTP tokens on both client and server side. Contains both low-level primitives, and high-level helpers for persisting and tracking client state.
  • New :mod:`passlib.pwd` module added to aid in password generation and strength measurement (with contributions from Thomas Waldmann).
  • The :func:`~passlib.utils.pbkdf2.pbkdf2` function and all PBKDF2-based hashes have been sped up by ~20% compared to Passlib 1.6.
  • Passlib will now detect and work around the fatal concurrency bug in py-bcrypt 0.2 and earlier (a :exc:`~passlib.exc.PasslibSecurityWarning` will also be issued). Nevertheless, users are strongly encouraged to upgrade to py-bcrypt 0.3 or another bcrypt library if you are using the :doc:`bcrypt </lib/passlib.hash.bcrypt>` hash.

Minor Changes

Deprecations

Todo

  • Thread safety audit and tests for CryptContext, HasManyBackends, and lazy-init subclasses.

1.6.2 (2013-12-26)

Minor changes & compatibility fixes

1.6.1 (2012-08-02)

Minor bugfix release

1.6 (2012-05-01)

Overview

Welcome to Passlib 1.6.

The main goal of this release was to clean up the codebase, tighten input validation, and simplify the publically exposed interfaces. This release also brings a number of other improvements: 10 or so new hash algorithms, additional security precautions for the existing algorithms, a number of speed improvements, and updated documentation.

Deprecated APIs

In order to improve the publically exposed interface, some of the more cumbersome and less-used functions in Passlib have been deprecated / renamed. This should not affect 99% of applications. That said, all the deprecated interfaces are still present, and will continue to be supported for at least one more major release. To help with migration, all deprecated functions should issue an informative :exc:`DeprecationWarning` when they are invoked, detailing their suggested replacement. The following interfaces have changed:

New Hashes

The release adds support for a number of hash algorithms:

:doc:`cisco_pix <lib/passlib.hash.cisco_pix>`, :doc:`cisco_type7 <lib/passlib.hash.cisco_type7>`
Two hash formats frequently found on various Cisco devices (for Cisco Type 5 hashes, see :doc:`md5_crypt <lib/passlib.hash.md5_crypt>` ).
:ref:`django_pbkdf2_sha256 <django-1.4-hashes>`, :ref:`django_pbkdf2_sha1 <django-1.4-hashes>`, :ref:`django_bcrypt <django-1.4-hashes>`
All three of the new hash schemes introduced in Django 1.4.
:doc:`lmhash <lib/passlib.hash.lmhash>`, :doc:`nthash <lib/passlib.hash.nthash>`
Microsoft's legacy "Lan Manager" hash, and the replacement NT password hash. (the old nthash algorithm in Passlib 1.5 has been renamed to :class:`~passlib.hash.bsd_nthash` , to reflect its lineage).
:doc:`msdcc <lib/passlib.hash.msdcc>`, :doc:`msdcc2 <lib/passlib.hash.msdcc2>`
Microsoft Windows' Domain Cached Credentials, versions 1 and 2. These algorithms also go by the names "DCC", "MSCache", and "MSCash".
:doc:`mssql2000 <lib/passlib.hash.mssql2000>`, :doc:`mssql2005 <lib/passlib.hash.mssql2005>`
Hash algorithms used by MS SQL Server 2000 and later.
:doc:`scram <lib/passlib.hash.scram>`
A hash format added specifically for storing the complex digest information needed to authenticate a user via the SCRAM protocol (RFC 5802). It can also be used in the same way as any other password hash in Passlib.

Existing Hashes

Additionally, the following new features have been added to the existing hashes:

Password Size Limit

All hashes in Passlib will now throw :exc:`~passlib.exc.PasswordSizeError` if handed a password that's larger than 4096 characters.

This limit should be larger than any reasonable password size, and prevents various things including DOS abuses, and exploitation of OSes with a buggy :func:`!crypt` implementation. See :exc:`~passlib.exc.PasswordSizeError` for how to change this limit.

Constant Time Comparison

All hash comparisons in Passlib now use the "constant time" [1] comparison function :func:`~passlib.utils.consteq`, instead of ==.

This change is motivated a well-known hmac timing attack which exploits short-circuit string comparisons. While this attack is not currently feasible against most password hashes, some of the weaker unsalted hashes supported by Passlib may be vulnerable; and this change has been made preventatively to all of them.

[1]"constant time" is a misnomer, it actually takes THETA(len(righthand_value)) time.
Strict Parameters

Previous releases of Passlib would silently correct any invalid values (such as rounds parameters that were out of range). This is was deemed undesirable, as it leaves developers unaware they are requesting an incorrect (and potentially insecure) value.

Starting with this release, providing invalid values to :meth:`PasswordHash.encrypt <passlib.ifc.PasswordHash.encrypt>` will result in a :exc:`ValueError`. However, most hashes now accept an optional relaxed=True keyword, which causes Passlib to try and correct invalid values, and if successful, issue a :exc:`~passlib.exc.PasslibHashWarning` instead. These warnings can then be filtered if desired.

:doc:`bcrypt <lib/passlib.hash.bcrypt>`

The BCrypt hash now supports the crypt_blowfish project's $2y$ hash prefix.

On an unrelated note, Passlib now offers an (experimental) pure-python implementation of BCrypt. Unfortunately, it's still WAY too slow to be suitable for production use; and is disabled by default. If you really need it, see the BCrypt :ref:`documentation <bcrypt-backends>` for how to enable it.

:doc:`bsdi_crypt <lib/passlib.hash.bsdi_crypt>`
BSDi-Crypt will now issue a :exc:`~passlib.exc.PasslibSecurityWarning` if an application requests an even number of rounds, due to a known weakness in DES. Existing hashes with an even number of rounds will now be flagged by :meth:`CryptContext.needs_update() <passlib.context.CryptContext.needs_update>`.
:doc:`ldap_salted_{digest} </lib/passlib.hash.ldap_std>`
The LDAP salted digests now support salts of any size from 4-16 bytes, though they still default to 4 (:issue:`30`).
:doc:`md5_crypt </lib/passlib.hash.md5_crypt>`, :doc:`sha256_crypt </lib/passlib.hash.md5_crypt>`, :doc:`sha512_crypt </lib/passlib.hash.md5_crypt>`
The builtin implementation of these hashes has been sped up by about 25%, using an additional pre-computation step.
:doc:`unix_disabled <lib/passlib.hash.unix_disabled>`

The :class:`!unix_fallback` handler has been deprecated, and will be removed in Passlib 1.8. Applications should use the stricter-but-equivalent :class:`!unix_disabled` handler instead.

This most likely only affects internal Passlib code.

CryptContext

.. currentmodule:: passlib.context

The :ref:`CryptContext <context-overview>` class has had a thorough internal overhaul. While the primary interface has not changed at all, the internals are much stricter about input validation, common methods have shorter code-paths, and the construction and introspection of :class:`!CryptContext` objects has been greatly simplified. Changes include:

Other Modules

  • The api for the :mod:`passlib.apache` module has been updated to add more flexibility, and to fix some ambiguous method and keyword names. The old interface is still supported, but deprecated, and will be removed in Passlib 1.8.
  • Added the :data:`~passlib.apps.django14_context` preset to the the :mod:`!passlib.apps` module. this preconfigured CryptContext object should support all the hashes found in a typical Django 1.4 deployment.
  • new: Added :mod:`passlib.ext.django`, a Django plugin which can be used to override Django's password hashing framework with a custom Passlib policy (an undocumented beta version of this was present in the 1.5 release).
  • new: The :func:`passlib.utils.saslprep` function may be useful for applications which need to normalize the unicode representation of passwords before they are hashed.

Bugfixes

  • Handle platform-specific error strings that may be returned by the :func:`!crypt` methods of some OSes.
  • Fixed rare 'NoneType' object has no attribute 'decode' error that sometimes occurred on platforms with a deviant implementation of :func:`!crypt`.

Internal Changes

The following changes should not affect most end users, and have been documented just to keep track of them:

.. currentmodule:: passlib.utils.handlers

  • Passlib is now source-compatible with Python 2.5+ and Python 3.x. It no longer requires the use of the :command:`2to3` command to translate it for Python 3.

  • The unittest suite has been rewritten. It handles a number of additional border cases, enforcing uniform behavior across all hashes, and even features the addition of some simplistic fuzz testing. It will take a bit longer to run though. While not perfect, statement coverage is at about 95%. Additionally, the hash test suite has been enhanced with many more test vectors across the board, including 8-bit test vectors.

  • The internal framework used to construct the hash classes (:mod:`passlib.utils.handlers`) was rewritten drastically. The new version provides stricter input checking, reduction in boilerplate code. These changes should not affect any publically exposed routines.

.. currentmodule:: passlib.utils

1.5.3 (2011-10-08)

Bugfix release -- fixes BCrypt padding/verification issue (:issue:`25`)

This release fixes a single issue with Passlib's BCrypt support: Many BCrypt hashes generated by Passlib (<= 1.5.2) will not successfully verify under some of the other BCrypt implementations, such as OpenBSD's /etc/master.passwd.

In detail:

BCrypt hashes contain 4 "padding" bits in the encoded salt, and Passlib (<= 1.5.2) generated salts in a manner which frequently set some of the padding bits to 1. While Passlib ignores these bits, many BCrypt implementations perform password verification in a way which rejects all passwords if any of the padding bits are set. Thus Passlib's BCrypt salt generation needed to be fixed to ensure compatibility, and a route provided to correct existing hashes already out in the wild :issue:`25`.

Changes in this release:

.. currentmodule:: passlib.context

  • BCrypt hashes generated by Passlib now have all padding bits cleared.
  • Passlib will continue to accept BCrypt hashes that have padding bits set, but when it encounters them, it will issue a :exc:`UserWarning` recommending that the hash should be fixed (see below).
  • Applications which use :meth:`CryptContext.verify_and_update` will have any such hashes automatically re-encoded the next time the user logs in.

To fix existing hashes:

If you have BCrypt hashes which might have their padding bits set, you can import :class:`!passlib.hash.bcrypt`, and call clean_hash = bcrypt.normhash(hash). This function will clear the padding bits of any BCrypt hashes, and should leave all other strings alone.

1.5.2 (2011-09-19)

Minor bugfix release -- mainly Django-related fixes

Hashes

.. currentmodule:: passlib.hash

CryptContext

.. currentmodule:: passlib.context

1.5.1 (2011-08-17)

Minor bugfix release -- now compatible with Google App Engine.

  • bugfix: make passlib.hash.__loader__ attribute writable - needed by Google App Engine (GAE) :issue:`19`.
  • bugfix: provide fallback for loading passlib/default.cfg if :mod:`pkg_resources` is not present, such as for GAE :issue:`19`.
  • bugfix: fixed error thrown by CryptContext.verify when issuing min_verify_time warning :issue:`17`.
  • removed min_verify_time setting from custom_app_context, min_verify_time is too host & load dependant to be hardcoded :issue:`17`.
  • under GAE, disable all unittests which require writing to filesystem.
  • more unittest coverage for :mod:`passlib.apps` and :mod:`passlib.hosts`.
  • improved version datestamps in build script.

1.5 (2011-07-11)

"20% more unicode than the leading breakfast cereal"

The main new feature in this release is that Passlib now supports Python 3 (via the 2to3 tool). Everything has been recoded to have better separation between unicode and bytes, and to use unicode internally where possible. When run under Python 2, Passlib 1.5 attempts to provide the same behavior as Passlib 1.4; but when run under Python 3, most functions will return unicode instead of ascii bytes.

Besides this major change, there have been some other additions:

Hashes

  • added support for Cryptacular's PBKDF2 format.
  • added support for the FSHP family of hashes.
  • added support for using BCryptor as BCrypt backend.
  • added support for all of Django's hash formats.

CryptContext

.. currentmodule:: passlib.context

Documentation

Internal Changes

1.4 (2011-05-04)

This release contains a large number of changes, both large and small. It adds a number of PBKDF2-based schemes, better support for LDAP-format hashes, improved documentation, and faster load times. In detail...

Hashes

  • added LDAP {CRYPT} support for all hashes known to be supported by OS crypt()
  • added 3 custom PBKDF2 schemes for general use, as well as 3 LDAP-compatible versions.
  • added support for Dwayne Litzenberger's PBKDF2 scheme.
  • added support for Grub2's PBKDF2 hash scheme.
  • added support for Atlassian's PBKDF2 password hash
  • added support for all hashes used by the Roundup Issue Tracker
  • bsdi_crypt, sha1_crypt now check for OS crypt() support
  • salt_size keyword added to encrypt() method of all the hashes which support variable-length salts.
  • security fix: disabled unix_fallback's "wildcard password" support unless explicitly enabled by user.

CryptContext

  • host_context now dynamically detects which formats OS crypt() supports, instead of guessing based on sys.platform.
  • added predefined context for Roundup Issue Tracker database.
  • added CryptContext.verify_and_update() convenience method, to make it easier to perform both operations at once.
  • bugfix: fixed NameError in category+min_verify_time border case
  • apps & hosts modules now use new :class:`LazyCryptContext` wrapper class - this should speed up initial import, and reduce memory by not loading unneeded hashes.

Documentation

  • greatly expanded documentation on how to use CryptContexts.
  • roughly documented framework for writing & testing custom password handlers.
  • various minor improvements.

Internals

  • added generate_password() convenience method
  • refactored framework for building hash handlers, using new mixin-based system.
  • deprecated old handler framework - will remove in 1.5
  • deprecated list_to_bytes & bytes_to_list - not used, will remove in 1.5

Other

  • password hash api - as part of cleaning up optional attributes specification, renamed a number of them to reduce ambiguity:

    • renamed {xxx}_salt_chars attributes -> xxx_salt_size
    • renamed salt_charset -> salt_chars
    • old attributes still present, but deprecated - will remove in 1.5
  • password hash api - tightened specifications for salt & rounds parameters, added support for hashes w/ no max salt size.

  • improved password hash api conformance tests

  • PyPy compatibility

1.3.1 (2011-03-28)

Minor bugfix release.

  • bugfix: replaced "sys.maxsize" reference that was failing under py25
  • bugfix: fixed default_rounds>max_rounds border case that could cause ValueError during CryptContext.encrypt()
  • minor documentation changes
  • added instructions for building html documentation from source

1.3 (2011-03-25)

First public release.

  • documentation completed
  • 99% unittest coverage
  • some refactoring and lots of bugfixes
  • added support for a number of additional password schemes: bigcrypt, crypt16, sun md5 crypt, nthash, lmhash, oracle10 & 11, phpass, sha1, generic hex digests, ldap digests.

1.2 (2011-01-06)

Note

For this and all previous versions, Passlib did not exist independently, but as a subpackage of BPS, a private & unreleased toolkit library.

  • many bugfixes
  • global registry added
  • transitional release for applications using BPS library.
  • first truly functional release since splitting from BPS library (see below).

1.0 (2009-12-11)

  • CryptContext & CryptHandler framework
  • added support for: des-crypt, bcrypt (via py-bcrypt), postgres, mysql
  • added unit tests

0.5 (2008-05-10)

  • initial production version
  • consolidated from code scattered across multiple applications
  • MD5-Crypt, SHA256-Crypt, SHA512-Crypt support