summaryrefslogtreecommitdiff
path: root/docs/history/1.7.rst
blob: 42ffeecea7ebdb7d35e26072706d1cea0d2c4517 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
.. _whats-new:

===========
Passlib 1.7
===========

.. rst-class:: without-title

.. warning::

    **Passlib 1.8 will drop support for Python 2.x, 3.3, and 3.4**;
    and will require Python >= 3.5.  The 1.7 series will be the last
    to support Python 2.7.  (See :issue:`119` for rationale).

**1.7.4** (NOT YET RELEASED)
============================

Other Changes
-------------
* .. py:currentmodule:: passlib.context

  :class:`CryptContext` will now throw :exc:`~passlib.exc.UnknownHashError` when it can't identify
  a hash provided to methods such as :meth:`!CryptContext.verify`.
  Previously it would throw a generic :exc:`ValueError`.


**1.7.3** (2020-10-06)
======================

This release rolls up assorted bug & compatibility fixes since 1.7.2.

Administrative Changes
----------------------

.. rst-class:: without-title

.. note::

  **Passlib has moved to Heptapod!**

  Due to BitBucket deprecating Mercurial support, Passlib's public repository and issue tracker
  has been relocated.  It's now located at `<https://foss.heptapod.net/python-libs/passlib>`_,
  and is powered by `Heptapod <https://heptapod.net/>`_.

  Hosting for this and other open-source projects graciously provided by the people at
  `Octobus <https://octobus.net/>`_ and `CleverCloud <https://clever-cloud.com/>`_!

  The mailing list and documentation urls remain the same.

New Features
------------

* .. py:currentmodule:: passlib.hash

  :class:`ldap_salted_sha512`: LDAP "salted hash" support added for SHA-256 and SHA-512 (:issue:`124`).

Bugfixes
--------

* .. py:currentmodule:: passlib.hash

  :class:`bcrypt`: Under python 3, OS native backend wasn't being detected on BSD platforms.
  This was due to a few internal issues in feature-detection code, which have been fixed.

* :func:`passlib.utils.safe_crypt`: Support :func:`crypt.crypt` unexpectedly
  returning bytes under Python 3 (:issue:`113`).

* :func:`passlib.utils.safe_crypt`: Support :func:`crypt.crypt` throwing :exc:`OSError`,
  which can happen as of Python 3.9 (:issue:`115`).

* :mod:`passlib.ext.django`: fixed lru_cache import (django 3 compatibility)

* :mod:`!passlib.tests`: fixed bug where :meth:`HandlerCase.test_82_crypt_support` wasn't
  being run on systems lacking support for the hasher being tested.
  This test now runs regardless of system support.

Other Changes
-------------

* .. py:currentmodule:: passlib.hash

  :class:`bcrypt_sha256`:  Internal algorithm has been changed to use HMAC-SHA256 instead of
  plain SHA256.  This should strengthen the hash against brute-force attempts which bypass
  the intermediary hash by using known-sha256-digest lookup tables (:issue:`114`).

* .. py:currentmodule:: passlib.hash

  :class:`bcrypt`: OS native backend ("os_crypt") now raises the new :exc:`~passlib.exc.PasswordValueError`
  if password is provided as non-UTF8 bytes under python 3
  (These can't be passed through, due to limitation in stdlib's :func:`!crypt.crypt`).
  Prior to this release, it confusingly raised :exc:`~passlib.exc.MissingBackendError` instead.

  Also improved legacy bcrypt format workarounds, to support a few more UTF8 edge cases than before.

* Modified some internals to help run on FIPS systems (:issue:`116`):

  In particular, when MD5 hash is not available, :class:`~passlib.hash.hex_md5`
  will now return a dummy hasher which throws an error if used; rather than throwing
  an uncaught :exc:`!ValueError` when an application attempts to import it.  (Similar behavior
  added for the other unsalted digest hashes).

  .. py:currentmodule:: passlib.crypto.digest

  Also, :func:`lookup_hash`'s ``required=False`` kwd was modified to report unsupported hashes
  via the :attr:`HashInfo.supported` attribute; rather than letting ValueErrors through uncaught.

  This should allow CryptContext instances to be created on FIPS systems without having
  a load-time error (though they will still receive an error if an attempt is made to actually
  *use* a FIPS-disabled hash).

