#! /bin/sh
#
# Test suite for the wallet command-line client.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2006, 2007, 2008, 2010
#     The Board of Trustees of the Leland Stanford Junior University
#
# See LICENSE for licensing terms.

# Load the test library.
. "$SOURCE/tap/libtap.sh"
. "$SOURCE/tap/kerberos.sh"
. "$SOURCE/tap/remctl.sh"
cd "$SOURCE"

# We need a modified krb5.conf file to test wallet configuration settings in
# krb5.conf.  Despite the hard-coding of test-k5.stanford.edu, this test isn't
# Stanford-specific; it just matches the files that are distributed with the
# package.
krb5conf=
for p in /etc/krb5.conf /usr/local/etc/krb5.conf data/krb5.conf ; do
    if [ -r "$p" ] ; then
        krb5conf="$p"
        sed -e '/^[ 	]*test-k5.stanford.edu =/,/}/d' \
            -e 's/\(default_realm.*=\) .*/\1 test-k5.stanford.edu/' \
            -e 's/^[ 	]*wallet_.*//' \
            -e '/^[ 	]*wallet[ 	]*=[ 	]*{/,/}/d' \
            "$p" > ./krb5.conf
        cat >> krb5.conf <<EOF

[realms]
    test-k5.stanford.edu = {
        v4_realm = test-k5.stanford.edu
    }
EOF
        KRB5_CONFIG="./krb5.conf"
        export KRB5_CONFIG
        break
    fi
done
if [ -z "$krb5conf" ] ; then
    skip_all 'no krb5.conf found, put one in tests/data/krb5.conf'
fi

# Test setup.
kerberos_setup
if [ $? != 0 ] ; then
    rm krb5.conf
    skip_all 'Kerberos tests not configured'
elif [ -z '@REMCTLD@' ] ; then
    rm krb5.conf
    skip_all 'No remctld found'
else
    plan 36
fi
remctld_start '@REMCTLD@' "$SOURCE/data/basic.conf"
wallet="$BUILD/../client/wallet"

# Make sure everything's clean.
rm -f output output.bak keytab keytab.bak srvtab srvtab.bak autocreated

# Now, we can finally run our tests.  First, basic operations.
ok_program 'get file' 0 '' \
    "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet -f output \
    get file fake-test
ok '...and file is correct' cmp output data/fake-data
ok '...and no backup files' [ ! -f output.bak ]
ok '...and no new files' [ ! -f output.new ]
ok '...and we tried autocreation' [ -f autocreated ]
ok_program 'get file again' 0 '' \
   "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet -f output \
    get file fake-test
ok '...and file is correct' cmp output data/fake-data
ok '...and now there is a backup file' [ -f output.bak ]
ok '...which has the right contents' cmp output.bak data/fake-data
ok '...but there is no new file' [ ! -f output.new ]

# Now, append configuration to krb5.conf and test getting configuration from
# there.
cat >> krb5.conf <<EOF

[appdefaults]
    wallet_server = localhost
    wallet = {
        wallet_port = 14373
        wallet_type = fake-wallet
        wallet_principal = $principal
    }
EOF
ok_program 'get file with configuration' 0 '' \
    "$wallet" -f output get file fake-test
ok '...and file is correct' cmp output data/fake-data
rm -f output output.bak

# Test keytab support.
ok_program 'get keytab' 0 '' \
    "$wallet" -f keytab get keytab service/fake-srvtab
ok '...and keytab is correct' cmp keytab data/fake-keytab
rm -f keytab

# Test srvtab support.
ok_program 'get srvtab' 0 '' \
    "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
ok '...and keytab is correct' cmp keytab data/fake-keytab
rm -f keytab
ok_program 'get srvtab again' 0 '' \
    "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
ok '...and keytab is correct' cmp keytab data/fake-keytab
ok '...and srvtab is correct' cmp srvtab data/fake-srvtab
ok '...and srvtab backup is correct' cmp srvtab.bak data/fake-srvtab
rm -f srvtab srvtab.bak

# Test keytab merging.
ok_program 'keytab merging' 0 '' \
    "$wallet" -f keytab get keytab service/fake-keytab
ktutil_list keytab klist-seen
ktutil_list data/fake-keytab-merge klist-good
ok '...and the merged keytab is correct' cmp klist-seen klist-good
rm -f keytab klist-good klist-seen

# Test srvtab download into a merged keytab with an older version.
cp data/fake-keytab-old keytab
ok_program 'keytab merging with srvtab creation' 0 '' \
    "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
ok '...and the srvtab is correct' cmp srvtab data/fake-srvtab
rm -f keytab srvtab

# Test store from standard input.
echo "This is a test of store" > input
ok_program 'store from stdin' 0 '' "$wallet" store file fake-test < input
rm -f input
echo "file fake-test" > store-correct
echo "This is a test of store" >> store-correct
ok '...and the correct data was stored' diff store-output store-correct
rm -f store-output store-correct

# Test store with -f.
echo "This is more store input" > store-input
echo "file fake-test" > store-correct
cat store-input >> store-correct
ok_program 'store from a file' 0 '' \
    "$wallet" -f store-input store file fake-test
ok '...and the correct data was stored' cmp store-output store-correct
rm -f store-input store-output store-correct
printf 'This is store input\000with a nul character' > store-input
echo 'file fake-nul' > store-correct
cat store-input >> store-correct
ok_program 'store from a file with a nul' 0 '' \
    "$wallet" -f store-input store file fake-nul
ok '...and the correct data was stored' cmp store-output store-correct
rm -f store-input store-output store-correct

# Test various other client functions and errors.
ok_program 'get output to stdout' 0 'This is a fake keytab.' \
    "$wallet" get keytab service/fake-output
ok_program 'show output' 0 'Some stuff about file fake-test' \
    "$wallet" show file fake-test
ok_program 'unknown object type' 1 'wallet: Unknown object type srvtab' \
    "$wallet" get srvtab service/fake-test
ok_program 'unknown keytab name in show' 1 \
    'wallet: Unknown keytab service/unknown' \
    "$wallet" show keytab service/unknown
ok_program 'unknown keytab name in get' 1 \
    'wallet: Unknown keytab service/unknown' \
    "$wallet" get keytab service/unknown
ok_program 'expiration date' 0 'Expiration date of keytab service/fake-test' \
    "$wallet" expires keytab service/fake-test

# Clean up.
rm -f autocreated krb5.conf
remctld_stop
kerberos_cleanup