diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 659921d50aa9..0adb2fe2beda 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -266,6 +266,9 @@ fi sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-device-data_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +# package for supporting password hardening +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libpam-cracklib + # Install pam-tacplus and nss-tacplus sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libtac2_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f diff --git a/src/sonic-host-services-data/templates/common-password.j2 b/src/sonic-host-services-data/templates/common-password.j2 new file mode 100644 index 000000000000..c5fd3f889c24 --- /dev/null +++ b/src/sonic-host-services-data/templates/common-password.j2 @@ -0,0 +1,43 @@ +#THIS IS AN AUTO-GENERATED FILE +# +# /etc/pam.d/common-password - password-related modules common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of modules that define the services to be +# used to change user passwords. The default is pam_unix. + +# Explanation of pam_unix options: +# The "yescrypt" option enables +#hashed passwords using the yescrypt algorithm, introduced in Debian +#11. Without this option, the default is Unix crypt. Prior releases +#used the option "sha512"; if a shadow password hash will be shared +#between Debian 11 and older releases replace "yescrypt" with "sha512" +#for compatibility . The "obscure" option replaces the old +#`OBSCURE_CHECKS_ENAB' option in login.defs. See the pam_unix manpage +#for other options. + +# As of pam 1.0.1-6, this file is managed by pam-auth-update by default. +# To take advantage of this, it is recommended that you configure any +# local modules either before or after the default block, and use +# pam-auth-update to manage selection of other modules. See +# pam-auth-update(8) for details. + +# here are the per-package modules (the "Primary" block) + +{% if passw_policies %} +{% if passw_policies['state'] == 'enabled' %} +password requisite pam_cracklib.so retry=3 maxrepeat=0 {% if passw_policies['len_min'] %}minlen={{passw_policies['len_min']}}{% endif %} {% if passw_policies['upper_class'] %}ucredit=-1{% else %}ucredit=0{% endif %} {% if passw_policies['lower_class'] %}lcredit=-1{% else %}lcredit=0{% endif %} {% if passw_policies['digits_class'] %}dcredit=-1{% else %}dcredit=0{% endif %} {% if passw_policies['special_class'] %}ocredit=-1{% else %}ocredit=0{% endif %} {% if passw_policies['reject_user_passw_match'] %}reject_username{% endif %} enforce_for_root + +password required pam_pwhistory.so {% if passw_policies['history_cnt'] %}remember={{passw_policies['history_cnt']}}{% endif %} use_authtok enforce_for_root +{% endif %} +{% endif %} + +password [success=1 default=ignore] pam_unix.so obscure yescrypt +# here's the fallback if no module succeeds +password requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +password required pam_permit.so +# and here are more per-package modules (the "Additional" block) +# end of pam-auth-update config diff --git a/src/sonic-host-services/scripts/hostcfgd b/src/sonic-host-services/scripts/hostcfgd index 7f8f4be0b2e7..fe111c9a9012 100755 --- a/src/sonic-host-services/scripts/hostcfgd +++ b/src/sonic-host-services/scripts/hostcfgd @@ -8,7 +8,7 @@ import sys import subprocess import syslog import signal - +import re import jinja2 from sonic_py_common import device_info from swsscommon.swsscommon import ConfigDBConnector, DBConnector, Table @@ -16,6 +16,8 @@ from swsscommon.swsscommon import ConfigDBConnector, DBConnector, Table # FILE PAM_AUTH_CONF = "/etc/pam.d/common-auth-sonic" PAM_AUTH_CONF_TEMPLATE = "/usr/share/sonic/templates/common-auth-sonic.j2" +PAM_PASSWORD_CONF = "/etc/pam.d/common-password" +PAM_PASSWORD_CONF_TEMPLATE = "/usr/share/sonic/templates/common-password.j2" NSS_TACPLUS_CONF = "/etc/tacplus_nss.conf" NSS_TACPLUS_CONF_TEMPLATE = "/usr/share/sonic/templates/tacplus_nss.conf.j2" NSS_RADIUS_CONF = "/etc/radius_nss.conf" @@ -24,6 +26,16 @@ PAM_RADIUS_AUTH_CONF_TEMPLATE = "/usr/share/sonic/templates/pam_radius_auth.conf NSS_CONF = "/etc/nsswitch.conf" ETC_PAMD_SSHD = "/etc/pam.d/sshd" ETC_PAMD_LOGIN = "/etc/pam.d/login" +ETC_LOGIN_DEF = "/etc/login.defs" + +# Linux login.def default values (password hardening disable) +LINUX_DEFAULT_PASS_MAX_DAYS = 99999 +LINUX_DEFAULT_PASS_WARN_AGE = 7 + +ACCOUNT_NAME = 0 # index of account name +AGE_DICT = { 'MAX_DAYS': {'REGEX_DAYS': r'^PASS_MAX_DAYS[ \t]*(?P\d*)', 'DAYS': 'max_days', 'CHAGE_FLAG': '-M '}, + 'WARN_DAYS': {'REGEX_DAYS': r'^PASS_WARN_AGE[ \t]*(?P\d*)', 'DAYS': 'warn_days', 'CHAGE_FLAG': '-W '} + } PAM_LIMITS_CONF_TEMPLATE = "/usr/share/sonic/templates/pam_limits.j2" LIMITS_CONF_TEMPLATE = "/usr/share/sonic/templates/limits.conf.j2" PAM_LIMITS_CONF = "/etc/pam.d/pam-limits-conf" @@ -85,8 +97,10 @@ def run_cmd(cmd, log_err=True, raise_exception=False): def is_true(val): if val == 'True' or val == 'true': return True - else: + elif val == 'False' or val == 'false': return False + syslog.syslog(syslog.LOG_ERR, "Failed to get bool value, instead val= {}".format(val)) + return False def is_vlan_sub_interface(ifname): @@ -857,6 +871,189 @@ class AaaCfg(object): .format(err.cmd, err.returncode, err.output)) +class PasswHardening(object): + def __init__(self): + self.passw_policies_default = {} + self.passw_policies = {} + + self.debug = False + self.trace = False + + def load(self, policies_conf): + for row in policies_conf: + self.passw_policies_update(row, policies_conf[row], modify_conf=False) + + self.modify_passw_conf_file() + + def passw_policies_update(self, key, data, modify_conf=True): + syslog.syslog(syslog.LOG_DEBUG, "passw_policies_update - key: {}".format(key)) + syslog.syslog(syslog.LOG_DEBUG, "passw_policies_update - data: {}".format(data)) + + if data == {}: + self.passw_policies = {} + else: + if 'reject_user_passw_match' in data: + data['reject_user_passw_match'] = is_true(data['reject_user_passw_match']) + if 'lower_class' in data: + data['lower_class'] = is_true(data['lower_class']) + if 'upper_class' in data: + data['upper_class'] = is_true(data['upper_class']) + if 'digits_class' in data: + data['digits_class'] = is_true(data['digits_class']) + if 'special_class' in data: + data['special_class'] = is_true(data['special_class']) + + if key == 'POLICIES': + self.passw_policies = data + + if modify_conf: + self.modify_passw_conf_file() + + def modify_single_file_inplace(self, filename, operations=None): + if operations: + cmd = "sed -i {0} {1}".format(' -i '.join(operations), filename) + syslog.syslog(syslog.LOG_DEBUG, "modify_single_file_inplace: cmd - {}".format(cmd)) + os.system(cmd) + + def set_passw_hardening_policies(self, passw_policies): + # Password Hardening flow + # When feature is enabled, the passw_policies from CONFIG_DB will be set in the pam files /etc/pam.d/common-password and /etc/login.def. + # When the feature is disabled, the files above will be generate with the linux default (without secured passw_policies). + syslog.syslog(syslog.LOG_DEBUG, "modify_conf_file: passw_policies - {}".format(passw_policies)) + + template_passwh_file = os.path.abspath(PAM_PASSWORD_CONF_TEMPLATE) + env = jinja2.Environment(loader=jinja2.FileSystemLoader('/'), trim_blocks=True) + env.filters['sub'] = sub + template_passwh = env.get_template(template_passwh_file) + + # Render common-password file with passw hardening policies if any. Other render without them. + pam_passwh_conf = template_passwh.render(debug=self.debug, passw_policies=passw_policies) + + # Use rename(), which is atomic (on the same fs) to avoid empty file + with open(PAM_PASSWORD_CONF + ".tmp", 'w') as f: + f.write(pam_passwh_conf) + os.chmod(PAM_PASSWORD_CONF + ".tmp", 0o644) + os.rename(PAM_PASSWORD_CONF + ".tmp", PAM_PASSWORD_CONF) + + # Age policy + # When feature disabled or age policy disabled, expiry days policy should be as linux default, other, accoriding CONFIG_DB. + curr_expiration = LINUX_DEFAULT_PASS_MAX_DAYS + curr_expiration_warning = LINUX_DEFAULT_PASS_WARN_AGE + + if passw_policies: + if 'state' in passw_policies: + if passw_policies['state'] == 'enabled': + if 'expiration' in passw_policies: + if int(self.passw_policies['expiration']) != 0: # value '0' meaning age policy is disabled + # the logic is to modify the expiration time according the last updated modificatiion + # + curr_expiration = int(passw_policies['expiration']) + + if 'expiration_warning' in passw_policies: + if int(self.passw_policies['expiration_warning']) != 0: # value '0' meaning age policy is disabled + curr_expiration_warning = int(passw_policies['expiration_warning']) + + if self.is_passwd_aging_expire_update(curr_expiration, 'MAX_DAYS'): + # Set aging policy for existing users + self.passwd_aging_expire_modify(curr_expiration, 'MAX_DAYS') + + # Aging policy for new users + self.modify_single_file_inplace(ETC_LOGIN_DEF, ["\'/^PASS_MAX_DAYS/c\PASS_MAX_DAYS " +str(curr_expiration)+"\'"]) + + if self.is_passwd_aging_expire_update(curr_expiration_warning, 'WARN_DAYS'): + # Aging policy for existing users + self.passwd_aging_expire_modify(curr_expiration_warning, 'WARN_DAYS') + + # Aging policy for new users + self.modify_single_file_inplace(ETC_LOGIN_DEF, ["\'/^PASS_WARN_AGE/c\PASS_WARN_AGE " +str(curr_expiration_warning)+"\'"]) + + def passwd_aging_expire_modify(self, curr_expiration, age_type): + normal_accounts = self.get_normal_accounts() + if not normal_accounts: + syslog.syslog(syslog.LOG_ERR,"failed, no normal users found in /etc/passwd") + return + chage_flag = AGE_DICT[age_type]['CHAGE_FLAG'] + for normal_account in normal_accounts: + try: + chage_p_m = subprocess.Popen(('chage', chage_flag + str(curr_expiration), normal_account), stdout=subprocess.PIPE) + return_code_chage_p_m = chage_p_m.poll() + if return_code_chage_p_m != 0: + syslog.syslog(syslog.LOG_ERR, "failed: return code - {}".format(return_code_chage_p_m)) + + except subprocess.CalledProcessError as e: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(e.cmd, e.returncode, e.output)) + + def is_passwd_aging_expire_update(self, curr_expiration, age_type): + """ Function verify that the current age expiry policy values are equal from the old one + Return update_age_status 'True' value meaning that was a modification from the last time, and vice versa. + """ + update_age_status = False + days_num = None + regex_days = AGE_DICT[age_type]['REGEX_DAYS'] + days_type = AGE_DICT[age_type]['DAYS'] + if os.path.exists(ETC_LOGIN_DEF): + with open(ETC_LOGIN_DEF, 'r') as f: + login_def_data = f.readlines() + + for line in login_def_data: + m1 = re.match(regex_days, line) + if m1: + days_num = int(m1.group(days_type)) + break + + if curr_expiration != days_num: + update_age_status = True + + return update_age_status + + def get_normal_accounts(self): + # Get user list + try: + getent_out = subprocess.check_output(['getent', 'passwd']).decode('utf-8').split('\n') + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + return False + + # Get range of normal users + REGEX_UID_MAX = r'^UID_MAX[ \t]*(?P\d*)' + REGEX_UID_MIN = r'^UID_MIN[ \t]*(?P\d*)' + uid_max = None + uid_min = None + if os.path.exists(ETC_LOGIN_DEF): + with open(ETC_LOGIN_DEF, 'r') as f: + login_def_data = f.readlines() + + for line in login_def_data: + m1 = re.match(REGEX_UID_MAX, line) + m2 = re.match(REGEX_UID_MIN, line) + if m1: + uid_max = int(m1.group("uid_max")) + if m2: + uid_min = int(m2.group("uid_min")) + + if not uid_max or not uid_min: + syslog.syslog(syslog.LOG_ERR,"failed, no UID_MAX/UID_MIN founded in login.def file") + return False + + # Get normal user list + normal_accounts = [] + for account in getent_out[0:-1]: # last item is always empty + account_spl = account.split(':') + account_number = int(account_spl[2]) + if account_number >= uid_min and account_number <= uid_max: + normal_accounts.append(account_spl[ACCOUNT_NAME]) + + normal_accounts.append('root') # root is also a candidate to be age modify. + return normal_accounts + + def modify_passw_conf_file(self): + passw_policies = self.passw_policies_default.copy() + passw_policies.update(self.passw_policies) + + # set new Password Hardening policies. + self.set_passw_hardening_policies(passw_policies) + + class KdumpCfg(object): def __init__(self, CfgDb): self.config_db = CfgDb @@ -1080,6 +1277,9 @@ class HostConfigDaemon: self.hostname_cache="" self.aaacfg = AaaCfg() + # Initialize PasswHardening + self.passwcfg = PasswHardening() + # Initialize PamLimitsCfg self.pamLimitsCfg = PamLimitsCfg(self.config_db) self.pamLimitsCfg.update_config_file() @@ -1095,12 +1295,14 @@ class HostConfigDaemon: ntp_server = init_data['NTP_SERVER'] ntp_global = init_data['NTP'] kdump = init_data['KDUMP'] + passwh = init_data['PASSW_HARDENING'] self.feature_handler.sync_state_field(features) self.aaacfg.load(aaa, tacacs_global, tacacs_server, radius_global, radius_server) self.iptables.load(lpbk_table) self.ntpcfg.load(ntp_global, ntp_server) self.kdumpCfg.load(kdump) + self.passwcfg.load(passwh) dev_meta = self.config_db.get_table('DEVICE_METADATA') if 'localhost' in dev_meta: @@ -1121,6 +1323,10 @@ class HostConfigDaemon: self.aaacfg.aaa_update(key, data) syslog.syslog(syslog.LOG_INFO, 'AAA Update: key: {}, op: {}, data: {}'.format(key, op, data)) + def passwh_handler(self, key, op, data): + self.passwcfg.passw_policies_update(key, data) + syslog.syslog(syslog.LOG_INFO, 'PASSW_HARDENING Update: key: {}, op: {}, data: {}'.format(key, op, data)) + def tacacs_server_handler(self, key, op, data): self.aaacfg.tacacs_server_update(key, data) log_data = copy.deepcopy(data) @@ -1219,6 +1425,7 @@ class HostConfigDaemon: self.config_db.subscribe('TACPLUS_SERVER', make_callback(self.tacacs_server_handler)) self.config_db.subscribe('RADIUS', make_callback(self.radius_global_handler)) self.config_db.subscribe('RADIUS_SERVER', make_callback(self.radius_server_handler)) + self.config_db.subscribe('PASSW_HARDENING', make_callback(self.passwh_handler)) # Handle IPTables configuration self.config_db.subscribe('LOOPBACK_INTERFACE', make_callback(self.lpbk_handler)) # Handle NTP & NTP_SERVER updates diff --git a/src/sonic-host-services/tests/hostcfgd/hostcfgd_passwh_test.py b/src/sonic-host-services/tests/hostcfgd/hostcfgd_passwh_test.py new file mode 100755 index 000000000000..da68ad861207 --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/hostcfgd_passwh_test.py @@ -0,0 +1,182 @@ +import importlib.machinery +import importlib.util +import filecmp +import shutil +import os +import sys +import subprocess +import re + +from parameterized import parameterized +from unittest import TestCase, mock +from tests.hostcfgd.test_passwh_vectors import HOSTCFGD_TEST_PASSWH_VECTOR +from tests.common.mock_configdb import MockConfigDb, MockDBConnector + +test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +modules_path = os.path.dirname(test_path) +scripts_path = os.path.join(modules_path, "scripts") +src_path = os.path.dirname(modules_path) +templates_path = os.path.join(src_path, "sonic-host-services-data/templates") +output_path = os.path.join(test_path, "hostcfgd/output") +sample_output_path = os.path.join(test_path, "hostcfgd/sample_output") +sys.path.insert(0, modules_path) + +# Load the file under test +hostcfgd_path = os.path.join(scripts_path, 'hostcfgd') +loader = importlib.machinery.SourceFileLoader('hostcfgd', hostcfgd_path) +spec = importlib.util.spec_from_loader(loader.name, loader) +hostcfgd = importlib.util.module_from_spec(spec) +loader.exec_module(hostcfgd) +sys.modules['hostcfgd'] = hostcfgd + +# Mock swsscommon classes +hostcfgd.ConfigDBConnector = MockConfigDb +hostcfgd.DBConnector = MockDBConnector +hostcfgd.Table = mock.Mock() + +AGE_DICT = { 'MAX_DAYS': {'REGEX_DAYS': r'^PASS_MAX_DAYS[ \t]*(?P\d*)', 'DAYS': 'max_days', 'CHAGE_FLAG': '-M '}, + 'WARN_DAYS': {'REGEX_DAYS': r'^PASS_WARN_AGE[ \t]*(?P\d*)', 'DAYS': 'warn_days', 'CHAGE_FLAG': '-W '} + } + +class TestHostcfgdPASSWH(TestCase): + """ + Test hostcfd daemon - PASSWH + """ + def run_diff(self, file1, file2): + try: + diff_out = subprocess.check_output('diff -ur {} {} || true'.format(file1, file2), shell=True) + return diff_out + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + return -1 + + def get_passw_days(self, login_file, age_type): + days_num = -1 + + regex_days = AGE_DICT[age_type]['REGEX_DAYS'] + days_type = AGE_DICT[age_type]['DAYS'] + + with open(login_file, 'r') as f: + login_def_data = f.readlines() + + for line in login_def_data: + m1 = re.match(regex_days, line) + if m1: + days_num = int(m1.group(days_type)) + break + return days_num + + """ + Check different config + """ + def check_config(self, test_name, test_data, config_name): + t_path = templates_path + op_path = output_path + "/" + test_name + "_" + config_name + sop_path = sample_output_path + "/" + test_name + "_" + config_name + sop_path_common = sample_output_path + "/" + test_name + + hostcfgd.PAM_PASSWORD_CONF_TEMPLATE = t_path + "/common-password.j2" + hostcfgd.PAM_AUTH_CONF_TEMPLATE = t_path + "/common-auth-sonic.j2" + hostcfgd.NSS_TACPLUS_CONF_TEMPLATE = t_path + "/tacplus_nss.conf.j2" + hostcfgd.NSS_RADIUS_CONF_TEMPLATE = t_path + "/radius_nss.conf.j2" + hostcfgd.PAM_RADIUS_AUTH_CONF_TEMPLATE = t_path + "/pam_radius_auth.conf.j2" + hostcfgd.PAM_PASSWORD_CONF = op_path + "/common-password" + hostcfgd.ETC_LOGIN_DEF = op_path + "/login.defs" + hostcfgd.PAM_AUTH_CONF = op_path + "/common-auth-sonic" + hostcfgd.NSS_TACPLUS_CONF = op_path + "/tacplus_nss.conf" + hostcfgd.NSS_RADIUS_CONF = op_path + "/radius_nss.conf" + hostcfgd.NSS_CONF = op_path + "/nsswitch.conf" + hostcfgd.ETC_PAMD_SSHD = op_path + "/sshd" + hostcfgd.ETC_PAMD_LOGIN = op_path + "/login" + hostcfgd.RADIUS_PAM_AUTH_CONF_DIR = op_path + "/" + + shutil.rmtree(op_path, ignore_errors=True) + os.mkdir(op_path) + + shutil.copyfile(sop_path_common + "/login.defs.old", op_path + "/login.defs") + MockConfigDb.set_config_db(test_data[config_name]) + host_config_daemon = hostcfgd.HostConfigDaemon() + + try: + passwh_table = host_config_daemon.config_db.get_table('PASSW_HARDENING') + except Exception as e: + syslog.syslog(syslog.LOG_ERR, "failed: get_table 'PASSW_HARDENING', exception={}".format(e)) + passwh_table = [] + + host_config_daemon.passwcfg.load(passwh_table) + + + diff_output = "" + files_to_compare = ['common-password'] + + # check output files exists + for name in files_to_compare: + if not os.path.isfile(sop_path + "/" + name): + raise ValueError('filename: %s not exit' % (sop_path + "/" + name)) + if not os.path.isfile(op_path + "/" + name): + raise ValueError('filename: %s not exit' % (op_path + "/" + name)) + + # deep comparison + match, mismatch, errors = filecmp.cmpfiles(sop_path, op_path, files_to_compare, shallow=False) + + if not match: + for name in files_to_compare: + diff_output += self.run_diff( sop_path + "/" + name,\ + op_path + "/" + name).decode('utf-8') + + self.assertTrue(len(diff_output) == 0, diff_output) + + # compare age data in login.def file. + out_passw_age_days = self.get_passw_days(op_path + "/login.defs", 'MAX_DAYS') + sout_passw_age_days = self.get_passw_days(sop_path + "/login.defs", 'MAX_DAYS') + out_passw_age_warn_days = self.get_passw_days(op_path + "/login.defs", 'WARN_DAYS') + sout_passw_age_warn_days = self.get_passw_days(sop_path + "/login.defs", 'WARN_DAYS') + + self.assertEqual(out_passw_age_days, sout_passw_age_days) + self.assertEqual(out_passw_age_warn_days, sout_passw_age_warn_days) + + @parameterized.expand(HOSTCFGD_TEST_PASSWH_VECTOR) + def test_hostcfgd_passwh(self, test_name, test_data): + """ + Test PASSWH hostcfd daemon initialization + + Args: + test_name(str): test name + test_data(dict): test data which contains initial Config Db tables, and expected results + + Returns: + None + """ + + self.check_config(test_name, test_data, "default_values") + + @parameterized.expand(HOSTCFGD_TEST_PASSWH_VECTOR) + def test_hostcfgd_passwh_enable(self, test_name, test_data): + """ + Test PASSWH hostcfd daemon initialization + + Args: + test_name(str): test name + test_data(dict): test data which contains initial Config Db tables, and expected results + + Returns: + None + """ + + self.check_config(test_name, test_data, "enable_feature") + + + @parameterized.expand(HOSTCFGD_TEST_PASSWH_VECTOR) + def test_hostcfgd_passwh_classes(self, test_name, test_data): + """ + Test PASSWH hostcfd daemon initialization + + Args: + test_name(str): test name + test_data(dict): test data which contains initial Config Db tables, and expected results + + Returns: + None + """ + + self.check_config(test_name, test_data, "enable_digits_class") \ No newline at end of file diff --git a/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING/login.defs.old b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING/login.defs.old new file mode 100644 index 000000000000..db8baa4d2bf8 --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING/login.defs.old @@ -0,0 +1,340 @@ +# +# /etc/login.defs - Configuration control definitions for the login package. +# +# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH. +# If unspecified, some arbitrary (and possibly incorrect) value will +# be assumed. All other items are optional - if not specified then +# the described action or option will be inhibited. +# +# Comment lines (lines beginning with "#") and blank lines are ignored. +# +# Modified for Linux. --marekm + +# REQUIRED for useradd/userdel/usermod +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define MAIL_DIR and MAIL_FILE, +# MAIL_DIR takes precedence. +# +# Essentially: +# - MAIL_DIR defines the location of users mail spool files +# (for mbox use) by appending the username to MAIL_DIR as defined +# below. +# - MAIL_FILE defines the location of the users mail spool files as the +# fully-qualified filename obtained by prepending the user home +# directory before $MAIL_FILE +# +# NOTE: This is no more used for setting up users MAIL environment variable +# which is, starting from shadow 4.0.12-1 in Debian, entirely the +# job of the pam_mail PAM modules +# See default PAM configuration files provided for +# login, su, etc. +# +# This is a temporary situation: setting these variables will soon +# move to /etc/default/useradd and the variables will then be +# no more supported +MAIL_DIR /var/mail +#MAIL_FILE .mail + +# +# Enable logging and display of /var/log/faillog login failure info. +# This option conflicts with the pam_tally PAM module. +# +FAILLOG_ENAB yes + +# +# Enable display of unknown usernames when login failures are recorded. +# +# WARNING: Unknown usernames may become world readable. +# See #290803 and #298773 for details about how this could become a security +# concern +LOG_UNKFAIL_ENAB no + +# +# Enable logging of successful logins +# +LOG_OK_LOGINS no + +# +# Enable "syslog" logging of su activity - in addition to sulog file logging. +# SYSLOG_SG_ENAB does the same for newgrp and sg. +# +SYSLOG_SU_ENAB yes +SYSLOG_SG_ENAB yes + +# +# If defined, all su activity is logged to this file. +# +#SULOG_FILE /var/log/sulog + +# +# If defined, file which maps tty line to TERM environment parameter. +# Each line of the file is in a format something like "vt100 tty01". +# +#TTYTYPE_FILE /etc/ttytype + +# +# If defined, login failures will be logged here in a utmp format +# last, when invoked as lastb, will read /var/log/btmp, so... +# +FTMP_FILE /var/log/btmp + +# +# If defined, the command name to display when running "su -". For +# example, if this is defined as "su" then a "ps" will display the +# command is "-su". If not defined, then "ps" would display the +# name of the shell actually being run, e.g. something like "-sh". +# +SU_NAME su + +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# +# *REQUIRED* The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a "write" program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP to the group number and +# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign +# TTYPERM to either 622 or 600. +# +# In Debian /usr/bin/bsd-write or similar programs are setgid tty +# However, the default and recommended value for TTYPERM is still 0600 +# to not allow anyone to write to anyone else console or terminal + +# Users can still allow other people to write them by issuing +# the "mesg y" command. + +TTYGROUP tty +TTYPERM 0600 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# UMASK Default "umask" value. +# +# The ERASECHAR and KILLCHAR are used only on System V machines. +# +# UMASK is the default umask value for pam_umask and is used by +# useradd and newusers to set the mode of the new home directories. +# 022 is the "historical" value in Debian for UMASK +# 027, or even 077, could be considered better for privacy +# There is no One True Answer here : each sysadmin must make up his/her +# mind. +# +# If USERGROUPS_ENAB is set to "yes", that will modify this UMASK default value +# for private user groups, i. e. the uid is the same as gid, and username is +# the same as the primary group name: for these, the user permissions will be +# used as group permissions, e. g. 022 will become 002. +# +# Prefix these values with "0" to get octal, "0x" to get hexadecimal. +# +ERASECHAR 0177 +KILLCHAR 025 +UMASK 022 + +# +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +PASS_WARN_AGE 7 + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +#SYS_UID_MIN 100 +#SYS_UID_MAX 999 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +#SYS_GID_MIN 100 +#SYS_GID_MAX 999 + +# +# Max number of login retries if password is bad. This will most likely be +# overriden by PAM, since the default pam_unix module has it's own built +# in of 3 retries. However, this is a safe fallback in case you are using +# an authentication module that does not enforce PAM_MAXTRIES. +# +LOGIN_RETRIES 5 + +# +# Max time in seconds for login +# +LOGIN_TIMEOUT 60 + +# +# Which fields may be changed by regular users using chfn - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +CHFN_RESTRICT rwh + +# +# Should login be allowed if we can't cd to the home directory? +# Default in no. +# +DEFAULT_HOME yes + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# If set to yes, userdel will remove the user's group if it contains no +# more members, and useradd will create by default a group with the name +# of the user. +# +# Other former uses of this variable such as setting the umask when +# user==primary group are not used in PAM environments, such as Debian +# +USERGROUPS_ENAB yes + +# +# Instead of the real user shell, the program specified by this parameter +# will be launched, although its visible name (argv[0]) will be the shell's. +# The program may do whatever it wants (logging, additional authentification, +# banner, ...) before running the actual shell. +# +# FAKE_SHELL /bin/fakeshell + +# +# If defined, either full pathname of a file containing device names or +# a ":" delimited list of device names. Root logins will be allowed only +# upon these devices. +# +# This variable is used by login and su. +# +#CONSOLE /etc/consoles +#CONSOLE console:tty01:tty02:tty03:tty04 + +# +# List of groups to add to the user's supplementary group set +# when logging in on the console (as determined by the CONSOLE +# setting). Default is none. +# +# Use with caution - it is possible for users to gain permanent +# access to these groups, even when not logged in on the console. +# How to do it is left as an exercise for the reader... +# +# This variable is used by login and su. +# +#CONSOLE_GROUPS floppy:audio:cdrom + +# +# If set to "yes", new passwords will be encrypted using the MD5-based +# algorithm compatible with the one used by recent releases of FreeBSD. +# It supports passwords of unlimited length and longer salt strings. +# Set to "no" if you need to copy encrypted passwords to other systems +# which don't understand the new algorithm. Default is "no". +# +# This variable is deprecated. You should use ENCRYPT_METHOD. +# +#MD5_CRYPT_ENAB no + +# +# If set to MD5 , MD5-based algorithm will be used for encrypting password +# If set to SHA256, SHA256-based algorithm will be used for encrypting password +# If set to SHA512, SHA512-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# Overrides the MD5_CRYPT_ENAB option +# +# Note: It is recommended to use a value consistent with +# the PAM modules configuration. +# +ENCRYPT_METHOD SHA512 + +# +# Only used if ENCRYPT_METHOD is set to SHA256 or SHA512. +# +# Define the number of SHA rounds. +# With a lot of rounds, it is more difficult to brute forcing the password. +# But note also that it more CPU resources will be needed to authenticate +# users. +# +# If not specified, the libc will choose the default number of rounds (5000). +# The values must be inside the 1000-999999999 range. +# If only one of the MIN or MAX values is set, then this value will be used. +# If MIN > MAX, the highest value will be used. +# +# SHA_CRYPT_MIN_ROUNDS 5000 +# SHA_CRYPT_MAX_ROUNDS 5000 + +################# OBSOLETED BY PAM ############## +# # +# These options are now handled by PAM. Please # +# edit the appropriate file in /etc/pam.d/ to # +# enable the equivelants of them. +# +############### + +#MOTD_FILE +#DIALUPS_CHECK_ENAB +#LASTLOG_ENAB +#MAIL_CHECK_ENAB +#OBSCURE_CHECKS_ENAB +#PORTTIME_CHECKS_ENAB +#SU_WHEEL_ONLY +#CRACKLIB_DICTPATH +#PASS_CHANGE_TRIES +#PASS_ALWAYS_WARN +#ENVIRON_FILE +#NOLOGINS_FILE +#ISSUE_FILE +#PASS_MIN_LEN +#PASS_MAX_LEN +#ULIMIT +#ENV_HZ +#CHFN_AUTH +#CHSH_AUTH +#FAIL_DELAY + +################# OBSOLETED ####################### +# # +# These options are no more handled by shadow. # +# # +# Shadow utilities will display a warning if they # +# still appear. # +# # +################################################### + +# CLOSE_SESSIONS +# LOGIN_STRING +# NO_PASSWORD_CONSOLE +# QMAIL_DIR + + + diff --git a/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_default_values/common-password b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_default_values/common-password new file mode 100644 index 000000000000..0da639249c94 --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_default_values/common-password @@ -0,0 +1,36 @@ +#THIS IS AN AUTO-GENERATED FILE +# +# /etc/pam.d/common-password - password-related modules common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of modules that define the services to be +# used to change user passwords. The default is pam_unix. + +# Explanation of pam_unix options: +# The "yescrypt" option enables +#hashed passwords using the yescrypt algorithm, introduced in Debian +#11. Without this option, the default is Unix crypt. Prior releases +#used the option "sha512"; if a shadow password hash will be shared +#between Debian 11 and older releases replace "yescrypt" with "sha512" +#for compatibility . The "obscure" option replaces the old +#`OBSCURE_CHECKS_ENAB' option in login.defs. See the pam_unix manpage +#for other options. + +# As of pam 1.0.1-6, this file is managed by pam-auth-update by default. +# To take advantage of this, it is recommended that you configure any +# local modules either before or after the default block, and use +# pam-auth-update to manage selection of other modules. See +# pam-auth-update(8) for details. + +# here are the per-package modules (the "Primary" block) + + +password [success=1 default=ignore] pam_unix.so obscure yescrypt +# here's the fallback if no module succeeds +password requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +password required pam_permit.so +# and here are more per-package modules (the "Additional" block) +# end of pam-auth-update config \ No newline at end of file diff --git a/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_default_values/login.defs b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_default_values/login.defs new file mode 100644 index 000000000000..db8baa4d2bf8 --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_default_values/login.defs @@ -0,0 +1,340 @@ +# +# /etc/login.defs - Configuration control definitions for the login package. +# +# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH. +# If unspecified, some arbitrary (and possibly incorrect) value will +# be assumed. All other items are optional - if not specified then +# the described action or option will be inhibited. +# +# Comment lines (lines beginning with "#") and blank lines are ignored. +# +# Modified for Linux. --marekm + +# REQUIRED for useradd/userdel/usermod +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define MAIL_DIR and MAIL_FILE, +# MAIL_DIR takes precedence. +# +# Essentially: +# - MAIL_DIR defines the location of users mail spool files +# (for mbox use) by appending the username to MAIL_DIR as defined +# below. +# - MAIL_FILE defines the location of the users mail spool files as the +# fully-qualified filename obtained by prepending the user home +# directory before $MAIL_FILE +# +# NOTE: This is no more used for setting up users MAIL environment variable +# which is, starting from shadow 4.0.12-1 in Debian, entirely the +# job of the pam_mail PAM modules +# See default PAM configuration files provided for +# login, su, etc. +# +# This is a temporary situation: setting these variables will soon +# move to /etc/default/useradd and the variables will then be +# no more supported +MAIL_DIR /var/mail +#MAIL_FILE .mail + +# +# Enable logging and display of /var/log/faillog login failure info. +# This option conflicts with the pam_tally PAM module. +# +FAILLOG_ENAB yes + +# +# Enable display of unknown usernames when login failures are recorded. +# +# WARNING: Unknown usernames may become world readable. +# See #290803 and #298773 for details about how this could become a security +# concern +LOG_UNKFAIL_ENAB no + +# +# Enable logging of successful logins +# +LOG_OK_LOGINS no + +# +# Enable "syslog" logging of su activity - in addition to sulog file logging. +# SYSLOG_SG_ENAB does the same for newgrp and sg. +# +SYSLOG_SU_ENAB yes +SYSLOG_SG_ENAB yes + +# +# If defined, all su activity is logged to this file. +# +#SULOG_FILE /var/log/sulog + +# +# If defined, file which maps tty line to TERM environment parameter. +# Each line of the file is in a format something like "vt100 tty01". +# +#TTYTYPE_FILE /etc/ttytype + +# +# If defined, login failures will be logged here in a utmp format +# last, when invoked as lastb, will read /var/log/btmp, so... +# +FTMP_FILE /var/log/btmp + +# +# If defined, the command name to display when running "su -". For +# example, if this is defined as "su" then a "ps" will display the +# command is "-su". If not defined, then "ps" would display the +# name of the shell actually being run, e.g. something like "-sh". +# +SU_NAME su + +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# +# *REQUIRED* The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a "write" program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP to the group number and +# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign +# TTYPERM to either 622 or 600. +# +# In Debian /usr/bin/bsd-write or similar programs are setgid tty +# However, the default and recommended value for TTYPERM is still 0600 +# to not allow anyone to write to anyone else console or terminal + +# Users can still allow other people to write them by issuing +# the "mesg y" command. + +TTYGROUP tty +TTYPERM 0600 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# UMASK Default "umask" value. +# +# The ERASECHAR and KILLCHAR are used only on System V machines. +# +# UMASK is the default umask value for pam_umask and is used by +# useradd and newusers to set the mode of the new home directories. +# 022 is the "historical" value in Debian for UMASK +# 027, or even 077, could be considered better for privacy +# There is no One True Answer here : each sysadmin must make up his/her +# mind. +# +# If USERGROUPS_ENAB is set to "yes", that will modify this UMASK default value +# for private user groups, i. e. the uid is the same as gid, and username is +# the same as the primary group name: for these, the user permissions will be +# used as group permissions, e. g. 022 will become 002. +# +# Prefix these values with "0" to get octal, "0x" to get hexadecimal. +# +ERASECHAR 0177 +KILLCHAR 025 +UMASK 022 + +# +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +PASS_WARN_AGE 7 + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +#SYS_UID_MIN 100 +#SYS_UID_MAX 999 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +#SYS_GID_MIN 100 +#SYS_GID_MAX 999 + +# +# Max number of login retries if password is bad. This will most likely be +# overriden by PAM, since the default pam_unix module has it's own built +# in of 3 retries. However, this is a safe fallback in case you are using +# an authentication module that does not enforce PAM_MAXTRIES. +# +LOGIN_RETRIES 5 + +# +# Max time in seconds for login +# +LOGIN_TIMEOUT 60 + +# +# Which fields may be changed by regular users using chfn - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +CHFN_RESTRICT rwh + +# +# Should login be allowed if we can't cd to the home directory? +# Default in no. +# +DEFAULT_HOME yes + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# If set to yes, userdel will remove the user's group if it contains no +# more members, and useradd will create by default a group with the name +# of the user. +# +# Other former uses of this variable such as setting the umask when +# user==primary group are not used in PAM environments, such as Debian +# +USERGROUPS_ENAB yes + +# +# Instead of the real user shell, the program specified by this parameter +# will be launched, although its visible name (argv[0]) will be the shell's. +# The program may do whatever it wants (logging, additional authentification, +# banner, ...) before running the actual shell. +# +# FAKE_SHELL /bin/fakeshell + +# +# If defined, either full pathname of a file containing device names or +# a ":" delimited list of device names. Root logins will be allowed only +# upon these devices. +# +# This variable is used by login and su. +# +#CONSOLE /etc/consoles +#CONSOLE console:tty01:tty02:tty03:tty04 + +# +# List of groups to add to the user's supplementary group set +# when logging in on the console (as determined by the CONSOLE +# setting). Default is none. +# +# Use with caution - it is possible for users to gain permanent +# access to these groups, even when not logged in on the console. +# How to do it is left as an exercise for the reader... +# +# This variable is used by login and su. +# +#CONSOLE_GROUPS floppy:audio:cdrom + +# +# If set to "yes", new passwords will be encrypted using the MD5-based +# algorithm compatible with the one used by recent releases of FreeBSD. +# It supports passwords of unlimited length and longer salt strings. +# Set to "no" if you need to copy encrypted passwords to other systems +# which don't understand the new algorithm. Default is "no". +# +# This variable is deprecated. You should use ENCRYPT_METHOD. +# +#MD5_CRYPT_ENAB no + +# +# If set to MD5 , MD5-based algorithm will be used for encrypting password +# If set to SHA256, SHA256-based algorithm will be used for encrypting password +# If set to SHA512, SHA512-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# Overrides the MD5_CRYPT_ENAB option +# +# Note: It is recommended to use a value consistent with +# the PAM modules configuration. +# +ENCRYPT_METHOD SHA512 + +# +# Only used if ENCRYPT_METHOD is set to SHA256 or SHA512. +# +# Define the number of SHA rounds. +# With a lot of rounds, it is more difficult to brute forcing the password. +# But note also that it more CPU resources will be needed to authenticate +# users. +# +# If not specified, the libc will choose the default number of rounds (5000). +# The values must be inside the 1000-999999999 range. +# If only one of the MIN or MAX values is set, then this value will be used. +# If MIN > MAX, the highest value will be used. +# +# SHA_CRYPT_MIN_ROUNDS 5000 +# SHA_CRYPT_MAX_ROUNDS 5000 + +################# OBSOLETED BY PAM ############## +# # +# These options are now handled by PAM. Please # +# edit the appropriate file in /etc/pam.d/ to # +# enable the equivelants of them. +# +############### + +#MOTD_FILE +#DIALUPS_CHECK_ENAB +#LASTLOG_ENAB +#MAIL_CHECK_ENAB +#OBSCURE_CHECKS_ENAB +#PORTTIME_CHECKS_ENAB +#SU_WHEEL_ONLY +#CRACKLIB_DICTPATH +#PASS_CHANGE_TRIES +#PASS_ALWAYS_WARN +#ENVIRON_FILE +#NOLOGINS_FILE +#ISSUE_FILE +#PASS_MIN_LEN +#PASS_MAX_LEN +#ULIMIT +#ENV_HZ +#CHFN_AUTH +#CHSH_AUTH +#FAIL_DELAY + +################# OBSOLETED ####################### +# # +# These options are no more handled by shadow. # +# # +# Shadow utilities will display a warning if they # +# still appear. # +# # +################################################### + +# CLOSE_SESSIONS +# LOGIN_STRING +# NO_PASSWORD_CONSOLE +# QMAIL_DIR + + + diff --git a/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/common-password b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/common-password new file mode 100644 index 000000000000..841074728a4f --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/common-password @@ -0,0 +1,39 @@ +#THIS IS AN AUTO-GENERATED FILE +# +# /etc/pam.d/common-password - password-related modules common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of modules that define the services to be +# used to change user passwords. The default is pam_unix. + +# Explanation of pam_unix options: +# The "yescrypt" option enables +#hashed passwords using the yescrypt algorithm, introduced in Debian +#11. Without this option, the default is Unix crypt. Prior releases +#used the option "sha512"; if a shadow password hash will be shared +#between Debian 11 and older releases replace "yescrypt" with "sha512" +#for compatibility . The "obscure" option replaces the old +#`OBSCURE_CHECKS_ENAB' option in login.defs. See the pam_unix manpage +#for other options. + +# As of pam 1.0.1-6, this file is managed by pam-auth-update by default. +# To take advantage of this, it is recommended that you configure any +# local modules either before or after the default block, and use +# pam-auth-update to manage selection of other modules. See +# pam-auth-update(8) for details. + +# here are the per-package modules (the "Primary" block) + +password requisite pam_cracklib.so retry=3 maxrepeat=0 minlen=8 ucredit=0 lcredit=0 dcredit=-1 ocredit=0 enforce_for_root + +password required pam_pwhistory.so remember=0 use_authtok enforce_for_root + +password [success=1 default=ignore] pam_unix.so obscure yescrypt +# here's the fallback if no module succeeds +password requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +password required pam_permit.so +# and here are more per-package modules (the "Additional" block) +# end of pam-auth-update config \ No newline at end of file diff --git a/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/login.defs b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/login.defs new file mode 100644 index 000000000000..db8baa4d2bf8 --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/login.defs @@ -0,0 +1,340 @@ +# +# /etc/login.defs - Configuration control definitions for the login package. +# +# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH. +# If unspecified, some arbitrary (and possibly incorrect) value will +# be assumed. All other items are optional - if not specified then +# the described action or option will be inhibited. +# +# Comment lines (lines beginning with "#") and blank lines are ignored. +# +# Modified for Linux. --marekm + +# REQUIRED for useradd/userdel/usermod +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define MAIL_DIR and MAIL_FILE, +# MAIL_DIR takes precedence. +# +# Essentially: +# - MAIL_DIR defines the location of users mail spool files +# (for mbox use) by appending the username to MAIL_DIR as defined +# below. +# - MAIL_FILE defines the location of the users mail spool files as the +# fully-qualified filename obtained by prepending the user home +# directory before $MAIL_FILE +# +# NOTE: This is no more used for setting up users MAIL environment variable +# which is, starting from shadow 4.0.12-1 in Debian, entirely the +# job of the pam_mail PAM modules +# See default PAM configuration files provided for +# login, su, etc. +# +# This is a temporary situation: setting these variables will soon +# move to /etc/default/useradd and the variables will then be +# no more supported +MAIL_DIR /var/mail +#MAIL_FILE .mail + +# +# Enable logging and display of /var/log/faillog login failure info. +# This option conflicts with the pam_tally PAM module. +# +FAILLOG_ENAB yes + +# +# Enable display of unknown usernames when login failures are recorded. +# +# WARNING: Unknown usernames may become world readable. +# See #290803 and #298773 for details about how this could become a security +# concern +LOG_UNKFAIL_ENAB no + +# +# Enable logging of successful logins +# +LOG_OK_LOGINS no + +# +# Enable "syslog" logging of su activity - in addition to sulog file logging. +# SYSLOG_SG_ENAB does the same for newgrp and sg. +# +SYSLOG_SU_ENAB yes +SYSLOG_SG_ENAB yes + +# +# If defined, all su activity is logged to this file. +# +#SULOG_FILE /var/log/sulog + +# +# If defined, file which maps tty line to TERM environment parameter. +# Each line of the file is in a format something like "vt100 tty01". +# +#TTYTYPE_FILE /etc/ttytype + +# +# If defined, login failures will be logged here in a utmp format +# last, when invoked as lastb, will read /var/log/btmp, so... +# +FTMP_FILE /var/log/btmp + +# +# If defined, the command name to display when running "su -". For +# example, if this is defined as "su" then a "ps" will display the +# command is "-su". If not defined, then "ps" would display the +# name of the shell actually being run, e.g. something like "-sh". +# +SU_NAME su + +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# +# *REQUIRED* The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a "write" program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP to the group number and +# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign +# TTYPERM to either 622 or 600. +# +# In Debian /usr/bin/bsd-write or similar programs are setgid tty +# However, the default and recommended value for TTYPERM is still 0600 +# to not allow anyone to write to anyone else console or terminal + +# Users can still allow other people to write them by issuing +# the "mesg y" command. + +TTYGROUP tty +TTYPERM 0600 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# UMASK Default "umask" value. +# +# The ERASECHAR and KILLCHAR are used only on System V machines. +# +# UMASK is the default umask value for pam_umask and is used by +# useradd and newusers to set the mode of the new home directories. +# 022 is the "historical" value in Debian for UMASK +# 027, or even 077, could be considered better for privacy +# There is no One True Answer here : each sysadmin must make up his/her +# mind. +# +# If USERGROUPS_ENAB is set to "yes", that will modify this UMASK default value +# for private user groups, i. e. the uid is the same as gid, and username is +# the same as the primary group name: for these, the user permissions will be +# used as group permissions, e. g. 022 will become 002. +# +# Prefix these values with "0" to get octal, "0x" to get hexadecimal. +# +ERASECHAR 0177 +KILLCHAR 025 +UMASK 022 + +# +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +PASS_WARN_AGE 7 + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +#SYS_UID_MIN 100 +#SYS_UID_MAX 999 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +#SYS_GID_MIN 100 +#SYS_GID_MAX 999 + +# +# Max number of login retries if password is bad. This will most likely be +# overriden by PAM, since the default pam_unix module has it's own built +# in of 3 retries. However, this is a safe fallback in case you are using +# an authentication module that does not enforce PAM_MAXTRIES. +# +LOGIN_RETRIES 5 + +# +# Max time in seconds for login +# +LOGIN_TIMEOUT 60 + +# +# Which fields may be changed by regular users using chfn - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +CHFN_RESTRICT rwh + +# +# Should login be allowed if we can't cd to the home directory? +# Default in no. +# +DEFAULT_HOME yes + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# If set to yes, userdel will remove the user's group if it contains no +# more members, and useradd will create by default a group with the name +# of the user. +# +# Other former uses of this variable such as setting the umask when +# user==primary group are not used in PAM environments, such as Debian +# +USERGROUPS_ENAB yes + +# +# Instead of the real user shell, the program specified by this parameter +# will be launched, although its visible name (argv[0]) will be the shell's. +# The program may do whatever it wants (logging, additional authentification, +# banner, ...) before running the actual shell. +# +# FAKE_SHELL /bin/fakeshell + +# +# If defined, either full pathname of a file containing device names or +# a ":" delimited list of device names. Root logins will be allowed only +# upon these devices. +# +# This variable is used by login and su. +# +#CONSOLE /etc/consoles +#CONSOLE console:tty01:tty02:tty03:tty04 + +# +# List of groups to add to the user's supplementary group set +# when logging in on the console (as determined by the CONSOLE +# setting). Default is none. +# +# Use with caution - it is possible for users to gain permanent +# access to these groups, even when not logged in on the console. +# How to do it is left as an exercise for the reader... +# +# This variable is used by login and su. +# +#CONSOLE_GROUPS floppy:audio:cdrom + +# +# If set to "yes", new passwords will be encrypted using the MD5-based +# algorithm compatible with the one used by recent releases of FreeBSD. +# It supports passwords of unlimited length and longer salt strings. +# Set to "no" if you need to copy encrypted passwords to other systems +# which don't understand the new algorithm. Default is "no". +# +# This variable is deprecated. You should use ENCRYPT_METHOD. +# +#MD5_CRYPT_ENAB no + +# +# If set to MD5 , MD5-based algorithm will be used for encrypting password +# If set to SHA256, SHA256-based algorithm will be used for encrypting password +# If set to SHA512, SHA512-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# Overrides the MD5_CRYPT_ENAB option +# +# Note: It is recommended to use a value consistent with +# the PAM modules configuration. +# +ENCRYPT_METHOD SHA512 + +# +# Only used if ENCRYPT_METHOD is set to SHA256 or SHA512. +# +# Define the number of SHA rounds. +# With a lot of rounds, it is more difficult to brute forcing the password. +# But note also that it more CPU resources will be needed to authenticate +# users. +# +# If not specified, the libc will choose the default number of rounds (5000). +# The values must be inside the 1000-999999999 range. +# If only one of the MIN or MAX values is set, then this value will be used. +# If MIN > MAX, the highest value will be used. +# +# SHA_CRYPT_MIN_ROUNDS 5000 +# SHA_CRYPT_MAX_ROUNDS 5000 + +################# OBSOLETED BY PAM ############## +# # +# These options are now handled by PAM. Please # +# edit the appropriate file in /etc/pam.d/ to # +# enable the equivelants of them. +# +############### + +#MOTD_FILE +#DIALUPS_CHECK_ENAB +#LASTLOG_ENAB +#MAIL_CHECK_ENAB +#OBSCURE_CHECKS_ENAB +#PORTTIME_CHECKS_ENAB +#SU_WHEEL_ONLY +#CRACKLIB_DICTPATH +#PASS_CHANGE_TRIES +#PASS_ALWAYS_WARN +#ENVIRON_FILE +#NOLOGINS_FILE +#ISSUE_FILE +#PASS_MIN_LEN +#PASS_MAX_LEN +#ULIMIT +#ENV_HZ +#CHFN_AUTH +#CHSH_AUTH +#FAIL_DELAY + +################# OBSOLETED ####################### +# # +# These options are no more handled by shadow. # +# # +# Shadow utilities will display a warning if they # +# still appear. # +# # +################################################### + +# CLOSE_SESSIONS +# LOGIN_STRING +# NO_PASSWORD_CONSOLE +# QMAIL_DIR + + + diff --git a/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/common-password b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/common-password new file mode 100644 index 000000000000..a66c1b1ade0c --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/common-password @@ -0,0 +1,39 @@ +#THIS IS AN AUTO-GENERATED FILE +# +# /etc/pam.d/common-password - password-related modules common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of modules that define the services to be +# used to change user passwords. The default is pam_unix. + +# Explanation of pam_unix options: +# The "yescrypt" option enables +#hashed passwords using the yescrypt algorithm, introduced in Debian +#11. Without this option, the default is Unix crypt. Prior releases +#used the option "sha512"; if a shadow password hash will be shared +#between Debian 11 and older releases replace "yescrypt" with "sha512" +#for compatibility . The "obscure" option replaces the old +#`OBSCURE_CHECKS_ENAB' option in login.defs. See the pam_unix manpage +#for other options. + +# As of pam 1.0.1-6, this file is managed by pam-auth-update by default. +# To take advantage of this, it is recommended that you configure any +# local modules either before or after the default block, and use +# pam-auth-update to manage selection of other modules. See +# pam-auth-update(8) for details. + +# here are the per-package modules (the "Primary" block) + +password requisite pam_cracklib.so retry=3 maxrepeat=0 minlen=8 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 reject_username enforce_for_root + +password required pam_pwhistory.so remember=10 use_authtok enforce_for_root + +password [success=1 default=ignore] pam_unix.so obscure yescrypt +# here's the fallback if no module succeeds +password requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +password required pam_permit.so +# and here are more per-package modules (the "Additional" block) +# end of pam-auth-update config \ No newline at end of file diff --git a/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/login.defs b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/login.defs new file mode 100644 index 000000000000..1c8b360a14aa --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/login.defs @@ -0,0 +1,340 @@ +# +# /etc/login.defs - Configuration control definitions for the login package. +# +# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH. +# If unspecified, some arbitrary (and possibly incorrect) value will +# be assumed. All other items are optional - if not specified then +# the described action or option will be inhibited. +# +# Comment lines (lines beginning with "#") and blank lines are ignored. +# +# Modified for Linux. --marekm + +# REQUIRED for useradd/userdel/usermod +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define MAIL_DIR and MAIL_FILE, +# MAIL_DIR takes precedence. +# +# Essentially: +# - MAIL_DIR defines the location of users mail spool files +# (for mbox use) by appending the username to MAIL_DIR as defined +# below. +# - MAIL_FILE defines the location of the users mail spool files as the +# fully-qualified filename obtained by prepending the user home +# directory before $MAIL_FILE +# +# NOTE: This is no more used for setting up users MAIL environment variable +# which is, starting from shadow 4.0.12-1 in Debian, entirely the +# job of the pam_mail PAM modules +# See default PAM configuration files provided for +# login, su, etc. +# +# This is a temporary situation: setting these variables will soon +# move to /etc/default/useradd and the variables will then be +# no more supported +MAIL_DIR /var/mail +#MAIL_FILE .mail + +# +# Enable logging and display of /var/log/faillog login failure info. +# This option conflicts with the pam_tally PAM module. +# +FAILLOG_ENAB yes + +# +# Enable display of unknown usernames when login failures are recorded. +# +# WARNING: Unknown usernames may become world readable. +# See #290803 and #298773 for details about how this could become a security +# concern +LOG_UNKFAIL_ENAB no + +# +# Enable logging of successful logins +# +LOG_OK_LOGINS no + +# +# Enable "syslog" logging of su activity - in addition to sulog file logging. +# SYSLOG_SG_ENAB does the same for newgrp and sg. +# +SYSLOG_SU_ENAB yes +SYSLOG_SG_ENAB yes + +# +# If defined, all su activity is logged to this file. +# +#SULOG_FILE /var/log/sulog + +# +# If defined, file which maps tty line to TERM environment parameter. +# Each line of the file is in a format something like "vt100 tty01". +# +#TTYTYPE_FILE /etc/ttytype + +# +# If defined, login failures will be logged here in a utmp format +# last, when invoked as lastb, will read /var/log/btmp, so... +# +FTMP_FILE /var/log/btmp + +# +# If defined, the command name to display when running "su -". For +# example, if this is defined as "su" then a "ps" will display the +# command is "-su". If not defined, then "ps" would display the +# name of the shell actually being run, e.g. something like "-sh". +# +SU_NAME su + +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# +# *REQUIRED* The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a "write" program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP to the group number and +# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign +# TTYPERM to either 622 or 600. +# +# In Debian /usr/bin/bsd-write or similar programs are setgid tty +# However, the default and recommended value for TTYPERM is still 0600 +# to not allow anyone to write to anyone else console or terminal + +# Users can still allow other people to write them by issuing +# the "mesg y" command. + +TTYGROUP tty +TTYPERM 0600 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# UMASK Default "umask" value. +# +# The ERASECHAR and KILLCHAR are used only on System V machines. +# +# UMASK is the default umask value for pam_umask and is used by +# useradd and newusers to set the mode of the new home directories. +# 022 is the "historical" value in Debian for UMASK +# 027, or even 077, could be considered better for privacy +# There is no One True Answer here : each sysadmin must make up his/her +# mind. +# +# If USERGROUPS_ENAB is set to "yes", that will modify this UMASK default value +# for private user groups, i. e. the uid is the same as gid, and username is +# the same as the primary group name: for these, the user permissions will be +# used as group permissions, e. g. 022 will become 002. +# +# Prefix these values with "0" to get octal, "0x" to get hexadecimal. +# +ERASECHAR 0177 +KILLCHAR 025 +UMASK 022 + +# +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 180 +PASS_MIN_DAYS 0 +PASS_WARN_AGE 15 + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +#SYS_UID_MIN 100 +#SYS_UID_MAX 999 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +#SYS_GID_MIN 100 +#SYS_GID_MAX 999 + +# +# Max number of login retries if password is bad. This will most likely be +# overriden by PAM, since the default pam_unix module has it's own built +# in of 3 retries. However, this is a safe fallback in case you are using +# an authentication module that does not enforce PAM_MAXTRIES. +# +LOGIN_RETRIES 5 + +# +# Max time in seconds for login +# +LOGIN_TIMEOUT 60 + +# +# Which fields may be changed by regular users using chfn - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +CHFN_RESTRICT rwh + +# +# Should login be allowed if we can't cd to the home directory? +# Default in no. +# +DEFAULT_HOME yes + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# If set to yes, userdel will remove the user's group if it contains no +# more members, and useradd will create by default a group with the name +# of the user. +# +# Other former uses of this variable such as setting the umask when +# user==primary group are not used in PAM environments, such as Debian +# +USERGROUPS_ENAB yes + +# +# Instead of the real user shell, the program specified by this parameter +# will be launched, although its visible name (argv[0]) will be the shell's. +# The program may do whatever it wants (logging, additional authentification, +# banner, ...) before running the actual shell. +# +# FAKE_SHELL /bin/fakeshell + +# +# If defined, either full pathname of a file containing device names or +# a ":" delimited list of device names. Root logins will be allowed only +# upon these devices. +# +# This variable is used by login and su. +# +#CONSOLE /etc/consoles +#CONSOLE console:tty01:tty02:tty03:tty04 + +# +# List of groups to add to the user's supplementary group set +# when logging in on the console (as determined by the CONSOLE +# setting). Default is none. +# +# Use with caution - it is possible for users to gain permanent +# access to these groups, even when not logged in on the console. +# How to do it is left as an exercise for the reader... +# +# This variable is used by login and su. +# +#CONSOLE_GROUPS floppy:audio:cdrom + +# +# If set to "yes", new passwords will be encrypted using the MD5-based +# algorithm compatible with the one used by recent releases of FreeBSD. +# It supports passwords of unlimited length and longer salt strings. +# Set to "no" if you need to copy encrypted passwords to other systems +# which don't understand the new algorithm. Default is "no". +# +# This variable is deprecated. You should use ENCRYPT_METHOD. +# +#MD5_CRYPT_ENAB no + +# +# If set to MD5 , MD5-based algorithm will be used for encrypting password +# If set to SHA256, SHA256-based algorithm will be used for encrypting password +# If set to SHA512, SHA512-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# Overrides the MD5_CRYPT_ENAB option +# +# Note: It is recommended to use a value consistent with +# the PAM modules configuration. +# +ENCRYPT_METHOD SHA512 + +# +# Only used if ENCRYPT_METHOD is set to SHA256 or SHA512. +# +# Define the number of SHA rounds. +# With a lot of rounds, it is more difficult to brute forcing the password. +# But note also that it more CPU resources will be needed to authenticate +# users. +# +# If not specified, the libc will choose the default number of rounds (5000). +# The values must be inside the 1000-999999999 range. +# If only one of the MIN or MAX values is set, then this value will be used. +# If MIN > MAX, the highest value will be used. +# +# SHA_CRYPT_MIN_ROUNDS 5000 +# SHA_CRYPT_MAX_ROUNDS 5000 + +################# OBSOLETED BY PAM ############## +# # +# These options are now handled by PAM. Please # +# edit the appropriate file in /etc/pam.d/ to # +# enable the equivelants of them. +# +############### + +#MOTD_FILE +#DIALUPS_CHECK_ENAB +#LASTLOG_ENAB +#MAIL_CHECK_ENAB +#OBSCURE_CHECKS_ENAB +#PORTTIME_CHECKS_ENAB +#SU_WHEEL_ONLY +#CRACKLIB_DICTPATH +#PASS_CHANGE_TRIES +#PASS_ALWAYS_WARN +#ENVIRON_FILE +#NOLOGINS_FILE +#ISSUE_FILE +#PASS_MIN_LEN +#PASS_MAX_LEN +#ULIMIT +#ENV_HZ +#CHFN_AUTH +#CHSH_AUTH +#FAIL_DELAY + +################# OBSOLETED ####################### +# # +# These options are no more handled by shadow. # +# # +# Shadow utilities will display a warning if they # +# still appear. # +# # +################################################### + +# CLOSE_SESSIONS +# LOGIN_STRING +# NO_PASSWORD_CONSOLE +# QMAIL_DIR + + + diff --git a/src/sonic-host-services/tests/hostcfgd/test_passwh_vectors.py b/src/sonic-host-services/tests/hostcfgd/test_passwh_vectors.py new file mode 100644 index 000000000000..acf1c7671125 --- /dev/null +++ b/src/sonic-host-services/tests/hostcfgd/test_passwh_vectors.py @@ -0,0 +1,244 @@ +""" + hostcfgd test password hardening vector +""" +HOSTCFGD_TEST_PASSWH_VECTOR = [ + [ + "PASSWORD_HARDENING", + { + "default_values":{ + "PASSW_HARDENING": { + "POLICIES":{ + "state": "disabled", + "expiration": "180", + "expiration_warning": "15", + "history_cnt": "10", + "len_min": "8", + "reject_user_passw_match": "True", + "lower_class": "True", + "upper_class": "True", + "digits_class": "True", + "special_class": "True" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hostname": "radius", + } + }, + "FEATURE": { + "dhcp_relay": { + "auto_restart": "enabled", + "has_global_scope": "True", + "has_per_asic_scope": "False", + "has_timer": "False", + "high_mem_alert": "disabled", + "set_owner": "kube", + "state": "enabled" + }, + }, + "KDUMP": { + "config": { + "enabled": "false", + "num_dumps": "3", + "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M" + } + } + }, + "enable_feature":{ + "PASSW_HARDENING": { + "POLICIES":{ + "state": "enabled", + "expiration": "180", + "expiration_warning": "15", + "history_cnt": "10", + "len_min": "8", + "reject_user_passw_match": "True", + "lower_class": "True", + "upper_class": "True", + "digits_class": "True", + "special_class": "True" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hostname": "radius", + } + }, + "FEATURE": { + "dhcp_relay": { + "auto_restart": "enabled", + "has_global_scope": "True", + "has_per_asic_scope": "False", + "has_timer": "False", + "high_mem_alert": "disabled", + "set_owner": "kube", + "state": "enabled" + }, + }, + "KDUMP": { + "config": { + "enabled": "false", + "num_dumps": "3", + "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M" + } + } + }, + "enable_digits_class":{ + "PASSW_HARDENING": { + "POLICIES":{ + "state": "enabled", + "expiration": "0", + "expiration_warning": "0", + "history_cnt": "0", + "len_min": "8", + "reject_user_passw_match": "False", + "lower_class": "False", + "upper_class": "False", + "digits_class": "True", + "special_class": "False" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hostname": "radius", + } + }, + "FEATURE": { + "dhcp_relay": { + "auto_restart": "enabled", + "has_global_scope": "True", + "has_per_asic_scope": "False", + "has_timer": "False", + "high_mem_alert": "disabled", + "set_owner": "kube", + "state": "enabled" + }, + }, + "KDUMP": { + "config": { + "enabled": "false", + "num_dumps": "3", + "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M" + } + } + }, + "enable_lower_class":{ + "PASSW_HARDENING": { + "POLICIES":{ + "state": "enabled", + "expiration": "0", + "expiration_warning": "0", + "history_cnt": "0", + "len_min": "8", + "reject_user_passw_match": "False", + "lower_class": "True", + "upper_class": "False", + "digits_class": "False", + "special_class": "False" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hostname": "radius", + } + }, + "FEATURE": { + "dhcp_relay": { + "auto_restart": "enabled", + "has_global_scope": "True", + "has_per_asic_scope": "False", + "has_timer": "False", + "high_mem_alert": "disabled", + "set_owner": "kube", + "state": "enabled" + }, + }, + "KDUMP": { + "config": { + "enabled": "false", + "num_dumps": "3", + "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M" + } + }, + }, + "enable_upper_class":{ + "PASSW_HARDENING": { + "POLICIES":{ + "state": "enabled", + "expiration": "0", + "expiration_warning": "0", + "history_cnt": "0", + "len_min": "8", + "reject_user_passw_match": "False", + "lower_class": "False", + "upper_class": "True", + "digits_class": "False", + "special_class": "False" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hostname": "radius", + } + }, + "FEATURE": { + "dhcp_relay": { + "auto_restart": "enabled", + "has_global_scope": "True", + "has_per_asic_scope": "False", + "has_timer": "False", + "high_mem_alert": "disabled", + "set_owner": "kube", + "state": "enabled" + }, + }, + "KDUMP": { + "config": { + "enabled": "false", + "num_dumps": "3", + "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M" + } + } + }, + "enable_special_class":{ + "PASSW_HARDENING": { + "POLICIES":{ + "state": "enabled", + "expiration": "0", + "expiration_warning": "0", + "history_cnt": "0", + "len_min": "8", + "reject_user_passw_match": "False", + "lower_class": "False", + "upper_class": "False", + "digits_class": "False", + "special_class": "True" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hostname": "radius", + } + }, + "FEATURE": { + "dhcp_relay": { + "auto_restart": "enabled", + "has_global_scope": "True", + "has_per_asic_scope": "False", + "has_timer": "False", + "high_mem_alert": "disabled", + "set_owner": "kube", + "state": "enabled" + }, + }, + "KDUMP": { + "config": { + "enabled": "false", + "num_dumps": "3", + "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M" + } + } + } + } + ] +]