Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update rules related to PAM hashing algorithm #12164

Merged

Conversation

marcusburghardt
Copy link
Member

Description:

These rules were using hard-coded hashing algorithm sha512.
However, there are at least 7 possible hashing algorithms to be used, while the most updated products use sha512 and yescrypt.

This PR makes these rules more flexible to use a variable instead of a hard-coded option.

Rationale:

  • Much easier adoption of changes in hashing algorithms values used in PAM.

Review Hints:

I recommend to review commit by commit in the order they are since there are commit messages giving more context about each change.

Technically, the rules can be tested with automatus:

./build_product rhel9

Test the Bash and Ansible remediation for the following rules:

  • set_password_hashing_algorithm_passwordauth
  • set_password_hashing_algorithm_systemauth
  • set_password_hashing_algorithm_logindefs
  • set_password_hashing_algorithm_libuserconf

For example:

./tests/automatus.py rule --libvirt qemu:///session rhel9 --datastream build/ssg-rhel9-ds.xml --dontclean --remediate-using bash set_password_hashing_algorithm_passwordauth
./tests/automatus.py rule --libvirt qemu:///session rhel9 --datastream build/ssg-rhel9-ds.xml --dontclean --remediate-using ansible set_password_hashing_algorithm_passwordauth

Currently there are at least 7 possible hashing algorithms to be used
with pam_unix.so, such as sha512, yescrypt and blowfish. Most of the
current Linux distributions uses sha512 or yescrypt. This variable gives
flexibility to select which algorithm to be checked.

Signed-off-by: Marcus Burghardt <[email protected]>
set_password_hashing_algorithm_systemauth description was updated to use
the value of var_password_hashing_algorithm_pam variable. Also some
minor improvements in wording were made.

Signed-off-by: Marcus Burghardt <[email protected]>
The regex for the textfilecontent54_object was also updated to consider
a situation where multiple hashing algorithms are specified as
pam_unix.so options. This may cause unexpected behaviors in the system.
If this situation happens, the rule will fail and demand remediation to
make sure that only one hashing algorithm is specified.

Signed-off-by: Marcus Burghardt <[email protected]>
Since the OVAL is now considering the new variable value, test scenarios
are also aligned to use it.

Signed-off-by: Marcus Burghardt <[email protected]>
If more than one option related to hashing algorithms in pam_unix.so
line is specified the rule should fail.

Signed-off-by: Marcus Burghardt <[email protected]>
Bash remediation is now considering the variable for hashing algorithm
option. It is also ensuring only one hashing algorithm option is used.

Signed-off-by: Marcus Burghardt <[email protected]>
Ansible remediation was also update in alignment to Bash remediation.
For the removal of multiple hashing algorithm options, the Ansible task
was inspired in ansible_remove_pam_module_option_configuration macro,
but with a change to attend the specific case of this rule.

Signed-off-by: Marcus Burghardt <[email protected]>
Aligned to the set_password_hashing_algorithm_systemauth rule.

Signed-off-by: Marcus Burghardt <[email protected]>
In alignment to set_password_hashing_algorithm_systemauth, oval, bash
and ansible and test scenarios were updated to properly use the
var_password_hashing_algorithm_pam variable.

Signed-off-by: Marcus Burghardt <[email protected]>
Minor description updates and also ensured the variable is honored in
test scenario scripts.

Signed-off-by: Marcus Burghardt <[email protected]>
Aligned to other rules related to hashing algorithm in order to use
variable instead of a hardcoded sha512 value.

Signed-off-by: Marcus Burghardt <[email protected]>
@marcusburghardt marcusburghardt added Ansible Ansible remediation update. refactoring Improvement which, once completed, will enable the project to progress faster. OVAL OVAL update. Related to the systems assessments. Bash Bash remediation update. Update Rule Issues or pull requests related to Rules updates. labels Jul 16, 2024
@marcusburghardt marcusburghardt added this to the 0.1.74 milestone Jul 16, 2024
@marcusburghardt marcusburghardt requested a review from a team July 16, 2024 14:11
Copy link

Start a new ephemeral environment with changes proposed in this pull request:

rhel8 (from CTF) Environment (using Fedora as testing environment)
Open in Gitpod

Fedora Testing Environment
Open in Gitpod

Oracle Linux 8 Environment
Open in Gitpod

Copy link

github-actions bot commented Jul 16, 2024

This datastream diff is auto generated by the check Compare DS/Generate Diff

Click here to see the full diff
New content has different text for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf'.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf
@@ -3,10 +3,10 @@
 Set Password Hashing Algorithm in /etc/libuser.conf
 
 [description]:
-In /etc/libuser.conf, add or correct the following line in its
-[defaults] section to ensure the system will use the SHA-512
+In /etc/libuser.conf, add or correct the following line in its [defaults]
+section to ensure the system will use the 'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm_pam'
 algorithm for password hashing:
-crypt_style = sha512
+crypt_style = 'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm_pam'
 
 [reference]:
 1
@@ -192,18 +192,16 @@
 8.3.2
 
 [rationale]:
-Passwords need to be protected at all times, and encryption is the standard
-method for protecting passwords. If passwords are not encrypted, they can
-be plainly read (i.e., clear text) and easily compromised. Passwords that
-are encrypted with a weak algorithm are no more protected than if they are
-kepy in plain text.
+Passwords need to be protected at all times, and encryption is the standard method for
+protecting passwords. If passwords are not encrypted, they can be plainly read
+(i.e., clear text) and easily compromised. Passwords that are encrypted with a weak algorithm
+are no more protected than if they are kept in plain text.
 
          
-This setting ensures user and group account administration utilities are
-configured to store only encrypted representations of passwords.
-Additionally, the crypt_style configuration option ensures the use
-of a strong hashing algorithm that makes password cracking attacks more
-difficult.
+This setting ensures user and group account administration utilities are configured to store
+only encrypted representations of passwords. Additionally, the crypt_style
+configuration option in /etc/libuser.conf ensures the use of a strong hashing
+algorithm that makes password cracking attacks more difficult.
 
 [ident]:
 CCE-80891-5

OVAL for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf' differs.
--- oval:ssg-set_password_hashing_algorithm_libuserconf:def:1
+++ oval:ssg-set_password_hashing_algorithm_libuserconf:def:1
@@ -1,2 +1,2 @@
 criteria AND
-criterion oval:ssg-test_etc_libuser_conf_cryptstyle:tst:1
+criterion oval:ssg-test_set_password_hashing_algorithm_libuserconf:tst:1

OCIL for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf' differs.
--- ocil:ssg-set_password_hashing_algorithm_libuserconf_ocil:questionnaire:1
+++ ocil:ssg-set_password_hashing_algorithm_libuserconf_ocil:questionnaire:1
@@ -5,6 +5,6 @@
 
 $ sudo grep -i crypt_style /etc/libuser.conf
 
-crypt_style = sha512
+crypt_style = 
       Is it the case that crypt_style is not set to sha512?
       