* Internal errors calling stdlib's :func:`crypt.crypt`, or third party libraries,
  will now raise the new :exc:`~passlib.exc.InternalBackendError` (a RuntimeError);
  where previously it would raise an :exc:`AssertionError`.

* Various Python 3.9 compatibility fixes (including ``NotImplemented``-related warning, :issue:`125`)


**1.7.2** (2019-11-22)
======================

This release rolls up assorted bug & compatibility fixes since 1.7.1.

New Features
------------

* .. py:currentmodule:: passlib.hash

  :class:`argon2`: Now supports Argon2 "ID" and "D" hashes (assuming new enough backend library).
  Now defaults to "ID" hashes instead of "I" hashes, but this can be overridden via ``type`` keyword.
  (:issue:`101`)

* .. py:currentmodule:: passlib.hash

  :class:`scrypt`: Now uses python 3.6 stdlib's :func:`hashlib.scrypt` as backend,
  if present (:issue:`86`).

Bugfixes
--------

* Python 3.8 compatibility fixes

* :class:`passlib.apache.HtpasswdFile`: Now generates bcrypt hashes using
  the ``"$2y$"`` prefix,  which should work properly with Apache 2.4's ``htpasswd`` tool.
  Previous releases used the functionally equivalent ``"$2b$"`` prefix,
  which ``htpasswd`` was unable to read (:issue:`95`).

* .. py:currentmodule:: passlib.totp

  :mod:`passlib.totp`: The :meth:`TOTP.to_uri` method now prepends the issuer to URI label,
  (per the KeyURI spec).  This should fix some compatibility issues with older TOTP clients
  (:issue:`92`)

* .. py:currentmodule:: passlib.hash

  Fixed error in :meth:`argon2.parsehash` (:issue:`97`)

* **unittests**: ``crypt()`` unittests now account for linux systems running libxcrypt
  (such as recent Fedora releases)

Deprecations
------------

.. rst-class:: float-center

.. warning::

    Due to lack of ``pip`` and ``venv`` support, Passlib is no longer fully tested on Python
    2.6 & 3.3.  There are no known issues, and bugfixes against these versions will still be
    accepted for the Passlib 1.7.x series.
    However, **Passlib 1.8 will drop support for Python 2.x & 3.3,** and require Python >= 3.4.

* Support for Python 2.x & 3.3 is deprecated; and will be dropped in Passlib 1.8.
  *(2020-05-10: Updated to include all of Python 2.x; when 1.7.2 was released,
  only Python 2.6 / 3.3 support was deprecated)*

* .. py:currentmodule:: passlib.hash

  :class:`bcrypt`: ``py-bcrypt`` and ``bcryptor`` backends are deprecated, and support
  will be removed in Passlib 1.8.  Please switch to the ``bcrypt`` backend.

Other Changes
-------------

* **setup.py**: now honors ``$SOURCE_DATE_EPOCH`` to help with reproducible builds

* .. py:currentmodule:: passlib.hash

  :class:`argon2`: Now throws helpful error if "argon2" package is actually an incompatible
  or supported version of argon2_cffi (:issue:`99`).

* **documentation**: Various updates & corrections.  
  building the documentation now requires Sphinx 1.6 or newer.
  

**1.7.1** (2017-1-30)
=====================

This release rolls up assorted bug & compatibility fixes since 1.7.0.

Bugfixes
--------
* .. py:currentmodule:: passlib.hash

  :class:`cisco_asa` and :class:`cisco_pix`: Fixed a number of issues
  which under :ref:`certain conditions <passlib-asa96-bug>`
  caused prior releases to generate hashes that were unverifiable
  on Cisco systems.

* .. py:currentmodule:: passlib.ifc

  :meth:`PasswordHash.hash` will now warn if passed any settings
  keywords.  This usage was deprecated in 1.7.0, but warning wasn't properly enabled.
  See :ref:`hash-configuring` for the preferred way to pass settings.

* **setup.py**: Don't append timestamp when run from an sdist.
  This should fix some downstream build issues.

