Ensure random passwords contain multiple character types

This commit is contained in:
shixuantong 2024-11-04 19:28:15 +08:00
parent 3f5fd53166
commit 7dab8f253d
3 changed files with 183 additions and 1 deletions

View File

@ -0,0 +1,146 @@
From 879945f56103d937a7fee84bfe7662dc2a5be708 Mon Sep 17 00:00:00 2001
From: sxt1001 <shixuantong1@huawei.com>
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 <james.falcon@canonical.com>
---
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

View File

@ -0,0 +1,31 @@
From 4c156a80375c01433cdd00546c6278edb0bb6025 Mon Sep 17 00:00:00 2001
From: sxt1001 <shixuantong1@huawei.com>
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

View File

@ -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 <shixuantong1@huawei.com> - 19.4-15
- Ensure random passwords contain multiple character types
* Thu Dec 14 2023 shixuantong <shixuantong1@huawei.com> - 19.4-14
- fix: Don't loosen the permissions of the log file