bash remediation for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf' differs.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf
@@ -1,5 +1,7 @@
 # Remediation is applicable only in certain platforms
 if rpm --quiet -q libuser; then
+
+var_password_hashing_algorithm_pam=''
 
 LIBUSER_CONF="/etc/libuser.conf"
 CRYPT_STYLE_REGEX='[[:space:]]*\[defaults](.*(\n)+)+?[[:space:]]*crypt_style[[:space:]]*'
@@ -7,11 +9,11 @@
 # Try find crypt_style in [defaults] section. If it is here, then change algorithm to sha512.
 # If it isn't here, then add it to [defaults] section.
 if grep -qzosP $CRYPT_STYLE_REGEX $LIBUSER_CONF ; then
-        sed -i "s/\(crypt_style[[:space:]]*=[[:space:]]*\).*/\1sha512/g" $LIBUSER_CONF
+        sed -i "s/\(crypt_style[[:space:]]*=[[:space:]]*\).*/\1$var_password_hashing_algorithm_pam/g" $LIBUSER_CONF
 elif grep -qs "\[defaults]" $LIBUSER_CONF ; then
-        sed -i "/[[:space:]]*\[defaults]/a crypt_style = sha512" $LIBUSER_CONF
+        sed -i "/[[:space:]]*\[defaults]/a crypt_style = $var_password_hashing_algorithm_pam" $LIBUSER_CONF
 else
-        echo -e "[defaults]\ncrypt_style = sha512" >> $LIBUSER_CONF
+        echo -e "[defaults]\ncrypt_style = $var_password_hashing_algorithm_pam" >> $LIBUSER_CONF
 fi
 
 else

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf' differs.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf
@@ -16,13 +16,19 @@
   - no_reboot_needed
   - restrict_strategy
   - set_password_hashing_algorithm_libuserconf
+- name: XCCDF Value var_password_hashing_algorithm_pam # promote to variable
+  set_fact:
+    var_password_hashing_algorithm_pam: !!str 
+  tags:
+    - always
 
-- name: Set Password Hashing Algorithm in /etc/libuser.conf
-  lineinfile:
+- name: Set Password Hashing Algorithm in /etc/libuser.conf - Set Password Hashing
+    Algorithm in /etc/libuser.conf
+  ansible.builtin.lineinfile:
     dest: /etc/libuser.conf
     insertafter: ^\s*\[defaults]
     regexp: ^#?crypt_style
-    line: crypt_style = sha512
+    line: crypt_style = {{ var_password_hashing_algorithm_pam }}
     state: present
     create: true
   when: '"libuser" in ansible_facts.packages'

New content has different text for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs'.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs
@@ -3,8 +3,8 @@
 Set Password Hashing Algorithm in /etc/login.defs
 
 [description]:
-In /etc/login.defs, add or correct the following line to ensure
-the system will use 'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm' as the hashing algorithm:
+In /etc/login.defs, add or update the following line to ensure the system will use
+'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm' as the hashing algorithm:
 ENCRYPT_METHOD 'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm'
 
 [reference]:
@@ -197,9 +197,10 @@
 SV-230231r877397_rule
 
 [rationale]:
-Passwords need to be protected at all times, and encryption is the standard method for protecting passwords.
-If passwords are not encrypted, they can be plainly read (i.e., clear text) and easily compromised. Passwords
-that are encrypted with a weak algorithm are no more protected than if they are kept in plain text.
+Passwords need to be protected at all times, and encryption is the standard method for
+protecting passwords. If passwords are not encrypted, they can be plainly read
+(i.e., clear text) and easily compromised. Passwords that are encrypted with a weak algorithm
+are no more protected than if they are kept in plain text.
 
          
 Using a stronger hashing algorithm makes password cracking attacks more difficult.

OVAL for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs' differs.
--- oval:ssg-set_password_hashing_algorithm_logindefs:def:1
+++ oval:ssg-set_password_hashing_algorithm_logindefs:def:1
@@ -1,2 +1,2 @@
 criteria AND
-criterion oval:ssg-test_etc_login_defs_encrypt_method:tst:1
+criterion oval:ssg-test_set_password_hashing_algorithm_logindefs:tst:1

New content has different text for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth'.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth
@@ -3,21 +3,30 @@
 Set PAM''s Password Hashing Algorithm - password-auth
 
 [description]:
-The PAM system service can be configured to only store encrypted
-representations of passwords. In
-/etc/pam.d/password-auth,
-the
-password section of the file controls which PAM modules execute
-during a password change. Set the pam_unix.so module in the
-password section to include the argument sha512, as shown
-below:
-
-         password    sufficient    pam_unix.so sha512 other arguments...
+The PAM system service can be configured to only store encrypted representations of passwords.
+In /etc/pam.d/password-auth, the password section of the file controls which
+PAM modules to execute during a password change.
+
+Set the pam_unix.so module in the password section to include the option
+'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm_pam' and no other hashing
+algorithms as shown below:
+
+         password    sufficient    pam_unix.so 'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm_pam'
+          other arguments...
          
          
-This will help ensure when local users change their passwords, hashes for
-the new passwords will be generated using the SHA-512 algorithm. This is
-the default.
+This will help ensure that new passwords for local users will be stored using the
+'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm_pam' algorithm.
+
+[warning]:
+The hashing algorithms to be used with pam_unix.so are defined with independent module
+options. There are at least 7 possible algorithms and likely more algorithms will be
+introduced along the time. Due the the number of options and its possible combinations,
+the use of multiple hashing algorithm options may bring unexpected behaviors to the
+system. For this reason the check will pass only when one hashing algorithm option is
+defined and is aligned to the "var_password_hashing_algorithm_pam" variable. The
+remediation will ensure the correct option and remove any other extra hashing algorithm
+option.
 
 [reference]:
 1
@@ -212,18 +221,16 @@
 SV-230237r809276_rule
 
 [rationale]:
-Passwords need to be protected at all times, and encryption is the standard
-method for protecting passwords. If passwords are not encrypted, they can
-be plainly read (i.e., clear text) and easily compromised. Passwords that
-are encrypted with a weak algorithm are no more protected than if they are
-kepy in plain text.
+Passwords need to be protected at all times, and encryption is the standard method for
+protecting passwords. If passwords are not encrypted, they can be plainly read
+(i.e., clear text) and easily compromised. Passwords that are encrypted with a weak algorithm
+are no more protected than if they are kept in plain text.
 
          
-This setting ensures user and group account administration utilities are
-configured to store only encrypted representations of passwords.
-Additionally, the crypt_style configuration option ensures the use
-of a strong hashing algorithm that makes password cracking attacks more
-difficult.
+This setting ensures user and group account administration utilities are configured to store
+only encrypted representations of passwords. Additionally, the crypt_style
+configuration option in /etc/libuser.conf ensures the use of a strong hashing
+algorithm that makes password cracking attacks more difficult.
 
 [ident]:
 CCE-85945-4

