summaryrefslogtreecommitdiffstats
path: root/debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh
diff options
context:
space:
mode:
Diffstat (limited to 'debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh')
-rw-r--r--debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh256
1 files changed, 256 insertions, 0 deletions
diff --git a/debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh b/debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh
new file mode 100644
index 0000000..0745ad4
--- /dev/null
+++ b/debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh
@@ -0,0 +1,256 @@
+#!/usr/bin/env bash
+# Copyright 2023 - Marco Trevisan
+# Released under the GPLv3 terms
+#
+# A simple tool to simulate PAM authentication using GDM smartcard settings
+#
+# To be used with https://gist.github.com/3v1n0/287d02ca8e03936f1c7bba992173d47a
+set -xe
+
+required_tools=(
+ gdm3 # debian package: gdm3
+ pamtester # debian package: pamtester
+ softhsm2-util # debian package: softhsm2
+ sssd # debian package: sssd
+)
+
+if [[ ! -v OFFLINE_MODE ]]; then
+ required_tools+=(
+ wget # debian package: wget
+ )
+fi
+
+if [ "$(id -u)" != 0 ] || [ -z "$SUDO_USER" ]; then
+ echo "This tool requires sudo!"
+ exit 2
+fi
+
+for cmd in "${required_tools[@]}"; do
+ if ! command -v "$cmd" > /dev/null; then
+ echo "Tool $cmd missing"
+ exit 1
+ fi
+done
+
+PIN=${PIN:-123456}
+GDM_USER=${GDM_USER:-gdm}
+tmpdir=${TEST_TMPDIR:-$(mktemp -d -t "sssd-softhsm2-gdm-certs-XXXXXX")}
+backupsdir=
+
+alternative_pam_configs=(
+ /etc/pam.d/gdm-smartcard-sssd-exclusive
+ /etc/pam.d/gdm-smartcard-sssd-or-password
+)
+
+declare -a restore_paths
+declare -a delete_paths
+
+function restore_changes() {
+ for path in "${restore_paths[@]}"; do
+ local original_path
+ original_path="/$(realpath --strip --relative-base="$backupsdir" "$path")"
+ rm "$original_path" && mv "$path" "$original_path" || true
+ done
+
+ for path in "${delete_paths[@]}"; do
+ rm -f "$path"
+ #find "$(dirname "$path")" -empty -delete || true
+ done
+
+ update-alternatives --auto gdm-smartcard
+
+ if [ -e /etc/sssd/sssd.conf ]; then
+ chmod 600 /etc/sssd/sssd.conf || return 1
+ systemctl restart sssd || true
+ else
+ systemctl stop sssd || true
+ fi
+
+ if [ -e /etc/softhsm/softhsm2.conf ]; then
+ chmod 600 /etc/softhsm/softhsm2.conf || return 1
+ fi
+
+ rm -rf "$tmpdir"
+}
+
+function backup_file() {
+ if [ -z "$backupsdir" ]; then
+ backupsdir=$(mktemp -d -t "sssd-softhsm2-gdm-backups-XXXXXX")
+ fi
+
+ if [ -e "$1" ]; then
+ local back_dir="$backupsdir/$(dirname "$1")"
+ local back_path="$back_dir/$(basename "$1")"
+ [ ! -e "$back_path" ] || return 1
+
+ mkdir -p "$back_dir" || return 1
+ cp -a "$1" "$back_path" || return 1
+
+ restore_paths+=("$back_path")
+ else
+ delete_paths+=("$1")
+ fi
+}
+
+function handle_exit() {
+ exit_code=$?
+
+ restore_changes || return 1
+
+ if [ $exit_code = 0 ]; then
+ rm -rf "$backupsdir"
+ set +x
+ echo "Script completed successfully!"
+ else
+ set +x
+ echo "Script failed, check the log!"
+ echo " Backup preserved at $backupsdir"
+ echo " PAM Log: /var/log/auth.log"
+ echo " SSSD PAM Log: /var/log/sssd/sssd_pam.log"
+ echo " SSSD p11_child Log: /var/log/sssd/p11_child.log"
+ fi
+}
+
+trap 'handle_exit' EXIT
+
+tester="$(dirname "$0")"/sssd-softhism2-certificates-tests.sh
+if [ ! -e "$tester" ]; then
+ echo "Required $tester missing, we're downloading it..."
+ tester="$tmpdir/sssd-softhism2-certificates-tests.sh"
+ wget -q -c https://gist.github.com/3v1n0/287d02ca8e03936f1c7bba992173d47a/raw/sssd-softhism2-certificates-tests.sh \
+ -O "$tester"
+ [ -e "$tester" ] || exit 1
+fi
+
+export PIN TEST_TMPDIR="$tmpdir" GENERATE_SMART_CARDS=1 KEEP_TEMPORARY_FILES=1 NO_SSSD_TESTS=1
+bash "$tester"
+
+find "$tmpdir" -type d -exec chmod 777 {} \;
+find "$tmpdir" -type f -exec chmod 666 {} \;
+
+backup_file /etc/passwd
+backup_file /etc/shadow
+
+# Ensure that the test user has a non-trivial password. If it had a blank
+# password, then /etc/pam.d/gdm-smartcard-sssd-or-password would always
+# authenticate successfully
+if pamtester -v gdm-password "$SUDO_USER" authenticate; then
+ ( echo -n "$SUDO_USER:"; cat /proc/sys/kernel/random/uuid ) | chpasswd
+fi
+# Same, but for root
+if pamtester -v gdm-password root authenticate; then
+ ( echo -n "root:"; cat /proc/sys/kernel/random/uuid ) | chpasswd
+fi
+
+backup_file /etc/sssd/sssd.conf
+rm -f /etc/sssd/sssd.conf
+
+user_home="$(runuser -u "$SUDO_USER" -- sh -c 'echo ~')"
+mkdir -p "$user_home"
+chown "$SUDO_USER:$SUDO_USER" "$user_home"
+
+gdm_home="$(runuser -u "$GDM_USER" -- sh -c 'echo ~')"
+mkdir -p "$gdm_home"
+chown "$GDM_USER:$GDM_USER" "$gdm_home"
+
+user_config="$(runuser -u "$SUDO_USER" -- sh -c 'echo ${XDG_CONFIG_HOME:-~/.config}')"
+gdm_config="$(runuser -u "$GDM_USER" -- sh -c 'echo ${XDG_CONFIG_HOME:-~/.config}')"
+system_config="/etc"
+
+softhsm2_conf_paths=(
+ "$SUDO_USER:$user_config/softhsm2/softhsm2.conf"
+ "$GDM_USER:$gdm_config/softhsm2/softhsm2.conf"
+ "root:$system_config/softhsm/softhsm2.conf"
+)
+
+for path_pair in "${softhsm2_conf_paths[@]}"; do
+ IFS=":" read -r -a path <<< "${path_pair}"
+ path="${path[1]}"
+ backup_file "$path"
+ rm -f "$path"
+done
+
+function test_authentication() {
+ certificate_config="$1"
+ ca_db="$2"
+ verification_options="$3"
+
+ mkdir -p -m 700 /etc/sssd
+
+ cat <<EOF > /etc/sssd/sssd.conf || return 2
+[sssd]
+enable_files_domain = True
+services = pam
+#certificate_verification = $verification_options
+
+[certmap/implicit_files/$SUDO_USER]
+matchrule = <SUBJECT>.*Test Organization.*
+
+[pam]
+pam_cert_db_path = $ca_db
+pam_cert_verification = $verification_options
+pam_cert_auth = True
+pam_verbosity = 10
+debug_level = 10
+EOF
+
+ chmod 600 /etc/sssd/sssd.conf || return 2
+
+ for path_pair in "${softhsm2_conf_paths[@]}"; do
+ IFS=":" read -r -a path <<< "${path_pair}"
+ user="${path[0]}"
+ path="${path[1]}"
+
+ runuser -u "$user" -- mkdir -p "$(dirname "$path")" || return 2
+ runuser -u "$user" -- ln -sf "$certificate_config" "$path" || return 2
+ runuser -u "$user" -- softhsm2-util --show-slots | grep "Test Organization" \
+ || return 2
+ done
+
+ systemctl restart sssd || return 2
+
+ for alternative in "${alternative_pam_configs[@]}"; do
+ sudo update-alternatives --set gdm-smartcard "$alternative"
+
+ echo -n -e "$PIN" | runuser -u "$SUDO_USER" -- \
+ pamtester -v gdm-smartcard "$SUDO_USER" authenticate || return 2
+ echo -n -e "$PIN" | runuser -u "$SUDO_USER" -- \
+ pamtester -v gdm-smartcard "" authenticate || return 2
+
+ if echo -n -e "wrong${PIN}" | runuser -u "$SUDO_USER" -- \
+ pamtester -v gdm-smartcard "$SUDO_USER" authenticate; then
+ echo "Unexpected pass!"
+ return 2
+ fi
+
+ if echo -n -e "wrong${PIN}" | runuser -u "$SUDO_USER" -- \
+ pamtester -v gdm-smartcard "" authenticate; then
+ echo "Unexpected pass!"
+ return 2
+ fi
+
+ if echo -n -e "$PIN" | pamtester -v gdm-smartcard root authenticate; then
+ echo "Unexpected pass!"
+ return 2
+ fi
+
+ if [[ -v WAIT ]]; then
+ echo "Press any key and enter to continue"
+ systemctl restart gdm3
+ read
+ fi
+ done
+}
+
+test_authentication \
+ "$tmpdir/softhsm2-test-root-CA-trusted-certificate-0001.conf" \
+ "$tmpdir/test-full-chain-CA.pem"
+
+test_authentication \
+ "$tmpdir/softhsm2-test-sub-intermediate-CA-trusted-certificate-0001.conf" \
+ "$tmpdir/test-full-chain-CA.pem"
+
+test_authentication \
+ "$tmpdir/softhsm2-test-sub-intermediate-CA-trusted-certificate-0001.conf" \
+ "$tmpdir/test-sub-intermediate-CA.pem" \
+ "partial_chain"