From 7dab8f253d0c1bcdbc1f478b6317676285fd09e1 Mon Sep 17 00:00:00 2001 From: shixuantong Date: Mon, 4 Nov 2024 19:28:15 +0800 Subject: [PATCH] Ensure random passwords contain multiple character types --- ...om-passwords-contain-multiple-charac.patch | 146 ++++++++++++++++++ ...te-judgment-conditions-in-password-g.patch | 31 ++++ cloud-init.spec | 7 +- 3 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 backport-feat-Ensure-random-passwords-contain-multiple-charac.patch create mode 100644 backport-test-Fix-duplicate-judgment-conditions-in-password-g.patch diff --git a/backport-feat-Ensure-random-passwords-contain-multiple-charac.patch b/backport-feat-Ensure-random-passwords-contain-multiple-charac.patch new file mode 100644 index 0000000..d24e1c8 --- /dev/null +++ b/backport-feat-Ensure-random-passwords-contain-multiple-charac.patch @@ -0,0 +1,146 @@ +From 879945f56103d937a7fee84bfe7662dc2a5be708 Mon Sep 17 00:00:00 2001 +From: sxt1001 +Date: Thu, 17 Oct 2024 20:45:07 +0800 +Subject: [PATCH] feat: Ensure random passwords contain multiple +character + types (#5815) + +Reference:https://github.com/canonical/cloud-init/commit/879945f56103d937a7fee84bfe7662dc2a5be708 +Conflict:(1)change cloudinit/config/tests/test_set_passwords.py not +tests/unittests/config/test_cc_set_passwords.py +(2)add "import pytest" for test_set_passwords.py + +The complexity of the random password generated by the +rand_user_password() method may not meet the security configuration +requirements of the system authentication module. This can cause +chpasswd to fail. + +This commit ensures we generate a password using 4 different character +classes. + +Fixes GH-5814 + +Co-authored-by: James Falcon +--- + cloudinit/config/cc_set_passwords.py | 35 ++++++++++++++---- + cloudinit/config/tests/test_set_passwords.py | 38 ++++++++++++++++++++ + 2 files changed, 66 insertions(+), 7 deletions(-) + +diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py +index d409447..c032f3c 100755 +--- a/cloudinit/config/cc_set_passwords.py ++++ b/cloudinit/config/cc_set_passwords.py +@@ -78,20 +78,16 @@ password. + """ + + import re ++import random ++import string + + from cloudinit.distros import ug_util + from cloudinit import log as logging + from cloudinit.ssh_util import update_ssh_config + from cloudinit import util + +-from string import ascii_letters, digits +- + LOG = logging.getLogger(__name__) + +-# We are removing certain 'painful' letters/numbers +-PW_SET = (''.join([x for x in ascii_letters + digits +- if x not in 'loLOI01'])) +- + + def handle_ssh_pwauth(pw_auth, service_cmd=None, service_name="ssh"): + """Apply sshd PasswordAuthentication changes. +@@ -238,7 +234,32 @@ def handle(_name, cfg, cloud, log, args): + + + def rand_user_password(pwlen=20): +- return util.rand_str(pwlen, select_from=PW_SET) ++ if pwlen < 4: ++ raise ValueError("Password length must be at least 4 characters.") ++ ++ # There are often restrictions on the minimum number of character ++ # classes required in a password, so ensure we at least one character ++ # from each class. ++ res_rand_list = [ ++ random.choice(string.digits), ++ random.choice(string.ascii_lowercase), ++ random.choice(string.ascii_uppercase), ++ random.choice(string.punctuation), ++ ] ++ ++ res_rand_list.extend( ++ list( ++ util.rand_str( ++ pwlen - len(res_rand_list), ++ select_from=string.digits ++ + string.ascii_lowercase ++ + string.ascii_uppercase ++ + string.punctuation, ++ ) ++ ) ++ ) ++ random.shuffle(res_rand_list) ++ return "".join(res_rand_list) + + + def chpasswd(distro, plist_in, hashed=False): +diff --git a/cloudinit/config/tests/test_set_passwords.py b/cloudinit/config/tests/test_set_passwords.py +index 1350c34..49842a1 100644 +--- a/cloudinit/config/tests/test_set_passwords.py ++++ b/cloudinit/config/tests/test_set_passwords.py +@@ -1,6 +1,7 @@ + # This file is part of cloud-init. See LICENSE file for license information. + + import mock ++import pytest + + from cloudinit.config import cc_set_passwords as setpass + from cloudinit.tests.helpers import CiTestCase +@@ -170,4 +171,41 @@ class TestSetPasswordsHandle(CiTestCase): + else: + self.fail("Password not emitted to console") + ++class TestRandUserPassword: ++ def _get_str_class_num(self, str): ++ return sum( ++ [ ++ any(c.islower() for c in str), ++ any(c.isupper() for c in str), ++ any(c.isupper() for c in str), ++ any(c in string.punctuation for c in str), ++ ] ++ ) ++ ++ @pytest.mark.parametrize( ++ "strlen, expected_result", ++ [ ++ (1, ValueError), ++ (2, ValueError), ++ (3, ValueError), ++ (4, 4), ++ (5, 4), ++ (5, 4), ++ (6, 4), ++ (20, 4), ++ ], ++ ) ++ def test_rand_user_password(self, strlen, expected_result): ++ if expected_result is ValueError: ++ with pytest.raises( ++ expected_result, ++ match="Password length must be at least 4 characters.", ++ ): ++ setpass.rand_user_password(strlen) ++ else: ++ rand_password = setpass.rand_user_password(strlen) ++ assert len(rand_password) == strlen ++ assert self._get_str_class_num(rand_password) == expected_result ++ ++ + # vi: ts=4 expandtab +-- +2.27.0 + diff --git a/backport-test-Fix-duplicate-judgment-conditions-in-password-g.patch b/backport-test-Fix-duplicate-judgment-conditions-in-password-g.patch new file mode 100644 index 0000000..1f8cbc4 --- /dev/null +++ b/backport-test-Fix-duplicate-judgment-conditions-in-password-g.patch @@ -0,0 +1,31 @@ +From 4c156a80375c01433cdd00546c6278edb0bb6025 Mon Sep 17 00:00:00 2001 +From: sxt1001 +Date: Mon, 21 Oct 2024 23:40:25 +0800 +Subject: [PATCH] test: Fix duplicate judgment conditions in password + generation (#5835) + +Reference:https://github.com/canonical/cloud-init/commit/4c156a80375c01433cdd00546c6278edb0bb6025 +Conflict:NA + +The problem was introduced by commit 879945f +--- + cloudinit/config/tests/test_set_passwords.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cloudinit/config/tests/test_set_passwords.py b/cloudinit/config/tests/test_set_passwords.py +index 73cb3d490..c068f62d8 100644 +--- a/cloudinit/config/tests/test_set_passwords.py ++++ b/cloudinit/config/tests/test_set_passwords.py +@@ -566,7 +566,7 @@ class TestRandUserPassword: + [ + any(c.islower() for c in str), + any(c.isupper() for c in str), +- any(c.isupper() for c in str), ++ any(c.isdigit() for c in str), + any(c in string.punctuation for c in str), + ] + ) +-- +2.33.0 + + diff --git a/cloud-init.spec b/cloud-init.spec index a6410dd..2d724d4 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -1,6 +1,6 @@ Name: cloud-init Version: 19.4 -Release: 14 +Release: 15 Summary: the defacto multi-distribution package that handles early initialization of a cloud instance. License: ASL 2.0 or GPLv3 URL: http://launchpad.net/cloud-init @@ -25,6 +25,8 @@ Patch14: backport-Create-the-log-file-with-640-permissions-858.patch Patch15: backport-CVE-2023-1786-Make-user-vendor-data-sensitive-and-remove-log-permi.patch Patch16: backport-fix-Don-t-loosen-the-permissions-of-the-log-file.patch Patch17: backport-add-get_permissions-get_owner-get_group-get_user_gro.patch +Patch18: backport-feat-Ensure-random-passwords-contain-multiple-charac.patch +Patch19: backport-test-Fix-duplicate-judgment-conditions-in-password-g.patch Patch9000: Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch @@ -133,6 +135,9 @@ fi %exclude /usr/share/doc/* %changelog +* Mon Nov 04 2024 shixuantong - 19.4-15 +- Ensure random passwords contain multiple character types + * Thu Dec 14 2023 shixuantong - 19.4-14 - fix: Don't loosen the permissions of the log file -- Gitee