#!/bin/sh
# Script to test svnserve cross-realm support breakage with GSSAPI.
#
# Prerequisites:
#
#	cyrus sasl (with GSSAPI support and then patch described below)
#	subversion (with SASL support)
#	heimdal
#	Ownership of the sasl2 config dir (or at least the svn.conf) file 
#		inside that directory.
# 		You need to chown <yourself> $SASLCONFDIR/svn.conf
#	Set SASLCONFDIR below.
#	
#
# The jist of this script is to create two realms (which incidentally
# are served by the same KDC).  Create a test subversion repository and
# run svnserve on it.  Attempt to log in as a user in the same realm as
# the server and then again as a user in a remote realm using cross-realm.
# Observe that the second attempt fails due to the sanity checking in 
# subversion/svnserve/cyrus_auth.c even though the user has a valid 
# cross-realm ticket as shown by klist -v.

# IMPORTANT: Cyrus SASL has it's own cross-realm crosses to bear.  I've
# been unable to make this script work without a patch I'm fond of in 
# Cyrus SASL's plugins/gssapi.c:
# 
# daffy% diff -u plugins/gssapi.c.orig plugins/gssapi.c
# --- plugins/gssapi.c.orig	2010-03-23 15:44:41.000000000 -0500
# +++ plugins/gssapi.c.new	2010-03-23 15:44:34.000000000 -0500
# @@ -719,7 +719,7 @@
#  	    
#  	    GSS_LOCK_MUTEX(params->utils);
#  	    maj_stat = gss_acquire_cred(&min_stat, 
# -					GSS_C_NO_NAME,
# +					text->server_name,
#  					GSS_C_INDEFINITE, 
#  					GSS_C_NO_OID_SET,
#  					GSS_C_ACCEPT,
# daffy% 
#
# This patch has been discussed on the heimdal-discuss list and while 
# not particularly elegant or complete, it's very useful.
#

set -e

password=_supersecret
SASLCONFDIR=/etc/sasl2

# To use non-system builds of Subversion or SASL consider
# uncommenting the variables below.  
# I find that sasl always looks in $SASLLIBDIR/sasl2 for 
# its plugins.  I usually boldly symlink into my working
# SASL2 install dir.

#SVNBIN=~/subversion/bin/
#export LD_LIBRARY_PATH=~/subversion/lib:~/sasl/lib


shutdown()
{
	[ "$kdc" ] && kill -0 "$kdc" && kill "$kdc"
	[ "$svnserve" ] && kill -0 "$svnserve" && kill "$svnserve"
}
trap shutdown EXIT

realms="REALM1 REALM2"
hostname=localhost
# for GSSAPI canonicalization issues, 
# hostname=`hostname`

rm -f heimdal.db svn.keytab messages.log
export KRB5_CONFIG=$PWD/krb5.conf

# create test config file
cat - > "$KRB5_CONFIG" << EOF
[libdefaults]
	rdns = no
	dns_lookup_kdc = false
	dns_lookup_realm = false
	default_realm = REALM1
[realms]
	REALM1 = {
		kdc = udp/127.0.0.1:8801
	}
	REALM2 = {
		kdc = udp/127.0.0.1:8801
	}
[kdc]
	database = {
		dbname = $PWD/heimdal
		#mkey_file = /dev/null
		#acl_file = /dev/null
	}
[logging]
	default = messages.log
	kdc = messages.log
	#default = STDERR
	#kdc = STDERR
EOF

# initialize realms in heimdal database
for realm in $realms ; do
	kadmin -l init --realm-max-ticket-life=10h --realm-max-renewable-life=7d $realm
done

# create cross-realm keys
kadmin -l add --random-password --use-defaults krbtgt/REALM2@REALM1
kadmin -l add --random-password --use-defaults krbtgt/REALM1@REALM2

# create a user in each realm
kadmin -l add --password=r1$password --use-defaults realm1user@REALM1
kadmin -l add --password=r2$password --use-defaults realm2user@REALM2

# create svn principal
kadmin -l add --password=svn$password --use-defaults svn/$hostname@REALM1
ktutil -k svn.keytab add \
	--principal=svn/$hostname@REALM1 \
	--kvno=1 \
	--enctype=aes256-cts-hmac-sha1-96 \
	--password=svn$password

# create svn instance
rm -rf svn
${SVNBIN}svnadmin create svn
cat - > svn/conf/svnserve.conf << EOF
[general]
realm = REALM1
[sasl]
use-sasl = true
EOF

# configure sasl
cat -- > $SASLCONFDIR/svn.conf << EOF
mech_list: GSSAPI
keytab: $PWD/svn.keytab
EOF

#start the kdc
kdc --addresses=127.0.0.1 --ports=8801 &
kdc="$!"

export cc1=realm1user.keytab
export cc2=realm2user.keytab

#start svnserve
env KRB5CCNAME= ${SVNBIN}svnserve -X --root $PWD/svn &
svnserve=$!
# try accessing subversion as a local realm user
export KRB5CCNAME=FILE:$PWD/$cc1
echo r1$password | kinit --password-file=STDIN realm1user@REALM1
${SVNBIN}svn info svn://$hostname/ || klist -v

#start svnserve
env KRB5CCNAME= ${SVNBIN}svnserve -X --root $PWD/svn &
svnserve=$!
# try accessing subversion as a cross realm user
export KRB5CCNAME=FILE:$PWD/$cc2
echo r2$password | kinit --password-file=STDIN realm2user@REALM2
${SVNBIN}svn info svn://$hostname/ || klist -v

