mirror of https://github.com/python/cpython
gh-104773: PEP 594: Remove the crypt module (#104908)
Remove the crypt module and its private _crypt extension, deprecated in Python 3.11.
This commit is contained in:
parent
38539ef126
commit
e4127eaa1e
|
@ -1,182 +0,0 @@
|
|||
:mod:`crypt` --- Function to check Unix passwords
|
||||
=================================================
|
||||
|
||||
.. module:: crypt
|
||||
:platform: Unix
|
||||
:synopsis: The crypt() function used to check Unix passwords.
|
||||
:deprecated:
|
||||
|
||||
.. moduleauthor:: Steven D. Majewski <sdm7g@virginia.edu>
|
||||
.. sectionauthor:: Steven D. Majewski <sdm7g@virginia.edu>
|
||||
.. sectionauthor:: Peter Funk <pf@artcom-gmbh.de>
|
||||
|
||||
**Source code:** :source:`Lib/crypt.py`
|
||||
|
||||
.. index::
|
||||
single: crypt(3)
|
||||
pair: cipher; DES
|
||||
|
||||
.. deprecated-removed:: 3.11 3.13
|
||||
The :mod:`crypt` module is deprecated
|
||||
(see :pep:`PEP 594 <594#crypt>` for details and alternatives).
|
||||
The :mod:`hashlib` module is a potential replacement for certain use cases.
|
||||
|
||||
--------------
|
||||
|
||||
This module implements an interface to the :manpage:`crypt(3)` routine, which is
|
||||
a one-way hash function based upon a modified DES algorithm; see the Unix man
|
||||
page for further details. Possible uses include storing hashed passwords
|
||||
so you can check passwords without storing the actual password, or attempting
|
||||
to crack Unix passwords with a dictionary.
|
||||
|
||||
.. index:: single: crypt(3)
|
||||
|
||||
Notice that the behavior of this module depends on the actual implementation of
|
||||
the :manpage:`crypt(3)` routine in the running system. Therefore, any
|
||||
extensions available on the current implementation will also be available on
|
||||
this module.
|
||||
|
||||
.. availability:: Unix, not VxWorks.
|
||||
|
||||
.. include:: ../includes/wasm-notavail.rst
|
||||
|
||||
Hashing Methods
|
||||
---------------
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
The :mod:`crypt` module defines the list of hashing methods (not all methods
|
||||
are available on all platforms):
|
||||
|
||||
.. data:: METHOD_SHA512
|
||||
|
||||
A Modular Crypt Format method with 16 character salt and 86 character
|
||||
hash based on the SHA-512 hash function. This is the strongest method.
|
||||
|
||||
.. data:: METHOD_SHA256
|
||||
|
||||
Another Modular Crypt Format method with 16 character salt and 43
|
||||
character hash based on the SHA-256 hash function.
|
||||
|
||||
.. data:: METHOD_BLOWFISH
|
||||
|
||||
Another Modular Crypt Format method with 22 character salt and 31
|
||||
character hash based on the Blowfish cipher.
|
||||
|
||||
.. versionadded:: 3.7
|
||||
|
||||
.. data:: METHOD_MD5
|
||||
|
||||
Another Modular Crypt Format method with 8 character salt and 22
|
||||
character hash based on the MD5 hash function.
|
||||
|
||||
.. data:: METHOD_CRYPT
|
||||
|
||||
The traditional method with a 2 character salt and 13 characters of
|
||||
hash. This is the weakest method.
|
||||
|
||||
|
||||
Module Attributes
|
||||
-----------------
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
.. attribute:: methods
|
||||
|
||||
A list of available password hashing algorithms, as
|
||||
``crypt.METHOD_*`` objects. This list is sorted from strongest to
|
||||
weakest.
|
||||
|
||||
|
||||
Module Functions
|
||||
----------------
|
||||
|
||||
The :mod:`crypt` module defines the following functions:
|
||||
|
||||
.. function:: crypt(word, salt=None)
|
||||
|
||||
*word* will usually be a user's password as typed at a prompt or in a graphical
|
||||
interface. The optional *salt* is either a string as returned from
|
||||
:func:`mksalt`, one of the ``crypt.METHOD_*`` values (though not all
|
||||
may be available on all platforms), or a full encrypted password
|
||||
including salt, as returned by this function. If *salt* is not
|
||||
provided, the strongest method available in :attr:`methods` will be used.
|
||||
|
||||
Checking a password is usually done by passing the plain-text password
|
||||
as *word* and the full results of a previous :func:`crypt` call,
|
||||
which should be the same as the results of this call.
|
||||
|
||||
*salt* (either a random 2 or 16 character string, possibly prefixed with
|
||||
``$digit$`` to indicate the method) which will be used to perturb the
|
||||
encryption algorithm. The characters in *salt* must be in the set
|
||||
``[./a-zA-Z0-9]``, with the exception of Modular Crypt Format which
|
||||
prefixes a ``$digit$``.
|
||||
|
||||
Returns the hashed password as a string, which will be composed of
|
||||
characters from the same alphabet as the salt.
|
||||
|
||||
.. index:: single: crypt(3)
|
||||
|
||||
Since a few :manpage:`crypt(3)` extensions allow different values, with
|
||||
different sizes in the *salt*, it is recommended to use the full crypted
|
||||
password as salt when checking for a password.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Accept ``crypt.METHOD_*`` values in addition to strings for *salt*.
|
||||
|
||||
|
||||
.. function:: mksalt(method=None, *, rounds=None)
|
||||
|
||||
Return a randomly generated salt of the specified method. If no
|
||||
*method* is given, the strongest method available in :attr:`methods` is
|
||||
used.
|
||||
|
||||
The return value is a string suitable for passing as the *salt* argument
|
||||
to :func:`crypt`.
|
||||
|
||||
*rounds* specifies the number of rounds for ``METHOD_SHA256``,
|
||||
``METHOD_SHA512`` and ``METHOD_BLOWFISH``.
|
||||
For ``METHOD_SHA256`` and ``METHOD_SHA512`` it must be an integer between
|
||||
``1000`` and ``999_999_999``, the default is ``5000``. For
|
||||
``METHOD_BLOWFISH`` it must be a power of two between ``16`` (2\ :sup:`4`)
|
||||
and ``2_147_483_648`` (2\ :sup:`31`), the default is ``4096``
|
||||
(2\ :sup:`12`).
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
.. versionchanged:: 3.7
|
||||
Added the *rounds* parameter.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
A simple example illustrating typical use (a constant-time comparison
|
||||
operation is needed to limit exposure to timing attacks.
|
||||
:func:`hmac.compare_digest` is suitable for this purpose)::
|
||||
|
||||
import pwd
|
||||
import crypt
|
||||
import getpass
|
||||
from hmac import compare_digest as compare_hash
|
||||
|
||||
def login():
|
||||
username = input('Python login: ')
|
||||
cryptedpasswd = pwd.getpwnam(username)[1]
|
||||
if cryptedpasswd:
|
||||
if cryptedpasswd == 'x' or cryptedpasswd == '*':
|
||||
raise ValueError('no support for shadow passwords')
|
||||
cleartext = getpass.getpass()
|
||||
return compare_hash(crypt.crypt(cleartext, cryptedpasswd), cryptedpasswd)
|
||||
else:
|
||||
return True
|
||||
|
||||
To generate a hash of a password using the strongest available method and
|
||||
check it against the original::
|
||||
|
||||
import crypt
|
||||
from hmac import compare_digest as compare_hash
|
||||
|
||||
hashed = crypt.crypt(plaintext)
|
||||
if not compare_hash(hashed, crypt.crypt(plaintext, hashed)):
|
||||
raise ValueError("hashed version doesn't validate against original")
|
|
@ -8,7 +8,6 @@ Cryptographic Services
|
|||
|
||||
The modules described in this chapter implement various algorithms of a
|
||||
cryptographic nature. They are available at the discretion of the installation.
|
||||
On Unix systems, the :mod:`crypt` module may also be available.
|
||||
Here's an overview:
|
||||
|
||||
|
||||
|
|
|
@ -39,10 +39,8 @@ raised if the entry asked for cannot be found.
|
|||
|
||||
.. note::
|
||||
|
||||
.. index:: pair: module; crypt
|
||||
|
||||
In traditional Unix the field ``pw_passwd`` usually contains a password
|
||||
encrypted with a DES derived algorithm (see module :mod:`crypt`). However most
|
||||
encrypted with a DES derived algorithm. However most
|
||||
modern unices use a so-called *shadow password* system. On those unices the
|
||||
*pw_passwd* field only contains an asterisk (``'*'``) or the letter ``'x'``
|
||||
where the encrypted password is stored in a file :file:`/etc/shadow` which is
|
||||
|
|
|
@ -13,7 +13,6 @@ backwards compatibility. They have been superseded by other modules.
|
|||
aifc.rst
|
||||
audioop.rst
|
||||
chunk.rst
|
||||
crypt.rst
|
||||
imghdr.rst
|
||||
optparse.rst
|
||||
uu.rst
|
||||
|
|
|
@ -655,7 +655,7 @@ copyright and licensing notice::
|
|||
OpenSSL
|
||||
-------
|
||||
|
||||
The modules :mod:`hashlib`, :mod:`posix`, :mod:`ssl`, :mod:`crypt` use
|
||||
The modules :mod:`hashlib`, :mod:`posix` and :mod:`ssl` use
|
||||
the OpenSSL library for added performance if made available by the
|
||||
operating system. Additionally, the Windows and macOS installers for
|
||||
Python may include a copy of the OpenSSL libraries, so we include a copy
|
||||
|
|
|
@ -1733,7 +1733,7 @@ Modules
|
|||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||
| :mod:`aifc` | :mod:`chunk` | :mod:`!msilib` | :mod:`!pipes` | :mod:`!telnetlib` |
|
||||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||
| :mod:`audioop` | :mod:`crypt` | :mod:`!nis` | :mod:`!sndhdr` | :mod:`uu` |
|
||||
| :mod:`audioop` | :mod:`!crypt` | :mod:`!nis` | :mod:`!sndhdr` | :mod:`uu` |
|
||||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||
| :mod:`!cgi` | :mod:`imghdr` | :mod:`!nntplib` | :mod:`!spwd` | :mod:`!xdrlib` |
|
||||
+---------------------+---------------------+---------------------+---------------------+---------------------+
|
||||
|
|
|
@ -923,7 +923,7 @@ Modules (see :pep:`594`):
|
|||
* :mod:`!cgi`
|
||||
* :mod:`!cgitb`
|
||||
* :mod:`chunk`
|
||||
* :mod:`crypt`
|
||||
* :mod:`!crypt`
|
||||
* :mod:`imghdr`
|
||||
* :mod:`!mailcap`
|
||||
* :mod:`!msilib`
|
||||
|
|
|
@ -201,6 +201,22 @@ Removed
|
|||
* :pep:`594`: Remove the :mod:`!msilib` module, deprecated in Python 3.11.
|
||||
(Contributed by Zachary Ware in :gh:`104773`.)
|
||||
|
||||
* :pep:`594`: Remove the :mod:`!crypt` module and its private :mod:`!_crypt`
|
||||
extension, deprecated in Python 3.11.
|
||||
The :mod:`hashlib` module is a potential replacement for certain use cases.
|
||||
Otherwise, the following PyPI projects can be used:
|
||||
|
||||
* `bcrypt <https://pypi.org/project/bcrypt/>`_:
|
||||
Modern password hashing for your software and your servers.
|
||||
* `passlib <https://pypi.org/project/passlib/>`_:
|
||||
Comprehensive password hashing framework supporting over 30 schemes.
|
||||
* `argon2-cffi <https://pypi.org/project/argon2-cffi/>`_:
|
||||
The secure Argon2 password hashing algorithm.
|
||||
* `legacycrypt <https://pypi.org/project/legacycrypt/>`_:
|
||||
Wrapper to the POSIX crypt library call and associated functionality.
|
||||
|
||||
(Contributed by Victor Stinner in :gh:`104773`.)
|
||||
|
||||
|
||||
Porting to Python 3.13
|
||||
======================
|
||||
|
|
|
@ -1052,8 +1052,8 @@ their ``__init__`` method (for example, file objects) or in their
|
|||
crypt
|
||||
-----
|
||||
|
||||
Addition of salt and modular crypt format (hashing method) and the :func:`~crypt.mksalt`
|
||||
function to the :mod:`crypt` module.
|
||||
Addition of salt and modular crypt format (hashing method) and the :func:`~!crypt.mksalt`
|
||||
function to the :mod:`!crypt` module.
|
||||
|
||||
(:issue:`10924`)
|
||||
|
||||
|
|
|
@ -2274,7 +2274,7 @@ Changes in the Python API
|
|||
:class:`~collections.OrderedDict`.
|
||||
(Contributed by Steve Holden in :issue:`27842`.)
|
||||
|
||||
* The :const:`crypt.METHOD_CRYPT` will no longer be added to ``crypt.methods``
|
||||
* The :const:`!crypt.METHOD_CRYPT` will no longer be added to ``crypt.methods``
|
||||
if unsupported by the platform.
|
||||
(Contributed by Victor Stinner in :issue:`25287`.)
|
||||
|
||||
|
|
|
@ -848,10 +848,10 @@ alternative to script path. (Contributed by Sanyam Khurana in :issue:`21862`.)
|
|||
crypt
|
||||
-----
|
||||
|
||||
The :mod:`crypt` module now supports the Blowfish hashing method.
|
||||
The :mod:`!crypt` module now supports the Blowfish hashing method.
|
||||
(Contributed by Serhiy Storchaka in :issue:`31664`.)
|
||||
|
||||
The :func:`~crypt.mksalt` function now allows specifying the number of rounds
|
||||
The :func:`~!crypt.mksalt` function now allows specifying the number of rounds
|
||||
for hashing. (Contributed by Serhiy Storchaka in :issue:`31702`.)
|
||||
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ Interpreter improvements:
|
|||
now sped up using :pep:`590` vectorcall;
|
||||
* garbage collection does not block on resurrected objects;
|
||||
* a number of Python modules (:mod:`_abc`, :mod:`audioop`, :mod:`_bz2`,
|
||||
:mod:`_codecs`, :mod:`_contextvars`, :mod:`_crypt`, :mod:`_functools`,
|
||||
:mod:`_codecs`, :mod:`_contextvars`, :mod:`!_crypt`, :mod:`_functools`,
|
||||
:mod:`_json`, :mod:`_locale`, :mod:`math`, :mod:`operator`, :mod:`resource`,
|
||||
:mod:`time`, :mod:`_weakref`) now use multiphase initialization as defined
|
||||
by PEP 489;
|
||||
|
|
124
Lib/crypt.py
124
Lib/crypt.py
|
@ -1,124 +0,0 @@
|
|||
"""Wrapper to the POSIX crypt library call and associated functionality."""
|
||||
|
||||
import sys as _sys
|
||||
|
||||
try:
|
||||
import _crypt
|
||||
except ModuleNotFoundError:
|
||||
if _sys.platform == 'win32':
|
||||
raise ImportError("The crypt module is not supported on Windows")
|
||||
else:
|
||||
raise ImportError("The required _crypt module was not built as part of CPython")
|
||||
|
||||
import errno
|
||||
import string as _string
|
||||
import warnings
|
||||
from random import SystemRandom as _SystemRandom
|
||||
from collections import namedtuple as _namedtuple
|
||||
|
||||
|
||||
warnings._deprecated(__name__, remove=(3, 13))
|
||||
|
||||
|
||||
_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_{}>'.format(self.name)
|
||||
|
||||
|
||||
def mksalt(method=None, *, rounds=None):
|
||||
"""Generate a salt for the specified method.
|
||||
|
||||
If not specified, the strongest available method will be used.
|
||||
|
||||
"""
|
||||
if method is None:
|
||||
method = methods[0]
|
||||
if rounds is not None and not isinstance(rounds, int):
|
||||
raise TypeError(f'{rounds.__class__.__name__} object cannot be '
|
||||
f'interpreted as an integer')
|
||||
if not method.ident: # traditional
|
||||
s = ''
|
||||
else: # modular
|
||||
s = f'${method.ident}$'
|
||||
|
||||
if method.ident and method.ident[0] == '2': # Blowfish variants
|
||||
if rounds is None:
|
||||
log_rounds = 12
|
||||
else:
|
||||
log_rounds = int.bit_length(rounds-1)
|
||||
if rounds != 1 << log_rounds:
|
||||
raise ValueError('rounds must be a power of 2')
|
||||
if not 4 <= log_rounds <= 31:
|
||||
raise ValueError('rounds out of the range 2**4 to 2**31')
|
||||
s += f'{log_rounds:02d}$'
|
||||
elif method.ident in ('5', '6'): # SHA-2
|
||||
if rounds is not None:
|
||||
if not 1000 <= rounds <= 999_999_999:
|
||||
raise ValueError('rounds out of the range 1000 to 999_999_999')
|
||||
s += f'rounds={rounds}$'
|
||||
elif rounds is not None:
|
||||
raise ValueError(f"{method} doesn't support the rounds argument")
|
||||
|
||||
s += ''.join(_sr.choice(_saltchars) for char in range(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()``.
|
||||
|
||||
"""
|
||||
if salt is None or isinstance(salt, _Method):
|
||||
salt = mksalt(salt)
|
||||
return _crypt.crypt(word, salt)
|
||||
|
||||
|
||||
# available salting/crypto methods
|
||||
methods = []
|
||||
|
||||
def _add_method(name, *args, rounds=None):
|
||||
method = _Method(name, *args)
|
||||
globals()['METHOD_' + name] = method
|
||||
salt = mksalt(method, rounds=rounds)
|
||||
result = None
|
||||
try:
|
||||
result = crypt('', salt)
|
||||
except OSError as e:
|
||||
# Not all libc libraries support all encryption methods.
|
||||
if e.errno in {errno.EINVAL, errno.EPERM, errno.ENOSYS}:
|
||||
return False
|
||||
raise
|
||||
if result and len(result) == method.total_size:
|
||||
methods.append(method)
|
||||
return True
|
||||
return False
|
||||
|
||||
_add_method('SHA512', '6', 16, 106)
|
||||
_add_method('SHA256', '5', 16, 63)
|
||||
|
||||
# Choose the strongest supported version of Blowfish hashing.
|
||||
# Early versions have flaws. Version 'a' fixes flaws of
|
||||
# the initial implementation, 'b' fixes flaws of 'a'.
|
||||
# 'y' is the same as 'b', for compatibility
|
||||
# with openwall crypt_blowfish.
|
||||
for _v in 'b', 'y', 'a', '':
|
||||
if _add_method('BLOWFISH', '2' + _v, 22, 59 + len(_v), rounds=1<<4):
|
||||
break
|
||||
|
||||
_add_method('MD5', '1', 8, 34)
|
||||
_add_method('CRYPT', None, 2, 13)
|
||||
|
||||
del _v, _add_method
|
|
@ -13,9 +13,9 @@ except ModuleNotFoundError:
|
|||
|
||||
if support.check_sanitizer(address=True, memory=True):
|
||||
# bpo-46633: test___all__ is skipped because importing some modules
|
||||
# directly can trigger known problems with ASAN (like tk or crypt).
|
||||
# directly can trigger known problems with ASAN (like tk).
|
||||
raise unittest.SkipTest("workaround ASAN build issues on loading tests "
|
||||
"like tk or crypt")
|
||||
"like tk")
|
||||
|
||||
|
||||
class NoAll(RuntimeError):
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
import sys
|
||||
import unittest
|
||||
from test.support import check_sanitizer, warnings_helper
|
||||
|
||||
|
||||
try:
|
||||
if check_sanitizer(address=True, memory=True):
|
||||
raise unittest.SkipTest("The crypt module SEGFAULTs on ASAN/MSAN builds")
|
||||
crypt = warnings_helper.import_deprecated("crypt")
|
||||
IMPORT_ERROR = None
|
||||
except ImportError as ex:
|
||||
if sys.platform != 'win32':
|
||||
raise unittest.SkipTest(str(ex))
|
||||
crypt = None
|
||||
IMPORT_ERROR = str(ex)
|
||||
|
||||
|
||||
@unittest.skipUnless(sys.platform == 'win32', 'This should only run on windows')
|
||||
@unittest.skipIf(crypt, 'import succeeded')
|
||||
class TestWhyCryptDidNotImport(unittest.TestCase):
|
||||
|
||||
def test_import_failure_message(self):
|
||||
self.assertIn('not supported', IMPORT_ERROR)
|
||||
|
||||
|
||||
@unittest.skipUnless(crypt, 'crypt module is required')
|
||||
class CryptTestCase(unittest.TestCase):
|
||||
|
||||
def test_crypt(self):
|
||||
cr = crypt.crypt('mypassword')
|
||||
cr2 = crypt.crypt('mypassword', cr)
|
||||
self.assertEqual(cr2, cr)
|
||||
cr = crypt.crypt('mypassword', 'ab')
|
||||
if cr is not None:
|
||||
cr2 = crypt.crypt('mypassword', cr)
|
||||
self.assertEqual(cr2, cr)
|
||||
|
||||
def test_salt(self):
|
||||
self.assertEqual(len(crypt._saltchars), 64)
|
||||
for method in crypt.methods:
|
||||
salt = crypt.mksalt(method)
|
||||
self.assertIn(len(salt) - method.salt_chars, {0, 1, 3, 4, 6, 7})
|
||||
if method.ident:
|
||||
self.assertIn(method.ident, salt[:len(salt)-method.salt_chars])
|
||||
|
||||
def test_saltedcrypt(self):
|
||||
for method in crypt.methods:
|
||||
cr = crypt.crypt('assword', method)
|
||||
self.assertEqual(len(cr), method.total_size)
|
||||
cr2 = crypt.crypt('assword', cr)
|
||||
self.assertEqual(cr2, cr)
|
||||
cr = crypt.crypt('assword', crypt.mksalt(method))
|
||||
self.assertEqual(len(cr), method.total_size)
|
||||
|
||||
def test_methods(self):
|
||||
self.assertTrue(len(crypt.methods) >= 1)
|
||||
if sys.platform.startswith('openbsd'):
|
||||
self.assertEqual(crypt.methods, [crypt.METHOD_BLOWFISH])
|
||||
else:
|
||||
self.assertEqual(crypt.methods[-1], crypt.METHOD_CRYPT)
|
||||
|
||||
@unittest.skipUnless(
|
||||
crypt
|
||||
and (
|
||||
crypt.METHOD_SHA256 in crypt.methods or crypt.METHOD_SHA512 in crypt.methods
|
||||
),
|
||||
'requires support of SHA-2',
|
||||
)
|
||||
def test_sha2_rounds(self):
|
||||
for method in (crypt.METHOD_SHA256, crypt.METHOD_SHA512):
|
||||
for rounds in 1000, 10_000, 100_000:
|
||||
salt = crypt.mksalt(method, rounds=rounds)
|
||||
self.assertIn('$rounds=%d$' % rounds, salt)
|
||||
self.assertEqual(len(salt) - method.salt_chars,
|
||||
11 + len(str(rounds)))
|
||||
cr = crypt.crypt('mypassword', salt)
|
||||
self.assertTrue(cr)
|
||||
cr2 = crypt.crypt('mypassword', cr)
|
||||
self.assertEqual(cr2, cr)
|
||||
|
||||
@unittest.skipUnless(
|
||||
crypt and crypt.METHOD_BLOWFISH in crypt.methods, 'requires support of Blowfish'
|
||||
)
|
||||
def test_blowfish_rounds(self):
|
||||
for log_rounds in range(4, 11):
|
||||
salt = crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=1 << log_rounds)
|
||||
self.assertIn('$%02d$' % log_rounds, salt)
|
||||
self.assertIn(len(salt) - crypt.METHOD_BLOWFISH.salt_chars, {6, 7})
|
||||
cr = crypt.crypt('mypassword', salt)
|
||||
self.assertTrue(cr)
|
||||
cr2 = crypt.crypt('mypassword', cr)
|
||||
self.assertEqual(cr2, cr)
|
||||
|
||||
def test_invalid_rounds(self):
|
||||
for method in (crypt.METHOD_SHA256, crypt.METHOD_SHA512,
|
||||
crypt.METHOD_BLOWFISH):
|
||||
with self.assertRaises(TypeError):
|
||||
crypt.mksalt(method, rounds='4096')
|
||||
with self.assertRaises(TypeError):
|
||||
crypt.mksalt(method, rounds=4096.0)
|
||||
for rounds in (0, 1, -1, 1<<999):
|
||||
with self.assertRaises(ValueError):
|
||||
crypt.mksalt(method, rounds=rounds)
|
||||
with self.assertRaises(ValueError):
|
||||
crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=1000)
|
||||
for method in (crypt.METHOD_CRYPT, crypt.METHOD_MD5):
|
||||
with self.assertRaisesRegex(ValueError, 'support'):
|
||||
crypt.mksalt(method, rounds=4096)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -2650,7 +2650,7 @@ calling any callbacks. Patch by Kumar Aditya.
|
|||
.. section: Library
|
||||
|
||||
Fail gracefully if :data:`~errno.EPERM` or :data:`~errno.ENOSYS` is raised
|
||||
when loading :mod:`crypt` methods. This may happen when trying to load
|
||||
when loading :mod:`!crypt` methods. This may happen when trying to load
|
||||
``MD5`` on a Linux kernel with :abbr:`FIPS (Federal Information Processing
|
||||
Standard)` enabled.
|
||||
|
||||
|
|
|
@ -4856,7 +4856,7 @@ Patch by Srinivas Nyayapati.
|
|||
.. nonce: Akreij
|
||||
.. section: Windows
|
||||
|
||||
Trying to import the :mod:`crypt` module on Windows will result in an
|
||||
Trying to import the :mod:`!crypt` module on Windows will result in an
|
||||
:exc:`ImportError` with a message explaining that the module isn't supported
|
||||
on Windows. On other platforms, if the underlying ``_crypt`` module is not
|
||||
available, the ImportError will include a message explaining the problem.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
:pep:`594`: Remove the :mod:`!crypt` module and its private :mod:`!_crypt`
|
||||
extension, deprecated in Python 3.11. Patch by Victor Stinner.
|
|
@ -188,10 +188,6 @@ PYTHONPATH=$(COREPYTHONPATH)
|
|||
#syslog syslogmodule.c
|
||||
#termios termios.c
|
||||
|
||||
# Modules with UNIX dependencies that require external libraries
|
||||
|
||||
#_crypt _cryptmodule.c -lcrypt
|
||||
|
||||
# Modules that require external libraries.
|
||||
|
||||
#_bz2 _bz2module.c -lbz2
|
||||
|
|
|
@ -106,8 +106,6 @@
|
|||
# Modules with some UNIX dependencies
|
||||
#
|
||||
|
||||
# needs -lcrypt on some systems
|
||||
@MODULE__CRYPT_TRUE@_crypt _cryptmodule.c
|
||||
@MODULE_FCNTL_TRUE@fcntl fcntlmodule.c
|
||||
@MODULE_GRP_TRUE@grp grpmodule.c
|
||||
@MODULE_MMAP_TRUE@mmap mmapmodule.c
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
/* cryptmodule.c - by Steve Majewski
|
||||
*/
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
/* Module crypt */
|
||||
|
||||
/*[clinic input]
|
||||
module crypt
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c6252cf4f2f2ae81]*/
|
||||
|
||||
#include "clinic/_cryptmodule.c.h"
|
||||
|
||||
/*[clinic input]
|
||||
crypt.crypt
|
||||
|
||||
word: str
|
||||
salt: str
|
||||
/
|
||||
|
||||
Hash a *word* with the given *salt* and return the hashed password.
|
||||
|
||||
*word* will usually be a user's password. *salt* (either a random 2 or 16
|
||||
character string, possibly prefixed with $digit$ to indicate the method)
|
||||
will be used to perturb the encryption algorithm and produce distinct
|
||||
results for a given *word*.
|
||||
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
crypt_crypt_impl(PyObject *module, const char *word, const char *salt)
|
||||
/*[clinic end generated code: output=0512284a03d2803c input=0e8edec9c364352b]*/
|
||||
{
|
||||
char *crypt_result;
|
||||
#ifdef HAVE_CRYPT_R
|
||||
struct crypt_data data;
|
||||
memset(&data, 0, sizeof(data));
|
||||
crypt_result = crypt_r(word, salt, &data);
|
||||
#else
|
||||
crypt_result = crypt(word, salt);
|
||||
#endif
|
||||
if (crypt_result == NULL) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
return Py_BuildValue("s", crypt_result);
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef crypt_methods[] = {
|
||||
CRYPT_CRYPT_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyModuleDef_Slot _crypt_slots[] = {
|
||||
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef cryptmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_crypt",
|
||||
NULL,
|
||||
0,
|
||||
crypt_methods,
|
||||
_crypt_slots,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit__crypt(void)
|
||||
{
|
||||
return PyModuleDef_Init(&cryptmodule);
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*[clinic input]
|
||||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
# include "pycore_gc.h" // PyGC_Head
|
||||
# include "pycore_runtime.h" // _Py_ID()
|
||||
#endif
|
||||
|
||||
|
||||
PyDoc_STRVAR(crypt_crypt__doc__,
|
||||
"crypt($module, word, salt, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Hash a *word* with the given *salt* and return the hashed password.\n"
|
||||
"\n"
|
||||
"*word* will usually be a user\'s password. *salt* (either a random 2 or 16\n"
|
||||
"character string, possibly prefixed with $digit$ to indicate the method)\n"
|
||||
"will be used to perturb the encryption algorithm and produce distinct\n"
|
||||
"results for a given *word*.");
|
||||
|
||||
#define CRYPT_CRYPT_METHODDEF \
|
||||
{"crypt", _PyCFunction_CAST(crypt_crypt), METH_FASTCALL, crypt_crypt__doc__},
|
||||
|
||||
static PyObject *
|
||||
crypt_crypt_impl(PyObject *module, const char *word, const char *salt);
|
||||
|
||||
static PyObject *
|
||||
crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
const char *word;
|
||||
const char *salt;
|
||||
|
||||
if (!_PyArg_CheckPositional("crypt", nargs, 2, 2)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!PyUnicode_Check(args[0])) {
|
||||
_PyArg_BadArgument("crypt", "argument 1", "str", args[0]);
|
||||
goto exit;
|
||||
}
|
||||
Py_ssize_t word_length;
|
||||
word = PyUnicode_AsUTF8AndSize(args[0], &word_length);
|
||||
if (word == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
if (strlen(word) != (size_t)word_length) {
|
||||
PyErr_SetString(PyExc_ValueError, "embedded null character");
|
||||
goto exit;
|
||||
}
|
||||
if (!PyUnicode_Check(args[1])) {
|
||||
_PyArg_BadArgument("crypt", "argument 2", "str", args[1]);
|
||||
goto exit;
|
||||
}
|
||||
Py_ssize_t salt_length;
|
||||
salt = PyUnicode_AsUTF8AndSize(args[1], &salt_length);
|
||||
if (salt == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
if (strlen(salt) != (size_t)salt_length) {
|
||||
PyErr_SetString(PyExc_ValueError, "embedded null character");
|
||||
goto exit;
|
||||
}
|
||||
return_value = crypt_crypt_impl(module, word, salt);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=235ccef9211184f4 input=a9049054013a1b77]*/
|
|
@ -22,7 +22,6 @@ static const char* _Py_stdlib_module_names[] = {
|
|||
"_compat_pickle",
|
||||
"_compression",
|
||||
"_contextvars",
|
||||
"_crypt",
|
||||
"_csv",
|
||||
"_ctypes",
|
||||
"_curses",
|
||||
|
@ -121,7 +120,6 @@ static const char* _Py_stdlib_module_names[] = {
|
|||
"contextvars",
|
||||
"copy",
|
||||
"copyreg",
|
||||
"crypt",
|
||||
"csv",
|
||||
"ctypes",
|
||||
"curses",
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
_asyncio
|
||||
audioop
|
||||
_bz2
|
||||
_crypt
|
||||
_decimal
|
||||
_pickle
|
||||
pyexpat _elementtree
|
||||
|
|
|
@ -81,7 +81,6 @@ OMIT_NETWORKING_FILES = (
|
|||
OMIT_MODULE_FILES = {
|
||||
"_asyncio": ["asyncio/"],
|
||||
"audioop": ["aifc.py", "wave.py"],
|
||||
"_crypt": ["crypt.py"],
|
||||
"_curses": ["curses/"],
|
||||
"_ctypes": ["ctypes/"],
|
||||
"_decimal": ["decimal.py"],
|
||||
|
|
|
@ -678,8 +678,6 @@ MODULE__CURSES_FALSE
|
|||
MODULE__CURSES_TRUE
|
||||
MODULE__CTYPES_FALSE
|
||||
MODULE__CTYPES_TRUE
|
||||
MODULE__CRYPT_FALSE
|
||||
MODULE__CRYPT_TRUE
|
||||
MODULE__BLAKE2_FALSE
|
||||
MODULE__BLAKE2_TRUE
|
||||
MODULE__SHA3_FALSE
|
||||
|
@ -818,8 +816,6 @@ HAVE_GETHOSTBYNAME_R
|
|||
HAVE_GETHOSTBYNAME_R_3_ARG
|
||||
HAVE_GETHOSTBYNAME_R_5_ARG
|
||||
HAVE_GETHOSTBYNAME_R_6_ARG
|
||||
LIBCRYPT_LIBS
|
||||
LIBCRYPT_CFLAGS
|
||||
LIBOBJS
|
||||
LIBLZMA_LIBS
|
||||
LIBLZMA_CFLAGS
|
||||
|
@ -1118,8 +1114,6 @@ BZIP2_CFLAGS
|
|||
BZIP2_LIBS
|
||||
LIBLZMA_CFLAGS
|
||||
LIBLZMA_LIBS
|
||||
LIBCRYPT_CFLAGS
|
||||
LIBCRYPT_LIBS
|
||||
LIBREADLINE_CFLAGS
|
||||
LIBREADLINE_LIBS
|
||||
LIBEDIT_CFLAGS
|
||||
|
@ -1940,10 +1934,6 @@ Some influential environment variables:
|
|||
C compiler flags for LIBLZMA, overriding pkg-config
|
||||
LIBLZMA_LIBS
|
||||
linker flags for LIBLZMA, overriding pkg-config
|
||||
LIBCRYPT_CFLAGS
|
||||
C compiler flags for LIBCRYPT, overriding pkg-config
|
||||
LIBCRYPT_LIBS
|
||||
linker flags for LIBCRYPT, overriding pkg-config
|
||||
LIBREADLINE_CFLAGS
|
||||
C compiler flags for LIBREADLINE, overriding pkg-config
|
||||
LIBREADLINE_LIBS
|
||||
|
@ -9618,7 +9608,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
|
|||
|
||||
# checks for header files
|
||||
for ac_header in \
|
||||
alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \
|
||||
alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \
|
||||
ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/memfd.h \
|
||||
linux/random.h linux/soundcard.h \
|
||||
linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \
|
||||
|
@ -18767,297 +18757,6 @@ fi
|
|||
done
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBCRYPT" >&5
|
||||
$as_echo_n "checking for LIBCRYPT... " >&6; }
|
||||
|
||||
if test -n "$LIBCRYPT_CFLAGS"; then
|
||||
pkg_cv_LIBCRYPT_CFLAGS="$LIBCRYPT_CFLAGS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxcrypt >= 3.1.1\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libxcrypt >= 3.1.1") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_LIBCRYPT_CFLAGS=`$PKG_CONFIG --cflags "libxcrypt >= 3.1.1" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
if test -n "$LIBCRYPT_LIBS"; then
|
||||
pkg_cv_LIBCRYPT_LIBS="$LIBCRYPT_LIBS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxcrypt >= 3.1.1\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libxcrypt >= 3.1.1") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_LIBCRYPT_LIBS=`$PKG_CONFIG --libs "libxcrypt >= 3.1.1" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
LIBCRYPT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libxcrypt >= 3.1.1" 2>&1`
|
||||
else
|
||||
LIBCRYPT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libxcrypt >= 3.1.1" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$LIBCRYPT_PKG_ERRORS" >&5
|
||||
|
||||
|
||||
save_CFLAGS=$CFLAGS
|
||||
save_CPPFLAGS=$CPPFLAGS
|
||||
save_LDFLAGS=$LDFLAGS
|
||||
save_LIBS=$LIBS
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5
|
||||
$as_echo_n "checking for library containing crypt_r... " >&6; }
|
||||
if ${ac_cv_search_crypt_r+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char crypt_r ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return crypt_r ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' crypt; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_crypt_r=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_crypt_r+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_crypt_r+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_crypt_r=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt_r" >&5
|
||||
$as_echo "$ac_cv_search_crypt_r" >&6; }
|
||||
ac_res=$ac_cv_search_crypt_r
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
$as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h
|
||||
|
||||
if test "$ac_cv_search_crypt_r" = "none required"; then
|
||||
libcrypt=
|
||||
else
|
||||
libcrypt="$ac_cv_search_crypt_r"
|
||||
fi
|
||||
LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt}
|
||||
|
||||
fi
|
||||
|
||||
|
||||
CFLAGS=$save_CFLAGS
|
||||
CPPFLAGS=$save_CPPFLAGS
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
LIBS=$save_LIBS
|
||||
|
||||
|
||||
|
||||
elif test $pkg_failed = untried; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
|
||||
save_CFLAGS=$CFLAGS
|
||||
save_CPPFLAGS=$CPPFLAGS
|
||||
save_LDFLAGS=$LDFLAGS
|
||||
save_LIBS=$LIBS
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5
|
||||
$as_echo_n "checking for library containing crypt_r... " >&6; }
|
||||
if ${ac_cv_search_crypt_r+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char crypt_r ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return crypt_r ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' crypt; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_crypt_r=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_crypt_r+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_crypt_r+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_crypt_r=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt_r" >&5
|
||||
$as_echo "$ac_cv_search_crypt_r" >&6; }
|
||||
ac_res=$ac_cv_search_crypt_r
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
$as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h
|
||||
|
||||
if test "$ac_cv_search_crypt_r" = "none required"; then
|
||||
libcrypt=
|
||||
else
|
||||
libcrypt="$ac_cv_search_crypt_r"
|
||||
fi
|
||||
LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt}
|
||||
|
||||
fi
|
||||
|
||||
|
||||
CFLAGS=$save_CFLAGS
|
||||
CPPFLAGS=$save_CPPFLAGS
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
LIBS=$save_LIBS
|
||||
|
||||
|
||||
|
||||
else
|
||||
LIBCRYPT_CFLAGS=$pkg_cv_LIBCRYPT_CFLAGS
|
||||
LIBCRYPT_LIBS=$pkg_cv_LIBCRYPT_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
$as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h
|
||||
|
||||
|
||||
fi
|
||||
|
||||
save_CFLAGS=$CFLAGS
|
||||
save_CPPFLAGS=$CPPFLAGS
|
||||
save_LDFLAGS=$LDFLAGS
|
||||
save_LIBS=$LIBS
|
||||
|
||||
|
||||
CPPFLAGS="$CPPFLAGS $LIBCRYPT_CFLAGS"
|
||||
LIBS="$LIBCRYPT_LIBS $LIBS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt or crypt_r" >&5
|
||||
$as_echo_n "checking for crypt or crypt_r... " >&6; }
|
||||
if ${ac_cv_crypt_crypt+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
#ifdef HAVE_CRYPT_R
|
||||
void *x = crypt_r;
|
||||
#else
|
||||
void *x = crypt;
|
||||
#endif
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_crypt_crypt=yes
|
||||
else
|
||||
ac_cv_crypt_crypt=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_crypt_crypt" >&5
|
||||
$as_echo "$ac_cv_crypt_crypt" >&6; }
|
||||
|
||||
CFLAGS=$save_CFLAGS
|
||||
CPPFLAGS=$save_CPPFLAGS
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
LIBS=$save_LIBS
|
||||
|
||||
|
||||
|
||||
for ac_func in clock_gettime
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
|
||||
|
@ -25376,7 +25075,6 @@ case $ac_sys_system in #(
|
|||
|
||||
|
||||
py_cv_module__scproxy=n/a
|
||||
py_cv_module__crypt=n/a
|
||||
py_cv_module_termios=n/a
|
||||
py_cv_module_grp=n/a
|
||||
;; #(
|
||||
|
@ -26774,40 +26472,6 @@ $as_echo "$py_cv_module__blake2" >&6; }
|
|||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _crypt" >&5
|
||||
$as_echo_n "checking for stdlib extension module _crypt... " >&6; }
|
||||
if test "$py_cv_module__crypt" != "n/a"; then :
|
||||
|
||||
if true; then :
|
||||
if test "$ac_cv_crypt_crypt" = yes; then :
|
||||
py_cv_module__crypt=yes
|
||||
else
|
||||
py_cv_module__crypt=missing
|
||||
fi
|
||||
else
|
||||
py_cv_module__crypt=disabled
|
||||
fi
|
||||
|
||||
fi
|
||||
as_fn_append MODULE_BLOCK "MODULE__CRYPT_STATE=$py_cv_module__crypt$as_nl"
|
||||
if test "x$py_cv_module__crypt" = xyes; then :
|
||||
|
||||
as_fn_append MODULE_BLOCK "MODULE__CRYPT_CFLAGS=$LIBCRYPT_CFLAGS$as_nl"
|
||||
as_fn_append MODULE_BLOCK "MODULE__CRYPT_LDFLAGS=$LIBCRYPT_LIBS$as_nl"
|
||||
|
||||
fi
|
||||
if test "$py_cv_module__crypt" = yes; then
|
||||
MODULE__CRYPT_TRUE=
|
||||
MODULE__CRYPT_FALSE='#'
|
||||
else
|
||||
MODULE__CRYPT_TRUE='#'
|
||||
MODULE__CRYPT_FALSE=
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__crypt" >&5
|
||||
$as_echo "$py_cv_module__crypt" >&6; }
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes" >&5
|
||||
$as_echo_n "checking for stdlib extension module _ctypes... " >&6; }
|
||||
if test "$py_cv_module__ctypes" != "n/a"; then :
|
||||
|
@ -28046,10 +27710,6 @@ if test -z "${MODULE__BLAKE2_TRUE}" && test -z "${MODULE__BLAKE2_FALSE}"; then
|
|||
as_fn_error $? "conditional \"MODULE__BLAKE2\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${MODULE__CRYPT_TRUE}" && test -z "${MODULE__CRYPT_FALSE}"; then
|
||||
as_fn_error $? "conditional \"MODULE__CRYPT\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${MODULE__CTYPES_TRUE}" && test -z "${MODULE__CTYPES_FALSE}"; then
|
||||
as_fn_error $? "conditional \"MODULE__CTYPES\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
|
|
50
configure.ac
50
configure.ac
|
@ -2810,7 +2810,7 @@ AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.])
|
|||
|
||||
# checks for header files
|
||||
AC_CHECK_HEADERS([ \
|
||||
alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \
|
||||
alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \
|
||||
ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/memfd.h \
|
||||
linux/random.h linux/soundcard.h \
|
||||
linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \
|
||||
|
@ -5049,48 +5049,6 @@ AC_CHECK_FUNCS(setpgrp,
|
|||
# check for namespace functions
|
||||
AC_CHECK_FUNCS([setns unshare])
|
||||
|
||||
dnl We search for both crypt and crypt_r as one or the other may be defined
|
||||
dnl libxcrypt provides <crypt.h> and libcrypt with crypt_r() since
|
||||
dnl at least 3.1.1 from 2015.
|
||||
dnl FreeBSD defines crypt_r() in <unistd.h>
|
||||
AH_TEMPLATE([HAVE_CRYPT_R], [Define if you have the crypt_r() function.])
|
||||
|
||||
PKG_CHECK_MODULES([LIBCRYPT], [libxcrypt >= 3.1.1], [
|
||||
AC_DEFINE([HAVE_CRYPT_R], [1])
|
||||
], [
|
||||
WITH_SAVE_ENV([
|
||||
AC_SEARCH_LIBS([crypt_r], [crypt], [
|
||||
AC_DEFINE([HAVE_CRYPT_R], [1])
|
||||
if test "$ac_cv_search_crypt_r" = "none required"; then
|
||||
libcrypt=
|
||||
else
|
||||
libcrypt="$ac_cv_search_crypt_r"
|
||||
fi
|
||||
LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt}
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
WITH_SAVE_ENV([
|
||||
CPPFLAGS="$CPPFLAGS $LIBCRYPT_CFLAGS"
|
||||
LIBS="$LIBCRYPT_LIBS $LIBS"
|
||||
AC_CACHE_CHECK([for crypt or crypt_r], [ac_cv_crypt_crypt], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
], [
|
||||
#ifdef HAVE_CRYPT_R
|
||||
void *x = crypt_r;
|
||||
#else
|
||||
void *x = crypt;
|
||||
#endif
|
||||
])
|
||||
], [ac_cv_crypt_crypt=yes], [ac_cv_crypt_crypt=no])
|
||||
])
|
||||
])
|
||||
|
||||
AC_CHECK_FUNCS(clock_gettime, [], [
|
||||
AC_CHECK_LIB(rt, clock_gettime, [
|
||||
LIBS="$LIBS -lrt"
|
||||
|
@ -7060,10 +7018,9 @@ AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
|
|||
|
||||
# stdlib not available
|
||||
dnl Modules that are not available on some platforms
|
||||
dnl VxWorks does not provide crypt() function
|
||||
AS_CASE([$ac_sys_system],
|
||||
[AIX], [PY_STDLIB_MOD_SET_NA([_scproxy])],
|
||||
[VxWorks*], [PY_STDLIB_MOD_SET_NA([_scproxy], [_crypt], [termios], [grp])],
|
||||
[VxWorks*], [PY_STDLIB_MOD_SET_NA([_scproxy], [termios], [grp])],
|
||||
dnl The _scproxy module is available on macOS
|
||||
[Darwin], [],
|
||||
[CYGWIN*], [PY_STDLIB_MOD_SET_NA([_scproxy])],
|
||||
|
@ -7271,9 +7228,6 @@ PY_STDLIB_MOD([_blake2],
|
|||
[test "$with_builtin_blake2" = yes], [],
|
||||
[$LIBB2_CFLAGS], [$LIBB2_LIBS])
|
||||
|
||||
PY_STDLIB_MOD([_crypt],
|
||||
[], [test "$ac_cv_crypt_crypt" = yes],
|
||||
[$LIBCRYPT_CFLAGS], [$LIBCRYPT_LIBS])
|
||||
PY_STDLIB_MOD([_ctypes],
|
||||
[], [test "$have_libffi" = yes],
|
||||
[$NO_STRICT_OVERFLOW_CFLAGS $LIBFFI_CFLAGS], [$LIBFFI_LIBS])
|
||||
|
|
|
@ -175,12 +175,6 @@
|
|||
/* Define to 1 if you have the `copy_file_range' function. */
|
||||
#undef HAVE_COPY_FILE_RANGE
|
||||
|
||||
/* Define to 1 if you have the <crypt.h> header file. */
|
||||
#undef HAVE_CRYPT_H
|
||||
|
||||
/* Define if you have the crypt_r() function. */
|
||||
#undef HAVE_CRYPT_R
|
||||
|
||||
/* Define to 1 if you have the `ctermid' function. */
|
||||
#undef HAVE_CTERMID
|
||||
|
||||
|
|
Loading…
Reference in New Issue