-
Notifications
You must be signed in to change notification settings - Fork 374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use legacycrypt instead of crypt on Python >= 3.13 #3070
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
# Requires Python 2.6+ and Openssl 1.0+ | ||
# | ||
|
||
import array | ||
import base64 | ||
import datetime | ||
import errno | ||
|
@@ -26,23 +27,33 @@ | |
import os | ||
import platform | ||
import pwd | ||
import random | ||
import re | ||
import shutil | ||
import socket | ||
import string | ||
import struct | ||
import sys | ||
import time | ||
from pwd import getpwall | ||
|
||
import array | ||
from azurelinuxagent.common.exception import OSUtilError | ||
# 'crypt' was removed in Python 3.13; use legacycrypt instead | ||
if sys.version_info[0] == 3 and sys.version_info[1] >= 13 or sys.version_info[0] > 3: | ||
try: | ||
from legacycrypt import crypt | ||
except ImportError: | ||
def crypt(password, salt): | ||
raise OSUtilError("Please install the legacycrypt Python module to use this feature.") | ||
else: | ||
from crypt import crypt # pylint: disable=deprecated-module | ||
|
||
from azurelinuxagent.common import conf | ||
from azurelinuxagent.common import logger | ||
from azurelinuxagent.common.utils import fileutil | ||
from azurelinuxagent.common.utils import shellutil | ||
from azurelinuxagent.common.utils import textutil | ||
|
||
from azurelinuxagent.common.exception import OSUtilError | ||
from azurelinuxagent.common.future import ustr, array_to_bytes | ||
from azurelinuxagent.common.utils.cryptutil import CryptUtil | ||
from azurelinuxagent.common.utils.flexible_version import FlexibleVersion | ||
|
@@ -433,11 +444,21 @@ def chpasswd(self, username, password, crypt_id=6, salt_len=10): | |
if self.is_sys_user(username): | ||
raise OSUtilError(("User {0} is a system user, " | ||
"will not set password.").format(username)) | ||
passwd_hash = textutil.gen_password_hash(password, crypt_id, salt_len) | ||
passwd_hash = DefaultOSUtil.gen_password_hash(password, crypt_id, salt_len) | ||
|
||
self._run_command_raising_OSUtilError(["usermod", "-p", passwd_hash, username], | ||
err_msg="Failed to set password for {0}".format(username)) | ||
|
||
@staticmethod | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved here from textutils.py; this is a better place for this function |
||
def gen_password_hash(password, crypt_id, salt_len): | ||
collection = string.ascii_letters + string.digits | ||
salt = ''.join(random.choice(collection) for _ in range(salt_len)) | ||
salt = "${0}${1}".format(crypt_id, salt) | ||
if sys.version_info[0] == 2: | ||
# if python 2.*, encode to type 'str' to prevent Unicode Encode Error from crypt.crypt | ||
password = password.encode('utf-8') | ||
return crypt(password, salt) | ||
|
||
def get_users(self): | ||
return getpwall() | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
distro; python_version >= '3.8' | ||
pyasn1 | ||
pyasn1 | ||
legacycrypt; python_version >= '3.13' |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -314,13 +314,16 @@ def run(self): | |
|
||
|
||
# Note to packagers and users from source. | ||
# In version 3.5 of Python distribution information handling in the platform | ||
# module was deprecated. Depending on the Linux distribution the | ||
# implementation may be broken prior to Python 3.7 wher the functionality | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it was actually removed on 3.8 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question for my understanding, what is this requires does? will setup fail if these modules not present? |
||
# will be removed from Python 3 | ||
requires = [] # pylint: disable=invalid-name | ||
if sys.version_info[0] >= 3 and sys.version_info[1] >= 7: | ||
requires = ['distro'] # pylint: disable=invalid-name | ||
# * In version 3.5 of Python distribution information handling in the platform | ||
# module was deprecated. Depending on the Linux distribution the | ||
# implementation may be broken prior to Python 3.8 where the functionality | ||
# will be removed from Python 3. | ||
# * In version 3.13 of Python, the crypt module was removed and legacycrypt is | ||
# required instead. | ||
requires = [ | ||
"distro;python_version>='3.8'", | ||
"legacycrypt;python_version>='3.13'", | ||
] | ||
|
||
modules = [] # pylint: disable=invalid-name | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We provide this stub implementation in case the module is not present, otherwise the entire process will crash