OVAL for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth' differs.
--- oval:ssg-set_password_hashing_algorithm_passwordauth:def:1
+++ oval:ssg-set_password_hashing_algorithm_passwordauth:def:1
@@ -1,2 +1,2 @@
 criteria AND
-criterion oval:ssg-test_pam_unix_passwordauth_sha512:tst:1
+criterion oval:ssg-test_set_password_hashing_algorithm_passwordauth:tst:1

OCIL for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth' differs.
--- ocil:ssg-set_password_hashing_algorithm_passwordauth_ocil:questionnaire:1
+++ ocil:ssg-set_password_hashing_algorithm_passwordauth_ocil:questionnaire:1
@@ -1,6 +1,7 @@
 Inspect the password section of /etc/pam.d/password-auth
-and ensure that the pam_unix.so module includes the argument
-sha512:
-$ grep sha512 /etc/pam.d/password-auth
+and ensure that the pam_unix.so module is configured to use the argument
+:
+
+$ grep  /etc/pam.d/password-auth
       Is it the case that it does not?
       
bash remediation for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth' differs.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth
@@ -1,8 +1,12 @@
 # Remediation is applicable only in certain platforms
 if rpm --quiet -q pam; then
 
-if [ -e "/etc/pam.d/password-auth" ] ; then
-    PAM_FILE_PATH="/etc/pam.d/password-auth"
+var_password_hashing_algorithm_pam=''
+
+PAM_FILE_PATH="/etc/pam.d/password-auth"
+
+if [ -e "$PAM_FILE_PATH" ] ; then
+    PAM_FILE_PATH="$PAM_FILE_PATH"
     if [ -f /usr/bin/authselect ]; then
         
         if ! authselect check; then
@@ -29,7 +33,7 @@
             
             authselect apply-changes -b --backup=after-hardening-custom-profile
         fi
-        PAM_FILE_NAME=$(basename "/etc/pam.d/password-auth")
+        PAM_FILE_NAME=$(basename "$PAM_FILE_PATH")
         PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
 
         authselect apply-changes -b
@@ -44,16 +48,70 @@
             fi
         fi
         # Check the option
-        if ! grep -qP "^\s*password\s+sufficient\s+pam_unix.so\s*.*\ssha512\b" "$PAM_FILE_PATH"; then
-            sed -i -E --follow-symlinks "/\s*password\s+sufficient\s+pam_unix.so.*/ s/$/ sha512/" "$PAM_FILE_PATH"
+        if ! grep -qP "^\s*password\s+sufficient\s+pam_unix.so\s*.*\s$var_password_hashing_algorithm_pam\b" "$PAM_FILE_PATH"; then
+            sed -i -E --follow-symlinks "/\s*password\s+sufficient\s+pam_unix.so.*/ s/$/ $var_password_hashing_algorithm_pam/" "$PAM_FILE_PATH"
         fi
     if [ -f /usr/bin/authselect ]; then
         
         authselect apply-changes -b
     fi
 else
-    echo "/etc/pam.d/password-auth was not found" >&2
+    echo "$PAM_FILE_PATH was not found" >&2
 fi
