# Kerberos rsh test.
# This is a DejaGnu test script.
# This script tests Kerberos rsh.
# Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.

# Find the programs we need.  We use the binaries from the build tree
# if they exist.  If they do not, then they must be in PATH.  We
# expect $objdir to be .../kerberos/src.

if ![info exists RSH] {
    set RSH [findfile $objdir/../../appl/bsd/rsh]
}

if ![info exists KRSHD] {
    set KRSHD [findfile $objdir/../../appl/bsd/kshd]
}

if ![info exists KLIST] {
    set KLIST [findfile $objdir/../../clients/klist/klist]
}

# Make sure .k5login is reasonable.
if ![check_k5login rsh] {
    return
}

# Set up the kerberos database.
if {![get_hostname] \
    || ![setup_kerberos_files] \
    || ![setup_kerberos_db 0]} {
    return
}

# A procedure to start up the rsh daemon.

proc start_rsh_daemon { option } {
    global REALMNAME
    global KRSHD
    global tmppwd
    global krshd_spawn_id
    global krshd_pid

    # The -D argument tells it to accept a single connection, so we
    # don't need to use inetd.  The 3544 is the port to listen at.
    spawn $KRSHD -k -c -D 3544 -S $tmppwd/srvtab -M $REALMNAME -A $option
    set krshd_spawn_id $spawn_id
    set krshd_pid [exp_pid]

    # Give the rsh daemon a few seconds to get set up.
    catch "exec sleep 2"
}

# A procedure to stop the rsh daemon.

proc stop_rsh_daemon { } {
    global krshd_spawn_id
    global krshd_pid

    if [info exists krshd_pid] {
	catch "exec kill $krshd_pid"
	catch "expect -i $krshd_spawn_id eof"
	catch "close -i $krshd_spawn_id"
	catch "wait -i $krshd_spawn_id"
	unset krshd_pid
    }
}

# Wrap the tests in a procedure, so that we can kill the daemons if
# we get some sort of error.

proc rsh_test { } {
    global REALMNAME
    global KLIST
    global RSH
    global KEY
    global BINSH
    global hostname
    global env
    global spawn_id
    global tmppwd

    # Start up the kerberos and kadmind daemons and get a srvtab and a
    # ticket file.
    if {![start_kerberos_daemons 0] \
        || ![add_kerberos_key host/$hostname 0] \
        || ![setup_srvtab 0] \
	|| ![add_kerberos_key $env(USER) 0] \
	|| ![setup_kerberos_env client] \
	|| ![kinit $env(USER) $env(USER)$KEY 0]} {
	return
    }

    # Start up the rsh daemon.
    start_rsh_daemon -k

    # Run rsh date.
    set testname "date"
    spawn $RSH $hostname -k $REALMNAME -D 3544 -A date
    expect {
	-re "\[A-Za-z0-9\]+ \[A-Za-z0-9\]+ +\[0-9\]+ \[0-9\]+:\[0-9\]+:\[0-9\]+ \[A-Za-z0-9\]+ \[0-9\]+\r\n" {
	    set result $expect_out(0,string)
	}
	timeout {
	    fail "$testname (timeout)"
	    return
	}
	eof {
	    fail "$testname (eof)"
	    return
	}
    }
    expect eof
    if ![check_exit_status $testname] {
	return
    }

    if [check_date $result] {
	pass $testname
    } else {
	fail $testname
    }

    # The rsh daemon should have stopped, but we have no easy way
    # of checking whether it actually did.  Kill it just in case.
    stop_rsh_daemon

    # Check encrypted rsh.
    set failed no
    start_rsh_daemon -ek
    set testname "encrypted rsh"
    spawn $RSH $hostname -x -k $REALMNAME -D 3544 -A echo hello
    expect {
	"hello" { expect eof }
	timeout {
	    fail "$testname (timeout)"
	    set failed yes
	}
	eof {
	    fail "$testname (eof)"
	    set failed yes
	}
    }

    catch "expect eof"
    if { $failed == "no" } {
	if ![check_exit_status $testname] {
	    return
	}
	pass $testname
	stop_rsh_daemon
    } else {
	catch "wait -i $spawn_id"
	catch "close -i $spawn_id"
	stop_rsh_daemon
    }

    # Check ticket forwarding
    set failed no
    start_rsh_daemon -k
    set testname "rsh forwarding tickets"

    # We need a wrapper for klist in order to setup for shared library 
    # runtime environment
    setup_wrapper $tmppwd/klist.wrap $KLIST

    spawn $RSH $hostname -f -k $REALMNAME -D 3544 -A $BINSH -c $tmppwd/klist.wrap 
    expect {
	"Ticket cache:*\r" {
	    expect eof
	}
 	"klist: No credentials cache file found" {
	    fail "$testname (not forwarded)"
	    return
	}
	timeout {
	    fail "$testname (timeout)"
	    return
	}
	eof {
	    fail "$testname (eof)"
	    return
	}
    }

    if ![check_exit_status $testname] {
	return
    }

    pass $testname

    stop_rsh_daemon

    # Check encrypted ticket forwarding
    set failed no
    start_rsh_daemon -e
    set testname "encrypted rsh forwarding tickets"
    spawn $RSH $hostname -x -f -k $REALMNAME -D 3544 -A $BINSH -c $tmppwd/klist.wrap 
    expect {
	"Ticket cache:*\r" {
	    expect eof
	}
 	"klist: No credentials cache file found" {
	    fail "$testname (not forwarded)"
	    return
	}
	timeout {
	    fail "$testname (timeout)"
	    return
	}
	eof {
	    fail "$testname (eof)"
	    return
	}
    }

    if ![check_exit_status $testname] {
	return
    }

    pass $testname

    stop_rsh_daemon

    # Check stderr
    start_rsh_daemon -k
    set testname "rsh to stderr"
    spawn $RSH $hostname -k $REALMNAME -D 3544 -A $BINSH -c "'echo hello 1>&2'"
    expect {
	"hello" { expect eof }
	timeout {
	    fail "$testname (timeout)"
	    return
	}
	eof {
	    fail "$testname (eof)"
	    return
	}
    }

    if ![check_exit_status $testname] {
	return
    }

    pass $testname

    stop_rsh_daemon

    start_rsh_daemon -e
    set testname "encrypted rsh to stderr"
    spawn $RSH $hostname -x -k $REALMNAME -D 3544 -A $BINSH -c "'echo hello 1>&2'"
    expect {
	"hello" { expect eof }
	timeout {
	    fail "$testname (timeout)"
	    return
	}
	eof {
	    fail "$testname (eof)"
	    return
	}
    }

    if ![check_exit_status $testname] {
	return
    }

    pass $testname

    # The rsh daemon should have stopped, but we have no easy way
    # of checking whether it actually did.  Kill it just in case.
    stop_rsh_daemon
}

# Run the test.
set status [catch rsh_test msg]

# Shut down the kerberos daemons and the rsh daemon.
stop_kerberos_daemons

stop_rsh_daemon

if { $status != 0 } {
    send_error "ERROR: error in rsh.exp\n"
    send_error "$msg\n"
    exit 1
}
