dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0019-intg-add-Smartcard-authentication-tests.patch

71e593
From 6155a267d399d111706c4496c3877e216936c3b2 Mon Sep 17 00:00:00 2001
71e593
From: Sumit Bose <sbose@redhat.com>
71e593
Date: Fri, 7 Sep 2018 22:26:21 +0200
71e593
Subject: [PATCH 19/19] intg: add Smartcard authentication tests
71e593
71e593
Two test for Smartcard authentication of a local user, i.e. a user
71e593
managed by the files provider, are added. One for a successful
71e593
authentication, the other for a failed authentication with a wrong PIN.
71e593
71e593
Related to https://pagure.io/SSSD/sssd/issue/3500
71e593
71e593
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
71e593
(cherry picked from commit 657f3b89bca9adfb13f0867c91f1d76845d2d6dd)
71e593
---
71e593
 configure.ac                         |   1 +
71e593
 contrib/ci/deps.sh                   |   2 +
71e593
 contrib/sssd.spec.in                 |   1 +
71e593
 src/external/cwrap.m4                |   5 ++
71e593
 src/external/intgcheck.m4            |   1 +
71e593
 src/tests/intg/Makefile.am           |  24 ++++++-
71e593
 src/tests/intg/test_pam_responder.py | 131 ++++++++++++++++++++++++++++++++---
71e593
 7 files changed, 155 insertions(+), 10 deletions(-)
71e593
71e593
diff --git a/configure.ac b/configure.ac
71e593
index 1aac65f4d85b9974adc5ba3e5196b00be5d279f1..891610e14490a4e78e1e95e63c18d9c6a9a8afb4 100644
71e593
--- a/configure.ac
71e593
+++ b/configure.ac
71e593
@@ -488,6 +488,7 @@ AM_CONDITIONAL([HAVE_CHECK], [test x$have_check != x])
71e593
 AM_CHECK_CMOCKA
71e593
 AM_CHECK_UID_WRAPPER
71e593
 AM_CHECK_NSS_WRAPPER
71e593
+AM_CHECK_PAM_WRAPPER
71e593
 AM_CHECK_TEST_CA
71e593
 
71e593
 # Check if the user wants SSSD to be compiled with systemtap probes
71e593
diff --git a/contrib/ci/deps.sh b/contrib/ci/deps.sh
71e593
index 5906e5332ba99ce137174f3630e269b8c561f996..c04c7aab03f78185d96000142a71001ab52a66a7 100644
71e593
--- a/contrib/ci/deps.sh
71e593
+++ b/contrib/ci/deps.sh
71e593
@@ -46,6 +46,7 @@ if [[ "$DISTRO_BRANCH" == -redhat-* ]]; then
71e593
         pyldb
71e593
         rpm-build
71e593
         uid_wrapper
71e593
+        pam_wrapper
71e593
         python-requests
71e593
         curl-devel
71e593
         krb5-server
71e593
@@ -117,6 +118,7 @@ if [[ "$DISTRO_BRANCH" == -debian-* ]]; then
71e593
         fakeroot
71e593
         libnss-wrapper
71e593
         libuid-wrapper
71e593
+        libpam-wrapper
71e593
         python-pytest
71e593
         python-ldap
71e593
         python-ldb
71e593
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
71e593
index 5ebd51f41f60cfdcd1d65c1c58dea4b296fd1ed1..26fae6d68dbe4d14f85ddf34bb4871bc34db3b3d 100644
71e593
--- a/contrib/sssd.spec.in
71e593
+++ b/contrib/sssd.spec.in
71e593
@@ -237,6 +237,7 @@ BuildRequires: selinux-policy-targeted
71e593
 BuildRequires: libcmocka-devel >= 1.0.0
71e593
 BuildRequires: uid_wrapper
71e593
 BuildRequires: nss_wrapper
71e593
+BuildRequires: pam_wrapper
71e593
 
71e593
 # Test CA requires openssl independent if SSSD is build with NSS or openssl,
71e593
 # openssh is needed for ssh-keygen and NSS builds need nss-tools for certutil.
71e593
diff --git a/src/external/cwrap.m4 b/src/external/cwrap.m4
71e593
index b8489cc765f34f3bc6ad4e4b7e69626f6ea8060e..6e3487c13f734e311a2262b0f71495167489c710 100644
71e593
--- a/src/external/cwrap.m4
71e593
+++ b/src/external/cwrap.m4
71e593
@@ -28,3 +28,8 @@ AC_DEFUN([AM_CHECK_NSS_WRAPPER],
71e593
 [
71e593
     AM_CHECK_WRAPPER(nss_wrapper, HAVE_NSS_WRAPPER)
71e593
 ])
