summaryrefslogtreecommitdiff
path: root/docs/lib
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2011-03-23 14:36:19 -0400
committerEli Collins <elic@assurancetechnologies.com>2011-03-23 14:36:19 -0400
commitba4e357ba3db8c0fc5ba20ba6a5e7ad8ffbba1ec (patch)
treef83a5d0a612aa3ee73523ba13ce3e5b518ba8f75 /docs/lib
parent6a96a86a1d16f47b20b65a751f480429dd215cbf (diff)
downloadpasslib-ba4e357ba3db8c0fc5ba20ba6a5e7ad8ffbba1ec.tar.gz
lots of work documenting CryptContext class
Diffstat (limited to 'docs/lib')
-rw-r--r--docs/lib/passlib.context-interface.rst9
-rw-r--r--docs/lib/passlib.context-options.rst144
-rw-r--r--docs/lib/passlib.context.rst246
3 files changed, 234 insertions, 165 deletions
diff --git a/docs/lib/passlib.context-interface.rst b/docs/lib/passlib.context-interface.rst
new file mode 100644
index 0000000..e7689b2
--- /dev/null
+++ b/docs/lib/passlib.context-interface.rst
@@ -0,0 +1,9 @@
+===============================================
+:mod:`passlib.context` - CryptContext interface
+===============================================
+
+.. currentmodule:: passlib.context
+
+.. autoclass:: CryptContext(schemes=None, policy=<default policy>, \*\*kwds)
+
+.. autoclass:: CryptPolicy(\*\*kwds)
diff --git a/docs/lib/passlib.context-options.rst b/docs/lib/passlib.context-options.rst
new file mode 100644
index 0000000..24ddc72
--- /dev/null
+++ b/docs/lib/passlib.context-options.rst
@@ -0,0 +1,144 @@
+=============================================
+:mod:`passlib.context` - CryptContext options
+=============================================
+
+.. currentmodule:: passlib.context
+
+Context Configuration Policy
+============================
+.. warning::
+
+ This section's writing and design are still very much in flux.
+
+Each CryptContext instance is extremely configuration through a wide range
+of options. All of these options can be specified via the CryptContext
+constructor, or by loading the configuration of a section of an ini file
+(allowing an application's password policy to be specified externally).
+
+All configuration options are stored in a CryptPolicy object,
+which can be created in the following ways:
+
+* passing in options as keywords to it's constructor
+* loading options from a section of a :mod:`ConfigParser` ini file.
+* compositing together existing CryptPolicy objects (this allows for default policies, application policies, and run-time policies)
+
+Hash Configuration Options
+==========================
+Options for configuring a specific hash take the form of the name of
+``{name}.{option}`` (eg ``sha512_crypt.default_rounds``); where ``{name}`` is usually the name of a password hash,
+and ``{option}`` is one of the options specified below.
+There are a few reserved hash names:
+Any options of the form ``all.{option}`` will be inherited by all hashes
+if they do not have a ``{hash}.{option}`` value overriding the default.
+Any options of the form ``context.{option}`` will be treated as options for the context object itself,
+and not for a specified hash. Any options of the form ``{option}`` are taken to implicitly
+belong to the context, and are treated as if they started with the prefix ``context.``.
+The remaining options -
+
+``context.schemes``
+ comma separated list of the schemes this context should recognize, specified by name.
+ when a context is identifying hashes, it will check each scheme in this list
+ in order. if this value is being specified programmatically,
+ it may also be a python list containing a mixture of names
+ and password hash handler objects.
+
+``context.deprecated``
+ comma separated list of the schemes which this context should recognize,
+ generated hashes only if explicitly requested, and for which ``context.hash_needs_update()`` should return ``False``.
+ if not specified, none are considered deprecated.
+ this must be a subset of the names listed in context.schemes
+
+``context.default``
+ the default scheme context should use for generating new hashes.
+ if not specified, the first entry in ``context.schemes`` is used.
+
+``context.min_verify_time``
+ if specified, all ``context.verify()`` calls will take at least this many seconds.
+ if set to an amount larger than the time used by the strongest hash in the system,
+ this prevents an attacker from guessing the strength of particular hashes remotely.
+ (specified in fractional seconds).
+
+``{hash}.min_rounds``, ``{hash}.max_rounds``
+
+ place limits on the number of rounds allowed for a specific hash.
+
+ * these are configurable per-context limits, hard limits set by algorithm are always applied
+ * if min > max, max will be increased to equal min.
+ * ``context.genconfig()`` or ``config.encrypt()`` - requests outside of these bounds will be clipped.
+ * ``context.hash_needs_update()`` - existing hashes w/ rounds outside of range are not compliant
+ * for hashes which do not have a rounds parameter, these values are ignored.
+
+``{hash}.default_rounds``
+
+ sets the default number of rounds to use when generating new hashes.
+
+ * if this value is out side of per-policy min/max, it will be clipped just like user provided value.
+ * ``context.genconfig()`` or ``config.encrypt()`` - if rounds are not provided explicitly, this value will be used.
+ * for hashes which do not have a rounds parameter, this value is ignored.
+ * if not specified, max_rounds is used if available, then min_rounds, then the algorithm default.
+
+``{hash}.vary_rounds``
+
+ [only applies if ``{hash}.default_rounds`` is specified and > 0]
+
+ if specified, every time a new hash is created using {hash}/default_rounds for it's rounds value,
+ the actual value used is generated at random, using default_rounds as a hint.
+
+ * integer value - a value will be chosen using the formula ``randint(default_rounds-vary_rounds, default_rounds+vary_rounds)``.
+ * integer value between 0 and 100 with ``%`` suffix - same as above, with integer value equal to ``vary_rounds*default_rounds/100``.
+ * note that if algorithms indicate they use a logarthmic rounds parameter, the percent syntax equation uses ``log(vary_rounds*(2**default_rounds)/100,2)``,
+ to permit a default value to be applicable to all schemes. XXX: this might be a bad / overly complex idea.
+
+``{hash}.{setting}``
+ any keys which match the name of a configuration parameter accepted by the hash
+ will be used directly as default values.
+
+ * for security purposes, ``salt`` is *forbidden* from being used in this way.
+ * if ``rounds`` is specified directly, it will override the entire min/max/default_rounds framework.
+
+``{hash}.{other}``
+ any keys which do not fall under the above categories will be ignored
+
+User Categories
+===============
+One frequent need is for certain categories of users (eg the root account)
+to have more strigent password requirements than default users.
+PassLib allows this by recognizing options of the format ``{category}.{name}.{option}``,
+and allowing many of it's entry methods to accept an optional ``category`` parameter.
+
+When one is specified, any ``{category}.{name}.{option}`` keywords in the configuration
+will override any ``{name}.{option}`` keywords.
+
+In order to simplify behavior and implementation, categories cannot override the ``context/schemes`` keyword,
+though they may override the other context keys.
+
+Default Policies
+================
+PassLib defines a library-default policy, updated perodically, providing (hopefully) sensible defaults for the various contexts.
+When a new CryptContext is created, a policy is generated from it's constructor arguments, which is then composited
+over the library-default policy. You may optionally override the default policy used by overriding the ``policy`` keyword
+of CryptContext. This keyword accepts a single CryptPolicy object or string (which will be treated as an ini file to load);
+it also accepts a list of CryptPolicys and/or strings, which will be composited together along with any constructor options.
+
+Sample Policy File
+==================
+A sample policy file::
+
+ [passlib]
+ #configure what schemes the context supports (note the "context." prefix is implied for these keys)
+ schemes = md5_crypt, sha512_crypt, bcrypt
+ deprecated = md5_crypt
+ default = sha512_crypt
+ min_verify_time = 0.1
+
+ #set some common options for all schemes
+ all.vary_rounds = 10%
+
+ #setup some hash-specific defaults
+ sha512_crypt.min_rounds = 40000
+ bcrypt.min_rounds = 10
+
+ #create a "root" category, which uses bcrypt by default, and has stronger hashes
+ root.context.fallback = bcrypt
+ root.sha512_crypt.min_rounds = 100000
+ root.bcrypt.min_rounds = 13
diff --git a/docs/lib/passlib.context.rst b/docs/lib/passlib.context.rst
index 138452e..b3af128 100644
--- a/docs/lib/passlib.context.rst
+++ b/docs/lib/passlib.context.rst
@@ -1,167 +1,83 @@
-=============================================
-:mod:`passlib.context` - CryptContext class
-=============================================
+==============================================
+:mod:`passlib.context` - CryptContext Overview
+==============================================
.. module:: passlib.context
-
-The :mod:`!passlib.base` module contains a number of core
-
-
-.. autoclass:: CryptContext
-
-Context Configuration Policy
-============================
-.. warning::
-
- This section's writing and design are still very much in flux.
-
-Each CryptContext instance is extremely configuration through a wide range
-of options. All of these options can be specified via the CryptContext
-constructor, or by loading the configuration of a section of an ini file
-(allowing an application's password policy to be specified externally).
-
-All configuration options are stored in a CryptPolicy object,
-which can be created in the following ways:
-
-* passing in options as keywords to it's constructor
-* loading options from a section of a :mod:`ConfigParser` ini file.
-* compositing together existing CryptPolicy objects (this allows for default policies, application policies, and run-time policies)
-
-Hash Configuration Options
-==========================
-Options for configuring a specific hash take the form of the name of
-``{name}.{option}`` (eg ``sha512_crypt.default_rounds``); where ``{name}`` is usually the name of a password hash,
-and ``{option}`` is one of the options specified below.
-There are a few reserved hash names:
-Any options of the form ``all.{option}`` will be inherited by all hashes
-if they do not have a ``{hash}.{option}`` value overriding the default.
-Any options of the form ``context.{option}`` will be treated as options for the context object itself,
-and not for a specified hash. Any options of the form ``{option}`` are taken to implicitly
-belong to the context, and are treated as if they started with the prefix ``context.``.
-The remaining options -
-
-``context.schemes``
- comma separated list of the schemes this context should recognize, specified by name.
- when a context is identifying hashes, it will check each scheme in this list
- in order. if this value is being specified programmatically,
- it may also be a python list containing a mixture of names
- and password hash handler objects.
-
-``context.deprecated``
- comma separated list of the schemes which this context should recognize,
- generated hashes only if explicitly requested, and for which ``context.hash_needs_update()`` should return ``False``.
- if not specified, none are considered deprecated.
- this must be a subset of the names listed in context.schemes
-
-``context.default``
- the default scheme context should use for generating new hashes.
- if not specified, the first entry in ``context.schemes`` is used.
-
-``context.min_verify_time``
- if specified, all ``context.verify()`` calls will take at least this many seconds.
- if set to an amount larger than the time used by the strongest hash in the system,
- this prevents an attacker from guessing the strength of particular hashes remotely.
- (specified in fractional seconds).
-
-``{hash}.min_rounds``, ``{hash}.max_rounds``
-
- place limits on the number of rounds allowed for a specific hash.
-
- * these are configurable per-context limits, hard limits set by algorithm are always applied
- * if min > max, max will be increased to equal min.
- * ``context.genconfig()`` or ``config.encrypt()`` - requests outside of these bounds will be clipped.
- * ``context.hash_needs_update()`` - existing hashes w/ rounds outside of range are not compliant
- * for hashes which do not have a rounds parameter, these values are ignored.
-
-``{hash}.default_rounds``
-
- sets the default number of rounds to use when generating new hashes.
-
- * if this value is out side of per-policy min/max, it will be clipped just like user provided value.
- * ``context.genconfig()`` or ``config.encrypt()`` - if rounds are not provided explicitly, this value will be used.
- * for hashes which do not have a rounds parameter, this value is ignored.
- * if not specified, max_rounds is used if available, then min_rounds, then the algorithm default.
-
-``{hash}.vary_rounds``
-
- [only applies if ``{hash}.default_rounds`` is specified and > 0]
-
- if specified, every time a new hash is created using {hash}/default_rounds for it's rounds value,
- the actual value used is generated at random, using default_rounds as a hint.
-
- * integer value - a value will be chosen using the formula ``randint(default_rounds-vary_rounds, default_rounds+vary_rounds)``.
- * integer value between 0 and 100 with ``%`` suffix - same as above, with integer value equal to ``vary_rounds*default_rounds/100``.
- * note that if algorithms indicate they use a logarthmic rounds parameter, the percent syntax equation uses ``log(vary_rounds*(2**default_rounds)/100,2)``,
- to permit a default value to be applicable to all schemes. XXX: this might be a bad / overly complex idea.
-
-``{hash}.{setting}``
- any keys which match the name of a configuration parameter accepted by the hash
- will be used directly as default values.
-
- * for security purposes, ``salt`` is *forbidden* from being used in this way.
- * if ``rounds`` is specified directly, it will override the entire min/max/default_rounds framework.
-
-``{hash}.{other}``
- any keys which do not fall under the above categories will be ignored
-
-User Categories
-===============
-One frequent need is for certain categories of users (eg the root account)
-to have more strigent password requirements than default users.
-PassLib allows this by recognizing options of the format ``{category}.{name}.{option}``,
-and allowing many of it's entry methods to accept an optional ``category`` parameter.
-
-When one is specified, any ``{category}.{name}.{option}`` keywords in the configuration
-will override any ``{name}.{option}`` keywords.
-
-In order to simplify behavior and implementation, categories cannot override the ``context/schemes`` keyword,
-though they may override the other context keys.
-
-Default Policies
-================
-PassLib defines a library-default policy, updated perodically, providing (hopefully) sensible defaults for the various contexts.
-When a new CryptContext is created, a policy is generated from it's constructor arguments, which is then composited
-over the library-default policy. You may optionally override the default policy used by overriding the ``policy`` keyword
-of CryptContext. This keyword accepts a single CryptPolicy object or string (which will be treated as an ini file to load);
-it also accepts a list of CryptPolicys and/or strings, which will be composited together along with any constructor options.
-
-Sample Policy File
-==================
-A sample policy file::
-
- [passlib]
- #configure what schemes the context supports (note the "context." prefix is implied for these keys)
- schemes = md5_crypt, sha512_crypt, bcrypt
- deprecated = md5_crypt
- default = sha512_crypt
- min_verify_time = 0.1
-
- #set some common options for all schemes
- all.vary_rounds = 10%
-
- #setup some hash-specific defaults
- sha512_crypt.min_rounds = 40000
- bcrypt.min_rounds = 10
-
- #create a "root" category, which uses bcrypt by default, and has stronger hashes
- root.context.fallback = bcrypt
- root.sha512_crypt.min_rounds = 100000
- root.bcrypt.min_rounds = 13
-
-.. class:: CryptPolicy
-
- Stores configuration options for a CryptContext object.
-
- Policy objects can be constructed by the following methods:
-
- .. automethod:: from_path
- .. automethod:: from_string
- .. automethod:: from_source
- .. automethod:: from_sources
-
- .. method:: (constructor)
-
- You can specify options directly to the constructor.
- This accepts dot-seperated keywords such as found in the config file format,
- but for programmatic convience, it also accepts keys with ``.`` replaced with ``__``,
- allowing options to be specified programmatically in python.
+ :synopsis: CryptContext class for managing multiple password hash schemes
+
+Overview
+========
+Different storage contexts (eg: linux shadow files vs openbsd shadow files)
+may use different sets and subsets of the available algorithms.
+Similarly, over time, applications may need to deprecate password schemes
+in favor of newer ones, or raise the number of rounds required
+by existing hashes.
+
+This module provides the :class:`!CryptContext` class, which is designed
+to handle (as much as possible) of these tasks for an application.
+Essentially, a :class:`!CryptContext` instance contains a list
+of hash handlers that it should recognize, along with information
+about which ones are deprecated, which is the default,
+and what configuration constraints an application has placed
+on a particular hash.
+
+Since this class contains so many methods and options,
+the documentation for this module is broken up into three
+sections:
+
+* Usage examples (below)
+* Next, documentation of the complete :doc:`CryptContext interface <passlib.context-interface>`.
+* Finally, a comprehensive list of :doc:`CryptContext options <passlib.context-options>`.
+
+Usage
+=====
+To start off with a simple example::
+
+ >>> from passlib.context import CryptContext
+
+ >>> #create a new context that only understands Md5Crypt & DesCrypt:
+ >>> myctx = CryptContext([ "md5_crypt", "des_crypt" ])
+
+ >>> #unless overidden, the first hash listed
+ >>> #will be used as the default for encrypting
+ >>> #(in this case, md5_crypt):
+ >>> hash1 = myctx.encrypt("too many secrets")
+ >>> hash1
+ '$1$nH3CrcVr$pyYzik1UYyiZ4Bvl1uCtb.'
+
+ >>> #the scheme may be forced explicitly,
+ >>> #though it must be one of the ones recognized by the context:
+ >>> hash2 = myctx.encrypt("too many secrets", scheme="des-crypt")
+ >>> hash2
+ 'm9pvLj4.hWxJU'
+
+ >>> #verification will autodetect the correct type of hash:
+ >>> myctx.verify("too many secrets", hash1)
+ True
+ >>> myctx.verify("too many secrets", hash2)
+ True
+ >>> myctx.verify("too many socks", hash2)
+ False
+
+ >>> #you can also have it identify the algorithm in use:
+ >>> myctx.identify(hash1)
+ 'md5_crypt'
+
+ >>> #or just return the handler instance directly:
+ >>> myctx.identify(hash1, resolve=True)
+ <class 'passlib.handlers.md5_crypt.md5_crypt'>
+
+All of the configuration options for a :class:`!CryptContext` instance
+are stored in a :class:`CryptPolicy` instance accessible through
+their ``policy`` attribute::
+
+ >>> from passlib.context import CryptContext
+ >>> myctx = CryptContext([ "md5_crypt", "des_crypt" ], deprecated="des_crypt")
+
+ >>> #get a list of schemes recognized in this context:
+ >>> myctx.policy.schemes()
+ [ 'md5-crypt', 'bcrypt' ]
+
+ >>> #get the default handler class :
+ >>> myctx.policy.get_handler()
+ <class 'passlib.handlers.md5_crypt.md5_crypt'>