Ensure random passwords contain multiple character types
This commit is contained in:
parent
755d91c931
commit
c5ad5566ab
@ -0,0 +1,140 @@
|
|||||||
|
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:NA
|
||||||
|
|
||||||
|
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 | 33 +++++++++++++---
|
||||||
|
.../unittests/config/test_cc_set_passwords.py | 38 +++++++++++++++++++
|
||||||
|
2 files changed, 66 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py
|
||||||
|
index 24d8267..d46c7f2 100644
|
||||||
|
--- a/cloudinit/config/cc_set_passwords.py
|
||||||
|
+++ b/cloudinit/config/cc_set_passwords.py
|
||||||
|
@@ -9,7 +9,8 @@
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
-from string import ascii_letters, digits
|
||||||
|
+import random
|
||||||
|
+import string
|
||||||
|
from textwrap import dedent
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
@@ -89,9 +90,6 @@ __doc__ = get_meta_doc(meta)
|
||||||
|
|
||||||
|
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 get_users_by_type(users_list: list, pw_type: str) -> list:
|
||||||
|
"""either password or type: RANDOM is required, user is always required"""
|
||||||
|
@@ -307,4 +305,29 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
diff --git a/tests/unittests/config/test_cc_set_passwords.py b/tests/unittests/config/test_cc_set_passwords.py
|
||||||
|
index ef34a8c..b5d561c 100644
|
||||||
|
--- a/tests/unittests/config/test_cc_set_passwords.py
|
||||||
|
+++ b/tests/unittests/config/test_cc_set_passwords.py
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
# This file is part of cloud-init. See LICENSE file for license information.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
+import string
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
@@ -555,6 +556,43 @@ class TestExpire:
|
||||||
|
assert "Expired passwords" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
+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
|
||||||
|
+
|
||||||
|
+
|
||||||
|
class TestSetPasswordsSchema:
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"config, expectation",
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
@ -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
|
||||||
|
---
|
||||||
|
tests/unittests/config/test_cc_set_passwords.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/config/test_cc_set_passwords.py b/tests/unittests/config/test_cc_set_passwords.py
|
||||||
|
index 73cb3d490..c068f62d8 100644
|
||||||
|
--- a/tests/unittests/config/test_cc_set_passwords.py
|
||||||
|
+++ b/tests/unittests/config/test_cc_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
|
||||||
|
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
Name: cloud-init
|
Name: cloud-init
|
||||||
Version: 23.4.1
|
Version: 23.4.1
|
||||||
Release: 8
|
Release: 9
|
||||||
Summary: the defacto multi-distribution package that handles early initialization of a cloud instance.
|
Summary: the defacto multi-distribution package that handles early initialization of a cloud instance.
|
||||||
License: ASL 2.0 or GPLv3
|
License: ASL 2.0 or GPLv3
|
||||||
URL: http://launchpad.net/cloud-init
|
URL: http://launchpad.net/cloud-init
|
||||||
@ -29,6 +29,8 @@ Patch6011: backport-fix-netplan-Fix-predictable-interface-rename-issue-5.patch
|
|||||||
Patch6012: backport-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch
|
Patch6012: backport-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch
|
||||||
Patch6013: backport-fix-openstack-Fix-bond-mac_address-5369.patch
|
Patch6013: backport-fix-openstack-Fix-bond-mac_address-5369.patch
|
||||||
Patch6014: backport-fix-net-klibc-ipconfig-PROTO-compatibility-5437.patch
|
Patch6014: backport-fix-net-klibc-ipconfig-PROTO-compatibility-5437.patch
|
||||||
|
Patch6015: backport-feat-Ensure-random-passwords-contain-multiple-charac.patch
|
||||||
|
Patch6016: backport-test-Fix-duplicate-judgment-conditions-in-password-g.patch
|
||||||
|
|
||||||
Patch9000: do-not-generate-dsa.patch
|
Patch9000: do-not-generate-dsa.patch
|
||||||
|
|
||||||
@ -161,6 +163,12 @@ fi
|
|||||||
%exclude /usr/share/doc/*
|
%exclude /usr/share/doc/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Nov 04 2024 shixuantong <shixuantong1@huawei.com> - 23.4.1-9
|
||||||
|
- Type:bugfix
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:Ensure random passwords contain multiple character types
|
||||||
|
|
||||||
* Thu Sep 5 2024 dongyuzhen <dongyuzhen@h-partners.com> - 23.4.1-8
|
* Thu Sep 5 2024 dongyuzhen <dongyuzhen@h-partners.com> - 23.4.1-8
|
||||||
- Type:bugfix
|
- Type:bugfix
|
||||||
- CVE:NA
|
- CVE:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user