+
+# Ensure only the correct hashing algorithm option is used.
+declare -a HASHING_ALGORITHMS_OPTIONS=("sha512" "yescrypt" "gost_yescrypt" "blowfish" "sha256" "md5" "bigcrypt")
+
+for hash_option in "${HASHING_ALGORITHMS_OPTIONS[@]}"; do
+  if [ "$hash_option" != "$var_password_hashing_algorithm_pam" ]; then
+    if grep -qP "^\s*password\s+.*\s+pam_unix.so\s+.*\b$hash_option\b" "$PAM_FILE_PATH"; then
+      if [ -e "$PAM_FILE_PATH" ] ; then
+    PAM_FILE_PATH="$PAM_FILE_PATH"
+    if [ -f /usr/bin/authselect ]; then
+        
+        if ! authselect check; then
+        echo "
+        authselect integrity check failed. Remediation aborted!
+        This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
+        It is not recommended to manually edit the PAM files when authselect tool is available.
+        In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
+        exit 1
+        fi
+
+        CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
+        # If not already in use, a custom profile is created preserving the enabled features.
+        if [[ ! $CURRENT_PROFILE == custom/* ]]; then
+            ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
+            authselect create-profile hardening -b $CURRENT_PROFILE
+            CURRENT_PROFILE="custom/hardening"
+            
+            authselect apply-changes -b --backup=before-hardening-custom-profile
+            authselect select $CURRENT_PROFILE
+            for feature in $ENABLED_FEATURES; do
+                authselect enable-feature $feature;
+            done
+            
+            authselect apply-changes -b --backup=after-hardening-custom-profile
+        fi
+        PAM_FILE_NAME=$(basename "$PAM_FILE_PATH")
+        PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
+
+        authselect apply-changes -b
+    fi
+    
+if grep -qP "^\s*password\s+.*\s+pam_unix.so\s.*\b$hash_option\b" "$PAM_FILE_PATH"; then
+    sed -i -E --follow-symlinks "s/(.*password.*.*.*pam_unix.so.*)\s$hash_option=?[[:alnum:]]*(.*)/\1\2/g" "$PAM_FILE_PATH"
+fi
+    if [ -f /usr/bin/authselect ]; then
+        
+        authselect apply-changes -b
+    fi
+else
+    echo "$PAM_FILE_PATH was not found" >&2
+fi
+    fi
+  fi
+done
 
 else
     >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth' differs.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth
@@ -16,6 +16,11 @@
   - medium_severity
   - no_reboot_needed
   - set_password_hashing_algorithm_passwordauth
+- name: XCCDF Value var_password_hashing_algorithm_pam # promote to variable
+  set_fact:
+    var_password_hashing_algorithm_pam: !!str 
+  tags:
+    - always
 
 - name: Set PAM's Password Hashing Algorithm - password-auth - Check if /etc/pam.d/password-auth
     file is present
@@ -259,19 +264,20 @@
       PAM module option is present in {{ pam_file_path }}
     ansible.builtin.lineinfile:
       path: '{{ pam_file_path }}'
-      regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\ssha512\b
+      regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{
+        var_password_hashing_algorithm_pam }}\b
       state: absent
     check_mode: true
     changed_when: false
     register: result_pam_module_set_password_hashing_algorithm_passwordauth_option_present
 
-  - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the "sha512"
-      PAM option for "pam_unix.so" is included in {{ pam_file_path }}
+  - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the "{{ var_password_hashing_algorithm_pam
+      }}" PAM option for "pam_unix.so" is included in {{ pam_file_path }}
     ansible.builtin.lineinfile:
       path: '{{ pam_file_path }}'
       backrefs: true
       regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
-      line: \1 sha512
+      line: \1 {{ var_password_hashing_algorithm_pam }}
       state: present
     register: result_pam_set_password_hashing_algorithm_passwordauth_add
     when:
@@ -305,3 +311,216 @@
   - medium_severity
   - no_reboot_needed
   - set_password_hashing_algorithm_passwordauth
+
+- name: Set PAM's Password Hashing Algorithm - password-auth - Check if /etc/pam.d/password-auth
+    File is Present
+  ansible.builtin.stat:
+    path: /etc/pam.d/password-auth
+  register: result_pam_file_present
+  when: '"pam" in ansible_facts.packages'
+  tags:
+  - CCE-85945-4
+  - CJIS-5.6.2.2
+  - DISA-STIG-RHEL-08-010160
+  - NIST-800-171-3.13.11
+  - NIST-800-53-CM-6(a)
+  - NIST-800-53-IA-5(1)(c)
+  - NIST-800-53-IA-5(c)
+  - PCI-DSS-Req-8.2.1
+  - configure_strategy
+  - low_complexity
+  - medium_disruption
+  - medium_severity
+  - no_reboot_needed
+  - set_password_hashing_algorithm_passwordauth
+
+- name: Set PAM's Password Hashing Algorithm - password-auth - Check The Proper Remediation
+    For The System
+  block:
+
+  - name: Set PAM's Password Hashing Algorithm - password-auth - Define the PAM file
+      to be edited as a local fact
+    ansible.builtin.set_fact:
+      pam_file_path: /etc/pam.d/password-auth
+
+  - name: Set PAM's Password Hashing Algorithm - password-auth - Check if system relies
+      on authselect tool
+    ansible.builtin.stat:
+      path: /usr/bin/authselect
+    register: result_authselect_present
+
+  - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
+      custom profile is used if authselect is present
+    block:
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Check integrity
+        of authselect current profile
+      ansible.builtin.command:
+        cmd: authselect check
+      register: result_authselect_check_cmd
+      changed_when: false
+      failed_when: false
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Informative message
+        based on the authselect integrity check result
+      ansible.builtin.assert:
+        that:
+        - result_authselect_check_cmd.rc == 0
+        fail_msg:
+        - authselect integrity check failed. Remediation aborted!
+        - This remediation could not be applied because an authselect profile was
+          not selected or the selected profile is not intact.
+        - It is not recommended to manually edit the PAM files when authselect tool
+          is available.
+        - In cases where the default authselect profile does not cover a specific
+          demand, a custom authselect profile is recommended.
+        success_msg:
+        - authselect integrity check passed
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Get authselect
+        current profile
+      ansible.builtin.shell:
+        cmd: authselect current -r | awk '{ print $1 }'
+      register: result_authselect_profile
+      changed_when: false
+      when:
+      - result_authselect_check_cmd is success
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Define the current
+        authselect profile as a local fact
+      ansible.builtin.set_fact:
+        authselect_current_profile: '{{ result_authselect_profile.stdout }}'
+        authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
+      when:
+      - result_authselect_profile is not skipped
+      - result_authselect_profile.stdout is match("custom/")
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Define the new
+        authselect custom profile as a local fact
+      ansible.builtin.set_fact:
+        authselect_current_profile: '{{ result_authselect_profile.stdout }}'
+        authselect_custom_profile: custom/hardening
+      when:
+      - result_authselect_profile is not skipped
+      - result_authselect_profile.stdout is not match("custom/")
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Get authselect
+        current features to also enable them in the custom profile
+      ansible.builtin.shell:
+        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
+      register: result_authselect_features
+      changed_when: false
+      when:
+      - result_authselect_profile is not skipped
+      - authselect_current_profile is not match("custom/")
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Check if any custom
+        profile with the same name was already created
+      ansible.builtin.stat:
+        path: /etc/authselect/{{ authselect_custom_profile }}
+      register: result_authselect_custom_profile_present
+      changed_when: false
+      when:
+      - authselect_current_profile is not match("custom/")
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Create an authselect
+        custom profile based on the current profile
+      ansible.builtin.command:
+        cmd: authselect create-profile hardening -b {{ authselect_current_profile
+          }}
+      when:
+      - result_authselect_check_cmd is success
+      - authselect_current_profile is not match("custom/")
+      - not result_authselect_custom_profile_present.stat.exists
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
+        changes are applied
+      ansible.builtin.command:
+        cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
+      when:
+      - result_authselect_check_cmd is success
+      - result_authselect_profile is not skipped
+      - authselect_current_profile is not match("custom/")
+      - authselect_custom_profile is not match(authselect_current_profile)
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the authselect
+        custom profile is selected
+      ansible.builtin.command:
+        cmd: authselect select {{ authselect_custom_profile }}
+      register: result_pam_authselect_select_profile
+      when:
+      - result_authselect_check_cmd is success
+      - result_authselect_profile is not skipped
+      - authselect_current_profile is not match("custom/")
+      - authselect_custom_profile is not match(authselect_current_profile)
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Restore the authselect
+        features in the custom profile
+      ansible.builtin.command:
+        cmd: authselect enable-feature {{ item }}
+      loop: '{{ result_authselect_features.stdout_lines }}'
+      register: result_pam_authselect_restore_features
+      when:
+      - result_authselect_profile is not skipped
+      - result_authselect_features is not skipped
+      - result_pam_authselect_select_profile is not skipped
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
+        changes are applied
+      ansible.builtin.command:
+        cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
+      when:
+      - result_authselect_check_cmd is success
+      - result_authselect_profile is not skipped
+      - result_pam_authselect_restore_features is not skipped
+
+    - name: Set PAM's Password Hashing Algorithm - password-auth - Change the PAM
+        file to be edited according to the custom authselect profile
+      ansible.builtin.set_fact:
+        pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
+          | basename }}
+    when:
+    - result_authselect_present.stat.exists
+
+  - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure That Only
+      the Correct Hashing Algorithm Option For pam_unix.so Is Used in /etc/pam.d/password-auth
+    ansible.builtin.replace:
+      dest: '{{ pam_file_path }}'
+      regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*)
+      replace: \1\2
+    when: item != var_password_hashing_algorithm_pam
+    loop:
+    - sha512
+    - yescrypt
+    - gost_yescrypt
+    - blowfish
+    - sha256
+    - md5
+    - bigcrypt
+    register: result_pam_hashing_options_removal
+
+  - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect
+      changes are applied
+    ansible.builtin.command:
+      cmd: authselect apply-changes -b
+    when:
+    - result_authselect_present.stat.exists
+    - result_pam_hashing_options_removal is changed
+  when:
+  - '"pam" in ansible_facts.packages'
+  - result_pam_file_present.stat.exists
+  tags:
+  - CCE-85945-4
+  - CJIS-5.6.2.2
+  - DISA-STIG-RHEL-08-010160
+  - NIST-800-171-3.13.11
+  - NIST-800-53-CM-6(a)
+  - NIST-800-53-IA-5(1)(c)
+  - NIST-800-53-IA-5(c)
+  - PCI-DSS-Req-8.2.1
+  - configure_strategy
+  - low_complexity
+  - medium_disruption
+  - medium_severity
+  - no_reboot_needed
+  - set_password_hashing_algorithm_passwordauth

New content has different text for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth'.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
@@ -3,19 +3,30 @@
 Set PAM''s Password Hashing Algorithm
 
 [description]:
-The PAM system service can be configured to only store encrypted
-representations of passwords. In "/etc/pam.d/system-auth", the
-password section of the file controls which PAM modules execute
-during a password change. Set the pam_unix.so module in the
-password section to include the argument sha512, as shown
-below:
-
-         password    sufficient    pam_unix.so sha512 other arguments...
+The PAM system service can be configured to only store encrypted representations of passwords.
+In "/etc/pam.d/system-auth", the password section of the file controls which
+PAM modules to execute during a password change.
+
+Set the pam_unix.so module in the password section to include the option
+'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm_pam' and no other hashing
+algorithms as shown below:
+
+         password    sufficient    pam_unix.so 'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm_pam'
+          other arguments...
          
          
-This will help ensure when local users change their passwords, hashes for
-the new passwords will be generated using the SHA-512 algorithm. This is
-the default.
+This will help ensure that new passwords for local users will be stored using the
+'xccdf_org.ssgproject.content_value_var_password_hashing_algorithm_pam' algorithm.
+
+[warning]:
+The hashing algorithms to be used with pam_unix.so are defined with independent module
+options. There are at least 7 possible algorithms and likely more algorithms will be
+introduced along the time. Due the the number of options and its possible combinations,
+the use of multiple hashing algorithm options may bring unexpected behaviors to the
+system. For this reason the check will pass only when one hashing algorithm option is
+defined and is aligned to the "var_password_hashing_algorithm_pam" variable. The
+remediation will ensure the correct option and remove any other extra hashing algorithm
+option.
 
 [reference]:
 1
@@ -216,18 +227,16 @@
 SV-244524r809331_rule
 
 [rationale]:
-Passwords need to be protected at all times, and encryption is the standard
-method for protecting passwords. If passwords are not encrypted, they can
-be plainly read (i.e., clear text) and easily compromised. Passwords that
-are encrypted with a weak algorithm are no more protected than if they are
-kepy in plain text.
+Passwords need to be protected at all times, and encryption is the standard method for
+protecting passwords. If passwords are not encrypted, they can be plainly read
+(i.e., clear text) and easily compromised. Passwords that are encrypted with a weak algorithm
+are no more protected than if they are kept in plain text.
 
          
-This setting ensures user and group account administration utilities are
-configured to store only encrypted representations of passwords.
-Additionally, the crypt_style configuration option ensures the use
-of a strong hashing algorithm that makes password cracking attacks more
-difficult.
+This setting ensures user and group account administration utilities are configured to store
+only encrypted representations of passwords. Additionally, the crypt_style
+configuration option in /etc/libuser.conf ensures the use of a strong hashing
+algorithm that makes password cracking attacks more difficult.
 
 [ident]:
 CCE-80893-1

OVAL for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth' differs.
--- oval:ssg-set_password_hashing_algorithm_systemauth:def:1
+++ oval:ssg-set_password_hashing_algorithm_systemauth:def:1
@@ -1,2 +1,2 @@
 criteria AND
-criterion oval:ssg-test_pam_unix_sha512:tst:1
+criterion oval:ssg-test_pam_unix_hashing_algorithm_systemauth:tst:1

OCIL for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth' differs.
--- ocil:ssg-set_password_hashing_algorithm_systemauth_ocil:questionnaire:1
+++ ocil:ssg-set_password_hashing_algorithm_systemauth_ocil:questionnaire:1
@@ -1,9 +1,9 @@
 Inspect the password section of /etc/pam.d/system-auth
-and ensure that the pam_unix.so module  is configured to use the argument
-sha512:
+and ensure that the pam_unix.so module is configured to use the argument
+:
 
-$ sudo grep "^password.*pam_unix\.so.*sha512" /etc/pam.d/system-auth
+$ sudo grep "^password.*pam_unix\.so.*" /etc/pam.d/system-auth
 
-password sufficient pam_unix.so sha512
-      Is it the case that "sha512" is missing, or is commented out?
+password sufficient pam_unix.so 
+      Is it the case that "<sub idref="var_password_hashing_algorithm_pam" />" is missing, or is commented out?
       
bash remediation for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth' differs.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
@@ -1,8 +1,14 @@
 # Remediation is applicable only in certain platforms
 if rpm --quiet -q pam; then
 
-if [ -e "/etc/pam.d/system-auth" ] ; then
-    PAM_FILE_PATH="/etc/pam.d/system-auth"
+var_password_hashing_algorithm_pam=''
+
+
+PAM_FILE_PATH="/etc/pam.d/system-auth"
+CONTROL="sufficient"
+
+if [ -e "$PAM_FILE_PATH" ] ; then
+    PAM_FILE_PATH="$PAM_FILE_PATH"
     if [ -f /usr/bin/authselect ]; then
         
         if ! authselect check; then
@@ -29,31 +35,85 @@
             
             authselect apply-changes -b --backup=after-hardening-custom-profile
         fi
-        PAM_FILE_NAME=$(basename "/etc/pam.d/system-auth")
+        PAM_FILE_NAME=$(basename "$PAM_FILE_PATH")
         PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
 
         authselect apply-changes -b
     fi
-    if ! grep -qP "^\s*password\s+sufficient\s+pam_unix.so\s*.*" "$PAM_FILE_PATH"; then
+    if ! grep -qP "^\s*password\s+$CONTROL\s+pam_unix.so\s*.*" "$PAM_FILE_PATH"; then
             # Line matching group + control + module was not found. Check group + module.
             if [ "$(grep -cP '^\s*password\s+.*\s+pam_unix.so\s*' "$PAM_FILE_PATH")" -eq 1 ]; then
                 # The control is updated only if one single line matches.
-                sed -i -E --follow-symlinks "s/^(\s*password\s+).*(\bpam_unix.so.*)/\1sufficient \2/" "$PAM_FILE_PATH"
+                sed -i -E --follow-symlinks "s/^(\s*password\s+).*(\bpam_unix.so.*)/\1$CONTROL \2/" "$PAM_FILE_PATH"
             else
-                echo "password    sufficient    pam_unix.so" >> "$PAM_FILE_PATH"
+                echo "password    $CONTROL    pam_unix.so" >> "$PAM_FILE_PATH"
             fi
         fi
         # Check the option
-        if ! grep -qP "^\s*password\s+sufficient\s+pam_unix.so\s*.*\ssha512\b" "$PAM_FILE_PATH"; then
-            sed -i -E --follow-symlinks "/\s*password\s+sufficient\s+pam_unix.so.*/ s/$/ sha512/" "$PAM_FILE_PATH"
+        if ! grep -qP "^\s*password\s+$CONTROL\s+pam_unix.so\s*.*\s$var_password_hashing_algorithm_pam\b" "$PAM_FILE_PATH"; then
+            sed -i -E --follow-symlinks "/\s*password\s+$CONTROL\s+pam_unix.so.*/ s/$/ $var_password_hashing_algorithm_pam/" "$PAM_FILE_PATH"
         fi
     if [ -f /usr/bin/authselect ]; then
         
         authselect apply-changes -b
     fi
 else
-    echo "/etc/pam.d/system-auth was not found" >&2
+    echo "$PAM_FILE_PATH was not found" >&2
 fi
+
+# Ensure only the correct hashing algorithm option is used.
+declare -a HASHING_ALGORITHMS_OPTIONS=("sha512" "yescrypt" "gost_yescrypt" "blowfish" "sha256" "md5" "bigcrypt")
+
+for hash_option in "${HASHING_ALGORITHMS_OPTIONS[@]}"; do
+  if [ "$hash_option" != "$var_password_hashing_algorithm_pam" ]; then
+    if grep -qP "^\s*password\s+.*\s+pam_unix.so\s+.*\b$hash_option\b" "$PAM_FILE_PATH"; then
+      if [ -e "$PAM_FILE_PATH" ] ; then
+    PAM_FILE_PATH="$PAM_FILE_PATH"
+    if [ -f /usr/bin/authselect ]; then
+        
+        if ! authselect check; then
+        echo "
+        authselect integrity check failed. Remediation aborted!
+        This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
+        It is not recommended to manually edit the PAM files when authselect tool is available.
+        In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
+        exit 1
+        fi
+
+        CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
+        # If not already in use, a custom profile is created preserving the enabled features.
+        if [[ ! $CURRENT_PROFILE == custom/* ]]; then
+            ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
+            authselect create-profile hardening -b $CURRENT_PROFILE
+            CURRENT_PROFILE="custom/hardening"
+            
+            authselect apply-changes -b --backup=before-hardening-custom-profile
+            authselect select $CURRENT_PROFILE
+            for feature in $ENABLED_FEATURES; do
+                authselect enable-feature $feature;
+            done
+            
+            authselect apply-changes -b --backup=after-hardening-custom-profile
+        fi
+        PAM_FILE_NAME=$(basename "$PAM_FILE_PATH")
+        PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
+
+        authselect apply-changes -b
+    fi
+    
+if grep -qP "^\s*password\s+.*\s+pam_unix.so\s.*\b$hash_option\b" "$PAM_FILE_PATH"; then
+    sed -i -E --follow-symlinks "s/(.*password.*.*.*pam_unix.so.*)\s$hash_option=?[[:alnum:]]*(.*)/\1\2/g" "$PAM_FILE_PATH"
+fi
+    if [ -f /usr/bin/authselect ]; then
+        
+        authselect apply-changes -b
+    fi
+else
+    echo "$PAM_FILE_PATH was not found" >&2
+fi
+    fi
+  fi
+done
 
 else
     >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth' differs.
--- xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
+++ xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
@@ -17,6 +17,11 @@
   - medium_severity
   - no_reboot_needed
   - set_password_hashing_algorithm_systemauth
+- name: XCCDF Value var_password_hashing_algorithm_pam # promote to variable
+  set_fact:
+    var_password_hashing_algorithm_pam: !!str 
+  tags:
+    - always
 
 - name: Set PAM's Password Hashing Algorithm - Check if /etc/pam.d/system-auth file
     is present
@@ -257,19 +262,20 @@
       option is present in {{ pam_file_path }}
     ansible.builtin.lineinfile:
       path: '{{ pam_file_path }}'
-      regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\ssha512\b
+      regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{
+        var_password_hashing_algorithm_pam }}\b
       state: absent
     check_mode: true
     changed_when: false
     register: result_pam_module_set_password_hashing_algorithm_systemauth_option_present
 
-  - name: Set PAM's Password Hashing Algorithm - Ensure the "sha512" PAM option for
-      "pam_unix.so" is included in {{ pam_file_path }}
+  - name: Set PAM's Password Hashing Algorithm - Ensure the "{{ var_password_hashing_algorithm_pam
+      }}" PAM option for "pam_unix.so" is included in {{ pam_file_path }}
     ansible.builtin.lineinfile:
       path: '{{ pam_file_path }}'
       backrefs: true
       regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
-      line: \1 sha512
+      line: \1 {{ var_password_hashing_algorithm_pam }}
       state: present
     register: result_pam_set_password_hashing_algorithm_systemauth_add
     when:
@@ -303,3 +309,214 @@
   - medium_severity
   - no_reboot_needed
   - set_password_hashing_algorithm_systemauth
+
+- name: Set PAM's Password Hashing Algorithm - Check if /etc/pam.d/system-auth File
+    is Present
+  ansible.builtin.stat:
+    path: /etc/pam.d/system-auth
+  register: result_pam_file_present
+  when: '"pam" in ansible_facts.packages'
+  tags:
+  - CCE-80893-1
+  - CJIS-5.6.2.2
+  - DISA-STIG-RHEL-08-010159
+  - NIST-800-171-3.13.11
+  - NIST-800-53-CM-6(a)
+  - NIST-800-53-IA-5(1)(c)
+  - NIST-800-53-IA-5(c)
+  - PCI-DSS-Req-8.2.1
+  - PCI-DSSv4-8.3.2
+  - configure_strategy
+  - low_complexity
+  - medium_disruption
+  - medium_severity
+  - no_reboot_needed
+  - set_password_hashing_algorithm_systemauth
+
+- name: Set PAM's Password Hashing Algorithm - Check The Proper Remediation For The
+    System
+  block:
+
+  - name: Set PAM's Password Hashing Algorithm - Define the PAM file to be edited
+      as a local fact
+    ansible.builtin.set_fact:
+      pam_file_path: /etc/pam.d/system-auth
+
+  - name: Set PAM's Password Hashing Algorithm - Check if system relies on authselect
+      tool
+    ansible.builtin.stat:
+      path: /usr/bin/authselect
+    register: result_authselect_present
+
+  - name: Set PAM's Password Hashing Algorithm - Ensure authselect custom profile
+      is used if authselect is present
+    block:
+
+    - name: Set PAM's Password Hashing Algorithm - Check integrity of authselect current
+        profile
+      ansible.builtin.command:
+        cmd: authselect check
+      register: result_authselect_check_cmd
+      changed_when: false
+      failed_when: false
+
+    - name: Set PAM's Password Hashing Algorithm - Informative message based on the
+        authselect integrity check result
+      ansible.builtin.assert:
+        that:
+        - result_authselect_check_cmd.rc == 0
+        fail_msg:
+        - authselect integrity check failed. Remediation aborted!
+        - This remediation could not be applied because an authselect profile was
+          not selected or the selected profile is not intact.
+        - It is not recommended to manually edit the PAM files when authselect tool
+          is available.
+        - In cases where the default authselect profile does not cover a specific
+          demand, a custom authselect profile is recommended.
+        success_msg:
+        - authselect integrity check passed
+
+    - name: Set PAM's Password Hashing Algorithm - Get authselect current profile
+      ansible.builtin.shell:
+        cmd: authselect current -r | awk '{ print $1 }'
+      register: result_authselect_profile
+      changed_when: false
+      when:
+      - result_authselect_check_cmd is success
+
+    - name: Set PAM's Password Hashing Algorithm - Define the current authselect profile
+        as a local fact
+      ansible.builtin.set_fact:
+        authselect_current_profile: '{{ result_authselect_profile.stdout }}'
+        authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
+      when:
+      - result_authselect_profile is not skipped
+      - result_authselect_profile.stdout is match("custom/")
+
+    - name: Set PAM's Password Hashing Algorithm - Define the new authselect custom
+        profile as a local fact
+      ansible.builtin.set_fact:
+        authselect_current_profile: '{{ result_authselect_profile.stdout }}'
+        authselect_custom_profile: custom/hardening
+      when:
+      - result_authselect_profile is not skipped
+      - result_authselect_profile.stdout is not match("custom/")
+
+    - name: Set PAM's Password Hashing Algorithm - Get authselect current features
+        to also enable them in the custom profile
+      ansible.builtin.shell:
+        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
+      register: result_authselect_features
+      changed_when: false
+      when:
+      - result_authselect_profile is not skipped
+      - authselect_current_profile is not match("custom/")
+
+    - name: Set PAM's Password Hashing Algorithm - Check if any custom profile with
+        the same name was already created
+      ansible.builtin.stat:
+        path: /etc/authselect/{{ authselect_custom_profile }}
+      register: result_authselect_custom_profile_present
+      changed_when: false
+      when:
+      - authselect_current_profile is not match("custom/")
+
+    - name: Set PAM's Password Hashing Algorithm - Create an authselect custom profile
+        based on the current profile
+      ansible.builtin.command:
+        cmd: authselect create-profile hardening -b {{ authselect_current_profile
+          }}
+      when:
+      - result_authselect_check_cmd is success
+      - authselect_current_profile is not match("custom/")
+      - not result_authselect_custom_profile_present.stat.exists
+
+    - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
+      ansible.builtin.command:
+        cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
+      when:
+      - result_authselect_check_cmd is success
+      - result_authselect_profile is not skipped
+      - authselect_current_profile is not match("custom/")
+      - authselect_custom_profile is not match(authselect_current_profile)
+
+    - name: Set PAM's Password Hashing Algorithm - Ensure the authselect custom profile
+        is selected
+      ansible.builtin.command:
+        cmd: authselect select {{ authselect_custom_profile }}
+      register: result_pam_authselect_select_profile
+      when:
+      - result_authselect_check_cmd is success
+      - result_authselect_profile is not skipped
+      - authselect_current_profile is not match("custom/")
+      - authselect_custom_profile is not match(authselect_current_profile)
+
+    - name: Set PAM's Password Hashing Algorithm - Restore the authselect features
+        in the custom profile
+      ansible.builtin.command:
+        cmd: authselect enable-feature {{ item }}
+      loop: '{{ result_authselect_features.stdout_lines }}'
+      register: result_pam_authselect_restore_features
+      when:
+      - result_authselect_profile is not skipped
+      - result_authselect_features is not skipped
+      - result_pam_authselect_select_profile is not skipped
+
+    - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
+      ansible.builtin.command:
+        cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
+      when:
+      - result_authselect_check_cmd is success
+      - result_authselect_profile is not skipped
+      - result_pam_authselect_restore_features is not skipped
+
+    - name: Set PAM's Password Hashing Algorithm - Change the PAM file to be edited
+        according to the custom authselect profile
+      ansible.builtin.set_fact:
+        pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
+          | basename }}
+    when:
+    - result_authselect_present.stat.exists
+
+  - name: Set PAM's Password Hashing Algorithm - Ensure That Only the Correct Hashing
+      Algorithm Option For pam_unix.so Is Used in /etc/pam.d/system-auth
+    ansible.builtin.replace:
+      dest: '{{ pam_file_path }}'
+      regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*)
+      replace: \1\2
+    when: item != var_password_hashing_algorithm_pam
+    loop:
+    - sha512
+    - yescrypt
+    - gost_yescrypt
+    - blowfish
+    - sha256
+    - md5
+    - bigcrypt
+    register: result_pam_hashing_options_removal
+
+  - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
+    ansible.builtin.command:
+      cmd: authselect apply-changes -b
+    when:
+    - result_authselect_present.stat.exists
+    - result_pam_hashing_options_removal is changed
+  when:
+  - '"pam" in ansible_facts.packages'
+  - result_pam_file_present.stat.exists
+  tags:
+  - CCE-80893-1
+  - CJIS-5.6.2.2
+  - DISA-STIG-RHEL-08-010159
+  - NIST-800-171-3.13.11
+  - NIST-800-53-CM-6(a)
+  - NIST-800-53-IA-5(1)(c)
+  - NIST-800-53-IA-5(c)
+  - PCI-DSS-Req-8.2.1
+  - PCI-DSSv4-8.3.2
+  - configure_strategy
+  - low_complexity
+  - medium_disruption
+  - medium_severity
+  - no_reboot_needed
+  - set_password_hashing_algorithm_systemauth

Copy link

github-actions bot commented Jul 16, 2024

🤖 A k8s content image for this PR is available at:
ghcr.io/complianceascode/k8scontent:12164
This image was built from commit: b6897f6

Click here to see how to deploy it

If you alread have Compliance Operator deployed:
utils/build_ds_container.py -i ghcr.io/complianceascode/k8scontent:12164

Otherwise deploy the content and operator together by checking out ComplianceAsCode/compliance-operator and:
CONTENT_IMAGE=ghcr.io/complianceascode/k8scontent:12164 make deploy-local

Copy link
Collaborator

@jan-cerny jan-cerny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please check the CI fails

@jan-cerny jan-cerny self-assigned this Jul 16, 2024
Ubuntu doesn't use CONTROL variable.

Signed-off-by: Marcus Burghardt <[email protected]>
@marcusburghardt
Copy link
Member Author

I am checking the remediation failures in Fedora Latest.

The test scenarios were assuming that sha512 was already present in the
system used for test, which is not the case, for example in Fedora.
It was also included a new test scenario script for cases where multiple
hashing algorithm options are used.

Signed-off-by: Marcus Burghardt <[email protected]>
The former regex were not matching all possible cases.

Signed-off-by: Marcus Burghardt <[email protected]>
@marcusburghardt
Copy link
Member Author

I am checking the remediation failures in Fedora Latest.

Everything should be ok now.

@jan-cerny
Copy link
Collaborator

@marcusburghardt The Automatus tests are passing for me and the code looks good to me. But, I have realized that we should set the variable to some value in profiles and control files where the variable is used.

@marcusburghardt
Copy link
Member Author

@marcusburghardt The Automatus tests are passing for me and the code looks good to me. But, I have realized that we should set the variable to some value in profiles and control files where the variable is used.

Hum, good point. Let's make it explicit instead of relying in the default value. I will update.

Include the new variable var_password_hashing_algorithm_pam in control
files where there are rules using this variable. This variable is shared
by rules used by different requirements in CIS so it is informed twice
since this doesn't cause any issue but make it easier to see when
analysing requirements individually.

Signed-off-by: Marcus Burghardt <[email protected]>
Profiles for RHEL and Fedora products that don't consume rules from a
control file and use the relevant rules were also update to include
var_password_hashing_algorithm_pam variable.

Signed-off-by: Marcus Burghardt <[email protected]>
@marcusburghardt
Copy link
Member Author

@marcusburghardt The Automatus tests are passing for me and the code looks good to me. But, I have realized that we should set the variable to some value in profiles and control files where the variable is used.

Hum, good point. Let's make it explicit instead of relying in the default value. I will update.

Done. Let's follow the CI tests because many profiles were changed. I will analyse the results tomorrow.

Copy link

codeclimate bot commented Jul 18, 2024

Code Climate has analyzed commit b6897f6 and detected 0 issues on this pull request.

The test coverage on the diff in this pull request is 100.0% (50% is the threshold).

This pull request will bring the total coverage in the repository to 59.4% (0.0% change).

View more on Code Climate.

@marcusburghardt
Copy link
Member Author

@marcusburghardt The Automatus tests are passing for me and the code looks good to me. But, I have realized that we should set the variable to some value in profiles and control files where the variable is used.

Hum, good point. Let's make it explicit instead of relying in the default value. I will update.

Done. Let's follow the CI tests because many profiles were changed. I will analyse the results tomorrow.

Should be fine now.

Copy link
Collaborator

@jan-cerny jan-cerny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scenarios have passed locally for me

jcerny@fedora:~/work/git/scap-security-guide (pr/12164)$ python3 tests/automatus.py rule --libvirt qemu:///system ssgts_rhel9 --remediate-using ansible set_password_hashing_algorithm_passwordauth set_password_hashing_algorithm_systemauth set_password_hashing_algorithm_logindefs set_password_hashing_algorithm_libuserconf 
Setting console output to log level INFO
INFO - The base image option has not been specified, choosing libvirt-based test environment.
INFO - Logging into /home/jcerny/work/git/scap-security-guide/logs/rule-custom-2024-07-19-0818/test_suite.log
WARNING - Script correct.pass.sh is not applicable on given platform
WARNING - Script missing.fail.sh is not applicable on given platform
WARNING - Script wrong_control.fail.sh is not applicable on given platform
WARNING - Script commented_value.fail.sh is not applicable on given platform
WARNING - Script correct.pass.sh is not applicable on given platform
WARNING - Script missing.fail.sh is not applicable on given platform
WARNING - Script wrong_control.fail.sh is not applicable on given platform
WARNING - Script wrong_value_concat.fail.sh is not applicable on given platform
INFO - xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf
INFO - Script correct_crypt_style.pass.sh using profile (all) OK
INFO - Script no_crypt_style.fail.sh using profile (all) OK
INFO - Script weak_algorithm.fail.sh using profile (all) OK
INFO - xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs
INFO - Script default_sha256.fail.sh using profile (all) OK
INFO - Script default_sha512.pass.sh using profile (all) OK
INFO - xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth
INFO - Script authselect_correct_value.pass.sh using profile (all) OK
INFO - Script authselect_incorrect_option.fail.sh using profile (all) OK
INFO - Script authselect_missing_option.fail.sh using profile (all) OK
INFO - Script authselect_modified_pam.fail.sh using profile (all) OK
INFO - Script authselect_multiple_options.fail.sh using profile (all) OK
INFO - Script authselect_wrong_control.fail.sh using profile (all) OK
INFO - xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
INFO - Script authselect_correct_value.pass.sh using profile (all) OK
INFO - Script authselect_incorrect_option.fail.sh using profile (all) OK
INFO - Script authselect_missing_option.fail.sh using profile (all) OK
INFO - Script authselect_modified_pam.fail.sh using profile (all) OK
INFO - Script authselect_multiple_options.fail.sh using profile (all) OK
INFO - Script authselect_wrong_control.fail.sh using profile (all) OK
jcerny@fedora:~/work/git/scap-security-guide (pr/12164)$ python3 tests/automatus.py rule --libvirt qemu:///system ssgts_rhel9 set_password_hashing_algorithm_passwordauth set_password_hashing_algorithm_systemauth set_password_hashing_algorithm_logindefs set_password_hashing_algorithm_libuserconf 
Setting console output to log level INFO
INFO - The base image option has not been specified, choosing libvirt-based test environment.
INFO - Logging into /home/jcerny/work/git/scap-security-guide/logs/rule-custom-2024-07-19-0826/test_suite.log
WARNING - Script correct.pass.sh is not applicable on given platform
WARNING - Script missing.fail.sh is not applicable on given platform
WARNING - Script wrong_control.fail.sh is not applicable on given platform
WARNING - Script commented_value.fail.sh is not applicable on given platform
WARNING - Script correct.pass.sh is not applicable on given platform
WARNING - Script missing.fail.sh is not applicable on given platform
WARNING - Script wrong_control.fail.sh is not applicable on given platform
WARNING - Script wrong_value_concat.fail.sh is not applicable on given platform
INFO - xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf
INFO - Script correct_crypt_style.pass.sh using profile (all) OK
INFO - Script no_crypt_style.fail.sh using profile (all) OK
INFO - Script weak_algorithm.fail.sh using profile (all) OK
INFO - xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs
INFO - Script default_sha256.fail.sh using profile (all) OK
INFO - Script default_sha512.pass.sh using profile (all) OK
INFO - xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_passwordauth
INFO - Script authselect_correct_value.pass.sh using profile (all) OK
INFO - Script authselect_incorrect_option.fail.sh using profile (all) OK
INFO - Script authselect_missing_option.fail.sh using profile (all) OK
INFO - Script authselect_modified_pam.fail.sh using profile (all) OK
INFO - Script authselect_multiple_options.fail.sh using profile (all) OK
INFO - Script authselect_wrong_control.fail.sh using profile (all) OK
INFO - xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
INFO - Script authselect_correct_value.pass.sh using profile (all) OK
INFO - Script authselect_incorrect_option.fail.sh using profile (all) OK
INFO - Script authselect_missing_option.fail.sh using profile (all) OK
INFO - Script authselect_modified_pam.fail.sh using profile (all) OK
INFO - Script authselect_multiple_options.fail.sh using profile (all) OK
INFO - Script authselect_wrong_control.fail.sh using profile (all) OK

@jan-cerny jan-cerny merged commit 31cfc0c into ComplianceAsCode:master Jul 19, 2024
92 of 95 checks passed
@marcusburghardt marcusburghardt deleted the pam_hashing_algorithm branch July 19, 2024 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Ansible Ansible remediation update. Bash Bash remediation update. OVAL OVAL update. Related to the systems assessments. refactoring Improvement which, once completed, will enable the project to progress faster. Update Rule Issues or pull requests related to Rules updates.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants