#!/bin/sh # # Copyright (c) 2006 - 2024 Kungliga Tekniska Högskolan # (Royal Institute of Technology, Stockholm, Sweden). # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. Neither the name of the Institute nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # Test Heimdal clients against MIT Kerberos KDC # top_builddir="@top_builddir@" env_setup="@env_setup@" objdir="@objdir@" . ${env_setup} # Skip if MIT Kerberos is not available if [ -z "$MITKRB5" ] || [ ! -d "$MITKRB5" ]; then echo "MIT Kerberos not available, skipping" exit 77 fi # Check for required MIT binaries for prog in kdb5_util krb5kdc kadmin.local; do if [ ! -x "${MITKRB5}/sbin/${prog}" ] && [ ! -x "${MITKRB5}/bin/${prog}" ]; then echo "MIT ${prog} not found, skipping" exit 77 fi done # Check for PKINIT support rsa=yes pkinit=no if ${hxtool} info | grep 'rsa: hx509 null RSA' > /dev/null ; then rsa=no fi if ${hxtool} info | grep 'rand: not available' > /dev/null ; then rsa=no fi if ${kinit} --help 2>&1 | grep "CA certificates" > /dev/null; then pkinit=yes fi testfailed="echo test failed; cat messages.log; exit 1" R=MIT-TEST.H5L.SE port=@port@ admport=@admport@ mitdir="${objdir}/mit-kdc" cache="FILE:${objdir}/mit-cache.krb5" keytab="${objdir}/mit-server.keytab" keyfile="${hx509_data}/key.der" keyfile2="${hx509_data}/key2.der" kinit="${kinit} -c $cache ${afs_no_afslog}" klist="${klist} -c $cache" kgetcred="${kgetcred} -c $cache" kdestroy="${kdestroy} -c $cache ${afs_no_unlog}" server=host/localhost KRB5_CONFIG="${objdir}/krb5-mit-kdc.conf" export KRB5_CONFIG # Clean up from previous runs rm -rf "${mitdir}" rm -f "${objdir}/krb5-mit-kdc.conf" rm -f "${objdir}/mit-kdc.conf" rm -f "${cache#FILE:}" rm -f "${keytab}" rm -f "${objdir}/mit-ca.crt" rm -f "${objdir}/mit-kdc.crt" rm -f "${objdir}/mit-user.crt" rm -f "${objdir}/mit-user.pem" rm -f "${objdir}/mit-kdc-key.pem" rm -f req-mit-kdc.der req-mit-user.der mkdir -p "${mitdir}" > messages.log ec=0 kdcpid= cleanup() { if [ -n "$kdcpid" ]; then echo "Killing MIT KDC (pid $kdcpid)" kill $kdcpid 2>/dev/null wait $kdcpid 2>/dev/null fi trap '' EXIT INT TERM # cat messages.log exit $ec } trap cleanup EXIT INT TERM # # Set up certificates for PKINIT # if [ "$pkinit" = yes ] && [ "$rsa" = yes ]; then echo "Setting up PKINIT certificates" ${hxtool} request-create \ --subject="CN=MIT KDC,DC=mit-test,DC=h5l,DC=se" \ --key=FILE:${keyfile2} \ req-mit-kdc.der || exit 1 ${hxtool} request-create \ --subject="CN=foo,DC=mit-test,DC=h5l,DC=se" \ --key=FILE:${keyfile2} \ req-mit-user.der || exit 1 echo "Issuing self-signed CA cert" ${hxtool} issue-certificate \ --self-signed \ --issue-ca \ --ca-private-key=FILE:${keyfile} \ --subject="CN=MIT Test CA,DC=mit-test,DC=h5l,DC=se" \ --certificate="PEM-FILE:${objdir}/mit-ca.crt" || exit 1 echo "Issuing MIT KDC certificate" ${hxtool} issue-certificate \ --ca-certificate=PEM-FILE:${objdir}/mit-ca.crt,${keyfile} \ --type="pkinit-kdc" \ --pk-init-principal="krbtgt/${R}@${R}" \ --req="PKCS10:req-mit-kdc.der" \ --certificate="PEM-FILE:${objdir}/mit-kdc.crt" || exit 1 echo "Issuing user certificate" ${hxtool} issue-certificate \ --ca-certificate=PEM-FILE:${objdir}/mit-ca.crt,${keyfile} \ --type="pkinit-client" \ --pk-init-principal="foo@${R}" \ --req="PKCS10:req-mit-user.der" \ --certificate="PEM-FILE:${objdir}/mit-user.crt" || exit 1 # Create combined PEM file for user PKINIT cat ${objdir}/mit-user.crt > ${objdir}/mit-user.pem openssl rsa -in ${keyfile2} -outform PEM >> ${objdir}/mit-user.pem 2>/dev/null || \ ${hxtool} print --content FILE:${keyfile2} >> ${objdir}/mit-user.pem # Create KDC key PEM file for MIT PKINIT openssl rsa -in ${keyfile2} -outform PEM > ${objdir}/mit-kdc-key.pem 2>/dev/null || \ ${hxtool} print --content FILE:${keyfile2} > ${objdir}/mit-kdc-key.pem pkinit_configured=yes else pkinit_configured=no fi # # Create krb5.conf for Heimdal clients (and MIT tools) # cat > ${objdir}/krb5-mit-kdc.conf <> ${objdir}/krb5-mit-kdc.conf <> ${objdir}/krb5-mit-kdc.conf <> ${objdir}/krb5-mit-kdc.conf < ${objdir}/mit-kdc.conf <> ${objdir}/mit-kdc.conf <> ${objdir}/mit-kdc.conf < ${mitdir}/kadm5.acl </dev/null; then echo "MIT KDC failed to start" cat messages.log exit 1 fi echo "MIT KDC running with PID $kdcpid" # # Test 1: Password authentication with Heimdal kinit # echo "" echo "=== Test 1: Heimdal kinit with password against MIT KDC ===" echo foo > ${objdir}/foopassword ${kinit} --password-file=${objdir}/foopassword foo@${R} || \ { ec=1; eval "${testfailed}"; } echo "Verifying ticket" ${klist} || { ec=1; eval "${testfailed}"; } ${klist} | grep "krbtgt/${R}@${R}" > /dev/null || { ec=1; echo "No TGT found"; eval "${testfailed}"; } echo "Getting service ticket" ${kgetcred} ${server}@${R} || { ec=1; eval "${testfailed}"; } ${klist} | grep "${server}@${R}" > /dev/null || { ec=1; echo "No service ticket found"; eval "${testfailed}"; } ${kdestroy} echo "Test 1 PASSED" # # Test 2: PKINIT authentication with Heimdal kinit # echo "=== Test 2: Heimdal kinit with PKINIT against MIT KDC (negotiate ECDH curve) ===" # Note that MIT does not support X25519, but Heimdal prefers X225519, but we # should negotiate to P-256: ${kinit} -C FILE:${objdir}/mit-user.pem foo@${R} 2>/dev/null || { ec=1; eval "${testfailed}"; } ${klist} || { ec=1; eval "${testfailed}"; } ${klist} | grep "krbtgt/${R}@${R}" > /dev/null || { ec=1; echo "No TGT found"; eval "${testfailed}"; } ${kgetcred} ${server}@${R} || { ec=1; eval "${testfailed}"; } ${kdestroy} echo "Test 2 PASSED" # # Test 3: PKINIT authentication with Heimdal kinit with a preference for an EC # DH curve (P-256) # echo "=== Test 3: Heimdal kinit with PKINIT against MIT KDC (P-256) ===" ${kinit} --key-agreement=P-256 -C FILE:${objdir}/mit-user.pem foo@${R} 2>/dev/null || { ec=1; eval "${testfailed}"; } ${klist} || { ec=1; eval "${testfailed}"; } ${klist} | grep "krbtgt/${R}@${R}" > /dev/null || { ec=1; echo "No TGT found"; eval "${testfailed}"; } ${kgetcred} ${server}@${R} || { ec=1; eval "${testfailed}"; } ${kdestroy} echo "Test 3 PASSED" # # Test 4: PKINIT authentication with Heimdal kinit with a preference for an EC # DH curve (P-521) # echo "=== Test 4: Heimdal kinit with PKINIT against MIT KDC (P-521) ===" ${kinit} --key-agreement=P-521 -C FILE:${objdir}/mit-user.pem foo@${R} 2>/dev/null || { ec=1; eval "${testfailed}"; } ${klist} || { ec=1; eval "${testfailed}"; } ${klist} | grep "krbtgt/${R}@${R}" > /dev/null || { ec=1; echo "No TGT found"; eval "${testfailed}"; } ${kgetcred} ${server}@${R} || { ec=1; eval "${testfailed}"; } ${kdestroy} echo "Test 4 PASSED" # # Test 5: PKINIT authentication with Heimdal kinit with a preference for an EC # DH curve (P-521) # echo "=== Test 5: Heimdal kinit with PKINIT against MIT KDC (modp 2048) ===" ${kinit} --key-agreement=modp_2048 -C FILE:${objdir}/mit-user.pem foo@${R} 2>/dev/null || { ec=1; eval "${testfailed}"; } ${klist} || { ec=1; eval "${testfailed}"; } ${klist} | grep "krbtgt/${R}@${R}" > /dev/null || { ec=1; echo "No TGT found"; eval "${testfailed}"; } ${kgetcred} ${server}@${R} || { ec=1; eval "${testfailed}"; } ${kdestroy} echo "Test 5 PASSED" # # Test 6: FAST with Heimdal kinit (if MIT KDC supports it) # echo "" echo "=== Test 6: Testing with FAST armor ===" # Get armor ticket ${kinit} --password-file=${objdir}/foopassword foo@${R} || \ { ec=1; eval "${testfailed}"; } acache="FILE:${objdir}/mit-acache.krb5" ${kinit} -c ${acache} --password-file=${objdir}/foopassword bar@${R} --fast-armor-cache=$cache || \ { echo "FAST kinit failed (may be expected if MIT KDC does not support it)"; } rm -f "${acache#FILE:}" ${kdestroy} echo "Test 6 completed" # # Done # echo "" echo "All tests passed!" ec=0 exit 0