summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2015-07-25 11:11:49 -0400
committerEli Collins <elic@assurancetechnologies.com>2015-07-25 11:11:49 -0400
commit3bd0a6920af5a3fd2dc04f8a20027d71ada745dc (patch)
tree4e934d8fc7e34f3ca9e0a51fb1d2bec66d048958 /docs
parent5b79dd7fa81171e3a5e3601ccde2315354eb125b (diff)
parentef13f80854a8694bc8f1674207a0a02b91139a66 (diff)
downloadpasslib-3bd0a6920af5a3fd2dc04f8a20027d71ada745dc.tar.gz
Merge
Diffstat (limited to 'docs')
-rw-r--r--docs/_static/masthead.pngbin7827 -> 9173 bytes
-rw-r--r--docs/_static/masthead.svg42
-rw-r--r--docs/conf.py42
-rw-r--r--docs/contents.rst1
-rw-r--r--docs/dev-requirements.txt1
-rw-r--r--docs/index.rst12
-rw-r--r--docs/install.rst44
-rw-r--r--docs/lib/passlib.apache.rst9
-rw-r--r--docs/lib/passlib.context.rst7
-rw-r--r--docs/lib/passlib.exc.rst4
-rw-r--r--docs/lib/passlib.ext.django.rst7
-rw-r--r--docs/lib/passlib.hash.bcrypt.rst68
-rw-r--r--docs/lib/passlib.hash.bcrypt_sha256.rst1
-rw-r--r--docs/lib/passlib.totp.rst76
-rw-r--r--docs/requirements.txt3
15 files changed, 228 insertions, 89 deletions
diff --git a/docs/_static/masthead.png b/docs/_static/masthead.png
index 5aac437..890b2a1 100644
--- a/docs/_static/masthead.png
+++ b/docs/_static/masthead.png
Binary files differ
diff --git a/docs/_static/masthead.svg b/docs/_static/masthead.svg
index e02eca8..2257bb4 100644
--- a/docs/_static/masthead.svg
+++ b/docs/_static/masthead.svg
@@ -14,10 +14,10 @@
height="52"
id="svg2383"
sodipodi:version="0.32"
- inkscape:version="0.48.3.1 r9886"
+ inkscape:version="0.48.4 r9939"
sodipodi:docname="masthead.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
- inkscape:export-filename="/home/biscuit/dev/libs/passlib/stable/docs/_static/masthead.png"
+ inkscape:export-filename="/home/biscuit/dev/libs/passlib/default/docs/_static/masthead.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
version="1.0"
@@ -214,11 +214,11 @@
xlink:href="#linearGradient3910"
id="radialGradient4270"
gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1.9278492,0.04803928,-0.03632715,-1.4578329,160.96275,83.618729)"
- cx="67.387276"
- cy="44.127342"
- fx="67.387276"
- fy="44.127342"
+ gradientTransform="matrix(-3.8410307,-0.00823075,0.00312485,-1.4582821,288.14593,87.430435)"
+ cx="65.911835"
+ cy="40.810707"
+ fx="65.911835"
+ fy="40.810707"
r="21.542249" />
</defs>
<sodipodi:namedview
@@ -229,16 +229,16 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="2.4748737"
- inkscape:cx="68.856099"
+ inkscape:cx="23.601264"
inkscape:cy="26.997913"
inkscape:current-layer="layer6"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1920"
- inkscape:window-height="1021"
- inkscape:window-x="0"
- inkscape:window-y="0"
+ inkscape:window-height="1020"
+ inkscape:window-x="1920"
+ inkscape:window-y="33"
borderlayer="true"
inkscape:window-maximized="1" />
<metadata
@@ -365,7 +365,8 @@
inkscape:groupmode="layer"
id="layer3"
inkscape:label="logo"
- style="display:inline">
+ style="display:inline"
+ sodipodi:insensitive="true">
<path
style="fill:url(#linearGradient4152);fill-opacity:1;stroke:#c4a000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 30.198981,4.7423018 C 27.603462,3.3551933 24.497977,4.0990787 23.252373,6.4298176 22.806104,7.264865 22.657496,8.207834 22.773368,9.1120344 22.331047,7.8938257 21.39055,6.7848017 20.09279,6.0912475 17.497271,4.7041388 14.406213,5.4954406 13.16061,7.8261789 c -1.245603,2.3307391 -0.169335,5.3094541 2.426184,6.6965631 1.159336,0.619577 2.422664,0.787802 3.576144,0.600895 l 0.986978,4.775957 -12.1150241,22.669294 c 4.9198721,2.547763 5.3232811,2.757641 9.7151381,5.11259 l 1.766086,-3.304651 -6.062927,-3.240176 1.254416,-2.347229 6.062928,3.240176 1.914635,-3.582614 -6.062927,-3.240176 1.336944,-2.501653 6.124795,3.27324 1.914635,-3.582613 -6.124795,-3.273239 3.928305,-7.350535 4.533578,-1.785931 c 0.501629,0.956702 1.28838,1.800296 2.352778,2.369136 2.595519,1.387109 5.717509,0.612338 6.963112,-1.7184 1.245603,-2.330738 0.138402,-5.325986 -2.457117,-6.713095 -1.965927,-1.093746 -4.223756,-0.285853 -3.891712,-0.531306 0.482653,-0.371302 1.052777,-1.374623 1.353334,-1.937016 C 33.901701,9.1246576 32.7945,6.1294104 30.198981,4.7423018 z M 29.14263,6.7189161 c 1.020541,0.5454016 1.37928,1.809501 0.834737,2.8284351 C 29.432824,10.566283 28.182513,10.970469 27.161973,10.425067 26.141433,9.8796667 25.751761,8.5990343 26.296303,7.5801015 26.840846,6.5611674 28.12209,6.1735148 29.14263,6.7189161 z m 5.075829,9.7008179 c 1.02054,0.545402 1.410211,1.826033 0.865669,2.844966 -0.544543,1.018933 -1.825786,1.406587 -2.846327,0.861185 -1.020539,-0.545401 -1.410213,-1.826033 -0.86567,-2.844966 0.544543,-1.018934 1.825788,-1.406586 2.846328,-0.861185 z M 18.840451,8.360176 c 1.020541,0.5454016 1.37928,1.809501 0.834737,2.828434 -0.544543,1.018932 -1.794854,1.423118 -2.815394,0.877716 -1.02054,-0.545401 -1.410212,-1.826032 -0.86567,-2.8449654 0.544543,-1.0189336 1.825787,-1.406586 2.846327,-0.8611846 z"
@@ -376,7 +377,8 @@
inkscape:groupmode="layer"
id="layer8"
inkscape:label="title shadow"
- style="display:inline">
+ style="display:inline"
+ sodipodi:insensitive="true">
<text
xml:space="preserve"
style="font-size:46.00891495px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;opacity:0.31538463;fill:#000000;fill-opacity:1;stroke:none;display:inline;filter:url(#filter3883);font-family:Crimson Text;-inkscape-font-specification:Crimson Text"
@@ -393,17 +395,19 @@
<g
inkscape:groupmode="layer"
id="layer1"
- style="display:inline">
+ style="display:inline"
+ sodipodi:insensitive="true"
+ inkscape:label="title">
<text
xml:space="preserve"
- style="font-size:46.00891495px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Crimson Text;-inkscape-font-specification:Crimson Text"
- x="41.064335"
- y="39.446754"
+ style="font-size:39.73984528px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Noticia Text;-inkscape-font-specification:Noticia Text"
+ x="40.886795"
+ y="39.110039"
id="text2740"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan2742"
- x="41.064335"
- y="39.446754">PassLib</tspan></text>
+ x="40.886795"
+ y="39.110039">PassLib</tspan></text>
</g>
</svg>
diff --git a/docs/conf.py b/docs/conf.py
index c5b275c..4902f5e 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -51,8 +51,8 @@ extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.todo',
- # add autodoc support for ReST sections in class/function docstrings
- 'cloud_sptheme.ext.autodoc_sections',
+ # 3rd part extensions
+ 'sphinxcontrib.fulltoc',
# adds extra ids & classes to genindex html, for additional styling
'cloud_sptheme.ext.index_styling',
@@ -60,9 +60,6 @@ extensions = [
# inserts toc into right hand nav bar (ala old style python docs)
'cloud_sptheme.ext.relbar_toc',
- # replace sphinx :samp: role handler with one that allows escaped {} chars
- 'cloud_sptheme.ext.escaped_samp_literals',
-
# add "issue" role
'cloud_sptheme.ext.issue_tracker',
@@ -71,6 +68,12 @@ extensions = [
# modify logo per page
'cloud_sptheme.ext.perpage',
+
+ # monkeypatch sphinx to support a few extra things we can't do with extensions.
+ 'cloud_sptheme.ext.autodoc_sections',
+ 'cloud_sptheme.ext.autoattribute_search_bases',
+ 'cloud_sptheme.ext.docfield_markup',
+ 'cloud_sptheme.ext.escaped_samp_literals',
]
# Add any paths that contain templates here, relative to this directory.
@@ -166,13 +169,12 @@ html_theme_options = {}
if csp.is_cloud_theme(html_theme):
html_theme_options.update(roottarget=index_doc,
issueicon=None,
- lighter_decor=True,
-# borderless_decor=True,
- inline_admonitions=False,
+ # lighter_decor=True,
+ borderless_decor=True,
sidebar_localtoc_title="Page contents",
- sidebarwidth="280px",
- max_width="11.5in",
- compact_width="11.5in",
+ max_width="12in",
+ sidebarwidth="3.5in",
+ hyphenation_language="en",
)
if 'for-pypi' in options:
html_theme_options.update(
@@ -200,7 +202,7 @@ perpage_html_logo = {
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
-html_favicon = "logo.ico"
+html_favicon = os.path.join("_static", "logo.ico")
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
@@ -216,14 +218,14 @@ html_static_path = ['_static']
html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
-common_sidebars = ['quicklinks.html', 'searchbox.html']
-html_sidebars = {
- '**': ['localtoc.html', 'relations.html'] + common_sidebars,
- 'py-modindex': common_sidebars,
- 'genindex': common_sidebars,
- 'search': common_sidebars,
-}
-#html_sidebars = {'**': ['globaltoc.html', 'searchbox.html']}
+# common_sidebars = ['quicklinks.html', 'searchbox.html']
+# html_sidebars = {
+# '**': ['localtoc.html', 'relations.html'] + common_sidebars,
+# 'py-modindex': common_sidebars,
+# 'genindex': common_sidebars,
+# 'search': common_sidebars,
+# }
+html_sidebars = {'**': ['globaltoc.html', 'searchbox.html']}
# Additional templates that should be rendered to pages, maps page names to
# template names.
diff --git a/docs/contents.rst b/docs/contents.rst
index 700735f..3ad2ced 100644
--- a/docs/contents.rst
+++ b/docs/contents.rst
@@ -21,6 +21,7 @@ Table Of Contents
lib/passlib.apache
lib/passlib.ext.django
lib/passlib.pwd
+ lib/passlib.totp
lib/passlib.exc
lib/passlib.registry
diff --git a/docs/dev-requirements.txt b/docs/dev-requirements.txt
new file mode 100644
index 0000000..f49e8f6
--- /dev/null
+++ b/docs/dev-requirements.txt
@@ -0,0 +1 @@
+hg+https://bitbucket.org/ecollins/cloud_sptheme
diff --git a/docs/index.rst b/docs/index.rst
index 08d8a61..a776bd6 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -41,7 +41,7 @@ using the :doc:`SHA256-Crypt </lib/passlib.hash.sha256_crypt>` algorithm::
Content Summary
===============
-.. rst-class:: floater
+.. rst-class:: float-right inline-title
.. seealso:: :ref:`What's new in Passlib 1.7 <whats-new>`
@@ -99,6 +99,9 @@ Application Helpers
:mod:`passlib.pwd`
Password generation helpers.
+ :mod:`passlib.totp`
+ TOTP / Two Factor Authentication
+
..
Support Modules
---------------
@@ -126,12 +129,11 @@ Online Resources
:column-alignment: lr
================ ===================================================
- Homepage: `<http://passlib.googlecode.com>`_
+ Homepage: `<https://bitbucket.org/ecollins/passlib>`_
Online Docs: `<http://packages.python.org/passlib>`_
Discussion: `<http://groups.google.com/group/passlib-users>`_
---------------- ---------------------------------------------------
---------------- ---------------------------------------------------
- PyPI: `<http://pypi.python.org/pypi/passlib>`_
- Downloads: `<http://code.google.com/p/passlib/downloads>`_
- Source: `<http://code.google.com/p/passlib/source>`_
+ Downloads: `<https://pypi.python.org/pypi/passlib>`_
+ Source: `<https://bitbucket.org/ecollins/passlib/src>`_
================ ===================================================
diff --git a/docs/install.rst b/docs/install.rst
index 9407673..ece2198 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -6,33 +6,31 @@ Installation
Supported Platforms
===================
-Passlib requires Python 2 (>= 2.5) or Python 3.
+Passlib requires Python 2 (>= 2.6) or Python 3 (>= 3.2).
It is known to work with the following Python implementations:
-* CPython 2 -- v2.5 or newer.
-* CPython 3 -- all versions.
-* PyPy -- v1.5 or newer.
-* PyPy3 -- v2.1 or newer.
-* Jython -- v2.5 or newer.
+* CPython 2 -- v2.6 or newer.
+* CPython 3 -- v3.2 or newer.
+* PyPy -- v2.0 or newer.
+* PyPy3 -- v2.0 or newer.
+* Jython -- v2.7 or newer.
Passlib should work with all operating systems and environments,
-as it contains builtin fallbacks
-for almost all OS-dependant features.
+as it contains builtin fallbacks for almost all OS-dependant features.
Google App Engine is supported as well.
-.. warning::
+.. versionchanged:: 1.7
- **Passlib 1.7 will drop support for Python 2.5,** and require Python 2.6 or newer,
- unless significant feedback is received to reverse the decision.
- Too many core tools such as Setuptools, Pip, and Tox no longer support it,
- making testing increasingly burdensome.
+ Support for Python 2.5, 3.0, and 3.1 was dropped.
+ Support for PyPy 1.x was dropped.
+ Support for Python 3.2 may be dropped in the next major release.
.. _optional-libraries:
Optional Libraries
==================
-* `bcrypt <https://pypi.python.org/pypi/bcrypt>`_ or
- `py-bcrypt <https://pypi.python.org/pypi/py-bcrypt>`_ or
+* `bcrypt <https://pypi.python.org/pypi/bcrypt>`_,
+ `py-bcrypt <https://pypi.python.org/pypi/py-bcrypt>`_, or
`bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_
If any of these packages are installed, they will be used to provide
@@ -41,10 +39,13 @@ Optional Libraries
and your OS does not provide native BCrypt support
via stdlib's :mod:`!crypt` (which includes pretty much all non-BSD systems).
+ `bcrypt <https://pypi.python.org/pypi/bcrypt>`_ is currently the recommended
+ option -- it's actively maintained, and compatible with both CPython and PyPy.
+
* `M2Crypto <http://chandlerproject.org/bin/view/Projects/MeTooCrypto>`_
If installed, M2Crypto will be used to accelerate some internal
- functions used by PBKDF2-based hashes, but it is not required
+ functions used by some PBKDF2-based hashes, but it is not required
even in that case.
Installation Instructions
@@ -53,10 +54,6 @@ To install from PyPi using :command:`pip`::
pip install passlib
-To install from PyPi using :command:`easy_install`::
-
- easy_install passlib
-
To install from the source using :command:`setup.py`::
python setup.py install
@@ -73,7 +70,8 @@ which provide nearly complete coverage, and verification of the hash
algorithms using multiple external sources (if detected at runtime).
All unit tests are contained within the :mod:`passlib.tests` subpackage,
and are designed to be run using the
-`Nose <http://somethingaboutorange.com/mrl/projects/nose>`_ unit testing library.
+`Nose <http://somethingaboutorange.com/mrl/projects/nose>`_ unit testing library
+(as well as the ``unittest2`` library under Python 2.6).
Once Passlib and Nose have been installed, the main suite of tests may be run from the source directory::
@@ -95,8 +93,8 @@ online at `<http://packages.python.org/passlib>`_.
If you wish to generate your own copy of the documentation,
you will need to:
-1. Install `Sphinx <http://sphinx.pocoo.org/>`_ (1.1 or newer)
-2. Install the `Cloud Sphinx Theme <http://packages.python.org/cloud_sptheme>`_ (1.6 or newer).
+1. Install `Sphinx <http://sphinx.pocoo.org/>`_ (1.3 or newer)
+2. Install the `Cloud Sphinx Theme <http://packages.python.org/cloud_sptheme>`_ (1.7 or newer).
3. Download the Passlib source
4. From the Passlib source directory, run :samp:`python setup.py build_sphinx`.
5. Once Sphinx completes its run, point a web browser to the file at :samp:`{SOURCE}/build/sphinx/html/index.html`
diff --git a/docs/lib/passlib.apache.rst b/docs/lib/passlib.apache.rst
index 4fb89a7..a342492 100644
--- a/docs/lib/passlib.apache.rst
+++ b/docs/lib/passlib.apache.rst
@@ -52,6 +52,15 @@ A quick summary of its usage::
someuser:$apr1$T4f7D9ly$EobZDROnHblCNPCtrgh5i/
anotheruser:$apr1$vBdPWvh1$GrhfbyGvN/7HalW5cS9XB1
+.. warning::
+
+ :class:`!HtpasswdFile` currently defaults to using :class:`!apr_md5_crypt`,
+ as this is the only htpasswd hash guaranteed to be portable across operating systems.
+ However, for security reasons Passlib 1.7 will default to using the strongest algorithm
+ available on the host platform (e.g. :class:`!bcrypt` or :class:`!sha256_crypt`).
+ Applications that are relying on the old behavior should specify
+ ``HtpasswdFile(default_scheme="portable")`` (new in Passlib 1.6.3).
+
.. autoclass:: HtpasswdFile(path=None, new=False, autosave=False, ...)
.. index:: Apache; htdigest
diff --git a/docs/lib/passlib.context.rst b/docs/lib/passlib.context.rst
index 6d40067..4043aac 100644
--- a/docs/lib/passlib.context.rst
+++ b/docs/lib/passlib.context.rst
@@ -163,8 +163,11 @@ Options which directly affect the behavior of the CryptContext instance:
or fractional number of seconds.
.. deprecated:: 1.6
- This option has not proved very useful, and will
- be removed in version 1.8.
+ This option has not proved very useful, is ignored by 1.7,
+ and will be removed in version 1.8.
+
+ .. versionchanged:: 1.7
+ Per deprecation roadmap above, this option is now ignored.
.. _context-algorithm-options:
diff --git a/docs/lib/passlib.exc.rst b/docs/lib/passlib.exc.rst
index 96be468..f40d6f3 100644
--- a/docs/lib/passlib.exc.rst
+++ b/docs/lib/passlib.exc.rst
@@ -17,6 +17,10 @@ Exceptions
.. autoexception:: PasswordSizeError
+.. autoexception:: PasslibSecurityError
+
+.. autoexception:: TokenReuseError
+
Warnings
========
.. autoexception:: PasslibWarning
diff --git a/docs/lib/passlib.ext.django.rst b/docs/lib/passlib.ext.django.rst
index 909848c..28e7a3b 100644
--- a/docs/lib/passlib.ext.django.rst
+++ b/docs/lib/passlib.ext.django.rst
@@ -8,10 +8,9 @@
.. versionadded:: 1.6
-.. note::
+.. versionchanged:: 1.7
- Passlib 1.7's :mod:`passlib.ext.django` extension will drop
- support for Django 1.3 and earlier, and require Django 1.4 or newer.
+ As of Passlib 1.7, this module requires Django 1.6 or newer.
This module contains a `Django <http://www.djangoproject.com>`_ plugin which
overrides all of Django's password hashing functions, replacing them
@@ -41,7 +40,7 @@ of uses:
This plugin should be considered "release candidate" quality.
It works, and has good unittest coverage, but has seen only
limited real-world use. Please report any issues.
- It has been tested with Django 0.9.6 - 1.4.
+ It has been tested with Django 1.6 - 1.8.
Installation
=============
diff --git a/docs/lib/passlib.hash.bcrypt.rst b/docs/lib/passlib.hash.bcrypt.rst
index 041a2bf..55566fa 100644
--- a/docs/lib/passlib.hash.bcrypt.rst
+++ b/docs/lib/passlib.hash.bcrypt.rst
@@ -32,7 +32,6 @@ for new applications. This class can be used directly as follows::
It is strongly recommended that you install
`bcrypt <https://pypi.python.org/pypi/bcrypt>`_
- or `py-bcrypt <https://pypi.python.org/pypi/py-bcrypt>`_
when using this hash.
.. seealso:: the generic :ref:`PasswordHash usage examples <password-hash-examples>`
@@ -46,23 +45,30 @@ Interface
.. index::
pair: environmental variable; PASSLIB_BUILTIN_BCRYPT
-.. note::
+Bcrypt Backends
+---------------
+
+This class will use the first available of five possible backends:
- This class will use the first available of five possible backends:
+1. `bcrypt <https://pypi.python.org/pypi/bcrypt>`_, if installed.
+2. `py-bcrypt <https://pypi.python.org/pypi/py-bcrypt>`_, if installed.
+3. `bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_, if installed.
+4. stdlib's :func:`crypt.crypt()`, if the host OS supports BCrypt
+ (primarily BSD-derived systems).
+5. A pure-python implementation of BCrypt, built into Passlib.
- 1. `bcrypt <https://pypi.python.org/pypi/bcrypt>`_, if installed.
- 2. `py-bcrypt <https://pypi.python.org/pypi/py-bcrypt>`_, if installed.
- 3. `bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_, if installed.
- 4. stdlib's :func:`crypt.crypt()`, if the host OS supports BCrypt
- (primarily BSD-derived systems).
- 5. A pure-python implementation of BCrypt, built into Passlib.
+If no backends are available, :meth:`encrypt` and :meth:`verify`
+will throw :exc:`~passlib.exc.MissingBackendError` when they are invoked.
+You can check which backend is in use by calling :meth:`!bcrypt.get_backend()`.
- If no backends are available, :meth:`encrypt` and :meth:`verify`
- will throw :exc:`~passlib.exc.MissingBackendError` when they are invoked.
- You can check which backend is in use by calling :meth:`!bcrypt.get_backend()`.
+As of Passlib 1.6.3, a one-time check is peformed when the backend is first loaded,
+to detect the backend's capabilities & bugs. If this check detects a fatal bug,
+a :exc:`~passlib.exc.PasslibSecurityError` will be raised. This generally means
+you need to upgrade the external package being used as the backend
+(this will be detailed in the error message).
.. warning::
- The pure-python backend (#5) is disabled by default!
+ *The pure-python backend (#5) is disabled by default!*
That backend is currently too slow to be usable given the number of rounds required
for security. That said, if you have no other alternative and need to use it,
@@ -70,7 +76,7 @@ Interface
before importing Passlib.
What's "too slow"? Passlib's :ref:`rounds selection guidelines <rounds-selection-guidelines>`
- currently require BCrypt be able to do >= 12 cost in <= 300ms. By this standard
+ currently require BCrypt be able to do at least 12 cost in under 300ms. By this standard
the pure-python backend is 128x too slow under CPython 2.7, and 16x too slow under PyPy 1.8.
(speedups are welcome!)
@@ -171,6 +177,37 @@ This implementation of bcrypt differs from others in a few ways:
does not support this algorithmic variant either, though it should
be *very* rarely encountered in practice.
+ .. versionchanged:: 1.6.3
+
+ Passlib will now detect, and refuse to use, any backend which is vulnerable
+ to this bug.
+
+* The 'BSD wraparound' bug
+
+ .. _bsd-wraparound-bug:
+
+ OpenBSD <= 5.4, and most bcrypt libraries derived from it's source,
+ are vulnerable to a 'wraparound' bug [#wraparound]_, where passwords larger
+ than 254 characters will be incorrectly hashed using only the first few
+ characters of the string, resulting in a severely weakened hash.
+
+ OpenBSD 5.5 `fixed <http://undeadly.org/cgi?action=article&sid=20140224132743>`_ this flaw,
+ and introduced the ``$2b$`` hash identifier to indicate the hash was generated with the correct
+ algorithm.
+
+ py-bcrypt <= 0.4 is known to be vulnerable to this, as well as the os_crypt
+ backend (if running on a vulnerable operating system).
+
+ Passlib 1.6.3 adds the following:
+
+ * Support for the ``$2b$`` hash format (though for backward compat it has not been made
+ the default yet).
+
+ * Detects if the active backend is vulnerable to the bug, issues a warning,
+ and enables a workaround so that vulnerable passwords will still be hashed correctly.
+ (This does mean that existing hashes suffering this vulnerability will no longer verify
+ using their correct password).
+
.. rubric:: Footnotes
.. [#f1] the bcrypt format specification -
@@ -181,3 +218,6 @@ This implementation of bcrypt differs from others in a few ways:
.. [#eight] The flaw in pre-1.1 crypt_blowfish is described here -
`CVE-2011-2483 <http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-2483>`_
+
+.. [#wraparound] The wraparound flaw is described here -
+ `<http://www.openwall.com/lists/oss-security/2012/01/02/4>`_ \ No newline at end of file
diff --git a/docs/lib/passlib.hash.bcrypt_sha256.rst b/docs/lib/passlib.hash.bcrypt_sha256.rst
index 22420db..255455f 100644
--- a/docs/lib/passlib.hash.bcrypt_sha256.rst
+++ b/docs/lib/passlib.hash.bcrypt_sha256.rst
@@ -34,7 +34,6 @@ This class can be used directly as follows::
It is strongly recommended that you install
`bcrypt <https://pypi.python.org/pypi/bcrypt>`_
- or `py-bcrypt <https://pypi.python.org/pypi/py-bcrypt>`_
when using this hash. See :doc:`passlib.hash.bcrypt` for more details.
Interface
diff --git a/docs/lib/passlib.totp.rst b/docs/lib/passlib.totp.rst
new file mode 100644
index 0000000..2b4aae8
--- /dev/null
+++ b/docs/lib/passlib.totp.rst
@@ -0,0 +1,76 @@
+.. module:: passlib.totp
+ :synopsis: totp / two factor authentaction
+
+=======================================================
+:mod:`passlib.totp` -- TOTP / Two Factor Authentication
+=======================================================
+
+.. versionadded:: 1.7
+
+.. todo::
+
+ This module is still a work in progress, it's API may change before release.
+
+ Things left:
+
+ * finish unittests (there are a few cases left)
+ * write narrative documentation
+ * get api documentation formatted better (whether by getting nested sections integrated into TOC,
+ or splitting nested sections out into separate sections / pages).
+ * probably want a "beta" release of passlib so people can test this a bit before 1.7.0.
+
+ Optional:
+
+ * more verification against other TOTP servers & clients.
+ * consider native pyqrcode integration (e.g. a ``to_qrcode()`` method)
+
+.. rst-class:: emphasize-children
+
+API Reference
+=============
+
+Common Interface
+----------------
+.. autoclass:: BaseOTP()
+
+TOTP (Timed-based tokens)
+-------------------------
+.. autoclass:: TOTP(key=None, format="base32", \*, new=False, \*\*kwds)
+
+Helper Classes
+..............
+
+.. autoclass:: TotpToken()
+
+.. autoclass:: TotpMatch()
+
+HOTP (Counter-based tokens)
+---------------------------
+.. note::
+
+ HOTP is used much less frequently, since it's fragile
+ (as it's much easier for the server & client to get out of sync in their token
+ count). Unless you have a particular reason, you probably want :class:`TOTP` instead.
+
+.. autoclass:: HOTP(key=None, format="base32", \*, new=False, \*\*kwds)
+
+Helper Classes
+..............
+
+.. autoclass:: HotpMatch()
+
+Deviations
+==========
+
+* The TOTP Spec [#totpspec]_ includes an potentially offset from the base time (``T0``).
+ Passlib omits this (fixing it at ``0``), but so do pretty much all other TOTP implementations.
+
+.. rubric:: Footnotes
+
+.. [#hotpspec] HOTP Specification - :rfc:`4226`
+
+.. [#totpspec] TOTP Specification - :rfc:`6238`
+
+.. [#uriformat] Google's OTPAuth URI format -
+ `<https://code.google.com/p/google-authenticator/wiki/KeyUriFormat>`_
+
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 730b196..5afb30c 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1 +1,2 @@
-cloud_sptheme>=1.6
+sphinxcontrib-fulltoc
+hg+https://bitbucket.org/ecollins/cloud_sptheme