* :mod:`!passlib.tests.test_totp`: Test suite now traps additional errors that :func:`datetime.utcfromtimestamp`
  may throw under python 3, which should fix some test failures on architectures with rarer ILP sizes.
  It also works around Python 3.6 bug `29100 <https://bugs.python.org/issue29100>`_.

Deprecations
------------

* :class:`~passlib.context.CryptContext`: The ``harden_verify`` flag has been turned into a NOOP and deprecated.
  It will be removed in passlib 1.8 along with the already-deprecated ``min_verify_time`` (:issue:`83`).

Other Changes
-------------

* :mod:`!passlib.tests.utils`: General truncation policy details were hammered out,
  and additional hasher tests were added to enforce them.

* **documentation**: Various updates & corrections.

.. rst-class:: emphasize-children toc-always-open

**1.7.0** (2016-11-22)
======================

Overview
--------

    *Welcome to Passlib 1.7!*

    This release includes a number of new features, cleans up
    some long-standing design issues, and contains a number of internal
    improvements; all part of the roadmap towards a leaner and simpler Passlib 2.0.

    *Highlights include:*

    * Support for :class:`~passlib.hash.argon2` and
      :class:`~passlib.hash.scrypt` hashes.

    * TOTP Two-Factor Authentications helpers in the :mod:`passlib.totp` module.

    .. currentmodule:: passlib.ifc

    * The misnamed :meth:`PasswordHash.encrypt` method has been renamed to  :meth:`PasswordHash.hash`
      (and the old alias deprecated).  This is part of a much
      larger project to clean up passlib's password hashing API,
      see the :ref:`hash-tutorial` for a walkthrough.

    * Large speedup of the internal PBKDF2 routines.

    * Updated documentation

Requirements
------------

   * **Passlib now requires Python 2.6, 2.7, or >= 3.3**.
     Support for Python versions 2.5 and 3.0 through 3.2 have been dropped.
     Support for PyPy 1.x has also been dropped.

   * The :mod:`passlib.ext.django` extension now requires Django 1.8 or better.
     Django 1.7 and earlier are no longer supported.

New Features
------------

*New Hashes*

    * :doc:`passlib.hash.argon2 </lib/passlib.hash.argon2>` --
      Support for the Argon2 password hash (:issue:`69`).

    * :doc:`passlib.hash.scrypt </lib/passlib.hash.scrypt>` --
      New password hash format which uses the SCrypt KDF (:issue:`8`).

    * :doc:`passlib.hash.cisco_asa </lib/passlib.hash.cisco_asa>` --
      Support for Cisco ASA 7.0 and newer hashes (:issue:`51`).
      *Note: this should be considered experimental, and needs verification
      of it's test vectors.*

*New Modules*

    * New :mod:`passlib.totp` module provides full support for TOTP tokens
      on both client and server side.  This module 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.
      Features support for alphanumeric passwords, or generation
      of phrases using the EFF's password generation wordlist.

*CryptContext Features*

    * The :class:`~passlib.context.CryptContext` object now has helper
      methods for dealing with hashes representing
      :ref:`disabled accounts <context-disabled-hashes>` (:issue:`45`).

    * All hashers which truncate passwords (e.g. :class:`~passlib.hash.bcrypt`
      and :class:`~passlib.hash.des_crypt`) can now be configured to raise
      a :exc:`~passlib.exc.PasswordTruncateError` when a overly-large password is provided.
      This configurable via (for example) ``bcrypt.using(truncate_error=True).hash(secret)``,
      or globally as an option to CryptContext (:issue:`59`).

*Cryptographic Backends*

    * The :func:`~passlib.crypto.digest.pbkdf2_hmac` function and all PBKDF2-based
      hashes have been sped up by ~20% compared to Passlib 1.6. For an even greater
      speedup, it will now take advantage of the external `fastpbk2 <https://pypi.python.org/pypi/fastpbkdf2>`_
      library, or stdlib's :func:`hashlib.pbkdf2_hmac` (when available).

Other Changes
-------------

