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
|
============================================
:mod:`passlib.hosts` - OS Password Handling
============================================
.. module:: passlib.hosts
:synopsis: encrypting & verifying operating system passwords
This module provides :class:`!CryptContext` instances for encrypting & verifying password hashes
tied to user accounts of various operating systems. It currently
primarily centered around Linux & BSD unix variants.
(For details about how to *use* a :class:`!CryptContext` instance,
see the documentation for the :class:`CryptContext` class itself).
Unix-Specific Contexts
======================
Interface
---------
PassLib provides :class:`!CryptContext` instances
for the following Unix variants:
.. object:: linux_context
context instance which recognizes hashes used
by the majority of Linux distributions.
encryption defaults to :class:`!sha512_crypt`.
.. object:: freebsd_context
context instance which recognizes all hashes used by FreeBSD 8.
encryption defaults to :class:`!bcrypt`.
.. object:: netbsd_context
context instance which recognizes all hashes used by NetBSD.
encryption defaults to :class:`!bcrypt`.
.. object:: openbsd_context
context instance which recognizes all hashes used by OpenBSD.
encryption defaults to :class:`!bcrypt`.
.. note::
Unforunately, there is currently no reliable way to detect
the exact policy used on the above systems,
so each of the above contexts defaults to using the strongest supported scheme.
Supported Schemes
-----------------
The linux and bsd contexts above support the following schemes:
==================================== =========== =========== =========== ===========
Scheme Linux FreeBSD NetBSD OpenBSD
==================================== =========== =========== =========== ===========
:class:`~passlib.hash.nthash` y
:class:`~passlib.hash.des_crypt` y y y y
:class:`~passlib.hash.bsdi_crypt` y y
:class:`~passlib.hash.md5_crypt` y y y y
:class:`~passlib.hash.bcrypt` y y y
:class:`~passlib.hash.sha1_crypt` y
:class:`~passlib.hash.sha256_crypt` y
:class:`~passlib.hash.sha512_crypt` y
==================================== =========== =========== =========== ===========
.. note::
All of the above contexts will also recognize password hashes
of the form ``!`` or ``*`` as belonging to a special
:class:`unix_fallback` handler, whose ``verify()`` method
will return ``False`` for these strings, treating them as disabled.
This same handler will also recognize an empty string as being a wildcard password.
Usage
-----
A quick usage example, using the :data:`!linux_context` instance::
>>> from passlib.hosts import linux_context
>>> hash = linux_context.encrypt("password")
>>> hash
'$6$rounds=31779$X2o.7iqamZ.bAigR$ojbo/zh6sCmUuibhM7lnqR4Vy0aB3xGZXOYVLgtTFgNYiXaTNn/QLUz12lDSTdxJCLXHzsHiWCsaryAlcbAal0'
>>> linux_context.verify("password", hash)
True
>>> linux_context.identify(hash)
'sha512_crypt'
>>> linux_context.encrypt("password", scheme="des_crypt")
'2fmLLcoHXuQdI'
>>> linux_context.identify('2fmLLcoHXuQdI')
'des_crypt'
Current-Host Contexts
=====================
.. object:: host_context
PassLib provides this object, which will dynamically be an alias
for one of the above context instances (based on ``sys.platform``).
This can be used in conjunction with stdlib's :mod:`!spwd` module
to verify user passwords on the local system::
>>> #NOTE/WARNING: this example requires running as root on most systems.
>>> import spwd, os
>>> from passlib.hosts import host_context
>>> hash = spwd.getspnam(os.environ['USER']).sp_pwd
>>> host_context.verify("toomanysecrets", hash)
True
On non-unix systems, and unix systems whose platform isn't recognized
properly by passlib, this will fall back to a context which
recognizes no hash schemes besides :class:`unix_fallback`.
.. _modular-crypt-format:
Modular Crypt Format
====================
A side note regarding password hashes beginning with :samp:`${identifier}$`:
A vast majority of the schemes used on unix systems (and supported by this library)
follow the "Modular Crypt Format", introduced around the time :class:`~passlib.hash.md5_crypt` was developed.
This scheme allows hashes generates by multiple schemes to co-exist within a database,
by requiring that all hash string begin with a unique prefix :samp:`${identifier}$`;
where :samp:`{identifier}` is a short alphanumeric string globally identifying
hashes generated by that algorithm.
While not part of the specification, most modular crypt -compatible hashes
were designed to be used by unix systems to store user account passwords
in ``/etc/passwd`` or ``/etc/shadow``. Because of this, most of them
follow another defacto limitations: they avoid using the characters
``:``, ``\n``, and ``\x00`` anywhere in their encoded hash.
In fact, for the most part they avoid using any characters except
``a-zA-Z0-9./``, and ``$`` as an internal separator, though
this can be violated on some systems if the user intervenes.
.. note::
:class:`passlib.hash.des_crypt` and :class:`passlib.hash.bsdi_crypt`
do not follow this protocol, since they predate it by many years.
|