[Python-checkins] gh-104773: PEP 594: Remove the crypt module (#104908)
vstinner
webhook-mailer at python.org
Thu May 25 09:45:54 EDT 2023
https://github.com/python/cpython/commit/e4127eaa1ea9104be0a1d9d9e147d50ba88f59aa
commit: e4127eaa1ea9104be0a1d9d9e147d50ba88f59aa
branch: main
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2023-05-25T15:45:46+02:00
summary:
gh-104773: PEP 594: Remove the crypt module (#104908)
Remove the crypt module and its private _crypt extension, deprecated
in Python 3.11.
files:
A Misc/NEWS.d/next/Library/2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst
D Doc/library/crypt.rst
D Lib/crypt.py
D Lib/test/test_crypt.py
D Modules/_cryptmodule.c
D Modules/clinic/_cryptmodule.c.h
M Doc/library/crypto.rst
M Doc/library/pwd.rst
M Doc/library/superseded.rst
M Doc/license.rst
M Doc/whatsnew/3.11.rst
M Doc/whatsnew/3.12.rst
M Doc/whatsnew/3.13.rst
M Doc/whatsnew/3.3.rst
M Doc/whatsnew/3.6.rst
M Doc/whatsnew/3.7.rst
M Doc/whatsnew/3.9.rst
M Lib/test/test___all__.py
M Misc/NEWS.d/3.12.0a1.rst
M Misc/NEWS.d/3.9.0a1.rst
M Modules/Setup
M Modules/Setup.stdlib.in
M Python/stdlib_module_names.h
M Tools/wasm/Setup.local.example
M Tools/wasm/wasm_assets.py
M configure
M configure.ac
M pyconfig.h.in
diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst
deleted file mode 100644
index 740084b40c5ac..0000000000000
--- a/Doc/library/crypt.rst
+++ /dev/null
@@ -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 at virginia.edu>
-.. sectionauthor:: Steven D. Majewski <sdm7g at virginia.edu>
-.. sectionauthor:: Peter Funk <pf at 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")
diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst
index ae45549a6d894..5a3b7a807213f 100644
--- a/Doc/library/crypto.rst
+++ b/Doc/library/crypto.rst
@@ -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:
diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst
index 25aa8b82754de..300419301b9ff 100644
--- a/Doc/library/pwd.rst
+++ b/Doc/library/pwd.rst
@@ -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
diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst
index 1e7b3787f06e0..284716e8845de 100644
--- a/Doc/library/superseded.rst
+++ b/Doc/library/superseded.rst
@@ -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
diff --git a/Doc/license.rst b/Doc/license.rst
index 005d048b6eb20..947a9b1a8c5ac 100644
--- a/Doc/license.rst
+++ b/Doc/license.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
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 2382500960caa..efff13211c798 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -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` |
+---------------------+---------------------+---------------------+---------------------+---------------------+
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 0e4ccab14bafc..f01cc27f70622 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -923,7 +923,7 @@ Modules (see :pep:`594`):
* :mod:`!cgi`
* :mod:`!cgitb`
* :mod:`chunk`
-* :mod:`crypt`
+* :mod:`!crypt`
* :mod:`imghdr`
* :mod:`!mailcap`
* :mod:`!msilib`
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index bfd0995752b24..f570e0354daf6 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -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
======================
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst
index b25cf3673d1c4..3dca7227a91c3 100644
--- a/Doc/whatsnew/3.3.rst
+++ b/Doc/whatsnew/3.3.rst
@@ -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`)
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
index 944da78e9184b..b45dc80820c9d 100644
--- a/Doc/whatsnew/3.6.rst
+++ b/Doc/whatsnew/3.6.rst
@@ -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`.)
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 8b4aa17c21402..93915b2030e17 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -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`.)
diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index a1a4bf32b9b32..6656779e1a1ba 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -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;
diff --git a/Lib/crypt.py b/Lib/crypt.py
deleted file mode 100644
index de4a14a388476..0000000000000
--- a/Lib/crypt.py
+++ /dev/null
@@ -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
diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py
index ecf73b3ad1beb..6b0e2b020d0bc 100644
--- a/Lib/test/test___all__.py
+++ b/Lib/test/test___all__.py
@@ -13,9 +13,9 @@
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):
diff --git a/Lib/test/test_crypt.py b/Lib/test/test_crypt.py
deleted file mode 100644
index b2a5ce6db0919..0000000000000
--- a/Lib/test/test_crypt.py
+++ /dev/null
@@ -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)
-
-
- at unittest.skipUnless(sys.platform == 'win32', 'This should only run on windows')
- at unittest.skipIf(crypt, 'import succeeded')
-class TestWhyCryptDidNotImport(unittest.TestCase):
-
- def test_import_failure_message(self):
- self.assertIn('not supported', IMPORT_ERROR)
-
-
- at 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()
diff --git a/Misc/NEWS.d/3.12.0a1.rst b/Misc/NEWS.d/3.12.0a1.rst
index 2e1d39b0c7996..d706343adf583 100644
--- a/Misc/NEWS.d/3.12.0a1.rst
+++ b/Misc/NEWS.d/3.12.0a1.rst
@@ -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.
diff --git a/Misc/NEWS.d/3.9.0a1.rst b/Misc/NEWS.d/3.9.0a1.rst
index f75d42285cf11..5ae14293df3e3 100644
--- a/Misc/NEWS.d/3.9.0a1.rst
+++ b/Misc/NEWS.d/3.9.0a1.rst
@@ -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.
diff --git a/Misc/NEWS.d/next/Library/2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst b/Misc/NEWS.d/next/Library/2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst
new file mode 100644
index 0000000000000..d5443aef80d48
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst
@@ -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.
diff --git a/Modules/Setup b/Modules/Setup
index 05d037bdca922..7953913694d83 100644
--- a/Modules/Setup
+++ b/Modules/Setup
@@ -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
diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index ef3c5644fd0fd..e244efcad4995 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -106,8 +106,6 @@
# Modules with some UNIX dependencies
#
-# needs -lcrypt on some systems
- at MODULE__CRYPT_TRUE@_crypt _cryptmodule.c
@MODULE_FCNTL_TRUE at fcntl fcntlmodule.c
@MODULE_GRP_TRUE at grp grpmodule.c
@MODULE_MMAP_TRUE at mmap mmapmodule.c
diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c
deleted file mode 100644
index 75035084c9cd2..0000000000000
--- a/Modules/_cryptmodule.c
+++ /dev/null
@@ -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);
-}
diff --git a/Modules/clinic/_cryptmodule.c.h b/Modules/clinic/_cryptmodule.c.h
deleted file mode 100644
index 97b70b3c17e9a..0000000000000
--- a/Modules/clinic/_cryptmodule.c.h
+++ /dev/null
@@ -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]*/
diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h
index f2d3ecb975356..00742b39a327c 100644
--- a/Python/stdlib_module_names.h
+++ b/Python/stdlib_module_names.h
@@ -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",
diff --git a/Tools/wasm/Setup.local.example b/Tools/wasm/Setup.local.example
index ad58c31a2efe3..e3778c94ad0c8 100644
--- a/Tools/wasm/Setup.local.example
+++ b/Tools/wasm/Setup.local.example
@@ -3,7 +3,6 @@
_asyncio
audioop
_bz2
-_crypt
_decimal
_pickle
pyexpat _elementtree
diff --git a/Tools/wasm/wasm_assets.py b/Tools/wasm/wasm_assets.py
index c3db5d203498d..5e59ee7ef3752 100755
--- a/Tools/wasm/wasm_assets.py
+++ b/Tools/wasm/wasm_assets.py
@@ -81,7 +81,6 @@
OMIT_MODULE_FILES = {
"_asyncio": ["asyncio/"],
"audioop": ["aifc.py", "wave.py"],
- "_crypt": ["crypt.py"],
"_curses": ["curses/"],
"_ctypes": ["ctypes/"],
"_decimal": ["decimal.py"],
diff --git a/configure b/configure
index ab35842179d42..319b06d5e4c93 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/configure.ac b/configure.ac
index 09e5eff2c5332..587d1034514c6 100644
--- a/configure.ac
+++ b/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])
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 46b3448b40409..694fea93cf7a5 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -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
More information about the Python-checkins
mailing list