*Other changes of note in Passlib 1.7:*

    .. currentmodule:: passlib.ifc

    * New workflows have been for configuring the hashers through :meth:`PasswordHash.using`,
      and testing hashes through :meth:`PasswordHash.needs_update`.
      See the :ref:`hash-tutorial` for a walkthrough.

    * :class:`~passlib.hash.bcrypt` and :class:`~passlib.hash.bcrypt_sha256`
      now default to the "2b" format.

    * Added support for Django's Argon2 wrapper (:class:`~passlib.hash.django_argon2`)

    * :class:`passlib.apache.HtpasswdFile` has been updated to support all of Apache 2.4's
      hash schemes, as well as all host OS crypt formats; allowing for much more
      secure hashes in htpasswd files.

      You can now specify if the default hash should be compatible with apache 2.2 or 2.4, and host-specific or portable.
      See the ``default_schemes`` keyword for details.

    * Large parts of the documentation have been rewritten, to separate
      tutorial & api reference content, and provide more detail on various features.

    * Official documentation is now at https://passlib.readthedocs.io

*Internal Changes*

    .. currentmodule:: passlib.ifc

    * The majority of CryptContext's internal rounds handling & migration code has been
      moved to the password hashes themselves, taking advantage of the new :meth:`PasswordHash.using`
      and :meth:`PasswordHash.needs_update` methods.

      This allows much more flexibility when configuring a hasher directly,
      as well making it easier for CryptContext to support hash-specific parameters.

    * The shared :class:`!PasswordHash` unittests now check all hash handlers for
      basic thread-safety (motivated by the pybcrypt 0.2 concurrency bug).

    * :func:`~passlib.utils.consteq` is now wraps stdlib's :func:`hmac.compare_digest`
      when available (python 2.7.11, python 3.3 and up).

Bugfixes
--------
    * :class:`~passlib.hash.bcrypt`: Passlib will now detect and work around
      a 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.

    * :class:`~passlib.CryptContext` instances now pass contextual keywords (such as `"user"`)
      to the hashes that support them, but ignore them for hashes that don't (:issue:`63`).

    * The :mod:`passlib.apache` htpasswd helpers now preserve blank lines and comments,
      rather than throwing a parse error (:issue:`73`).

    * :mod:`passlib.ext.django` and unittests: compatibility fixes for Django 1.9 / 1.10,
      and some internal refactoring (:issue:`68`).

    * The :class:`~passlib.hash.django_disabled` hash now appends
      a 40-char alphanumeric string, to match Django's behavior.

.. _encrypt-method-cleanup:

Deprecations
------------
As part of a long-range plan to restructure and simplify both the API and the internals of Passlib,
a number of methods have been deprecated & replaced.  The eventually goal is a large cleanup
and overhaul as part of Passlib 2.0. There will be at least one more 1.x version
before Passlib 2.0, to provide a final transitional release
(see the `Project Roadmap <https://foss.heptapod.net/python-libs/passlib/wikis/roadmap>`_).

Password Hash API Deprecations
..............................
    .. currentmodule:: passlib.ifc

    As part of this cleanup, the :class:`~passlib.ifc.PasswordHash` API (used by all hashes in passlib),
    has had a number of changes:

    .. rst-class:: float-right

    .. seealso::

        :ref:`hash-tutorial`, which walks through using the new hasher interface.

    * **[major]** The :meth:`!PasswordHash.encrypt` method
      has been renamed to :meth:`PasswordHash.hash`,
      to clarify that it's performing one-way hashing rather than reversiable encryption.
      A compatibility alias will remain in place until Passlib 2.0.
      This should fix the longstanding :issue:`21`.

    * **[major]** Passing explicit configuration options to the :meth:`!PasswordHash.encrypt` method
      (now called :meth:`PasswordHash.hash`) is deprecated.
      To provide settings such as ``rounds`` and ``salt_size``, callers
      should use the new :meth:`PasswordHash.using`
      method, which generates a new hasher with a customized configuration.
      For example, instead of::

        >>>  sha256_crypt.encrypt("secret", rounds=12345)

      ... applications should now use::

        >>>  sha256_crypt.using(rounds=12345).hash("secret")

      Support for the old syntax will be removed in Passlib 2.0.

      .. note::

         This doesn't apply to contextual options such as :class:`~passlib.hash.cisco_pix`'s
         ``user`` keyword, which should still be passed into the :meth:`!hash` method.

    * **[minor]** The little-used :meth:`PasswordHash.genhash` and
      :meth:`PasswordHash.genconfig` methods have been deprecated.
      Compatibility aliases will remain in place until Passlib 2.0,
      at which point they will be removed entirely.

