Make the crypt module optional. Fix #67

The python stdlid crypt module is deprecated since version 3.11 and
will be removed in version 3.13. Check for the availability of the
crypt module.
All password checks using the crypt module will stop to work on
python 3.13.
This commit is contained in:
Valentin Samir 2024-08-18 12:56:48 +02:00
parent 437fdd05e4
commit 30f2358db8
4 changed files with 36 additions and 9 deletions

View file

@ -15,6 +15,16 @@ Added
* Support for Django 4.2
* Allow forms to be overridden from settings
Deprecated
----------
* Make the crypt module optional and deprecate it's usage.
The python stdlid crypt module is deprecated since version 3.11 and
will be removed in version 3.13. Check for the availability of the
crypt module.
All password checks using the crypt module will stop to work on
python 3.13.
v2.0.0 - 2022-10-17
===================

View file

@ -383,16 +383,17 @@ Only useful if you are using the mysql authentication backend:
* ``CAS_SQL_PASSWORD_CHECK``: The method used to check the user password. Must be one of the following:
* ``"crypt"`` (see <https://en.wikipedia.org/wiki/Crypt_(C)>), the password in the database
should begin with $
should begin with $. This method is deprecated and will stop to work in python 3.13.
* ``"ldap"`` (see https://tools.ietf.org/id/draft-stroeder-hashed-userpassword-values-01.html)
the password in the database must begin with one of {MD5}, {SMD5}, {SHA}, {SSHA}, {SHA256},
{SSHA256}, {SHA384}, {SSHA384}, {SHA512}, {SSHA512}, {CRYPT}.
{SSHA256}, {SHA384}, {SSHA384}, {SHA512}, {SSHA512}, {CRYPT}. {CRYPT} is deprecated
and will stop to work in python 3.13.
* ``"hex_HASH_NAME"`` with ``HASH_NAME`` in md5, sha1, sha224, sha256, sha384, sha512.
The hashed password in the database is compared to the hexadecimal digest of the clear
password hashed with the corresponding algorithm.
* ``"plain"``, the password in the database must be in clear.
The default is ``"crypt"``.
The default is ``"crypt"``. This default is deprecated and will stop to work in python 3.13.
Sql backend settings
@ -409,16 +410,18 @@ used by the sql backend.
* ``CAS_SQL_PASSWORD_CHECK``: The method used to check the user password. Must be one of the following:
* ``"crypt"`` (see <https://en.wikipedia.org/wiki/Crypt_(C)>), the password in the database
should begin with $
should begin with $. This method is deprecated and will stop to work in python 3.13.
* ``"ldap"`` (see https://tools.ietf.org/id/draft-stroeder-hashed-userpassword-values-01.html)
the password in the database must begin with one of {MD5}, {SMD5}, {SHA}, {SSHA}, {SHA256},
{SSHA256}, {SHA384}, {SSHA384}, {SHA512}, {SSHA512}, {CRYPT}.
{SSHA256}, {SHA384}, {SSHA384}, {SHA512}, {SSHA512}, {CRYPT}. {CRYPT} is deprecated
and will stop to work in python 3.13.
* ``"hex_HASH_NAME"`` with ``HASH_NAME`` in md5, sha1, sha224, sha256, sha384, sha512.
The hashed password in the database is compared to the hexadecimal digest of the clear
password hashed with the corresponding algorithm.
* ``"plain"``, the password in the database must be in clear.
The default is ``"crypt"``.
The default is ``"crypt"``. This default is deprecated and will stop to work in python 3.13.
* ``CAS_SQL_PASSWORD_CHARSET``: Charset the SQL users passwords was hash with. This is needed to
encode the user submitted password before hashing it for comparison. The default is ``"utf-8"``.
@ -439,10 +442,11 @@ Only useful if you are using the ldap authentication backend:
* ``CAS_LDAP_PASSWORD_CHECK``: The method used to check the user password. Must be one of the following:
* ``"crypt"`` (see <https://en.wikipedia.org/wiki/Crypt_(C)>), the password in the database
should begin with $
should begin with $. This method is deprecated and will stop to work in python 3.13.
* ``"ldap"`` (see https://tools.ietf.org/id/draft-stroeder-hashed-userpassword-values-01.html)
the password in the database must begin with one of {MD5}, {SMD5}, {SHA}, {SSHA}, {SHA256},
{SSHA256}, {SHA384}, {SSHA384}, {SHA512}, {SSHA512}, {CRYPT}.
{SSHA256}, {SHA384}, {SSHA384}, {SHA512}, {SSHA512}, {CRYPT}. {CRYPT} is deprecated and
will stop to work in python 3.13.
* ``"hex_HASH_NAME"`` with ``HASH_NAME`` in md5, sha1, sha224, sha256, sha384, sha512.
The hashed password in the database is compared to the hexadecimal digest of the clear
password hashed with the corresponding algorithm.

View file

@ -63,6 +63,9 @@ class CheckPasswordCase(TestCase):
def test_crypt(self):
"""test the crypt auth method"""
# Only run test if crypt is available
if utils.crypt is None:
return
salts = ["$6$UVVAQvrMyXMF3FF3", "aa"]
hashed_password1 = []
for salt in salts:

View file

@ -30,13 +30,17 @@ import random
import string
import json
import hashlib
import crypt
import base64
import six
import requests
import time
import logging
import binascii
# The crypt module is deprecated and will be removed in version 3.13
try:
import crypt
except ImportError:
crypt = None
from importlib import import_module
from datetime import datetime, timedelta
@ -411,6 +415,8 @@ def crypt_salt_is_valid(salt):
:return: ``True`` if ``salt`` is a valid crypt salt on this system, ``False`` otherwise
:rtype: bool
"""
if crypt is None:
return False
if len(salt) < 2:
return False
else:
@ -567,6 +573,8 @@ class LdapHashUserPassword(object):
cls._schemes_to_hash[scheme](password + salt).digest() + salt
)
except KeyError:
if crypt is None:
raise cls.BadScheme("Crypt is not available on the system")
if six.PY3:
password = password.decode(charset)
salt = salt.decode(charset)
@ -646,6 +654,8 @@ def check_password(method, password, hashed_password, charset):
if method == "plain":
return password == hashed_password
elif method == "crypt":
if crypt is None:
raise ValueError("Crypt is not available on the system")
if hashed_password.startswith(b'$'):
salt = b'$'.join(hashed_password.split(b'$', 3)[:-1])
elif hashed_password.startswith(b'_'): # pragma: no cover old BSD format not supported