This instance was upgraded to Heptapod 0.20.1 today

Commit 577adcd4 authored by Eli Collins's avatar Eli Collins

documentation work

==================
* finished password hash api description
* various documentation cleanups
* removed unused quickstart doc
parent a2ad5202a4fc
======================
The BPS Python Library
======================
==========================
The PassLib Python Library
==========================
* For installation instructions, see "docs/install.rst"
* For license & copyright information, see "docs/copyright.rst"
Installation
------------
* For detailed installation instructions, see "docs/install.rst"
Copyright & License
-------------------
* (c) 2008-2011 - Assurance Technologies LLC
* released under BSD license
* For more license & copyright information, see "docs/copyright.rst"
# -*- coding: utf-8 -*-
#
# BPS documentation build configuration file, created by
# PassLib documentation build configuration file, created by
# sphinx-quickstart on Mon Mar 2 14:12:06 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
......
......@@ -6,17 +6,15 @@ Table Of Contents
Front Page <index>
install
quickstart
overview
lib/passlib.base
password_hash_api
lib/passlib.hash
lib/passlib.base
lib/passlib.sqldb
lib/passlib.unix
lib/passlib.utils
password_hash_api
history
copyright
......
......@@ -9,7 +9,7 @@ Release History
2011-01-05 -- version 0.8
* various code cleanups preparing for public release
* ext-des-crypt, apr-md5-crypt, and other lesser known schemes added.
* bsdi-crypt, apr-md5-crypt, and other lesser known schemes added.
* documentation added
2009-03-10 -- version 0.7
......
......@@ -4,24 +4,20 @@ PassLib |release| documentation
Introduction
============
Passlib is a collection of routines for managing password hashes
in wide variety of different uses:
PassLib is a library for managing password hashes,
with support for over 18 current and historical :doc:`password hash schemes <lib/passlib.hash>`.
It can be used for a variety of purposes:
* cross-platform replacement for stdlib ``crypt()``.
* cross-platform replacement for stdlib's ``crypt()``.
* encrypting & verifying most known hash formats used by:
- Linux & BSD shadow files
- Apache htpasswd files
- MySQL & PostgreSQL user account tables
* drop-in secure hashing for new python applications
* quickly building a configurable hashing policy
for existing python applications and existing hashing schemes.
* drop-in password hashing for new python applications.
* building a configurable hashing policy
for python applications to migrate existing hashing schemes.
A quick sample of some of the more frequently used modules:
* :mod:`passlib` -- password hashing algorithms
* :mod:`passlib.hash` -- module containing all supported password hashes
... see the :doc:`library overview <overview>` for a complete list.
See the :doc:`Library Overview <overview>` for more details.
Quick Links
===========
......@@ -35,14 +31,14 @@ Quick Links
<span class="linkdescr">lists all sections and subsections</span></p>
<p class="biglink"><a class="biglink" href="overview.html">Library Overview</a><br>
<span class="linkdescr">describes how BPS is laid out</span></p>
<span class="linkdescr">describes how PassLib is laid out</span></p>
</td><td width="50%">
<p class="biglink"><a class="biglink" href="genindex.html">General Index</a><br>
<span class="linkdescr">all functions, classes, terms</span></p>
<p class="biglink"><a class="biglink" href="modindex.html">Module List</a><br>
<p class="biglink"><a class="biglink" href="py-modindex.html">Module List</a><br>
<span class="linkdescr">quick access to all modules</span></p>
<p class="biglink"><a class="biglink" href="search.html">Search Page</a><br>
......
......@@ -17,19 +17,21 @@ The following libraries are not required, but will be used if found:
* If installed, `py-bcrypt <http://www.mindrot.org/projects/py-bcrypt/>`_ will be
used instead of PassLib's slower pure-python bcrypt implementation.
(see :class:`passlib.hash.bcrypt`).
*This is strongly recommended, as the builtin implementation is VERY slow*.
* stdlib ``crypt.crypt()`` will be used if present, and if the underlying
* stdlib's :mod:`!crypt` module will be used if present, and if the host
OS supports the specific scheme in question. OS support is autodetected
from the following schemes: des-crypt, md5-crypt, bcrypt, sha256-crypt,
for the following schemes: des-crypt, md5-crypt, bcrypt, sha256-crypt,
and sha512-crypt.
* If installed, `M2Crypto <http://chandlerproject.org/bin/view/Projects/MeTooCrypto>`_ will be
used to accelerate some internal support functions, but it is not required.
Installing
==========
PassLib can be installed with easy_install, linked/copied into sys.path directly
from it's source directory, or installed using ``$SOURCE/setup.py install``,
where ``$SOURCE`` is the path to the PassLib source directory.
from it's source directory, or installed using :samp:`{$SOURCE}/setup.py install`,
where :samp:`{$SOURCE}` is the path to the PassLib source directory.
PassLib is pure python, there is nothing to compile or configure.
Testing
......@@ -52,9 +54,13 @@ The latest copy of this documentation should always be available
at the `PassLib homepage <http://www.assurancetechnologies.com/software/passlib>`_.
If you wish to generate your own copy of the documentation,
you will need to install `Sphinx <http://sphinx.pocoo.org/>`_ (1.0 or better)
as well `astdoc <http://www.assurancetechnologies.com/software/astdoc>`_ (a bundle of custom sphinx themes & extensions
used by Assurance Technologies). Next, download the PassLib source,
and run ``python $SOURCE/docs/make.py clean html`` (where ``$SOURCE`` is the path to the PassLib source directory).
Once Sphinx completes it's run, point a web browser to the file at ``$SOURCE/docs/_build/html/index.html``
you will need to:
* install `Sphinx <http://sphinx.pocoo.org/>`_ (1.0 or better)
* install `astdoc <http://www.assurancetechnologies.com/software/astdoc>`_ (a bundle of custom sphinx themes & extensions
used by Assurance Technologies).
* download the PassLib source
* run :samp:`python {$SOURCE}/docs/make.py clean html` (where :samp:`{$SOURCE}` is the path to the PassLib source directory).
Once Sphinx completes it's run, point a web browser to the file at :samp:`{$SOURCE}/docs/_build/html/index.html`
to access the PassLib documentation in html format.
......@@ -2,7 +2,7 @@
:mod:`passlib.base` - Crypt Contexts
=============================================
.. currentmodule:: passlib.base
.. module:: passlib.base
For more complex deployment scenarios than
the frontend functions described in :doc:`Quick Start </quickstart>`,
......
......@@ -47,7 +47,7 @@ This implementation of bcrypt differs from others in a few ways:
BCrypt does not specify what the behavior should be when
passed a salt string outside of the regexp range ``[./A-Za-z0-9]``.
In order to avoid this situtation, Passlib strictly limits salts to the
In order to avoid this situtation, PassLib strictly limits salts to the
allowed character set, and will throw a ValueError if an invalid
salt character is encountered.
......
......@@ -117,8 +117,8 @@ This implementation of bigcrypt differs from others in two ways:
various limits on maximum password length (commonly, 128 chars),
and discard the remaining part of the password.
Thus, while Passlib should be able to verify all existing
bigcrypt hashes, other systems may require hashes generated by Passlib
Thus, while PassLib should be able to verify all existing
bigcrypt hashes, other systems may require hashes generated by PassLib
to be truncated to their specific maximum length.
* Unicode Policy:
......
......@@ -132,7 +132,7 @@ This implementation of bsdi-crypt differs from others in one way:
PassLib will encode unicode passwords using ``utf-8``
before running them through bsdi-crypt. If a different
encoding is desired by an application, the password should be encoded
before handing it to Passlib.
before handing it to PassLib.
References
==========
......
......@@ -108,7 +108,7 @@ This implementation of des-crypt differs from others in a few ways:
Some implementations of des-crypt allow empty and single-character salt strings.
However, the behavior in these cases varies wildly between implementations,
including errors and broken hashes.
To avoid all this, Passlib will throw an "invalid salt" if the provided
To avoid all this, PassLib will throw an "invalid salt" if the provided
salt string is not at least 2 characters.
* Restricted salt string character set:
......@@ -118,7 +118,7 @@ This implementation of des-crypt differs from others in a few ways:
a 12-bit integer. Many implementations of des-crypt will
accept a salt containing other characters, but
vary wildly in how they are handled, including errors and implementation-specific value mappings.
To avoid all this, Passlib will throw an "invalid salt" if the salt
To avoid all this, PassLib will throw an "invalid salt" if the salt
string contains any non-standard characters.
* Unicode Policy:
......@@ -134,4 +134,4 @@ This implementation of des-crypt differs from others in a few ways:
References
==========
.. [#] A java implementation of des-crypt, used as base for Passlib's pure-python implementation, is located at `<http://www.dynamic.net.au/christos/crypt/UnixCrypt2.txt>`_
.. [#] A java implementation of des-crypt, used as base for PassLib's pure-python implementation, is located at `<http://www.dynamic.net.au/christos/crypt/UnixCrypt2.txt>`_
......@@ -9,7 +9,7 @@ hexidecimal-encoded message digests, such as MD5 or SHA1.
Such schemes are *extremely* vulnerable to pre-computed brute-force attacks,
and should not be used in new applications. However, for the sake
of backwards compatibility when converting existing applications,
Passlib provides wrappers for few of the common hashes.
PassLib provides wrappers for few of the common hashes.
Usage
=====
......
......@@ -140,13 +140,13 @@ though it is not yet considered broken:
Deviations
==========
Passlib's implementation of md5-crypt differs from the reference implementation (and others) in two ways:
PassLib's implementation of md5-crypt differs from the reference implementation (and others) in two ways:
* Restricted salt string character set:
The underlying algorithm can unambigously handle salt strings
which contain any possible byte value besides ``\x00`` and ``$``.
However, Passlib strictly limits salts to the
However, PassLib strictly limits salts to the
:mod:`hash 64 <passlib.utils.h64>` character set,
as nearly all implementations of md5-crypt generate
and expect salts containing those characters,
......
......@@ -18,7 +18,7 @@ also be imported and used directly from this package, as in the following exampl
>>> from passlib.hash import md5_crypt
>>> hash = md5_crypt.encrypt("password")
Passlib contains the following builtin password algorithms:
PassLib contains the following builtin password algorithms:
Archaic Unix Schemes
--------------------
......@@ -47,20 +47,10 @@ They all follow the :ref:`modular crypt format <modular-crypt-format>` for encod
passlib.hash.md5_crypt
passlib.hash.bcrypt
passlib.hash.sha1_crypt
passlib.hash.sun_md5_crypt
passlib.hash.sha256_crypt
passlib.hash.sha512_crypt
.. toctree::
:hidden:
passlib.hash.sun_md5_crypt
.. todo::
These aren't fully implemented / tested yet:
* :doc:`passlib.hash.sun_md5_crypt <passlib.hash.sun_md5_crypt>` - MD5-based scheme used by Solaris 10 (NOT related to md5-crypt above).
Non-Standard Unix-Compatible Schemes
------------------------------------
While most of these schemes are not commonly used by any unix flavor to store user passwords,
......
......@@ -79,7 +79,7 @@ in a few ways:
The underlying algorithm can unambigously handle salt strings
which contain any possible byte value besides ``\x00`` and ``$``.
However, Passlib strictly limits salts to the
However, PassLib strictly limits salts to the
:mod:`hash 64 <passlib.utils.h64>` character set,
as nearly all implementations of sha1-crypt generate
and expect salts containing those characters.
......
......@@ -88,7 +88,7 @@ and other implementations, in a few ways:
The underlying algorithm can unambigously handle salt strings
which contain any possible byte value besides ``\x00`` and ``$``.
However, Passlib strictly limits salts to the
However, PassLib strictly limits salts to the
:mod:`hash 64 <passlib.utils.h64>` character set,
as nearly all implementations of sha512-crypt generate
and expect salts containing those characters,
......
......@@ -13,7 +13,7 @@ in common with the :class:`~passlib.hash.md5_crypt` algorithm. It supports
.. warning::
This implementation has not been compared
very carefully against any existing implementations,
very carefully against the official implementation or reference documentation,
and it's behavior may not match under various border cases.
It should not be relied on for anything but novelty purposes
for the time being.
......@@ -118,7 +118,7 @@ using the following formula:
Deviations
==========
Passlib's implementation of Sun-MD5-Crypt deviates from the official implementation
PassLib's implementation of Sun-MD5-Crypt deviates from the official implementation
in at least one way:
* Unicode Policy:
......@@ -134,7 +134,7 @@ in at least one way:
encoding is desired by an application, the password should be encoded
before handing it to PassLib.
Since Passlib's pure python implmentation was written based on the algorithm
Since PassLib's pure python implmentation was written based on the algorithm
description above, and has not been properly tested against a reference implementation,
it may have other bugs and deviations from the correct behavior.
......
......@@ -7,15 +7,14 @@
.. warning::
NIST has declared DES to be "inadequate" for encryption purpose.
These routines, and algorithms based on them,
NIST has declared DES to be "inadequate" for cryptographic purposes.
These routines, and the password hashes based on them,
should not be used in new applications.
This module contains routines for encrypting blocks of data using the DES algorithm.
They do not support multi-block operation or decryption,
since they are designed for use in password hash algorithms
such as :class:`~passlib.hash.des_crypt` and :class:`~passlib.hash.ext_des_crypt`.
since they are designed primarily for use in password hash algorithms
(such as :class:`~passlib.hash.des_crypt` and :class:`~passlib.hash.bsdi_crypt`).
.. autofunction:: expand_des_key
.. autofunction:: des_encrypt_block
......
......@@ -2,7 +2,7 @@
Library Overview
================
Passlib is a collection of routines for managing password hashes
PassLib is a collection of routines for managing password hashes
as found in unix /etc/shadow files, as returned by stdlib `crypt()`,
as stored in mysql and postgres, and various other contexts.
......
.. _password-hash-api:
======================
=================
Password Hash API
======================
Motivation
==========
Passlib supports many different password hashing schemes.
A majority of them were originally designed to be used on a unix
system, follow some variant of the unix ``crypt()`` api,
and have are encoded using the :ref:`modular-crypt-format`.
Others were designed for use specific contexts only,
such as PostgreSQL.
Passlib was designed to provide a uniform interface to implementations
of all these schemes, as well as hide away as much of the implementation
detail as possible; both in order to make it easier to integrate password hashing
into new and existing applications. Because of these goals, some of the methods
required by the crypt handler api tend to overlap slightly,
in order to accomodate a wide variety of application requirements,
and other parts have been kept intentionally non-commital, in order to allow
flexibility of implementation.
All of the schemes built into passlib implement this interface;
most them as modules within the :mod:`passlib.hash` package.
=================
Overview
========
A handler which implements a password hash may be a module, class, or instance
(though most of the ones builtin to Passlib are classes).
The only requirement is that it expose a minimum of the following attributes
and functions (for classes, the following functions must be static or class methods).
All handlers have the following three attributes:
* ``name`` - unique identifier used to distinguish scheme within
* ``setting_kwds`` - list of settings recognized by ``genconfig()`` and ``encrypt()``.
* ``context_kwds`` - list of context specified keywords required by algorithm
All handlers have the following five functions:
* ``encrypt(secret, **context_and_settings) -> hash`` - used for encrypting secret using specified options
* ``identify(hash) -> True|False`` - used for identifying hash belonging to this algorithm
* ``verify(secret, hash, **context)`` - used for verifying a secret against an existing hash
* ``genconfig(**settings) -> configuration string`` - used for generating configuration strings.
* ``genhash(secret, config, **context) -> hash`` - used for encrypting secret using configuration string or existing hash
Usage Examples
==============
.. todo::
show some quick examples using bcrypt.
Informational Attributes
========================
.. attribute:: name
All of the hashes supported by PassLib are implemented using classes
which support an identical interface; this document describes that
interface in terms of a non-existent abstract class called :class:`!PasswordHash`.
All of the :doc:`supported password hashes <lib/passlib.hash>`
expose (at a minimum) the following methods and attributes:
The `required informational attributes`_
These consist of the attributes :attr:`~PasswordHash.name`,
:attr:`~PasswordHash.setting_kwds`, and :attr:`~PasswordHash.context_kwds`.
They permit users and applications to detect what features a specific :class:`!PasswordHash`
allows and/or requires.
The `application interface`_
This consists of the :meth:`~PasswordHash.encrypt`,
:meth:`~PasswordHash.identify`, and :meth:`~PasswordHash.verify` classmethods.
Most applications will only need to make use of these methods.
The `crypt interface`_
This consists of the :meth:`~PasswordHash.genconfig`,
:meth:`~PasswordHash.genhash`. This mimics the standard unix crypt interface,
but is usually used directly by applications.
The `optional informational attributes`_
These attributes provide additional information
about the capabilities and limitations of certain password hash schemes.
Usage
=====
While most uses of PassLib are done through a :class:`~passlib.base.CryptContext` class,
the various :class:`!PasswordHash` classes can be used directly to manipulate
passwords:
>>> # for example, the SHA256-Crypt class:
>>> from passlib.hash import sha256_crypt as sc
>>> # using it to encrypt a password:
>>> h = sc.encrypt("password")
>>> h
'$5$rounds=40000$HIo6SCnVL9zqF8TK$y2sUnu13gp4cv0YgLQMW56PfQjWaTyiHjVbXTgleYG9'
>>> # subsequent calls to sc.encrypt() will generate a new salt:
>>> sc.encrypt("password")
'$5$rounds=40000$1JfxoiYM5Pxokyh8$ez8uV8jjXW7SjpaTg2vHJmx3Qn36uyZpjhyC9AfBi7B'
>>> # the same, but with an explict number of rounds:
>>> sc.encrypt("password", rounds=10000)
'$5$rounds=10000$UkvoKJb8BPrLnR.D$OrUnOdr.IJx74hmyyzuRdr5k9lSXdkFxKmr7bLQTty5'
>>> #the identify method can be used to determine the format of an unknown hash:
>>> sc.identify(h)
True
>>> #check if some other hash is recognized (in this case, an MD5-Crypt hash)
>>> sc.identify('$1$3azHgidD$SrJPt7B.9rekpmwJwtON31')
False
>>> #the verify method encapsulates all hash comparison logic for a class:
>>> sc.verify("password", h)
True
>>> sc.verify("wrongpassword", h)
False
.. _required-informational-attributes:
Required Informational Attributes
=================================
.. attribute:: PasswordHash.name
A unique name used to identify
the particular algorithm this handler implements.
the particular scheme this class implements.
These names should consist only of lowercase a-z, the digits 0-9, and hyphens.
These names should consist only of lowercase a-z, the digits 0-9, and underscores.
.. note::
All handlers built into passlib are implemented as modules
whose path corresponds to the name, with an underscore replacing the hyphen.
For example, ``des-crypt`` is stored as the module ``passlib.hash.des_crypt``.
All handlers built into passlib are implemented as classes
located under :samp:`passlib.hash.{name}`, where :samp:`{name}`
is both the class name, and the value of the ``name`` attribute.
This is not a requirement, and may not be true for externally-defined handers.
.. attribute:: setting_kwds
.. attribute:: PasswordHash.setting_kwds
If the algorithm supports per-hash configuration
If the scheme supports per-hash configuration
(such as salts, variable rounds, etc), this attribute
should contain a tuple of keywords corresponding
to each of those configuration options.
This should correspond with the keywords accepted
by :func:`genconfig`, see that method for details.
This should list all the main configuration keywords accepted
by :meth:`~PasswordHash.genconfig` and :meth:`~PasswordHash.encrypt`.
If no settings are supported, this attribute
is an empty tuple.
If no configuration options are supported, this attribute should be an empty tuple.
.. attribute:: context_kwds
While each class may support a variety of options, each with their own meaning
and semantics, the following keywords should have the same behavior
across all schemes:
Some algorithms require external contextual information
in order to generate a checksum for a password.
An example of this is Postgres' md5 algorithm,
which requires the username to be provided
(which it uses as a salt).
``salt``
If present, this means the algorithm contains some number of bits of salt
which should vary with every new hash created.
Providing this as a keyword should allow the application to select
a specific salt string; though not only is this far from needed
for most cases, the salt string's content constraints vary for each algorithm.
``rounds``
If present, this means the algorithm allows for a variable number of rounds
to be used, allowing the processor time required to be increased.
Providing this as a keyword should allow the application to
override the class' default number of rounds. While this
must be a non-negative integer for all implementations,
additional constraints may be present for each algorith
(such as the cost varying on a linear or logarithmic scale).
``ident``
If present, the class supports multiple formats for encoding
the same hash. The class's documentation will generally list
the allowed values, allowing alternate output formats to be selected.
.. attribute:: PasswordHash.context_kwds
This attribute should contain a tuple of keywords
which should be passed into :func:`encrypt`, :func:`verify`,
and :func:`genhash` in order to encrypt a password.
Some algorithms require external contextual information
in order to generate a checksum for a password.
An example of this is :doc:`Postgres' MD5 algorithm <lib/passlib.hash.postgres_md5>`,
which requires the username to be provided when generating a hash
(see that class for an example of how this works in pratice).
Since most password hashes require no external information,
this tuple will usually be empty.
this tuple will usually be empty, and references
to context keywords can be ignored for all but a few classes.
Primary Interface
=================
The ``encrypt()``, ``identify()``, and ``verify()`` methods are designed
to provide an easy interface for applications to encrypt new passwords
and verify existing passwords, without having to deal with details such
as salt formats.
.. _application-interface:
.. function:: encrypt(secret, \*\*settings_and_context)
Application Interface
=====================
The :meth:`~PasswordHash.encrypt`, :meth:`~PasswordHash.identify`, and :meth:`~PasswordHash.verify` methods are designed
to provide an easy interface for applications. They allow encrypt new passwords
without having to deal with details such as salt generation, verifying
passwords without having to deal with hash comparison rules, and determining
which scheme a hash belongs to when multiple schemes are in use.
.. classmethod:: PasswordHash.encrypt(secret, \*\*settings_and_context)
encrypt secret, returning resulting hash string.
......@@ -115,12 +162,12 @@ as salt formats.
but the common case is to encode into utf-8
before processing.
:param kwds:
:param settings_and_context:
All other keywords are algorithm-specified,
and should be listed in :attr:`setting_kwds`
and :attr:`context_kwds`.
and should be listed in :attr:`~PasswordHash.setting_kwds`
and :attr:`~PasswordHash.context_kwds`.
Common keywords include ``salt`` and ``rounds``.
Common settings keywords include ``salt`` and ``rounds``.
:raises ValueError:
* if settings are invalid and not correctable.
......@@ -134,9 +181,9 @@ as salt formats.
on the types of characters.
:returns:
Hash encoded in algorithm-specified format.
Hash string, encoded in algorithm-specific format.
.. function:: identify(hash)
.. classmethod:: PasswordHash.identify(hash)
identify if a hash string belongs to this algorithm.
......@@ -150,11 +197,12 @@ as salt formats.
* ``False`` if none of the above conditions was met.
.. note::
Some handlers may or may not return ``True`` for malformed hashes.
Those that do will raise a ValueError once the hash is passed to :func:`verify`.
Those that do will raise a ValueError once the hash is passed to :meth:`~PasswordHash.verify`.
Most handlers, however, will just return ``False``.
.. function:: verify(secret, hash, \*\*context)
.. classmethod:: PasswordHash.verify(secret, hash, \*\*context)
verify a secret against an existing hash.
......@@ -169,7 +217,7 @@ as salt formats.
:param context:
Any additional keywords will be passed to the encrypt
method. These should be limited to those listed
in :attr:`context_kwds`.
in :attr:`~PasswordHash.context_kwds`.
:raises TypeError:
* if the secret is not a string.
......@@ -177,21 +225,24 @@ as salt formats.
:raises ValueError:
</