Crypt Context API Deprecations
..............................
    .. currentmodule:: passlib.context

    Applications which use passlib's :class:`~passlib.context.CryptContext` should not be
    greatly affected by this release; only one major deprecation was made:

    * **[major]** To match the :class:`!PasswordHash` API changes above,
      the :meth:`!CryptContext.encrypt` method was renamed to :meth:`CryptContext.hash`.
      A compatibility alias will remain until Passlib 2.0.

    A fewer internal options and infrequently used features have been deprecated:

    * **[minor]** :meth:`CryptContext.hash`, :meth:`~CryptContext.verify`,
      :meth:`~CryptContext.verify_and_update`, and
      :meth:`~CryptContext.needs_update`:
      The ``scheme`` keyword is now deprecated; support will be removed in Passlib 2.0.

    * **[minor]** :meth:`CryptContext.hash`: Passing
      settings keywords to :meth:`!hash` such as ``rounds`` and ``salt`` is deprecated.
      Code should now get ahold of the default hasher, and invoke it explicitly::

        >>>  # for example, calls that did this:
        >>>  context.hash(secret, rounds=1234)

        >>>  # should use this instead:
        >>>  context.handler().using(rounds=1234).hash(secret)

    * **[minor]** The ``vary_rounds`` option has been deprecated,
      and will be removed in Passlib 2.0.  It provided very little security benefit,
      and was judged not worth the additional code complexity it requires.

    * **[minor]** The special wildcard ``all`` scheme name
      has been deprecated, and will be removed in Passlib 2.0.  The only legitimate use
      was to support ``vary_rounds``, which itself will be removed in 2.0.

Other Deprecations
..................
    A few other assorted deprecations have been made:

    * The :func:`passlib.utils.generate_secret` function has been deprecated
      in favor of the new :mod:`passlib.pwd` module, and the old function will be removed
      in Passlib 2.0.

    * Most of passlib's internal cryptography helpers have been moved from
      :mod:`passlib.utils` to :mod:`passlib.crypto`, and the APIs refactored.
      This allowed unification of various hash management routines,
      some speed ups to the HMAC and PBKDF2 primitives, and opens up the architecture
      to support more optional backend libraries.

      Compatibility wrappers will be kept in place at the old location until Passlib 2.0.

    * Some deprecations and internal changes have been made to the :mod:`passlib.utils.handlers`
      module, which provides the common framework Passlib uses to implement hashers.

    .. caution::

      More backwards-incompatible relocations are planned for the internal
      :mod:`!passlib.utils` module in the Passlib 1.8 / 1.9 releases.

Backwards Incompatibilities
---------------------------
Changes in existing behavior:

    * **[minor]** M2Crypto no longer used to accelerate pbkdf2-hmac-sha1; applications relying on this
      to speed up :class:`~passlib.hash.pbkdf2_sha1` should install
      `fastpbkdf2 <https://pypi.python.org/pypi/fastpbkdf2>`_.

Scheduled removal of features:

    * **[minor]** :mod:`passlib.context`: The :ref:`min_verify_time <context-min-verify-time-option>` keyword
      that was deprecated in release 1.6, is now completely ignored.
      Support will be removed entirely in release 1.8.

    * **[trivial]** :mod:`passlib.hash`: The internal :meth:`!PasswordHash.parse_rounds` method, deprecated in 1.6, has been removed.

Minor incompatibilities:

    * **[minor]** :mod:`passlib.hash`: The little-used method :meth:`~passlib.ifc.PasswordHash.genconfig`
      will now always return a valid hash, rather than a truncated configuration
      string or ``None``.

    * **[minor]** :mod:`passlib.hash`: The little-used method :meth:`~passlib.ifc.PasswordHash.genhash` no longer accepts
      ``None`` as a config argument.

    * **[trivial]** :func:`passlib.utils.pbkdf2.pbkdf2` no longer supports custom PRF callables.
      this was an unused feature, and prevented some useful optimizations.