1#!/bin/sh
2#
3# Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
4# (Royal Institute of Technology, Stockholm, Sweden). 
5# All rights reserved. 
6#
7# Redistribution and use in source and binary forms, with or without 
8# modification, are permitted provided that the following conditions 
9# are met: 
10#
11# 1. Redistributions of source code must retain the above copyright 
12#    notice, this list of conditions and the following disclaimer. 
13#
14# 2. Redistributions in binary form must reproduce the above copyright 
15#    notice, this list of conditions and the following disclaimer in the 
16#    documentation and/or other materials provided with the distribution. 
17#
18# 3. Neither the name of the Institute nor the names of its contributors 
19#    may be used to endorse or promote products derived from this software 
20#    without specific prior written permission. 
21#
22# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
23# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
24# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
25# ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
26# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
27# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
28# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
29# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
30# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
31# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
32# SUCH DAMAGE. 
33#
34# $Id$
35#
36
37env_setup="@env_setup@"
38confdir="@confdir@"
39testdir="@testdir@"
40
41. ${env_setup}
42
43# If there is no useful db support compile in, disable test
44${have_db} || exit 77
45
46mkdir -p "${testdir}"
47rm -rf "${testdir}/"*
48
49R=TEST.H5L.SE
50
51port=@port@
52
53keytabfile=${testdir}/server.keytab
54keytab="FILE:${keytabfile}"
55cache="FILE:${testdir}/krb5ccfile"
56
57kinit="${kinit} -c $cache ${afs_no_afslog}"
58klist="${klist} -c $cache"
59kgetcred="${kgetcred} -c $cache"
60kdestroy="${kdestroy} -c $cache"
61kadmin="${kadmin} -l -r $R"
62kdc="${kdc} --addresses=localhost -P $port"
63
64KRB5_CONFIG="${confdir}/krb5.conf"
65export KRB5_CONFIG
66
67KRB5CCNAME=${cache}
68export KRB5CCNAME
69
70rm -f ${keytabfile}
71rm -f current-db*
72rm -f out-*
73rm -f mkey.file*
74
75> ${testdir}/messages.log
76
77echo Creating database
78${kadmin} \
79    init \
80    --realm-max-ticket-life=1day \
81    --realm-max-renewable-life=1month \
82    ${R} || exit 1
83
84# add both lucid and lucid.test.h5l.se to simulate aliases
85${kadmin} add -p p1 --use-defaults host/lucid.test.h5l.se@${R} || exit 1
86${kadmin} ext -k ${keytab} host/lucid.test.h5l.se@${R} || exit 1
87${kadmin} add -p notp1 --use-defaults CIFS/lucid.test.h5l.se@${R} || exit 1
88${kadmin} ext -k ${keytab} CIFS/lucid.test.h5l.se@${R} || exit 1
89${kadmin} add -p p1 --use-defaults host/lucid@${R} || exit 1
90${kadmin} ext -k ${keytab} host/lucid@${R} || exit 1
91
92${kadmin} add -p p1 --use-defaults host/ok-delegate.test.h5l.se@${R} || exit 1
93${kadmin} mod --attributes=+ok-as-delegate host/ok-delegate.test.h5l.se@${R} || exit 1
94${kadmin} ext -k ${keytab} host/ok-delegate.test.h5l.se@${R} || exit 1
95
96
97${kadmin} add -p p1 --use-defaults host/short@${R} || exit 1
98${kadmin} mod --alias=host/long.test.h5l.se@${R} host/short@${R} || exit 1
99# XXX ext should ext aliases too
100${kadmin} ext -k ${keytab} host/short@${R} || exit 1
101${ktutil} -k ${keytab} rename --no-delete host/short@${R} host/long.test.h5l.se@${R} || exit 1
102
103${kadmin} add -p kaka --use-defaults digest/${R}@${R} || exit 1
104
105${kadmin} add -p u1 --use-defaults user1@${R} || exit 1
106
107# Create a server principal with no AES
108${kadmin} add -p p1 --use-defaults host/no-aes.test.h5l.se@${R} || exit 1
109${kadmin} get host/no-aes.test.h5l.se@${R} > /dev/null || exit 1
110${kadmin} del_enctype host/no-aes.test.h5l.se@${R} \
111    aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 || exit 1
112${kadmin} ext -k ${keytab} host/no-aes.test.h5l.se@${R} || exit 1
113
114echo "Doing database check"
115${kadmin} check ${R} || exit 1
116
117echo u1 > ${testdir}/foopassword
118
119echo Starting kdc
120env MallocStackLogging=1 MallocStackLoggingNoCompact=1 MallocErrorAbort=1 MallocLogFile=${testdir}/malloc-log \
121${kdc} &
122kdcpid=$!
123
124trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
125
126sh ${wait_kdc} KDC ${testdir}/messages.log || exit 1
127
128testfailed="echo test failed; cat ${testdir}/messages.log; exit 1"
129
130echo "Getting client initial tickets" ; > ${testdir}/messages.log
131${kinit} --password-file=${testdir}/foopassword --forwardable user1@${R} || \
132	{ eval "$testfailed"; }
133
134echo "======test acceptor name is service only" ; > ${testdir}/messages.log
135for mech in krb5 spnego; do
136
137	echo "  testing mech $mech"
138
139	${test_context} \
140	    --mech-type=$mech \
141	    --mutual-auth \
142	    --acceptor-name=host \
143	    --name-type=hostbased-service host@lucid.test.h5l.se || \
144		{ eval "$testfailed"; }
145
146	echo "  testing mech $mech (check that it failes for wrong service used)"
147
148	${test_context} \
149	    --mech-type=$mech \
150	    --mutual-auth \
151	    --acceptor-name=CIFS \
152	    --name-type=hostbased-service host@lucid.test.h5l.se && \
153		{ eval "$testfailed"; }
154done
155
156echo "======test unreadable/non existant keytab and its error message" ; > ${testdir}/messages.log
157${test_context} --mech-type=krb5 host@lucid.test.h5l.se || \
158	{ eval "$testfailed"; }
159
160mv ${keytabfile} ${keytabfile}.no
161
162echo "checking non existant keytabfile (krb5)" ; > ${testdir}/messages.log
163${test_context} --mech-type=krb5 host@lucid.test.h5l.se  > ${testdir}/test_context.log 2>&1 && \
164	{ eval "$testfailed"; }
165grep ${keytabfile} ${testdir}/test_context.log > /dev/null || \
166	{ echo "string missing failed"; cat ${testdir}/test_context.log ; eval "$testfailed"; }
167echo "checking non existant keytabfile (spengo)" ; > ${testdir}/messages.log
168${test_context} --mech-type=spnego host@lucid.test.h5l.se > ${testdir}/test_context.log 2>&1 && \
169	{ eval "$testfailed"; }
170grep ${keytabfile} ${testdir}/test_context.log > /dev/null || \
171	{ echo "string missing failed"; cat ${testdir}/test_context.log ; eval "$testfailed"; }
172
173mv ${keytabfile}.no ${keytabfile}
174
175echo "======test naming combinations"
176echo "plain"  ; > ${testdir}/messages.log
177${test_context} --name-type=hostbased-service host@lucid.test.h5l.se || \
178	{ eval "$testfailed"; }
179echo "plain (krb5)" ; > ${testdir}/messages.log
180${test_context} --name-type=krb5-principal-name host/lucid.test.h5l.se@${R} || \
181	{ eval "$testfailed"; }
182echo "plain (krb5 realmless)" ; > ${testdir}/messages.log
183${test_context} --name-type=krb5-principal-name host/lucid.test.h5l.se || \
184	{ eval "$testfailed"; }
185echo "dns canon on (long name) OFF, need dns_wrapper" ; > ${testdir}/messages.log
186#${test_context} --dns-canon host@lucid.test.h5l.se || \
187#	{ eval "$testfailed"; }
188echo "dns canon off (long name)" ; > ${testdir}/messages.log
189${test_context} --no-dns-canon host@lucid.test.h5l.se || \
190	{ eval "$testfailed"; }
191echo "dns canon off (short name)" ; > ${testdir}/messages.log
192${test_context} --no-dns-canon host@lucid || \
193	{ eval "$testfailed"; }
194echo "dns canon off (short name, krb5)" ; > ${testdir}/messages.log
195${test_context}  --no-dns-canon --name-type=krb5-principal-name host/lucid@${R} || \
196	{ eval "$testfailed"; }
197echo "dns canon off (short name, krb5)" ; > ${testdir}/messages.log
198${test_context}  --no-dns-canon --name-type=krb5-principal-name host/lucid || \
199	{ eval "$testfailed"; }
200
201echo "======test context building"
202for mech in krb5 krb5iov spnego spnegoiov; do
203	if [ "$mech" = "krb5iov" ] ; then
204	    mech="krb5"
205	    iov="--iov"
206	fi
207	if [ "$mech" = "spnegoiov" ] ; then
208	    mech="spnego"
209	    iov="--iov"
210	fi
211
212	echo "${mech} no-mutual ${iov}" ; > ${testdir}/messages.log
213	${test_context} --mech-type=${mech} \
214	    --wrapunwrap ${iov} \
215	    --import-export \
216	    --name-type=hostbased-service host@lucid.test.h5l.se || \
217		{ eval "$testfailed"; }
218
219	echo "${mech} mutual ${iov}" ; > ${testdir}/messages.log
220	${test_context} --mech-type=${mech} \
221	    --mutual \
222	    --import-export \
223	    --wrapunwrap ${iov} \
224	    --name-type=hostbased-service host@lucid.test.h5l.se || \
225		{ eval "$testfailed"; }
226
227	echo "${mech} delegate ${iov}" ; > ${testdir}/messages.log
228	${test_context} --mech-type=${mech} \
229	    --delegate \
230	    --wrapunwrap ${iov} \
231	    --import-export \
232	    --name-type=hostbased-service host@lucid.test.h5l.se || \
233		{ eval "$testfailed"; }
234
235	echo "${mech} mutual delegate ${iov}" ; > ${testdir}/messages.log
236	${test_context} --mech-type=${mech} \
237	    --mutual --delegate \
238	    --wrapunwrap ${iov} \
239	    --import-export \
240	    --name-type=hostbased-service host@lucid.test.h5l.se || \
241		{ eval "$testfailed"; }
242done
243
244echo "======dce-style"
245for mech in krb5 krb5iov spnego; do
246	iov=""
247	if [ "$mech" = "krb5iov" ] ; then
248	    mech="krb5"
249	    iov="--iov"
250	fi
251	if [ "$mech" = "spnegoiov" ] ; then
252	    mech="spnego"
253	    iov="--iov"
254	fi
255
256	echo "${mech}: dce-style ${iov}" ; > ${testdir}/messages.log
257	${test_context} \
258	    --mech-type=${mech} \
259	    --mutual \
260	    --dce-style \
261	    --wrapunwrap ${iov} \
262	    --name-type=hostbased-service host@lucid.test.h5l.se || \
263	    { eval "$testfailed"; }
264
265done
266
267echo "test gsskrb5_register_acceptor_identity (both positive and negative)"
268
269cp ${keytabfile} ${keytabfile}.new
270for mech in krb5 spnego; do
271	echo "${mech}: acceptor_identity positive" ; > ${testdir}/messages.log
272	${test_context} --gsskrb5-acceptor-identity=${keytabfile}.new \
273		--mech-type=$mech host@lucid.test.h5l.se || \
274		{ eval "$testfailed"; }
275
276	echo "${mech}: acceptor_identity positive (prefix)" ; > messages.log
277	${test_context} --gsskrb5-acceptor-identity=FILE:${keytabfile}.new \
278		--mech-type=$mech host@lucid.test.h5l.se || \
279		{ eval "$testfailed"; }
280
281	echo "${mech}: acceptor_identity negative" ; > messages.log
282	${test_context} --gsskrb5-acceptor-identity=${keytabfile}.foo \
283		--mech-type=$mech host@lucid.test.h5l.se 2>/dev/null && \
284		{ eval "$testfailed"; }
285done
286
287rm ${keytabfile}.new
288
289
290#echo "sasl-digest-md5"
291#${test_context}  --mech-type=sasl-digest-md5 \
292#    --name-type=hostbased-service \
293#    host@lucid.test.h5l.se || \
294#	{ eval "$testfailed"; }
295
296
297echo "====== gss-api session key check"
298
299# this will break when oneone invents a cooler enctype then aes256-cts-hmac-sha1-96
300coolenctype="aes256-cts-hmac-sha1-96"
301limit_enctype="des3-cbc-sha1"
302
303echo "Getting client initial tickets" ; > ${testdir}/messages.log
304${kinit} --password-file=${testdir}/foopassword user1@${R} || \
305	{ eval "$testfailed"; }
306
307
308echo "Building context on cred w/o aes, but still ${coolenctype} session key" ; > ${testdir}/messages.log
309${test_context} \
310    --mech-type=krb5 \
311    --mutual-auth \
312    --session-enctype=${coolenctype} \
313    --name-type=hostbased-service host@no-aes.test.h5l.se || \
314	{ eval "$testfailed"; }
315
316echo "Building context on cred, check if its limited still to ${limit_enctype}" ; > ${testdir}/messages.log
317${test_context} \
318    --mech-type=krb5 \
319    --client-name=user1@${R} \
320    --limit-enctype="${limit_enctype}" \
321    --mutual-auth \
322    --name-type=hostbased-service host@no-aes.test.h5l.se || \
323	{ eval "$testfailed"; }
324
325
326echo "====== ok-as-delegate"
327
328echo "Getting client initial tickets" ; > ${testdir}/messages.log
329${kinit} --forwardable \
330    --password-file=${testdir}/foopassword user1@${R} || \
331	{ eval "$testfailed"; }
332
333echo "ok-as-delegate not used" ; > ${testdir}/messages.log
334${test_context} \
335    --mech-type=krb5 \
336    --delegate \
337    --name-type=hostbased-service host@lucid.test.h5l.se || \
338	{ eval "$testfailed"; }
339
340echo "host without ok-as-delegate with policy-delegate" ; > ${testdir}/messages.log
341${test_context} \
342    --mech-type=krb5 \
343    --policy-delegate \
344    --server-no-delegate \
345    --name-type=hostbased-service host@lucid.test.h5l.se || \
346	{ eval "$testfailed"; }
347
348echo "ok-as-delegate used by policy" ; > ${testdir}/messages.log
349${test_context} \
350    --mech-type=krb5 \
351    --policy-delegate \
352    --name-type=hostbased-service host@ok-delegate.test.h5l.se || \
353	{ eval "$testfailed"; }
354
355echo "Getting client initial tickets with --ok-as-delgate" ; > ${testdir}/messages.log
356${kinit} --ok-as-delegate  --forwardable \
357    --password-file=${testdir}/foopassword user1@${R} || \
358	{ eval "$testfailed"; }
359
360echo "policy delegate to non delegate host" ; > ${testdir}/messages.log
361${test_context} \
362    --mech-type=krb5 \
363    --policy-delegate \
364    --server-no-delegate \
365    --name-type=hostbased-service host@lucid.test.h5l.se || \
366	{ eval "$testfailed"; }
367
368echo "ok-as-delegate" ; > ${testdir}/messages.log
369${test_context} \
370    --mech-type=krb5 \
371    --delegate \
372    --name-type=hostbased-service host@lucid.test.h5l.se || \
373	{ eval "$testfailed"; }
374
375echo "======export/import cred"
376
377echo "export-import cred (krb5)" ; > ${testdir}/messages.log
378${test_context} \
379    --mech-type=krb5 \
380    --delegate \
381    --export-import-cred \
382    --name-type=hostbased-service host@ok-delegate.test.h5l.se || \
383	{ eval "$testfailed"; }
384
385echo "export-import cred (spnego)" ; > ${testdir}/messages.log
386${test_context} \
387    --mech-type=spnego \
388    --delegate \
389    --export-import-cred \
390    --name-type=hostbased-service host@ok-delegate.test.h5l.se || \
391	{ eval "$testfailed"; }
392
393
394echo "======time diffs between client and server"
395
396echo "Getting client initial ticket" ; > ${testdir}/messages.log
397${kinit} --password-file=${testdir}/foopassword user1@${R} || \
398	{ eval "$testfailed"; }
399
400echo "No time offset" ; > ${testdir}/messages.log
401${test_context} \
402    --mech-type=krb5 \
403    --name-type=hostbased-service host@lucid.test.h5l.se || \
404	{ eval "$testfailed"; }
405
406echo "Getting client initial ticket" ; > ${testdir}/messages.log
407${kinit} --password-file=${testdir}/foopassword user1@${R} || \
408	{ eval "$testfailed"; }
409
410echo "Server time offset" ; > ${testdir}/messages.log
411${test_context} \
412    --mech-type=krb5 \
413    --mutual-auth \
414    --server-time-offset=3600 \
415    --max-loops=3 \
416    --name-type=hostbased-service host@lucid.test.h5l.se || \
417	{ eval "$testfailed"; }
418
419echo "Server time offset (cached ?)" ; > ${testdir}/messages.log
420${test_context} \
421    --mech-type=krb5 \
422    --mutual-auth \
423    --server-time-offset=3600 \
424    --max-loops=2 \
425    --name-type=hostbased-service host@lucid.test.h5l.se || \
426	{ eval "$testfailed"; }
427
428echo "Getting client initial ticket" ; > ${testdir}/messages.log
429${kinit} --password-file=${testdir}/foopassword user1@${R} || \
430	{ eval "$testfailed"; }
431# Pre-poplute the cache since tgs-req will fail since our time is wrong
432${kgetcred} host/lucid.test.h5l.se@${R} || \
433	{ eval "$testfailed"; }
434
435echo "Client time offset" ; > ${testdir}/messages.log
436${test_context} \
437    --mech-type=krb5 \
438    --mutual-auth \
439    --client-time-offset=3600 \
440    --name-type=hostbased-service host@lucid.test.h5l.se || \
441	{ eval "$testfailed"; }
442
443echo "Getting client initial tickets (use-referrals)" ; > ${testdir}/messages.log
444${kinit} \
445    --password-file=${testdir}/foopassword \
446    --use-referrals user1@${R} || \
447	{ eval "$testfailed"; }
448
449# XXX these tests really need to use somethat that resolve to something
450${test_context} \
451    --mech-type=krb5 \
452    host@short || \
453	{ eval "$testfailed"; }
454
455${test_context} \
456    --mech-type=krb5 \
457    --name-type=krb5-principal-name host/short || \
458	{ eval "$testfailed"; }
459
460${test_context} \
461    --mech-type=krb5 \
462    host@long.test.h5l.se || \
463	{ eval "$testfailed"; }
464
465${test_context} \
466    --mech-type=krb5 \
467    --name-type=krb5-principal-name \
468    host/long.test.h5l.se || \
469	{ eval "$testfailed"; }
470
471echo "Make clients credentials cache stale (cpw)" ; > ${testdir}/messages.log
472
473echo "Getting client initial ticket" ; > ${testdir}/messages.log
474${kinit} --password-file=${testdir}/foopassword user1@${R} || \
475	{ eval "$testfailed"; }
476${kgetcred} host/lucid.test.h5l.se@${R} || \
477	{ eval "$testfailed"; }
478
479${kadmin} passwd -r host/lucid.test.h5l.se@${R} || exit 1
480${ktutil} -k ${keytab} delete -p host/lucid.test.h5l.se@${R} || exit 1
481${kadmin} ext -k ${keytab} host/lucid.test.h5l.se@${R} || exit 1
482
483${test_context} \
484    --mech-type=krb5 \
485    --mutual-auth \
486    --name-type=hostbased-service host@lucid.test.h5l.se || \
487	{ eval "$testfailed"; }
488
489echo "Make clients credentials cache stale (delete/add)" ; > ${testdir}/messages.log
490
491echo "Getting client initial ticket" ; > ${testdir}/messages.log
492${kinit} --password-file=${testdir}/foopassword user1@${R} || \
493	{ eval "$testfailed"; }
494${kgetcred} host/lucid.test.h5l.se@${R} || \
495	{ eval "$testfailed"; }
496
497${kadmin} delete host/lucid.test.h5l.se@${R} || exit 1
498${ktutil} -k ${keytab} delete -p host/lucid.test.h5l.se@${R} || exit 1
499${kadmin} add -p p2 --use-defaults host/lucid.test.h5l.se@${R} || exit 1
500${kadmin} ext -k ${keytab} host/lucid.test.h5l.se@${R} || exit 1
501
502${test_context} \
503    --mech-type=krb5 \
504    --mutual-auth \
505    --name-type=hostbased-service host@lucid.test.h5l.se || \
506	{ eval "$testfailed"; }
507
508echo "======fuzzer"
509
510if [ X"$HEIMDAL_FUZZER" != X ] ; then
511
512    for mech in krb5 spnego ; do
513    
514        echo "    $mech"
515    
516        rm -f ${testdir}/dumpdata.bin
517    
518        ${test_gss_fuzzer} \
519            --mech-type=${mech} \
520            --dump-data=${testdir}/dumpdata.bin \
521            --name-type=hostbased-service host@lucid.test.h5l.se || \
522                { \
523                  if [ -f ${testdir}/dumpdata.bin ] ; then \
524                      openssl base64 -e -in ${testdir}/dumpdata.bin; \
525                  fi ; \
526                  eval "$testfailed"; \
527                }
528    
529    done
530fi
531
532
533trap "" EXIT
534
535echo "killing kdc (${kdcpid})"
536sh ${leaks_kill} kdc $kdcpid || exit 1
537
538exit 0
539
540