#!/bin/sh # # Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan # (Royal Institute of Technology, Stockholm, Sweden). # All rights reserved. # # Portions Copyright (c) 2009 - 2010 Apple Inc. 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. env_setup="@env_setup@" confdir="@confdir@" testdir="@testdir@" if [ "$UID" != 0 ] ; then echo "must run script as root since it create users" exit 1 fi mkdir -p $testdir 2> /dev/null hodadmin="/System/Library/PrivateFrameworks/Heimdal.framework/Helpers/hod-admin" u=heimdaltestuser v=heimdaltestusersrp uid=82367346 o=heimdalother u2=heimdaltestuser2 s=heimdaltestservice mme="heimdaltestuser@me.com" mmeq="heimdaltestuser\\@me.com" r=WELLKNOWN:COM.APPLE.LKDC pw=foo . ${env_setup} KRB5_CONFIG="${1-${confdir}/krb5.conf}" export KRB5_CONFIG logfile=${testdir}/messages.log tempfile=${testdir}/tempfile cache="FILE:${testdir}/cache.krb5" testfailed="echo test failed; cat ${logfile}; exit 1" kdc="${kdc} --addresses=localhost" kkinit="${kinit}" kklist="${klist}" kkdestroy="${kdestroy}" kinit="${kinit} -c $cache" klist="${klist} -c $cache" kgetcred="${kgetcred} -c $cache" kdestroy="${kdestroy} -c $cache" mkdir -p ${testdir} rm -f ${testdir}/out-* rm -rf ${testdir}/smb mkdir "${testdir}/smb" > "${testdir}/smb/there-is-a-file-here" > ${logfile} toggle_launchd() { digestservice=com.apple.Kerberos.digest-service kcmservice=com.apple.Kerberos.kcm ds=/System/Library/LaunchDaemons/$digestservice.plist kcm=/System/Library/LaunchDaemons/$kcmservice.plist if [ $1 = "malloc-set" ] ; then launchctl setenv MallocStackLoggingNoCompact 1 launchctl setenv MallocErrorAbort 1 elif [ $1 = "malloc-unset" ] ; then launchctl unsetenv MallocStackLoggingNoCompact launchctl unsetenv MallocErrorAbort fi launchctl unload $ds killall -9 digest-service 2>/dev/null launchctl load $ds launchctl unload $kcm killall -9 kcm 2>/dev/null launchctl load $kcm } toogle_ntlm () { if [ $1 = "disable" ] ; then op=write arg="-bool false" elif [ $1 = "enable" ] ; then op=delete arg="" else exit 1 fi defaults $op /Library/Preferences/com.apple.GSS.NTLM NTLMv1 $arg defaults $op /Library/Preferences/com.apple.GSS.NTLM NTLMv2 $arg killall -9 digest-service killall -9 kcm } echo "Checking if UserEventAgent and smbplugin have done their job" if ! echo 'show com.apple.smb' | scutil | grep NetBIOSName > /dev/null ; then echo "they have not" echo 'show com.apple.smb' | scutil | sed 's/^/ /' exit 1 fi echo "Creating lkdc user" echo " delete" dscl . -delete /Users/$u 2>/dev/null >/dev/null echo " create" dscl . -create /Users/$u echo " RealName" dscl . -append /Users/$u RealName "Heimdal testuser" dscl . -append /Users/$u RecordName "${mme}" dscl . -append /Users/$u dsAttrTypeStandard:AltSecurityIdentities 'X509:C=SE,CN=hx509 Test Root CACN=pkinit,C=SE' dscl . -delete /Users/$u AuthenticationAuthority dscl . -append /Users/$u AuthenticationAuthority ';ShadowHash;HASHLIST:' dscl . -append /Users/$u UniqueID $uid dscl . -append /Users/$u PrimaryGroupID 20 dscl . -append /Users/$u NFSHomeDirectory "${testdir}/smb" echo " Password" dscl . -passwd /Users/$u $pw echo " Check keys" echo "Creating srp lkdc user" echo " delete" dscl . -delete /Users/$v 2>/dev/null >/dev/null echo " create" dscl . -create /Users/$v echo " RealName" dscl . -append /Users/$v RealName "Heimdal testuser srp" dscl . -append /Users/$v RecordName "srp${mme}" dscl . -delete /Users/$v AuthenticationAuthority dscl . -append /Users/$v AuthenticationAuthority ';ShadowHash;HASHLIST:' dscl . -append /Users/$v UniqueID $(expr $uid + 1) dscl . -append /Users/$v PrimaryGroupID 20 dscl . -append /Users/$v NFSHomeDirectory "${testdir}/smb" echo " SRP verififer (no pw)" dscl . -passwd /Users/$u $pw $hodadmin . srp-verifier $v srp$pw # XXX opendirectory/plist backend should do this $hodadmin . password \ --encryption-types=aes256-cts-hmac-sha1-96 \ --encryption-types=aes128-cts-hmac-sha1-96 \ --encryption-types=des3-cbc-sha1 \ --encryption-types=arcfour-hmac-md5 \ /Users/$u $pw { dscl . -read /Users/$u KerberosKeys 2>&1 | grep KerberosKeys: > /dev/null ; } || \ { echo "KerberosKeys missing" ; exit 1; } { dscl . -read /Users/$u HeimdalSRPKey 2>&1 | grep HeimdalSRPKey: > /dev/null ; } || \ { echo "SRP verififer missing" ; exit 1; } { dscl . -read /Users/$u dsAttrTypeStandard:AltSecurityIdentities | grep pkinit > /dev/null; } || \ { echo "asi missing" ; exit 1; } #{ dscl . -read /Users/$v KerberosKeys 2>&1 | grep KerberosKeys: > /dev/null ; } && \ # { echo "KerberosKey there when they should not be" ; exit 1; } { dscl . -read /Users/$v HeimdalSRPKey 2>&1 | grep HeimdalSRPKey: > /dev/null ; } || \ { echo "SRP verifier missing" ; exit 1; } chown -R $u "${testdir}/smb" echo $pw > ${testdir}/foopassword echo srp$pw > ${testdir}/srpfoopassword echo "Server domain" echo " delete" dscl . -delete /Users/$o 2>/dev/null >/dev/null echo " create" dscl . -create /Users/$o dscl . -append /Users/$o UniqueID $(expr $uid + 2) dscl . -append /Users/$o PrimaryGroupID 20 echo " setflags" $hodadmin . principal-setflags $o Server Forwardable echo " password" $hodadmin . password $o domain || exit 1 echo "Creating server user" echo " delete" dscl . -delete /Users/$u2 2>/dev/null >/dev/null echo " create" dscl . -create /Users/$u2 dscl . -append /Users/$u2 UniqueID $(expr $uid + 3) dscl . -append /Users/$u2 PrimaryGroupID 20 echo " password" dscl . -passwd /Users/$u2 $pw echo " checking user" (dscl . -read /Users/$u KerberosKeys | grep KerberosKeys > /dev/null) || \ { echo "KerberosKeys missing" ; exit 1; } echo " setflags" $hodadmin . principal-setflags /Computers/$s Server echo " password" $hodadmin . password /Computers/$s user-password foundlines=$(${kadmin} -l dump | wc -l) if [ "X${foundlines}" = "X" -o "X${foundlines}" = X0 ] ; then echo "dumpfile contained nothing" exit 1 fi echo "done user creation" toogle_ntlm enable echo Starting kdc env MallocStackLoggingNoCompact=1 MallocErrorAbort=1 MallocLogFile=${testdir}/malloc-log \ ${kdc} & kdcpid=$! sh ${wait_kdc} KDC ${logfile} if [ "$?" != 0 ] ; then kill -9 ${kdcpid} exit 1 fi trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT ec=0 for a in 1 2 3 4 5 6 7 8 9 10 ; do echo "Getting client initial tickets ${a}"; > ${logfile} ${kinit} --kdc-hostname=localhost --canon --password-file=${testdir}/foopassword ${u}@${r} || \ { ec=1 ; eval "${testfailed}"; } done echo "Getting client initial tickets";> ${logfile} ${kkdestroy} -A ${kkinit} --kdc-hostname=localhost --canon --password-file=${testdir}/foopassword ${u}@${r} || \ { ec=1 ; eval "${testfailed}"; } ${kkinit} --kdc-hostname=localhost --canon --password-file=${testdir}/srpfoopassword ${v}@${r} || \ { ec=1 ; eval "${testfailed}"; } echo "Checking that credentials are stored" (${kklist} -l | grep ${u}) >/dev/null || { ec=1 ; eval "${testfailed}"; } (${kklist} -l | grep ${v}) >/dev/null || { ec=1 ; eval "${testfailed}"; } echo "checking that u2 is first" > ${logfile} (${kklist} | grep ${v}) >/dev/null || { ec=1 ; eval "${testfailed}"; } echo "checking that u2 still is first (sleep 20)" > ${logfile} sleep 20 (${kklist} | grep ${v}) >/dev/null || { ec=1 ; eval "${testfailed}"; } ${kkdestroy} -A echo "Gettting client initial tickets" ${kinit} --kdc-hostname=localhost --canon --password-file=${testdir}/foopassword ${u}@${r} || \ { ec=1; eval "${testfailed}"; } echo "Getting tickets"; > ${logfile} ${kgetcred} host/${r}@${r} || { ec=1 ; eval "${testfailed}"; } echo "Listing tickets"; > ${logfile} ${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; } ${kdestroy} echo "Getting PKINIT credentials"; > ${logfile} ${kinit} -C FILE:${hx509_data}/pkinit.crt,${hx509_data}/pkinit.key \ -D KEYCHAIN: --canon \ --kdc-hostname=localhost \ "${mmeq}@${r}" || \ { ec=1 ; eval "${testfailed}"; } echo "Getting tickets"; > ${logfile} ${kgetcred} host/${r}@${r} || { ec=1 ; eval "${testfailed}"; } echo "Listing tickets"; > ${logfile} ${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; } ${kdestroy} echo "Get kerberos ticket for gss test"; > ${logfile} ${kinit} --kdc-hostname=localhost --canon --password-file=${testdir}/foopassword ${u}@${r} || \ { ec=1 ; eval "${testfailed}"; } echo "testing Kerberos GSS mech" ; > ${logfile} env KRB5CCNAME=FILE:/tmp/heimdal/cache.krb5 ${test_context} \ --mech=krb5 --wrap --verbose \ service@localhost || { ec=1 ; eval "${testfailed}"; } echo "testing Kerberos GSS mech (no homedir)" ; > ${logfile} sandbox-exec -p '(version 1) (allow default) (deny file* (subpath #"/private/var/root") (with send-signal SIGABRT))' \ env CFFIXED_USER_HOME=/ KRB5CCNAME=/tmp/heimdal/cache.krb5 \ ${test_context} \ --no-homedir \ --mech=krb5 --wrap --verbose \ service@localhost || { ec=1 ; eval "${testfailed}"; } ${kdestroy} #echo "testing IAKERB GSS mech" #${test_context} \ # --client-name=heimdaltestuser@WELLKNOWN:COM.APPLE.LKDC \ # --password="$pw" \ # --cred-type=iakerb \ # --mech=iakerb --wrap --verbose \ # service@localhost || { ec=1 ; eval "${testfailed}"; } echo "test_gssntlm" toggle_launchd malloc-set domain=$(echo 'show com.apple.smb ' | scutil | grep NetBIOSName | sed 's/ NetBIOSName : //') ${test_gssntlm} --user=$u --domain='' --password=$pw || { ec=1 ; eval "${testfailed}"; } ${test_gssntlm} --user=$u --domain=FOO --password=$pw || { ec=1 ; eval "${testfailed}"; } ${test_gssntlm} --user=$u --domain=$domain --password=$pw || { ec=1 ; eval "${testfailed}"; } defaults delete /Library/Preferences/com.apple.GSS.NTLM AllowedHosts defaults write /Library/Preferences/com.apple.GSS.NTLM AllowedHosts -array host.local for a in \ "0 host@host.local host.local" \ "0 host@host.local" \ "0 host@host.local \*.local" \ "1 host@host.local host2.local" \ "1 host@host.local 2host.local" \ "1 host@host.local \*.local2" \ "1 host@host.local \*.2local" do echo "---running test $a" set -- $a eres=$1 host=$2 shift 2 if test $# -ne 0 ; then defaults write \ /Library/Preferences/com.apple.GSS.NTLM AllowedHosts -array "$@" else defaults delete \ /Library/Preferences/com.apple.GSS.NTLM AllowedHosts fi echo " NTLM GSS mech" ${test_context} \ --client-name=$u \ --password=$pw \ --mech-type=ntlm \ --mutual \ --ret-mech-type=ntlm \ ${host} > /dev/null 2>&1 res=$? test "$res" = "$eres" || { \ defaults delete /Library/Preferences/com.apple.GSS.NTLM AllowedHosts ; \ echo "test failed"; exit 1; \ } echo " NTLM GSS mech channel bindings" ${test_context} \ --client-name=$u \ --password=$pw \ --mech-type=ntlm \ --mutual \ --channel-binding="0123456789abcdef" \ --ret-mech-type=ntlm \ ${host} > /dev/null 2>&1 res=$? test "$res" = "$eres" || { \ defaults delete /Library/Preferences/com.apple.GSS.NTLM AllowedHosts ; \ echo "test failed"; exit 1; \ } done defaults delete /Library/Preferences/com.apple.GSS.NTLM AllowedHosts echo "check NTLM GUEST account"; > ${logfile} ${test_context} \ --client-name=GUEST \ --password="" \ --mech-type=ntlm \ --mutual \ --ret-mech-type=ntlm \ cifs@localhost || { echo "test failed"; exit 1; } echo "check that NTLM can be disabled"; > ${logfile} toogle_ntlm disable ${test_context} \ --client-name=$u \ --password=$pw \ --mech-type=ntlm \ --mutual \ --ret-mech-type=ntlm \ cifs@localhost > /dev/null 2>&1 && \ { echo "test failed"; exit 1; } echo "check that NTLM can be enabled again"; > ${logfile} toogle_ntlm enable ${test_context} \ --client-name=$u \ --password=$pw \ --mech-type=ntlm \ --mutual \ --ret-mech-type=ntlm \ cifs@localhost > /dev/null 2>&1 || \ { echo "test failed"; exit 1; } echo "check NTLM GUEST@domain account"; > ${logfile} ${test_context} \ --client-name=GUEST@domain \ --password="" \ --mech-type=ntlm \ --mutual \ --ret-mech-type=ntlm \ --verbose \ cifs@localhost > ${tempfile} || { echo "test failed"; exit 1; } grep -e "^source.server.: GUEST@${domain}" ${tempfile} > /dev/null || \ { echo "failed to find guest@DOMAIN"; exit 1; } rm "${tempfile}" echo "Getting tickets (leaks check)"; > ${logfile} ${kinit} --kdc-hostname=localhost --canon --password-file=${testdir}/foopassword ${u}@${r} || \ { ec=1 ; eval "${testfailed}"; } echo "Getting PKINIT credentials (leaks check)"; > ${logfile} ${kinit} -C FILE:${hx509_data}/pkinit.crt,${hx509_data}/pkinit.key \ -D KEYCHAIN: --canon \ --kdc-hostname=localhost \ "${mmeq}@${r}" || \ { ec=1 ; eval "${testfailed}"; } #echo "checking policy" #pwpolicy -u $u -setpolicy "usingExpirationDate=1 expirationDateGMT=01/01/01" > /dev/null #echo "getting policy" #pwpolicy -u $u -getpolicy # #echo "getting ticket" #${kinit} --kdc-hostname=localhost --canon --password-file=${testdir}/foopassword ${u}@${r} && \ # { echo "expected to fail"; exit 1; } # #echo "unsetting policy" #pwpolicy -u $u -setpolicy "usingExpirationDate=0" # #echo "getting ticket" #${kinit} --kdc-hostname=localhost --canon --password-file=${testdir}/foopassword ${u}@${r} || \ # { echo "expected to pass"; exit 1; } echo "checking mounting with NTLM" host=$(hostname) if expr "$host" : '.*\.apple\.com' > /dev/null ; then #launchctl load -F /System/Library/LaunchDaemons/com.apple.smbd.plist #killall smbd ${winmount} ${testbase}/apple/coswin7-local.plist ${host} || exit 1 else echo "not running windows mount test since you are no on apple network" fi sh ${leaks_kill} --check digest-service digest-service || exit 1 sh ${leaks_kill} --check kcm kcm || exit 1 echo "killing kdc (${kdcpid})" sh ${leaks_kill} kdc $kdcpid || exit 1 toggle_launchd malloc-unset rm -rf "${testdir}/smb" dscl . -delete /Users/$u dscl . -delete /Users/$u2 dscl . -delete /Users/$v dscl . -delete /Users/$s dscl . -delete /Users/$o trap "" EXIT exit $ec