summaryrefslogtreecommitdiff
path: root/third_party/heimdal/tests/kdc/check-bx509.in
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/heimdal/tests/kdc/check-bx509.in')
-rw-r--r--third_party/heimdal/tests/kdc/check-bx509.in674
1 files changed, 674 insertions, 0 deletions
diff --git a/third_party/heimdal/tests/kdc/check-bx509.in b/third_party/heimdal/tests/kdc/check-bx509.in
new file mode 100644
index 00000000000..1cef2e0e766
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-bx509.in
@@ -0,0 +1,674 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 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.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+DCs="DC=test,DC=h5l,DC=se"
+
+port=@port@
+bx509port=@bx509port@
+
+kadmin="${kadmin} -l -r $R"
+bx509d="${bx509d} --reverse-proxied -p $bx509port"
+kdc="${kdc} --addresses=localhost -P $port"
+
+server=datan.test.h5l.se
+otherserver=other.test.h5l.se
+cachefile="${objdir}/cache.krb5"
+cache="FILE:${cachefile}"
+cachefile2="${objdir}/cache2.krb5"
+cache2="FILE:${cachefile2}"
+keyfile="${hx509_data}/key.der"
+keyfile2="${hx509_data}/key2.der"
+kt=${objdir}/kt
+keytab=FILE:${kt}
+ukt=${objdir}/ukt
+ukeytab=FILE:${ukt}
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist2="${klist} --hidden -v -c $cache2"
+klistjson="${klist} --json -c $cache"
+klist="${klist} --hidden -v -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+kx509="${kx509} -c $cache"
+
+KRB5_CONFIG="${objdir}/krb5-bx509.conf"
+export KRB5_CONFIG
+
+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
+
+# If we doesn't support pkinit and have RSA, give up
+if test "$pkinit" != yes -o "$rsa" != yes ; then
+ exit 77
+fi
+
+
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+rm -f *.pem *.crt *.der
+rm -rf simple_csr_authz
+
+mkdir -p simple_csr_authz
+
+> messages.log
+
+# We'll avoid using a KDC for now. For testing /bx509 we only need keys for
+# Negotiate tokens, and we'll use ktutil and kimpersonate to make it possible
+# to create and accept those without a KDC. When we test /bnegotiate, however,
+# we'll start a KDC.
+
+# csr_grant ext-type value grantee_principal
+csr_grant() {
+ mkdir -p "${objdir}/simple_csr_authz/${3}"
+ touch "${objdir}/simple_csr_authz/${3}/${1}-${2}"
+}
+
+csr_revoke() {
+ rm -rf "${objdir}/simple_csr_authz"
+ mkdir -p "${objdir}/simple_csr_authz"
+}
+
+# get_cert "" curl-opts
+# get_cert "&qparams" curl-opts
+get_cert() {
+ url="http://${server}:${bx509port}/bx509?csr=$csr${1}"
+ shift
+ curl -g --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "$@" "$url"
+}
+
+rm -f $kt $ukt
+$ktutil -k $keytab add -r -V 1 -e aes128-cts-hmac-sha1-96 \
+ -p HTTP/datan.test.h5l.se@${R} ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$ktutil -k $keytab list ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$kimpersonate --ccache=$cache -k $keytab -R -t aes128-cts-hmac-sha1-96 \
+ -c foo@${R} -s HTTP/datan.test.h5l.se@${R} ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$klist ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+
+echo "Setting up certificates"
+# We need:
+#
+# - a CA certificate for issuing client certificates
+# - a CA certificate for issuing server certificates
+# - a CA certificate for issuing mixed certificates
+# - a certificate for bx509 itself (well, not in reverse proxy mode, but we'll
+# make one anyways)
+
+# Make the realm's user cert issuer CA certificate.
+#
+# NOTE WELL: We need all three KeyUsage values listed below!
+# We also need this to be of type "pkinit-kdc",
+# which means we'll get an appropriate EKU OID as
+# well.
+$hxtool ca --issue-ca --self-signed --type=pkinit-kdc \
+ --ku=digitalSignature --ku=keyCertSign --ku=cRLSign \
+ --pk-init-principal=krbtgt/${R}@${R} \
+ --generate-key=rsa --key-bits=1024 \
+ --subject="OU=Users,CN=KDC,${DCs}" \
+ --certificate=PEM-FILE:"${objdir}/user-issuer.pem" ||
+ { echo "failed to setup CA certificate"; exit 2; }
+
+# We'll use the user cert issuer as the PKINIT anchor, allowing bx509-issued
+# certificates to be used for PKINIT. Though we won't be testing PKINIT here
+# -- we test kx509->PKINIT in check-pkinit.
+cp ${objdir}/user-issuer.pem ${objdir}/pkinit-anchor.pem
+
+# Put the cert alone in the trust anchors file
+ex "${objdir}/pkinit-anchor.pem" <<"EOF"
+/-----BEGIN CERTIFICATE-----
+1,.-1 d
+wq
+EOF
+
+$hxtool ca --issue-ca --self-signed \
+ --ku=digitalSignature --ku=keyCertSign --ku=cRLSign \
+ --generate-key=rsa --key-bits=1024 \
+ --subject="OU=Servers,CN=KDC,${DCs}" \
+ --certificate=PEM-FILE:"${objdir}/server-issuer.pem" ||
+ { echo "failed to setup CA certificate"; exit 2; }
+
+$hxtool ca --issue-ca --self-signed \
+ --ku=digitalSignature --ku=keyCertSign --ku=cRLSign \
+ --generate-key=rsa --key-bits=1024 \
+ --subject="OU=Users,CN=KDC,${DCs}" \
+ --certificate=PEM-FILE:"${objdir}/mixed-issuer.pem" ||
+ { echo "failed to setup CA certificate"; exit 2; }
+
+$hxtool ca --issue-ca --type=https-negotiate-server \
+ --ca-certificate=PEM-FILE:"${objdir}/server-issuer.pem" \
+ --ku=digitalSignature --pk-init-principal=HTTP/${server}@${R}\
+ --generate-key=rsa --key-bits=1024 --subject="" \
+ --certificate=PEM-FILE:"${objdir}/bx509.pem" ||
+ { echo "failed to setup CA certificate"; exit 2; }
+
+# XXX Before starting bx509d let us use kdc test programs to check that:
+#
+# - the negotiate token validator plugin works
+# - the simple CSR authorizer plugin works
+# - the KDC CA tester program works
+
+echo "Check gss-token and Negotiate token validator plugin"
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server | tr A B)
+$test_token_validator -a datan.test.h5l.se Negotiate "$token" &&
+ { echo "Negotiate token validator accepted invalid token"; exit 2; }
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+$test_token_validator -a datan.test.h5l.se Negotiate "$token" ||
+ { echo "Negotiate token validator failed to validate valid token"; exit 2; }
+
+echo "Making a plain CSR"
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" "${objdir}/req" ||
+ { echo "Failed to make a CSR"; exit 2; }
+
+rm -f trivial.pem server.pem email.pem
+
+echo "Testing plain user cert issuance KDC CA"
+$test_kdc_ca -a bx509 -A foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/trivial.pem ||
+ { echo "Trivial offline CA test failed"; exit 2; }
+$hxtool print --content PEM-FILE:${objdir}/trivial.pem ||
+ { echo "Trivial offline CA test failed"; exit 2; }
+$hxtool acert --end-entity \
+ --expr="%{certificate.subject} == \"CN=foo,$DCs\"" \
+ -P "foo@${R}" "FILE:${objdir}/trivial.pem" ||
+ { echo "Trivial offline CA test failed"; exit 2; }
+$hxtool acert --expr="%{certificate.subject} == \"OU=Users,CN=KDC,$DCs\"" \
+ --lacks-private-key "FILE:${objdir}/trivial.pem" ||
+ { echo "Trivial offline CA test failed (issuer private keys included!!)"; exit 2; }
+
+echo "Testing other cert issuance KDC CA"
+csr_revoke
+# https server cert
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" \
+ --eku=id_pkix_kp_serverAuth \
+ --dnsname=foo.test.h5l.se "${objdir}/req" ||
+ { echo "Failed to make a CSR with a dNSName SAN request"; exit 2; }
+$test_kdc_ca -a bx509 foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/server.pem &&
+ { echo "Trivial offline CA test failed: unauthorized issuance (dNSName)"; exit 2; }
+csr_grant dnsname foo.test.h5l.se foo@${R}
+csr_grant eku 1.3.6.1.5.5.7.3.1 foo@${R}
+$test_kdc_ca -a bx509 foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/server.pem ||
+ { echo "Offline CA test failed for explicitly authorized dNSName"; exit 2; }
+$hxtool print --content PEM-FILE:${objdir}/server.pem ||
+ { echo "Offline CA test failed for explicitly authorized dNSName"; exit 2; }
+$hxtool acert --expr="%{certificate.subject} == \"OU=Servers,CN=KDC,$DCs\"" \
+ --lacks-private-key "FILE:${objdir}/server.pem" ||
+ { echo "Trivial offline CA test failed (issuer private keys included!!)"; exit 2; }
+# email cert
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" \
+ --eku=id_pkix_kp_clientAuth \
+ --email=foo@test.h5l.se "${objdir}/req" ||
+ { echo "Failed to make a CSR with an rfc822Name SAN request"; exit 2; }
+$test_kdc_ca -a bx509 foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/email.pem &&
+ { echo "Offline CA test failed: unauthorized issuance (dNSName)"; exit 2; }
+csr_grant email foo@test.h5l.se foo@${R}
+csr_grant eku 1.3.6.1.5.5.7.3.2 foo@${R}
+$test_kdc_ca -a bx509 foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/email.pem ||
+ { echo "Offline CA test failed for explicitly authorized dNSName"; exit 2; }
+$hxtool print --content PEM-FILE:${objdir}/email.pem ||
+ { echo "Offline CA test failed for explicitly authorized dNSName"; exit 2; }
+$hxtool acert --expr="%{certificate.subject} == \"OU=Users,CN=KDC,$DCs\"" \
+ --lacks-private-key "FILE:${objdir}/email.pem" ||
+ { echo "Offline CA test failed (issuer private keys included!!)"; exit 2; }
+
+if ! which curl; then
+ echo "curl is not available -- not testing bx509d"
+ exit 77
+fi
+
+if ! test -x ${objdir}/../../kdc/bx509d; then
+ echo "Configured w/o libmicrohttpd -- not testing bx509d"
+ exit 77
+fi
+
+echo "Creating database"
+${kadmin} init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+${kadmin} add -r --use-defaults foo@${R} || exit 1
+${kadmin} add -r --use-defaults bar@${R} || exit 1
+${kadmin} modify --pkinit-acl="CN=foo,DC=test,DC=h5l,DC=se" foo@${R} || exit 1
+
+
+echo "Starting bx509d"
+${bx509d} -H $server --cert=${objdir}/bx509.pem -t --daemon ||
+ { echo "bx509 failed to start"; exit 2; }
+bx509pid=`getpid bx509d`
+
+trap "kill -9 ${bx509pid}; echo signal killing bx509d; exit 1;" EXIT
+ec=0
+
+rm -f trivial.pem server.pem email.pem
+
+echo "Making a plain CSR"
+csr_revoke
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" "${objdir}/req" ||
+ { echo "Failed to make a CSR"; exit 2; }
+csr=$($rkbase64 -- ${objdir}/req | $rkvis -h --stdin)
+
+# XXX Add autoconf check for curl?
+# Create a barebones bx509 HTTP/1.1 client test program?
+
+echo "Fetching a trivial user certificate"
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx; get_cert '' -sf -o "${objdir}/trivial.pem"); then
+ $hxtool print --content "FILE:${objdir}/trivial.pem"
+ if $hxtool acert --end-entity \
+ --expr="%{certificate.subject} == \"CN=foo,$DCs\"" \
+ -P "foo@${R}" "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ else
+ echo 'FAIL: Obtained a trivial client certificate w/o expected PKINIT SAN)'
+ exit 1
+ fi
+ if $hxtool acert --expr="%{certificate.subject} == \"OU=Users,$DCs\"" \
+ --has-private-key "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ fi
+else
+ echo 'Failed to get a certificate!'
+ exit 1
+fi
+
+echo "Checking that authorization is enforced"
+csr_revoke
+get_cert '&rfc822Name=foo@bar.example' -vvv -o "${objdir}/bad1.pem"
+if (set -vx; get_cert '&rfc822Name=foo@bar.example' -sf -o "${objdir}/trivial.pem"); then
+ $hxtool print --content "FILE:${objdir}/bad1.pem"
+ echo 'Obtained a client certificate for a non-granted name!'
+ exit 1
+else
+ echo 'Correctly failed to get a client certificate for a non-granted name'
+fi
+
+if (set -vx; get_cert "&dNSName=$server" -sf -o "${objdir}/bad2.pem"); then
+ $hxtool print --content "FILE:${objdir}/bad2.pem"
+ echo 'Obtained a server certificate for a non-granted name!'
+ exit 1
+else
+ echo 'Correctly failed to get a server certificate for a non-granted name'
+fi
+
+echo "Fetching a server certificate with one dNSName SAN"
+csr_grant dnsname $server foo@${R}
+if (set -vx; get_cert "&dNSName=$server" -sf -o "${objdir}/server.pem"); then
+ $hxtool print --content "FILE:${objdir}/server.pem"
+ if (set -vx; $hxtool acert --expr="%{certificate.subject} == \"\"" \
+ --end-entity -P foo@${R} \
+ "FILE:${objdir}/server.pem"); then
+ echo 'Got a broken server certificate (has PKINIT SAN)'
+ exit 1
+ elif $hxtool acert --end-entity -D $server "FILE:${objdir}/server.pem"; then
+ echo 'Successfully obtained a server certificate!'
+ else
+ echo 'Got a broken server certificate'
+ exit 1
+ fi
+else
+ echo 'Failed to get a server certificate!'
+ exit 1
+fi
+
+echo "Fetching a server certificate with two dNSName SANs"
+csr_grant dnsname "second-$server" foo@${R}
+if (set -vx;
+ get_cert "&dNSName=${server}&dNSName=second-$server" -sf \
+ -o "${objdir}/server2.pem"); then
+ $hxtool print --content "FILE:${objdir}/server2.pem"
+ if $hxtool acert --expr="%{certificate.subject} == \"\"" \
+ --end-entity -P foo@${R} \
+ "FILE:${objdir}/server2.pem"; then
+ echo 'Got a broken server certificate (has PKINIT SAN)'
+ exit 1
+ elif $hxtool acert --end-entity -D "$server" \
+ -D "second-$server" \
+ "FILE:${objdir}/server2.pem"; then
+ echo 'Successfully obtained a server certificate with two dNSName SANs!'
+ else
+ echo 'Got a broken server certificate (wanted two dNSName SANs)'
+ exit 1
+ fi
+else
+ echo 'Failed to get a server certificate with two dNSName SANs!'
+ exit 1
+fi
+
+echo "Fetching an email certificate"
+csr_grant email foo@bar.example foo@${R}
+if (set -vx; get_cert "&rfc822Name=foo@bar.example" -sf -o "${objdir}/email.pem"); then
+ $hxtool print --content "FILE:${objdir}/email.pem"
+ if $hxtool acert --end-entity -P "foo@${R}" "FILE:${objdir}/email.pem"; then
+ echo 'Got a broken email certificate (has PKINIT SAN)'
+ exit 1
+ elif $hxtool acert --expr="%{certificate.subject} == \"\"" \
+ --end-entity -M foo@bar.example \
+ "FILE:${objdir}/email.pem"; then
+ echo 'Successfully obtained a email certificate!'
+ else
+ echo 'Got a broken email certificate'
+ exit 1
+ fi
+else
+ echo 'Failed to get an email certificate!'
+ exit 1
+fi
+
+# Need to start a KDC to test this.
+rm -f $kt $ukt
+${kdestroy}
+${kadmin} add -r --use-defaults HTTP/${server}@${R} || exit 1
+${kadmin} ext_keytab -r -k $keytab HTTP/${server}@${R} || exit 1
+${kadmin} add -r --use-defaults HTTP/${otherserver}@${R} || exit 1
+${kadmin} ext_keytab -r -k $ukeytab foo@${R} || exit 1
+
+echo "Starting kdc";
+${kdc} --detach --testing || { echo "kdc failed to start"; exit 1; }
+kdcpid=`getpid kdc`
+trap "kill -9 ${kdcpid} ${bx509pid}; echo signal killing kdc and bx509d; exit 1;" EXIT
+
+${kinit} -kt $ukeytab foo@${R} || exit 1
+$klist || { echo "failed to setup kimpersonate credentials"; exit 2; }
+
+echo "Fetch TGT (not granted for other)"
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx;
+ curl -o "${cachefile2}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8"); then
+ echo "Got a TGT with /get-tgt end-point when not granted!"
+ exit 2
+fi
+
+echo "Fetch TGT"
+(set -vx; csr_grant pkinit foo@${R} foo@${R})
+(set -vx; csr_grant eku 1.3.6.1.5.2.3.4 foo@${R})
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile2}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?address=8.8.8.8"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+
+${klist2} | grep Addresses:.IPv4:8.8.8.8 ||
+ { echo "Failed to get a TGT with /get-tgt end-point with addresses"; exit 2; }
+
+echo "Fetch TGT (inception)"
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?address=8.8.8.8"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Trivial offline CA test failed (TGS)"; exit 2; }
+${klist} | grep Addresses:.IPv4:8.8.8.8 ||
+ { echo "Failed to get a TGT with /get-tgt end-point with addresses"; exit 2; }
+
+echo "Fetch TGT (for other)"
+(set -vx; csr_grant pkinit bar@${R} foo@${R})
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Trivial offline CA test failed (TGS)"; exit 2; }
+${klist} | grep Addresses:.IPv4:8.8.8.8 ||
+ { echo "Failed to get a TGT with /get-tgt end-point with addresses"; exit 2; }
+
+echo "Fetch TGT (for other, w/ lifetime req under max)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+(set -vx; csr_grant pkinit bar@${R} foo@${R})
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8&lifetime=3d"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Trivial offline CA test failed (TGS)"; exit 2; }
+if which jq >/dev/null; then
+ if ! ${klistjson} | jq -e '
+ (reduce (.tickets[0]|(.Issued,.Expires)|
+ strptime("%b %e %H:%M:%S %Y")|mktime) as $t
+ (0; if .==0 then $t else $t - . end) / 86400) | floor |
+ . == 3'; then
+ echo "Incorrect lifetime"
+ exit 2
+ fi
+fi
+
+echo "Fetch TGT (for other, w/ lifetime req over max)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+(set -vx; csr_grant pkinit bar@${R} foo@${R})
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8&lifetime=10d"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Trivial offline CA test failed (TGS)"; exit 2; }
+if which jq >/dev/null; then
+ if ! ${klistjson} | jq -e '
+ (reduce (.tickets[0]|(.Issued,.Expires)|
+ strptime("%b %e %H:%M:%S %Y")|mktime) as $t
+ (0; if .==0 then $t else $t - . end) / 86400) | floor |
+ . == 5'; then
+ echo "Incorrect lifetime"
+ exit 2
+ fi
+fi
+
+echo "Fetch TGT (for other, w/ lifetime req under max)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+(set -vx; csr_grant pkinit bar@${R} foo@${R})
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8&address=8.9.10.11&address=11.11.11.11&address=12.12.12.12&lifetime=5d"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Trivial offline CA test failed (TGS)"; exit 2; }
+if which jq >/dev/null; then
+ if ! ${klistjson} | jq -e '
+ (reduce (.tickets[0]|(.Issued,.Expires)|
+ strptime("%b %e %H:%M:%S %Y")|mktime) as $t
+ (0; if .==0 then $t else $t - . end) / 86400) |
+ . >= 4'; then
+ echo "Failed to get a TGT with /get-tgt end-point with addresses"
+ exit 2
+ fi
+fi
+
+echo "Fetch negotiate token (pre-test)"
+# Do what /bnegotiate does, roughly, prior to testing /bnegotiate
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=PEM-FILE:"${objdir}/k.pem" "${objdir}/req" ||
+ { echo "Failed to make a CSR"; exit 2; }
+$test_kdc_ca -a bx509 -A foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/pkinit-test.pem ||
+ { echo "Trivial offline CA test failed (CA)"; exit 2; }
+cat ${objdir}/k.pem >> ${objdir}/pkinit-test.pem
+${kinit} -C PEM-FILE:${objdir}/pkinit-test.pem foo@${R} ||
+ { echo "Trivial offline CA test failed (PKINIT)"; exit 2; }
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Trivial offline CA test failed (TGS)"; exit 2; }
+KRB5CCNAME=$cache $gsstoken HTTP@$server | KRB5_KTNAME="$keytab" $gsstoken -r ||
+ { echo "Trivial offline CA test failed (gss-token)"; exit 2; }
+
+# Check that we get up to three tixaddrs k/v in the log
+grep 'REQ.*numtixaddrs=4 tixaddrs=IPv4:8.8.8.8 tixaddrs=IPv4:8.9.10.11 tixaddrs=IPv4:11.11.11.11.*wrongaddr=yes' ${objdir}/messages.log ||
+ { echo "KDC not warning about requests from wrong address"; exit 2; }
+
+echo "Fetching a Negotiate token"
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx;
+ curl -o negotiate-token -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/bnegotiate?target=HTTP%40${server}"); then
+ # bx509 sends us a token w/o a newline for now; we add one because
+ # gss-token expects it.
+ test -s negotiate-token && echo >> negotiate-token
+ if test -s negotiate-token && KRB5_KTNAME="$keytab" $gsstoken -Nr < negotiate-token; then
+ echo 'Successfully obtained a Negotiate token!'
+ else
+ echo 'Failed to get a Negotiate token (got an unacceptable token)!'
+ exit 1
+ fi
+else
+ echo 'Failed to get a Negotiate token!'
+ exit 1
+fi
+
+referer=https://${otherserver}/blah
+redirect=$(${rkvis} -h https://${otherserver}/blah?q=whatever)
+if (set -vx;
+ curl -o negotiate-token -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/bnegotiate?target=HTTP%40${server}&redirect=${redirect}"); then
+ echo "Error: /bnegotiate with target and redirect succeeded"
+ exit 1
+fi
+
+if (set -vx;
+ curl -o negotiate-token -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/bnegotiate?redirect=${redirect}"); then
+ echo "Error: /bnegotiate with redirect but no Referer succeeded"
+ exit 1
+fi
+
+referer=http://${otherserver}/blah
+redirect=$(${rkvis} -h http://${otherserver}/blah?q=whatever)
+if (set -vx;
+ curl -gsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -H "Referer: $referer" \
+ "http://${server}:${bx509port}/bnegotiate?redirect=${redirect}"); then
+ echo "Error: redirect for non-https referer"
+ exit 1
+fi
+
+referer=https://${otherserver}/blah
+redirect=$(${rkvis} -h https://${otherserver}/blah?q=whatever)
+if (set -vx;
+ curl -gfs -D curlheaders \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -H "Referer: $referer" \
+ "http://${server}:${bx509port}/bnegotiate?redirect=${redirect}"); then
+ read junk code junk < curlheaders
+ if test "$code" = 307; then
+ echo "Got a proper redirect"
+ else
+ echo "Error: unexpected status code $code (wanted 307)"
+ fi
+else
+ echo "Error: no redirect"
+ exit 1
+fi
+
+echo "killing kdc (${kdcpid}) and bx509d (${bx509pid})"
+sh ${leaks_kill} kdc $kdcpid || ec=1
+sh ${leaks_kill} bx509d $bx509pid || ec=1
+
+trap "" EXIT
+
+exit $ec