mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
user/password: move to passlib hash.sha512_crypt to generate password hashes to replace deprecated crypt lib
This commit is contained in:
parent
f505efc8bb
commit
665592374d
6 changed files with 16 additions and 38 deletions
2
debian/control
vendored
2
debian/control
vendored
|
@ -15,7 +15,7 @@ Depends: ${python3:Depends}, ${misc:Depends}
|
|||
, python3-miniupnpc, python3-dbus, python3-jinja2
|
||||
, python3-toml, python3-packaging, python3-publicsuffix2
|
||||
, python3-ldap, python3-zeroconf (>= 0.47), python3-lexicon,
|
||||
, python3-cryptography, python3-jwt, python3-magic
|
||||
, python3-cryptography, python3-jwt, python3-passlib, python3-magic
|
||||
, python-is-python3, python3-pydantic, python3-email-validator
|
||||
, nginx, nginx-extras (>=1.22)
|
||||
, apt, apt-transport-https, apt-utils, dirmngr
|
||||
|
|
|
@ -3162,7 +3162,7 @@ def regen_mail_app_user_config_for_dovecot_and_postfix(only=None):
|
|||
dovecot = True if only in [None, "dovecot"] else False
|
||||
postfix = True if only in [None, "postfix"] else False
|
||||
|
||||
from yunohost.user import _hash_user_password
|
||||
from yunohost.utils.password import _hash_user_password
|
||||
|
||||
postfix_map = []
|
||||
dovecot_passwd = []
|
||||
|
|
|
@ -25,12 +25,12 @@ from typing import Any, Union
|
|||
import ldap
|
||||
from moulinette.utils.filesystem import read_json
|
||||
from yunohost.authenticators.ldap_ynhuser import Authenticator as Auth, user_is_allowed_on_domain
|
||||
from yunohost.user import _hash_user_password
|
||||
from yunohost.utils.error import YunohostError, YunohostValidationError
|
||||
from yunohost.utils.ldap import _get_ldap_interface, _ldap_path_extract, LDAPInterface
|
||||
from yunohost.utils.password import (
|
||||
assert_password_is_compatible,
|
||||
assert_password_is_strong_enough,
|
||||
_hash_user_password,
|
||||
)
|
||||
|
||||
logger = logging.getLogger("portal")
|
||||
|
|
|
@ -63,10 +63,10 @@ def tools_versions():
|
|||
|
||||
|
||||
def tools_rootpw(new_password, check_strength=True):
|
||||
from yunohost.user import _hash_user_password
|
||||
from yunohost.utils.password import (
|
||||
assert_password_is_strong_enough,
|
||||
assert_password_is_compatible,
|
||||
_hash_user_password,
|
||||
)
|
||||
import spwd
|
||||
|
||||
|
|
35
src/user.py
35
src/user.py
|
@ -160,6 +160,7 @@ def user_create(
|
|||
from yunohost.utils.password import (
|
||||
assert_password_is_strong_enough,
|
||||
assert_password_is_compatible,
|
||||
_hash_user_password,
|
||||
)
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
|
@ -381,6 +382,7 @@ def user_update(
|
|||
from yunohost.utils.password import (
|
||||
assert_password_is_strong_enough,
|
||||
assert_password_is_compatible,
|
||||
_hash_user_password,
|
||||
)
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
from yunohost.hook import hook_callback
|
||||
|
@ -1437,39 +1439,6 @@ def user_ssh_remove_key(username, key):
|
|||
# End SSH subcategory
|
||||
#
|
||||
|
||||
|
||||
def _hash_user_password(password):
|
||||
"""
|
||||
This function computes and return a salted hash for the password in input.
|
||||
This implementation is inspired from [1].
|
||||
|
||||
The hash follows SHA-512 scheme from Linux/glibc.
|
||||
Hence the {CRYPT} and $6$ prefixes
|
||||
- {CRYPT} means it relies on the OS' crypt lib
|
||||
- $6$ corresponds to SHA-512, the strongest hash available on the system
|
||||
|
||||
The salt is generated using random.SystemRandom(). It is the crypto-secure
|
||||
pseudo-random number generator according to the python doc [2] (c.f. the
|
||||
red square). It internally relies on /dev/urandom
|
||||
|
||||
The salt is made of 16 characters from the set [./a-zA-Z0-9]. This is the
|
||||
max sized allowed for salts according to [3]
|
||||
|
||||
[1] https://www.redpill-linpro.com/techblog/2016/08/16/ldap-password-hash.html
|
||||
[2] https://docs.python.org/2/library/random.html
|
||||
[3] https://www.safaribooksonline.com/library/view/practical-unix-and/0596003234/ch04s03.html
|
||||
"""
|
||||
|
||||
# FIXME: 'crypt' is deprecated and slated for removal in Python 3.13
|
||||
import crypt
|
||||
|
||||
char_set = string.ascii_uppercase + string.ascii_lowercase + string.digits + "./"
|
||||
salt = "".join([random.SystemRandom().choice(char_set) for x in range(16)])
|
||||
|
||||
salt = "$6$" + salt + "$"
|
||||
return "{CRYPT}" + crypt.crypt(str(password), salt)
|
||||
|
||||
|
||||
def _update_admins_group_aliases(old_main_domain, new_main_domain):
|
||||
current_admin_aliases = user_group_info("admins")["mail-aliases"]
|
||||
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import sys
|
||||
|
||||
import os
|
||||
import string
|
||||
import subprocess
|
||||
import yaml
|
||||
import passlib.hash
|
||||
|
||||
SMALL_PWD_LIST = [
|
||||
"yunohost",
|
||||
|
@ -71,6 +72,14 @@ def assert_password_is_strong_enough(profile, password):
|
|||
PasswordValidator(profile).validate(password)
|
||||
|
||||
|
||||
def _hash_user_password(password):
|
||||
import passlib
|
||||
# passlib will returns something like:
|
||||
# $6$rounds=656000$AwCIMolbTAyQhtev$46UvYfVgs.k0Bt6fLTekBHyCcCFkix/NNfgAWiICX.9YUPVYZ3PsIAwY99yP5/tXhg2sYBaAhKj6W3kuYWaR3.
|
||||
# cf https://passlib.readthedocs.io/en/stable/modular_crypt_format.html#modular-crypt-format
|
||||
return "{CRYPT}" + passlib.hash.sha512_crypt.hash(password)
|
||||
|
||||
|
||||
class PasswordValidator:
|
||||
def __init__(self, profile):
|
||||
"""
|
||||
|
|
Loading…
Add table
Reference in a new issue