71e593
+
71e593
+AC_DEFUN([AM_CHECK_PAM_WRAPPER],
71e593
+[
71e593
+    AM_CHECK_WRAPPER(pam_wrapper, HAVE_PAM_WRAPPER)
71e593
+])
71e593
diff --git a/src/external/intgcheck.m4 b/src/external/intgcheck.m4
71e593
index 60a7bf306ddefd748cf9bac62d3767e7512b6d64..c14f66978b8087586cf1c5ac2d60a07e4f90d45d 100644
71e593
--- a/src/external/intgcheck.m4
71e593
+++ b/src/external/intgcheck.m4
71e593
@@ -22,6 +22,7 @@ AC_DEFUN([SSS_ENABLE_INTGCHECK_REQS], [
71e593
     if test x"$enable_intgcheck_reqs" = xyes; then
71e593
         SSS_INTGCHECK_REQ([HAVE_UID_WRAPPER], [uid_wrapper])
71e593
         SSS_INTGCHECK_REQ([HAVE_NSS_WRAPPER], [nss_wrapper])
71e593
+        SSS_INTGCHECK_REQ([HAVE_PAM_WRAPPER], [pam_wrapper])
71e593
         SSS_INTGCHECK_REQ([HAVE_SLAPD], [slapd])
71e593
         SSS_INTGCHECK_REQ([HAVE_LDAPMODIFY], [ldapmodify])
71e593
         SSS_INTGCHECK_REQ([HAVE_FAKEROOT], [fakeroot])
71e593
diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
71e593
index 6f7605bd4edbf26ef3ce97acea74fc92216eede9..bb3a7f01ae4f79fa05cd661993e8f9872ecd0450 100644
71e593
--- a/src/tests/intg/Makefile.am
71e593
+++ b/src/tests/intg/Makefile.am
71e593
@@ -105,13 +105,29 @@ passwd: root
71e593
 group:
71e593
 	echo "root:x:0:" > $@
71e593
 
71e593
+PAM_SERVICE_DIR=pam_service_dir
71e593
+pam_sss_service:
71e593
+	$(MKDIR_P) $(PAM_SERVICE_DIR)
71e593
+	echo "auth     required       $(DESTDIR)$(pammoddir)/pam_sss.so"  > $(PAM_SERVICE_DIR)/$@
71e593
+	echo "account  required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
71e593
+	echo "password required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
71e593
+	echo "session  required       $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@
71e593
+
71e593
 CLEANFILES=config.py config.pyc passwd group
71e593
 
71e593
 clean-local:
71e593
 	rm -Rf root
71e593
 	rm -f $(builddir)/cwrap-dbus-system.conf
71e593
 
71e593
-intgcheck-installed: config.py passwd group
71e593
+if HAVE_NSS
71e593
+PAM_CERT_DB_PATH="sql:$(DESTDIR)$(sysconfdir)/pki/nssdb"
71e593
+SOFTHSM2_CONF=""
71e593
+else
71e593
+PAM_CERT_DB_PATH="$(abs_builddir)/../test_CA/SSSD_test_CA.pem"
71e593
+SOFTHSM2_CONF="$(abs_builddir)/../test_CA/softhsm2_one.conf"
71e593
+endif
71e593
+
71e593
+intgcheck-installed: config.py passwd group pam_sss_service
71e593
 	pipepath="$(DESTDIR)$(pipepath)"; \
71e593
 	if test $${#pipepath} -gt 80; then \
71e593
 	    echo "error: Pipe directory path too long," \
71e593
@@ -131,12 +147,18 @@ intgcheck-installed: config.py passwd group
71e593
 	LDB_MODULES_PATH="$(DESTDIR)$(ldblibdir)" \
71e593
 	NON_WRAPPED_UID=$$(id -u) \
71e593
 	LD_PRELOAD="$(libdir)/getsockopt_wrapper.so:$$nss_wrapper:$$uid_wrapper" \
71e593
+	LD_LIBRARY_PATH="$$LD_LIBRARY_PATH:$(DESTDIR)$(nsslibdir)" \
71e593
 	NSS_WRAPPER_PASSWD="$(abs_builddir)/passwd" \
71e593
 	NSS_WRAPPER_GROUP="$(abs_builddir)/group" \
71e593
 	NSS_WRAPPER_MODULE_SO_PATH="$(DESTDIR)$(nsslibdir)/libnss_sss.so.2" \
71e593
 	NSS_WRAPPER_MODULE_FN_PREFIX="sss" \
71e593
 	UID_WRAPPER=1 \
71e593
 	UID_WRAPPER_ROOT=1 \
71e593
+	PAM_WRAPPER=0 \
71e593
+	PAM_WRAPPER_SERVICE_DIR="$(abs_builddir)/$(PAM_SERVICE_DIR)" \
71e593
+	PAM_WRAPPER_PATH=$$(pkg-config --libs pam_wrapper) \
71e593
+	PAM_CERT_DB_PATH=$(PAM_CERT_DB_PATH) \
71e593
+	SOFTHSM2_CONF=$(SOFTHSM2_CONF) \
71e593
 	DBUS_SOCK_DIR="$(DESTDIR)$(runstatedir)/dbus/" \
71e593
 	DBUS_SESSION_BUS_ADDRESS="unix:path=$$DBUS_SOCK_DIR/fake_socket" \
71e593
 	DBUS_SYSTEM_BUS_ADDRESS="unix:path=$$DBUS_SOCK_DIR/system_bus_socket" \
71e593
diff --git a/src/tests/intg/test_pam_responder.py b/src/tests/intg/test_pam_responder.py
71e593
index cf6fff2db7ba9c9c69e1dd9abe5663a02cedd72e..c6d048cd342838fe312287eaffff734e30ba9e1c 100644
71e593
--- a/src/tests/intg/test_pam_responder.py
71e593
+++ b/src/tests/intg/test_pam_responder.py
71e593
@@ -27,31 +27,44 @@ import signal
71e593
 import errno
71e593
 import subprocess
71e593
 import time
71e593
-import pytest
71e593
+import shutil
71e593
 
71e593
 import config
71e593
 
71e593
-from util import unindent
71e593
+import pytest
71e593
 
71e593
+from intg.util import unindent
71e593
+from intg.files_ops import passwd_ops_setup
71e593
 
71e593
-def format_pam_cert_auth_conf():
71e593
+USER1 = dict(name='user1', passwd='x', uid=10001, gid=20001,
71e593
+             gecos='User for tests',
71e593
+             dir='/home/user1',
71e593
+             shell='/bin/bash')
71e593
+
71e593
+
71e593
+def format_pam_cert_auth_conf(config):
71e593
     """Format a basic SSSD configuration"""
71e593
     return unindent("""\
71e593
         [sssd]
71e593
+        debug_level = 10
71e593
         domains = auth_only
71e593
-        services = pam
71e593
+        services = pam, nss
71e593
 
71e593
         [nss]
71e593
+        debug_level = 10
71e593
 
71e593
         [pam]
71e593
         pam_cert_auth = True
71e593
+        pam_p11_allowed_services = +pam_sss_service
71e593
+        pam_cert_db_path = {config.PAM_CERT_DB_PATH}
71e593
         debug_level = 10
71e593
 
71e593
         [domain/auth_only]
71e593
-        id_provider = ldap
71e593
-        auth_provider = ldap
71e593
-        chpass_provider = ldap
71e593
-        access_provider = ldap
71e593
+        debug_level = 10
71e593
+        id_provider = files
71e593
+
71e593
+        [certmap/auth_only/user1]
71e593
+        matchrule = <SUBJECT>.*CN=SSSD test cert 0001.*
71e593
     """).format(**locals())
71e593
 
71e593
 
71e593
@@ -79,6 +92,8 @@ def create_conf_fixture(request, contents):
71e593
 
71e593
 def create_sssd_process():
71e593
     """Start the SSSD process"""
71e593
+    os.environ["SSS_FILES_PASSWD"] = os.environ["NSS_WRAPPER_PASSWD"]
71e593
+    os.environ["SSS_FILES_GROUP"] = os.environ["NSS_WRAPPER_GROUP"]
71e593
     if subprocess.call(["sssd", "-D", "-f"]) != 0:
71e593
         raise Exception("sssd start failed")
71e593
 
71e593
@@ -116,12 +131,41 @@ def create_sssd_fixture(request):
71e593
     request.addfinalizer(cleanup_sssd_process)
71e593
 
71e593
 
71e593
+def create_nssdb():
71e593
+    os.mkdir(config.SYSCONFDIR + "/pki")
71e593
+    os.mkdir(config.SYSCONFDIR + "/pki/nssdb")
71e593
+    if subprocess.call(["certutil", "-N", "-d",
71e593
+                        "sql:" + config.SYSCONFDIR + "/pki/nssdb/",
71e593
+                        "--empty-password"]) != 0:
71e593
+        raise Exception("certutil failed")
71e593
+
71e593
+    pkcs11_txt = open(config.SYSCONFDIR + "/pki/nssdb/pkcs11.txt", "w")
71e593
+    pkcs11_txt.write("library=libsoftokn3.so\nname=soft\n" +
71e593
+                     "parameters=configdir='sql:" + config.ABS_BUILDDIR +
71e593
+                     "/../test_CA/p11_nssdb' " +
71e593
+                     "dbSlotDescription='SSSD Test Slot' " +
71e593
+                     "dbTokenDescription='SSSD Test Token' " +
71e593
+                     "secmod='secmod.db' flags=readOnly)\n\n")
71e593
+    pkcs11_txt.close()
71e593
+
71e593
+
71e593
+def cleanup_nssdb():
71e593
+    shutil.rmtree(config.SYSCONFDIR + "/pki")
71e593
+
71e593
+
71e593
+def create_nssdb_fixture(request):
71e593
+    create_nssdb()
71e593
+    request.addfinalizer(cleanup_nssdb)
71e593
+
71e593
+
71e593
 @pytest.fixture
71e593
 def simple_pam_cert_auth(request):
71e593
     """Setup SSSD with pam_cert_auth=True"""
71e593
-    conf = format_pam_cert_auth_conf()
71e593
+    config.PAM_CERT_DB_PATH = os.environ['PAM_CERT_DB_PATH']
71e593
+    conf = format_pam_cert_auth_conf(config)
71e593
     create_conf_fixture(request, conf)
71e593
     create_sssd_fixture(request)
71e593
+    create_nssdb_fixture(request)
71e593
     return None
71e593
 
71e593
 
71e593
@@ -129,3 +173,72 @@ def test_preauth_indicator(simple_pam_cert_auth):
71e593
     """Check if preauth indicator file is created"""
71e593
     statinfo = os.stat(config.PUBCONF_PATH + "/pam_preauth_available")
71e593
     assert stat.S_ISREG(statinfo.st_mode)
71e593
+
71e593
+
71e593
+@pytest.fixture
71e593
+def pam_wrapper_setup(request):
71e593
+    pwrap_runtimedir = os.getenv("PAM_WRAPPER_SERVICE_DIR")
71e593
+    if pwrap_runtimedir is None:
71e593
+        raise ValueError("The PAM_WRAPPER_SERVICE_DIR variable is unset\n")
71e593
+
71e593
+
71e593
+def test_sc_auth_wrong_pin(simple_pam_cert_auth, pam_wrapper_setup,
71e593
+                           passwd_ops_setup):
71e593
+
71e593
+    passwd_ops_setup.useradd(**USER1)
71e593
+    current_env = os.environ.copy()
71e593
+    current_env['PAM_WRAPPER'] = "1"
71e593
+    current_env['SSSD_INTG_PEER_UID'] = "0"
71e593
+    current_env['SSSD_INTG_PEER_GID'] = "0"
71e593
+    current_env['LD_PRELOAD'] += ':' + os.environ['PAM_WRAPPER_PATH']
71e593
+
71e593
+    sssctl = subprocess.Popen(["sssctl", "user-checks", "user1",
71e593
+                               "--action=auth", "--service=pam_sss_service"],
71e593
+                              universal_newlines=True,
71e593
+                              env=current_env, stdin=subprocess.PIPE,
71e593
+                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
71e593
+
71e593
+    try:
71e593
+        out, err = sssctl.communicate(input="111")
71e593
+    except:
71e593
+        sssctl.kill()
71e593
+        out, err = sssctl.communicate()
71e593
+
71e593
+    sssctl.stdin.close()
71e593
+    sssctl.stdout.close()
71e593
+
71e593
+    if sssctl.wait() != 0:
71e593
+        raise Exception("sssctl failed")
71e593
+
71e593
+    assert err.find("pam_authenticate for user [user1]: " +
71e593
+                    "Authentication failure") != -1
71e593
+
71e593
+
71e593
+def test_sc_auth(simple_pam_cert_auth, pam_wrapper_setup, passwd_ops_setup):
71e593
+
71e593
+    passwd_ops_setup.useradd(**USER1)
71e593
+    current_env = os.environ.copy()
71e593
+    current_env['PAM_WRAPPER'] = "1"
71e593
+    current_env['SSSD_INTG_PEER_UID'] = "0"
71e593
+    current_env['SSSD_INTG_PEER_GID'] = "0"
71e593
+    current_env['LD_PRELOAD'] += ':' + os.environ['PAM_WRAPPER_PATH']
71e593
+
71e593
+    sssctl = subprocess.Popen(["sssctl", "user-checks", "user1",
71e593
+                               "--action=auth", "--service=pam_sss_service"],
71e593
+                              universal_newlines=True,
71e593
+                              env=current_env, stdin=subprocess.PIPE,
71e593
+                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
71e593
+
71e593
+    try:
71e593
+        out, err = sssctl.communicate(input="123456")
71e593
+    except:
71e593
+        sssctl.kill()
71e593
+        out, err = sssctl.communicate()
71e593
+
71e593
+    sssctl.stdin.close()
71e593
+    sssctl.stdout.close()
71e593
+
71e593
+    if sssctl.wait() != 0:
71e593
+        raise Exception("sssctl failed")
71e593
+
71e593
+    assert err.find("pam_authenticate for user [user1]: Success") != -1
71e593
-- 
71e593
2.14.4
71e593