From e4127eaa1ea9104be0a1d9d9e147d50ba88f59aa Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 25 May 2023 15:45:46 +0200 Subject: gh-104773: PEP 594: Remove the crypt module (#104908) Remove the crypt module and its private _crypt extension, deprecated in Python 3.11. --- Doc/library/crypt.rst | 182 ----------- Doc/library/crypto.rst | 1 - Doc/library/pwd.rst | 4 +- Doc/library/superseded.rst | 1 - Doc/license.rst | 2 +- Doc/whatsnew/3.11.rst | 2 +- Doc/whatsnew/3.12.rst | 2 +- Doc/whatsnew/3.13.rst | 16 + Doc/whatsnew/3.3.rst | 4 +- Doc/whatsnew/3.6.rst | 2 +- Doc/whatsnew/3.7.rst | 4 +- Doc/whatsnew/3.9.rst | 2 +- Lib/crypt.py | 124 -------- Lib/test/test___all__.py | 4 +- Lib/test/test_crypt.py | 112 ------- Misc/NEWS.d/3.12.0a1.rst | 2 +- Misc/NEWS.d/3.9.0a1.rst | 2 +- .../2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst | 2 + Modules/Setup | 4 - Modules/Setup.stdlib.in | 2 - Modules/_cryptmodule.c | 81 ----- Modules/clinic/_cryptmodule.c.h | 69 ----- Python/stdlib_module_names.h | 2 - Tools/wasm/Setup.local.example | 1 - Tools/wasm/wasm_assets.py | 1 - configure | 342 +-------------------- configure.ac | 50 +-- pyconfig.h.in | 6 - 28 files changed, 35 insertions(+), 991 deletions(-) delete mode 100644 Doc/library/crypt.rst delete mode 100644 Lib/crypt.py delete mode 100644 Lib/test/test_crypt.py create mode 100644 Misc/NEWS.d/next/Library/2023-05-25-00-53-08.gh-issue-104773.Iyjtt0.rst delete mode 100644 Modules/_cryptmodule.c delete mode 100644 Modules/clinic/_cryptmodule.c.h diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst deleted file mode 100644 index 740084b..0000000 --- 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 -.. sectionauthor:: Steven D. Majewski -.. sectionauthor:: Peter Funk - -**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 ae45549..5a3b7a8 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 25aa8b8..3004193 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 1e7b378..284716e 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 005d048..947a9b1 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 2382500..efff132 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 0e4ccab..f01cc27 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 bfd0995..f570e03 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 `_: + Modern password hashing for your software and your servers. + * `passlib `_: + Comprehensive password hashing framework supporting over 30 schemes. + * `argon2-cffi `_: + The secure Argon2 password hashing algorithm. + * `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 b25cf36..3dca722 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 944da78..b45dc80 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 8b4aa17..93915b2 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 a1a4bf3..6656779 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 de4a14a..0000000 --- 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 ''.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 ecf73b3..6b0e2b0 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -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): diff --git a/Lib/test/test_crypt.py b/Lib/test/test_crypt.py deleted file mode 100644 index b2a5ce6..0000000 --- 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) - - -@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() diff --git a/Misc/NEWS.d/3.12.0a1.rst b/Misc/NEWS.d/3.12.0a1.rst index 2e1d39b..d706343 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 f75d422..5ae1429 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 0000000..d5443ae --- /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 05d037b..7953913 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 ef3c564..e244efc 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 -@MODULE__CRYPT_TRUE@_crypt _cryptmodule.c @MODULE_FCNTL_TRUE@fcntl fcntlmodule.c @MODULE_GRP_TRUE@grp grpmodule.c @MODULE_MMAP_TRUE@mmap mmapmodule.c diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c deleted file mode 100644 index 7503508..0000000 --- a/Modules/_cryptmodule.c +++ /dev/null @@ -1,81 +0,0 @@ -/* cryptmodule.c - by Steve Majewski - */ - -#include "Python.h" - -#include -#ifdef HAVE_CRYPT_H -#include -#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 97b70b3..0000000 --- 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 f2d3ecb..00742b3 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 ad58c31..e3778c9 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 c3db5d2..5e59ee7 100755 --- a/Tools/wasm/wasm_assets.py +++ b/Tools/wasm/wasm_assets.py @@ -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"], diff --git a/configure b/configure index ab35842..319b06d 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 - #endif - #include - -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 09e5eff..587d103 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 and libcrypt with crypt_r() since -dnl at least 3.1.1 from 2015. -dnl FreeBSD defines crypt_r() in -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 - #endif - #include - ], [ - #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 46b3448..694fea9 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 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 -- cgit v0.12