summaryrefslogtreecommitdiffstats
path: root/Lib/crypt.py
diff options
context:
space:
mode:
authorFedora Python maintainers <python-devel@lists.fedoraproject.org>2020-07-15 13:40:21 (GMT)
committerPetr Viktorin <pviktori@redhat.com>2020-09-29 13:59:05 (GMT)
commit59fcc40a1023230fe9e5bf4189a68c30953e6b72 (patch)
treeb63f251607a033990f1c3277dd7596ced736240b /Lib/crypt.py
parente20a3150622d5b2b632b45c8704f43dda25e9810 (diff)
downloadcpython-59fcc40a1023230fe9e5bf4189a68c30953e6b72.zip
cpython-59fcc40a1023230fe9e5bf4189a68c30953e6b72.tar.gz
cpython-59fcc40a1023230fe9e5bf4189a68c30953e6b72.tar.bz2
00165-crypt-module-salt-backport.patch
00165 # Backport to Python 2 from Python 3.3 of improvements to the "crypt" module adding precanned ways of salting a password (rhbz#835021) Based on r88500 patch to py3k from Python 3.3 plus 6482dd1c11ed, 0586c699d467, 62994662676a, 74a1110a3b50, plus edits to docstrings to note that this additional functionality is not standard within 2.7
Diffstat (limited to 'Lib/crypt.py')
-rw-r--r--Lib/crypt.py71
1 files changed, 71 insertions, 0 deletions
diff --git a/Lib/crypt.py b/Lib/crypt.py
new file mode 100644
index 0000000..bf0a416
--- /dev/null
+++ b/Lib/crypt.py
@@ -0,0 +1,71 @@
+"""Wrapper to the POSIX crypt library call and associated functionality.
+
+Note that the ``methods`` and ``METHOD_*`` attributes are non-standard
+extensions to Python 2.7, backported from 3.3"""
+
+import _crypt
+import string as _string
+from random import SystemRandom as _SystemRandom
+from collections import namedtuple as _namedtuple
+
+
+_saltchars = _string.ascii_letters + _string.digits + './'
+_sr = _SystemRandom()
+
+
+class _Method(_namedtuple('_Method', 'name ident salt_chars total_size')):
+
+ """Class representing a salt method per the Modular Crypt Format or the
+ legacy 2-character crypt method."""
+
+ def __repr__(self):
+ return '<crypt.METHOD_%s>' % self.name
+
+
+def mksalt(method=None):
+ """Generate a salt for the specified method.
+
+ If not specified, the strongest available method will be used.
+
+ This is a non-standard extension to Python 2.7, backported from 3.3
+ """
+ if method is None:
+ method = methods[0]
+ s = '$%s$' % method.ident if method.ident else ''
+ s += ''.join(_sr.sample(_saltchars, method.salt_chars))
+ return s
+
+
+def crypt(word, salt=None):
+ """Return a string representing the one-way hash of a password, with a salt
+ prepended.
+
+ If ``salt`` is not specified or is ``None``, the strongest
+ available method will be selected and a salt generated. Otherwise,
+ ``salt`` may be one of the ``crypt.METHOD_*`` values, or a string as
+ returned by ``crypt.mksalt()``.
+
+ Note that these are non-standard extensions to Python 2.7's crypt.crypt()
+ entrypoint, backported from 3.3: the standard Python 2.7 crypt.crypt()
+ entrypoint requires two strings as the parameters, and does not support
+ keyword arguments.
+ """
+ if salt is None or isinstance(salt, _Method):
+ salt = mksalt(salt)
+ return _crypt.crypt(word, salt)
+
+
+# available salting/crypto methods
+METHOD_CRYPT = _Method('CRYPT', None, 2, 13)
+METHOD_MD5 = _Method('MD5', '1', 8, 34)
+METHOD_SHA256 = _Method('SHA256', '5', 16, 63)
+METHOD_SHA512 = _Method('SHA512', '6', 16, 106)
+
+methods = []
+for _method in (METHOD_SHA512, METHOD_SHA256, METHOD_MD5):
+ _result = crypt('', _method)
+ if _result and len(_result) == _method.total_size:
+ methods.append(_method)
+methods.append(METHOD_CRYPT)
+del _result, _method
+