diff options
Diffstat (limited to 'src/tests/dejagnu')
-rw-r--r-- | src/tests/dejagnu/ChangeLog | 6 | ||||
-rw-r--r-- | src/tests/dejagnu/Makefile.in | 3 | ||||
-rw-r--r-- | src/tests/dejagnu/config/ChangeLog | 216 | ||||
-rw-r--r-- | src/tests/dejagnu/config/default.exp | 2028 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-root/ChangeLog | 6 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-root/rlogin.exp | 10 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/ChangeLog | 204 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/gssapi.exp | 478 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/gssftp.exp | 105 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/kadmin.exp | 323 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/rcp.exp | 13 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/rsh.exp | 26 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/standalone.exp | 132 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/v4gssftp.exp | 501 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/v4krb524d.exp | 167 | ||||
-rw-r--r-- | src/tests/dejagnu/krb-standalone/v4standalone.exp | 95 |
16 files changed, 3361 insertions, 952 deletions
diff --git a/src/tests/dejagnu/ChangeLog b/src/tests/dejagnu/ChangeLog index ee65f85..a9062b2 100644 --- a/src/tests/dejagnu/ChangeLog +++ b/src/tests/dejagnu/ChangeLog @@ -1,3 +1,9 @@ +2000-08-08 Ezra Peisach <epeisach@mit.edu> + + * Makefile.in (KRB4_RUNTESTFLAGS): Set from configure.in and pass + to runtest if krb4 compatibility is enabled. + [pullup from trunk] + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/tests/dejagnu/Makefile.in b/src/tests/dejagnu/Makefile.in index a93bae0..668e118 100644 --- a/src/tests/dejagnu/Makefile.in +++ b/src/tests/dejagnu/Makefile.in @@ -7,6 +7,7 @@ RUNTESTFLAGS = KRB5_RUN_ENV= @KRB5_RUN_ENV@ PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) +KRB4_RUNTESTFLAGS=@KRB4_DEJAGNU_TEST@ SRCS=$(srcdir)/t_inetd.c @@ -21,7 +22,7 @@ check-:: @echo "+++" check-runtest:: t_inetd site.exp - $(HAVE_RUNTEST) --tool krb --srcdir $(srcdir) $(RUNTESTFLAGS) + $(HAVE_RUNTEST) --tool krb --srcdir $(srcdir) $(KRB4_RUNTESTFLAGS) $(RUNTESTFLAGS) t_inetd:: t_inetd.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_inetd t_inetd.o $(KRB5_BASE_LIBS) diff --git a/src/tests/dejagnu/config/ChangeLog b/src/tests/dejagnu/config/ChangeLog index 54d0e4b..b499111 100644 --- a/src/tests/dejagnu/config/ChangeLog +++ b/src/tests/dejagnu/config/ChangeLog @@ -1,3 +1,219 @@ +2003-03-26 Tom Yu <tlyu@mit.edu> + + * default.exp (v4kinit): Expect failure when kiniting to a des3 + TGT, due to fix for MITKRB5-SA-2003-004. + +2002-11-08 Tom Yu <tlyu@mit.edu> + + * default.exp: Add (disabled) debugging code for catching leaking + ptys. expect eof from the correct spawn_ids when killing kdc and + kadmind to avoid leaking ptys. + (do_klist, v4klist, v4klist_none): Check for eof to avoid leaking + ptys. + [pullup from trunk] + +2002-11-03 Tom Yu <tlyu@mit.edu> + + * default.exp (stop_kerberos_daemons): Kill, expect eof, wait, in + that order. Avoids delivery of multiple signals (HUP+TERM) to KDC + daemons when shutting down. + + * default.exp (start_kerberos_daemons): Fix to use "tail -f" to + check for setup messages from daemons; this avoids a few race + conditions. + + [pullups from trunk] + +2002-11-03 Ken Raeburn <raeburn@mit.edu> + + * default.exp (start_kerberos_daemons): When standalone, delete + KDC replay cache before starting it up. + [pullup from trunk] + +2002-02-07 Ken Raeburn <raeburn@mit.edu> + + * default.exp (modify_principal): Call check_exit_status. + +2002-02-05 Ken Raeburn <raeburn@mit.edu> + + * default.exp (modify_principal, kinit_kt, v4kinit_kt, do_klist, + do_klist_kt, do_klist_err, do_kdestroy, xst, v4klist, v4kdestroy, + v4klist_none): New procs. + (add_random_key): No need to call expect_after in 'body' since + both branches at invocation site will do it. + (setup_root_shell, setup_root_shell_remote): Set correct value for + KRB5_CONFIG. + (passes): Add des-crc and des-md5 krb4 passes. + (top level): Set KLIST and KDESTROY. + (spawn_xterm): New proc useful for debugging only. + +2001-10-31 Tom Yu <tlyu@mit.edu> + + * default.exp (check_k5login, check_klogin): Error out if there is + a nonexistent .k5login or .klogin for root. + (setup_{kadmind_,}srvtab, add_{random,kerberos}_key): Notice + unmatched output to avoid timing out on certain errors. Look for + command echoes. Clear the expect_after list in places to avoid + problems with lingering expect_after clauses against invalid + spawn_ids. expect eof in places to avoid pty deadlock. + +2001-10-27 Tom Yu <tlyu@mit.edu> + + * default.exp: Mark as unused the test passes that won't + accomplish anything due to disabling of SUPPORT_DESMD5 in the + code. + [pullup from trunk] + +2001-10-24 Tom Yu <tlyu@mit.edu> + + * default.exp: Add support for setting SUPPORT_DESMD5 flag on the + TGT principal. Add test pass des.md5-tgt for exercising enctype + similarity inconsistency. Add test pass des.no-kdc-md5 for + exercising failure to constrain session key issuance to + permitted_enctypes. Pepper the code with null calls to + expect_after to prevent misfiring of expect_after clauses. + (setup_srvtab): Look for some possible error cases to avoid timing + out. + (setup_root_shell): Restore timeout so we don't wait 5 minutes in + other places. + [pullup from trunk] + +2001-08-06 <epeisach@mit.edu> + + * default.exp (setup_root_shell): Also recognize "nection reset by + peer" as a failure to get a root shell. This happens if + tcp_wrappers are in use in inetd.conf, but rlogind is not prsent + on the machine. + [pullup from trunk] + +2001-06-22 Tom Yu <tlyu@mit.edu> + + * default.exp: Use the interface variable $TMPDIR to allow the + specification of an alternative temporary directory. Wrap a loop + around various testings and settings of interface variables that + specify the locations of programs to be tested, e.g. $KADMIND. + Add some support for having different sets of enctypes on client, + server, and kdc. The envstack changes and multiple config file + support should get cleaned up somewhat later to possibly allow for + programs to execute on different hosts. + (check_k5login): Fix up to reflect actual (perhaps bogus) behavior + of krb5_kuserok(), which doesn't do quite what we expect, so there + really does need to be something like "luser@KRBTEST.COM" in the + .k5login file. + (check_klogin): New procedure; .klogin also needs to be checked + for the v4gssftp test. + (envstack_push, envstack_pop): New procedure; keep a stack of + environment variable state, which is useful for running different + programs with different config files. + (setup_runtime_flags, setup_kerberos_env): Rewrite somewhat so + they play nice with the envstack. + (setup_krb5_conf): New procedure; write a config file with the + contents parameterized based on the type of program that will use + it. + (setup_kerberos_files): Create different krb5.conf files for + client, server, and kdc. + (setup_kadmind_srvtab, setup_kerberos_db, start_kerberos_daemons): + Rewrite to play nice with envstack. + (setup_root_shell_noremote): New procedure from raeburn; handle + the case where we're already running as root. + (setup_root_shell): Call setup_root_shell_noremote as appropriate. + [pullup from trunk] + +2001-06-17 Ezra Peisach <epeisach@mit.edu> + + * default.exp: Add an entry for krb524_server for the localhost + with a non-standard port number. + [pullup from trunk] + +2001-04-25 Ezra Peisach <epeisach@mit.edu> + + * default.exp: For Kerberos 4 tests, use a different ticket file + name from the V5 tests. + [pullup from trunk] + +2000-11-08 Tom Yu <tlyu@mit.edu> + + * default.exp: Use $KRBIV rather than $KRB4 since dejagnu-1.3 + doesn't deal with digits in passed-in variables. + [pullup from trunk] + +Thu Oct 12 12:06:03 2000 Ezra Peisach <epeisach@mit.edu> + + * default.exp: Add dict_file entry (and create one) for kdc.conf + [pullup from trunk] + +Tue Aug 22 09:47:50 2000 Ezra Peisach <epeisach@mit.edu> + + * default.exp: Create a properly formatted krb.conf file. Also + provide a krb4_srvtab stanza (even though we are falling back on + the keytab file) so the tests do not try to access an installed + systems /etc/srvtab file. + [pullup from trunk] + +2000-08-09 Tom Yu <tlyu@mit.edu> + + * default.exp: Add an eof clause to avoid breakage if rlogin exits + too quickly. + [pullup from trunk] + +2000-08-08 Ezra Peisach <epeisach@mit.edu> + + * default.exp: Create krb.conf and krb.realms files for v4 + compatibility. Set KRBTKFILE environment variable. Add + v4_compatible_enctype() proc to test if krb4 tests are being run + and if the current encryption type being tested is compatible with + V4. Added v4kinit() proc. Quoting of lists in mutipass variable + assignments is unnecessary. + [pullup from trunk] + +2000-08-07 Ezra Peisach <epeisach@mit.edu> + + * default.exp: Protect Quote quotation marks in multipass variable + assignments. Dejagnu (June 1999 release) fails overwise. + [pullup from trunk] + +2000-07-22 Tom Yu <tlyu@mit.edu> + + * default.exp: Add code to handle setting of PASS to constrain + multipass testing to particular passes. dejagnu-1.3 doesn't have + support for PASS, so we kludge it here, though some later versions + handle it by themselves. + (krb_exit): Add new proc to clean up on exit. + (kinit): Remove "expect \r" since "expect eof" will drain the pty + buffer properly anyway. + [pullup from trunk] + +2000-07-02 Tom Yu <tlyu@mit.edu> + + * default.exp: Add rudimentary support for multiple passes. For + now, iterate over a few combinations of des_krbtgt and assorted + enctype lists. Will eventually allow for separate krb5.conf files + for clients and servers. Add varibles RLOGIN and RLOGIN_FLAGS to + permit run-time configuration of rlogin program if necessary. Set + up an onexit handler that calls stop_kerberos_daemons. Replace + many uses of doubled-up send_log and verbose with single calls to + verbose -log. Replace instances of send_error with perror where + appropriate, since this will cause successor test to fail, which + is usually what we want. + (setup_root_shell): Replace calls to untested with calls to + unsupported; also use note for explanatory text previously printed + using untested. Add match string for "connection refused" and + collapse common code into a single expect clause by using the -re + flag. + (start_kerberos_daemons): Conditionalize calls to fail based on + $standalone; in the !$standalone case, call perror instead. Calls + to fail and pass for a given test should have consistent strings, + and extraneous calls to fail should not be made in order to keep + the total number of passed and failed tests constant regardless of + success of setup steps. Much remains to be done in this area + though. + [pullup from trunk] + +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * default.exp (setup_kerberos_files): Include des3 in supported + enctypes. + 2000-02-07 Tom Yu <tlyu@mit.edu> * default.exp: Remove default_tgs_enctypes for now as it was diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp index 44ffab7..1443ba6 100644 --- a/src/tests/dejagnu/config/default.exp +++ b/src/tests/dejagnu/config/default.exp @@ -7,7 +7,7 @@ # This file provides several functions which deal with a local # Kerberos database. We have to do this such that we don't interfere # with any existing Kerberos database. We will create all the files -# in the directory tmpdir, which will have been created by the +# in the directory $tmppwd, which will have been created by the # testsuite default script. We will use $REALMNAME as our Kerberos # realm name, defaulting to KRBTEST.COM. @@ -15,12 +15,249 @@ set timeout 100 set stty_init {erase \^h kill \^u} set env(TERM) dumb -set des3_krbtgt 1 +set des3_krbtgt 0 +set tgt_support_desmd5 0 +set supported_enctypes "des-cbc-crc:normal" +set kdc_supported_enctypes "des-cbc-crc:normal" + +# The names of the individual passes must be unique; lots of things +# depend on it. The PASSES variable may not contain comments; only +# small pieces get evaluated, so comments will do strange things. + +# Most of the purpose of using multiple passes is to exercise the +# dependency of various bugs on configuration file settings, +# particularly with regards to encryption types. + +# The des.no-kdc-md5 pass will fail if the KDC does not constrain +# session key enctypes to those in its permitted_enctypes list. It +# works by assuming enctype similarity, thus allowing the client to +# request a des-cbc-md4 session key. Since only des-cbc-crc is in the +# KDC's permitted_enctypes list, the TGT will be unusable. + +# KLUDGE for tracking down leaking ptys +if 0 { + rename spawn oldspawn + rename wait oldwait + proc spawn { args } { + upvar 1 spawn_id spawn_id + verbose "spawn: args=$args" + set pid [eval oldspawn $args] + verbose "spawn: pid=$pid spawn_id=$spawn_id" + return $pid + } + proc wait { args } { + upvar 1 spawn_id spawn_id + verbose "wait: args=$args" + set ret [eval oldwait $args] + verbose "wait: $ret" + return $ret + } +} -# We do everything in a temporary directory. -if ![file isdirectory tmpdir] {catch "exec mkdir tmpdir" status} +# The des.des3-tgt.no-kdc-des3 pass will fail if the KDC doesn't +# constrain ticket key enctypes to those in permitted_enctypes. It +# does this by not putting des3 in the permitted_enctypes, while +# creating a TGT princpal that has a des3 key as well as a des key. + +# XXX -- master_key_type is fragile w.r.t. permitted_enctypes; it is +# possible to configure things such that you have a master_key_type +# that is not permitted, and the error message used to be cryptic. + +set passes { + { + des + des3_krbtgt=0 + {supported_enctypes=des-cbc-crc:normal} + {kdc_supported_enctypes=des-cbc-crc:normal} + {dummy=[verbose -log "DES TGT, DES enctype"]} + } + { + des.des3tgt + des3_krbtgt=1 + {supported_enctypes=des-cbc-crc:normal} + {kdc_supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal} + {dummy=[verbose -log "DES3 TGT, DES enctype"]} + } + { + des3 + des3_krbtgt=1 + {supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal} + {kdc_supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal} + {dummy=[verbose -log "DES3 TGT, DES3 + DES enctypes"]} + } + { + des-v4 + des3_krbtgt=0 + {supported_enctypes=des-cbc-crc:v4} + {kdc_supported_enctypes=des-cbc-crc:v4} + {default_tkt_enctypes(client)=des-cbc-crc} + {dummy=[verbose -log "DES TGT, DES-CRC enctype, V4 salt"]} + } + { + des-md5-v4 + des3_krbtgt=0 + {supported_enctypes=des-cbc-md5:v4 des-cbc-crc:v4} + {kdc_supported_enctypes=des-cbc-md5:v4 des-cbc-crc:v4} + {default_tkt_enctypes(client)=des-cbc-md5 des-cbc-crc} + {dummy=[verbose -log "DES TGT, DES-MD5 and -CRC enctypes, V4 salt"]} + } + { + all-des-des3-enctypes + des3_krbtgt=1 + {supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal \ + des-cbc-md5:normal des-cbc-crc:v4 des-cbc-md5:norealm \ + des-cbc-md4:normal} + {kdc_supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal \ + des-cbc-md5:normal des-cbc-crc:v4 des-cbc-md5:norealm \ + des-cbc-md4:normal} + {dummy=[verbose -log "DES3 TGT, many DES3 + DES enctypes"]} + } + { + des.no-kdc-md5 + des3_krbtgt=0 + tgt_support_desmd5=0 + {permitted_enctypes(kdc)=des-cbc-crc} + {default_tgs_enctypes(client)=des-cbc-md5 des-cbc-md4 des-cbc-crc} + {default_tkt_enctypes(client)=des-cbc-md5 des-cbc-md4 des-cbc-crc} + {supported_enctypes=des-cbc-crc:normal} + {kdc_supported_enctypes=des-cbc-crc:normal} + {master_key_type=des-cbc-crc} + {dummy=[verbose -log \ + "DES TGT, KDC permitting only des-cbc-crc"]} + } + { + des.des3-tgt.no-kdc-des3 + tgt_support_desmd5=0 + {permitted_enctypes(kdc)=des-cbc-crc} + {default_tgs_enctypes(client)=des-cbc-crc} + {default_tkt_enctypes(client)=des-cbc-crc} + {supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal} + {kdc_supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal} + {master_key_type=des-cbc-crc} + {dummy=[verbose -log \ + "DES3 TGT, KDC permitting only des-cbc-crc"]} + } +} -set tmppwd "[pwd]/tmpdir" +# des.md5-tgt is set as unused, since it won't trigger the error case +# if SUPPORT_DESMD5 isn't honored. + +# The des.md5-tgt pass will fail if enctype similarity is inconsisent; +# between 1.0.x and 1.1, the decrypt functions became more strict +# about matching enctypes, while the KDB retrieval functions didn't +# coerce the enctype to match what was requested. It works by setting +# SUPPORT_DESMD5 on the TGT principal, forcing an enctype of +# des-cbc-md5 on the TGT key. Since the database only contains a +# des-cbc-crc key, the decrypt will fail if enctypes are not coerced. + +# des.no-kdc-md5.client-md4-skey is retained in unsed_passes, even +# though des.no-kdc-md5 is roughly equivalent, since the associated +# comment needs additional investigation at some point re the kadmin +# client. + +# The des.no-kdc-md5.client-md4-skey will fail on TGS requests due to +# the KDC issuing session keys that it won't accept. It will also +# fail for a kadmin client, but for different reasons, since the kadm5 +# library does some curious filtering of enctypes, and also uses +# get_in_tkt() rather than get_init_creds(); the former does an +# intersection of the enctypes provided by the caller and those listed +# in the config file! + +set unused_passes { + { + des.md5-tgt + des3_krbtgt=0 + tgt_support_desmd5=1 + supported_enctypes=des-cbc-crc:normal + kdc_supported_enctypes=des-cbc-crc:normal + {permitted_enctypes(kdc)=des-cbc-md5 des-cbc-md4 des-cbc-crc} + {permitted_enctypes(client)=des-cbc-md5 des-cbc-md4 des-cbc-crc} + {dummy=[verbose -log "DES TGT, SUPPORTS_DESMD5"]} + } + { + des.md5-tgt.no-kdc-md5 + des3_krbtgt=0 + tgt_support_desmd5=1 + {permitted_enctypes(kdc)=des-cbc-crc} + {default_tgs_enctypes(client)=des-cbc-crc} + {default_tkt_enctypes(client)=des-cbc-crc} + {supported_enctypes=des-cbc-crc:normal} + {kdc_supported_enctypes=des-cbc-crc:normal} + {master_key_type=des-cbc-crc} + {dummy=[verbose -log \ + "DES TGT, SUPPORTS_DESMD5, KDC permitting only des-cbc-crc"]} + } + { + des.no-kdc-md5.client-md4-skey + des3_krbtgt=0 + {permitted_enctypes(kdc)=des-cbc-crc} + {permitted_enctypes(client)=des-cbc-crc des-cbc-md4} + {default_tgs_enctypes(client)=des-cbc-crc des-cbc-md4} + {default_tkt_enctypes(client)=des-cbc-md4} + {supported_enctypes=des-cbc-crc:normal} + {kdc_supported_enctypes=des-cbc-crc:normal} + {dummy=[verbose -log \ + "DES TGT, DES enctype, KDC permitting only des-cbc-crc, client requests des-cbc-md4 session key"]} + } + { + all-enctypes + des3_krbtgt=1 + {supported_enctypes=\ + rijndael256-hmac-sha1:normal rijndael192-hmac-sha1:normal rijndael128-hmac-sha1:normal \ + serpent256-hmac-sha1:normal serpent192-hmac-sha1:norealm serpent128-hmac-sha1:normal \ + twofish256-hmac-sha1:normal twofish192-hmac-sha1:norealm twofish128-hmac-sha1:normal \ + des3-cbc-sha1:normal des3-cbc-sha1:none \ + des-cbc-md5:normal des-cbc-md4:normal des-cbc-crc:normal \ + des-cbc-md5:v4 des-cbc-md4:v4 des-cbc-crc:v4 \ + } + {kdc_supported_enctypes=\ + rijndael256-hmac-sha1:normal rijndael192-hmac-sha1:normal rijndael128-hmac-sha1:normal \ + serpent256-hmac-sha1:normal serpent192-hmac-sha1:norealm serpent128-hmac-sha1:normal \ + twofish256-hmac-sha1:normal twofish192-hmac-sha1:norealm twofish128-hmac-sha1:normal \ + des3-cbc-sha1:normal des3-cbc-sha1:none \ + des-cbc-md5:normal des-cbc-md4:normal des-cbc-crc:normal \ + des-cbc-md5:v4 des-cbc-md4:v4 des-cbc-crc:v4 \ + } + {dummy=[verbose -log "DES3 TGT, default enctypes"]} + } + { + aes + des3_krbtgt=0 + {supported_enctypes=des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal} + {kdc_supported_enctypes=des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal} + {default_tgs_enctypes=rijndael256-hmac-sha1 des-cbc-crc} + {default_tkt_enctypes=rijndael256-hmac-sha1 des-cbc-crc} + {dummy=[verbose -log "DES3 TGT, default enctypes"]} + } +} +# {supported_enctypes=des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal } +# {kdc_supported_enctypes= des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal} + +# This shouldn't be necessary on dejagnu-1.4 and later, but 1.3 seems +# to need it because its runtest.exp doesn't deal with PASS at all. +if [info exists PASS] { + foreach pass $passes { + if { [lsearch -exact $PASS [lindex $pass 0]] >= 0 } { + lappend MULTIPASS $pass + } + } +} else { + set MULTIPASS $passes +} + +set last_passname_conf "" +set last_passname_db "" + +# We do everything in a temporary directory. +if ![info exists TMPDIR] { + set tmppwd "[pwd]/tmpdir" + if ![file isdirectory $tmppwd] { + catch "exec mkdir $tmppwd" status + } +} else { + set tmppwd $TMPDIR +} +verbose "tmppwd=$tmppwd" # On Ultrix, use /bin/sh5 in preference to /bin/sh. if ![info exists BINSH] { @@ -41,7 +278,7 @@ if ![info exists BINSH] { if ![info exists KEY] { catch {exec $BINSH -c "echo $$"} KEY verbose "KEY is $KEY" - set keyfile [open tmpdir/KEY w] + set keyfile [open $tmppwd/KEY w] puts $keyfile "$KEY" close $keyfile } @@ -49,7 +286,7 @@ if ![info exists KEY] { # Clear away any files left over from a previous run. # We can't use them now because we don't know the right KEY. # krb5.conf might change if running tests on another host -catch "exec rm -f tmpdir/db.ok tmpdir/srvtab tmpdir/krb5.conf tmpdir/kdc.conf tmpdir/cpw_srvtab" +catch "exec rm -f $tmppwd/db.ok $tmppwd/srvtab $tmppwd/krb5.conf $tmppwd/kdc.conf $tmppwd/cpw_srvtab $tmppwd/krb.realms $tmppwd/krb.conf" # Put the installed kerberos directories on PATH. # This needs to be fixed for V5. @@ -79,41 +316,37 @@ verbose "Test realm is $REALMNAME" # if they exist. If they do not, then they must be in PATH. We # expect $objdir to be ...tests/dejagnu. -if ![info exists KDB5_UTIL] { - set KDB5_UTIL [findfile $objdir/../../kadmin/dbutil/kdb5_util] -} - -if ![info exists KRB5KDC] { - set KRB5KDC [findfile $objdir/../../kdc/krb5kdc] -} - -if ![info exists KADMIND] { - set KADMIND [findfile $objdir/../../kadmin/server/kadmind] -} - -if ![info exists KADMIN] { - set KADMIN [findfile $objdir/../../kadmin/cli/kadmin] -} - -if ![info exists KADMIN_LOCAL] { - set KADMIN_LOCAL [findfile $objdir/../../kadmin/cli/kadmin.local] -} - - -if ![info exists KINIT] { - set KINIT [findfile $objdir/../../clients/kinit/kinit] -} - -if ![info exists KTUTIL] { - set KTUTIL [findfile $objdir/../../kadmin/ktutil/ktutil] +foreach i { + {KDB5_UTIL $objdir/../../kadmin/dbutil/kdb5_util} + {KRB5KDC $objdir/../../kdc/krb5kdc} + {KADMIND $objdir/../../kadmin/server/kadmind} + {KADMIN $objdir/../../kadmin/cli/kadmin} + {KADMIN_LOCAL $objdir/../../kadmin/cli/kadmin.local} + {KINIT $objdir/../../clients/kinit/kinit} + {KTUTIL $objdir/../../kadmin/ktutil/ktutil} + {KLIST $objdir/../../clients/klist/klist} + {KDESTROY $objdir/../../clients/kdestroy/kdestroy} + {RESOLVE $objdir/../resolve/resolve} + {T_INETD $objdir/t_inetd} +} { + set varname [lindex $i 0] + if ![info exists $varname] { + eval set varval [lindex $i 1] + set varval [findfile $varval] + set $varname $varval + verbose "$varname=$varval" + } { + eval set varval \$$varname + verbose "$varname already set to $varval" + } } -if ![info exists RESOLVE] { - set RESOLVE [findfile $objdir/../resolve/resolve] +if ![info exists RLOGIN] { + set RLOGIN rlogin } -if ![info exists T_INETD] { - set T_INETD [findfile $objdir/t_inetd] +if ![info exists RLOGIN_FLAGS] { + set RLOGIN_FLAGS "" } # We use a couple of variables to hold shell prompts which may be @@ -127,23 +360,40 @@ if ![info exists SHELL_PROMPT] { set SHELL_PROMPT "(%|#|>|\\$) $" } +verbose "setting up onexit handler (old handler=[exit -onexit])" +exit -onexit [concat { + verbose "calling stop_kerberos_daemons (onexit handler)" + stop_kerberos_daemons; +} [exit -onexit]] + # check_k5login + # Most of the tests won't work if the user has a .k5login file, unless -# the user's name appears unadorned in .k5login (in which case kuserok -# will assume a null instance and the local realm). This procedure -# returns 1 if the .k5login file appears to be OK, 0 otherwise. This -# check is not foolproof. +# the user's name appears with $REALMNAME in .k5login + +# This procedure returns 1 if the .k5login file appears to be OK, 0 +# otherwise. This check is not foolproof. + +# Note that this previously checked for a username with no realm; this +# works for krb4's kuserok() but not for krb5_kuserok(), due to some +# implementation details. *sigh* proc check_k5login { testname } { global env global REALMNAME - if ![file exists ~/.k5login] { - return 1 + if {![file exists ~/.k5login]} { + if {$env(USER) == "root"} { + return 0 + } else { + return 1 + } } + verbose "looking for $env(USER)@$REALMNAME in ~/.k5login" 2 set file [open ~/.k5login r] while { [gets $file principal] != -1 } { + verbose " found $principal" 2 if { $principal == "$env(USER)@$REALMNAME" } { close $file return 1 @@ -151,8 +401,40 @@ proc check_k5login { testname } { } close $file - untested "$testname test requires that your name appear in your ~/.k5login" - untested "file with no realm or instance." + note "$testname test requires that your name appear in your ~/.k5login" + note "file in the form $env(USER)@$REALMNAME" + unsupported "$testname" + + return 0 +} + +proc check_klogin { testname } { + global env + global REALMNAME + + if {![file exists ~/.klogin]} { + if {$env(USER) == "root"} { + return 0 + } else { + return 1 + } + } + + verbose "looking for $env(USER) in ~/.klogin" 2 + set file [open ~/.klogin r] + while { [gets $file principal] != -1 } { + verbose " found $principal" 2 + if { $principal == "$env(USER)" \ + || $principal == "$env(USER)@$REALMNAME" } { + close $file + return 1 + } + } + close $file + + note "$testname test requires that your name appear in your ~/.klogin" + note "file without a realm." + unsupported "$testname" return 0 } @@ -169,8 +451,7 @@ proc check_exit_status { testname } { verbose "wait -i $spawn_id returned $status_list ($testname)" catch "close -i $spawn_id" if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 0 } { - send_log "exit status: $status_list\n" - verbose "exit status: $status_list" + verbose -log "exit status: $status_list" fail "$testname" return 0 } else { @@ -178,73 +459,126 @@ proc check_exit_status { testname } { } } -# setup_runtime_flags -# Sets the proper flags for shared libraries. -# Configuration is through a site.exp and the runvarlist variable -# Returns 1 if variables were already set, otherwise 0 -proc setup_runtime_env { } { - global env - global runvarlist - global krb5_init_vars - global krb5_old_vars - global runtime_setup +# +# ENVSTACK +# - if [info exists runtime_setup] { - return 1 - } +# These procedures implement an environment variable stack. They use +# the global variable $envvars_tosave for the purpose of identifying +# which environment variables to save. They also track which ones are +# unset at any particular point. The stack pointer is $envstackp, +# which is an integer. The arrays $envstack$envstackp and +# $unenvstack$envstackp store respectively the set of old environment +# variables/values pushed onto the stack and the set of old unset +# environment variables for a given value of $envstackp. - set runtime_setup 1 - set krb5_init_vars [list ] - set krb5_old_vars [list ] +# Changing the value of $envvars_tosave after performing the first +# push operation may result in strangeness. - # Only keep the foo=bar and ignore export commands... - foreach i $runvarlist { - if {[regexp ".*=.*" $i]} { - lappend krb5_init_vars $i +# +# envstack_push +# +# Push set of current environment variables. +# +proc envstack_push { } { + global env + global envvars_tosave + global envstackp + global envstack$envstackp + global unenvstack$envstackp + + verbose "envstack_push: starting, sp=$envstackp" + foreach i $envvars_tosave { + if [info exists env($i)] { + verbose "envstack_push: saving $i=$env($i)" + set envstack${envstackp}($i) $env($i) + } { + verbose "envstack_push: marking $i as unset" + set unenvstack${envstackp}($i) unset } } + incr envstackp + verbose "envstack_push: exiting, sp=$envstackp" +} - - # Set the variables... (and save the old ones) - foreach i $krb5_init_vars { - regexp "^(\[^=\]*)=(.*)" $i foo evar evalue - if [info exists env($evar)] { - lappend krb5_old_vars $evar=$env($evar) - } - set env($evar) "$evalue" - verbose "$evar=$evalue" +# +# envstack_pop +# +# Pop set of current environment variables. +# +proc envstack_pop { } { + global env + global envstackp + + verbose "envstack_pop: starting, sp=$envstackp" + incr envstackp -1 + global envstack$envstackp # YUCK!!! no obvious better way though... + global unenvstack$envstackp + if {$envstackp < 0} { + perror "envstack_pop: stack underflow!" + return + } + if [info exists envstack$envstackp] { + foreach i [array names envstack$envstackp] { + if [info exists env($i)] { + verbose "envstack_pop: $i was $env($i)" + } + eval set env($i) \$envstack${envstackp}($i) + verbose "envstack_pop: restored $i to $env($i)" + } + unset envstack$envstackp + } + if [info exists unenvstack$envstackp] { + foreach i [array names unenvstack$envstackp] { + if [info exists env($i)] { + verbose "envstack_pop: $i was $env($i)" + unset env($i) + verbose "envstack_pop: $i unset" + } { + verbose "envstack_pop: ignoring already unset $i" + } + } + unset unenvstack$envstackp } + verbose "envstack_pop: exiting, sp=$envstackp" +} - return 0 +# +# Initialize the envstack +# +set envvars_tosave { + KRB5_CONFIG KRB5CCNAME KRBTKFILE KRB5RCACHEDIR + KERBEROS_SERVER KRB5_KDC_PROFILE } +set krb5_init_vars [list ] +# XXX -- fix me later! +foreach i $runvarlist { + verbose "processing $i" + if {[regexp "^(\[^=\]*)=(.*)" $i foo evar evalue]} { + verbose "adding $evar to savelist" + lappend envvars_tosave $evar + verbose "savelist $envvars_tosave" + lappend krb5_init_vars $i + } +} +set envstackp 0 +envstack_push +# setup_runtime_flags +# Sets the proper flags for shared libraries. # Configuration is through a site.exp and the runvarlist variable -proc restore_runtime_env { } { +# Returns 1 if variables were already set, otherwise 0 +proc setup_runtime_env { } { global env global krb5_init_vars - global krb5_old_vars - global runtime_setup - - if ![info exists runtime_setup] { - return 1 - } - - # restore the variables... + # Set the variables foreach i $krb5_init_vars { regexp "^(\[^=\]*)=(.*)" $i foo evar evalue - set idx [lsearch -regexp $krb5_old_vars "^$evar=" ] - if {$idx >= 0} { - - regexp "^(\[^=\]*)=(.*)" [lindex $krb5_old_vars $idx] foo evar evalue - set env($evar) "$evalue" - - } else { - catch "unset env($evar)" - } + set env($evar) "$evalue" + verbose "$evar=$evalue" } - - unset runtime_setup + return 0 } # get_hostname @@ -257,37 +591,65 @@ proc get_hostname { } { global hostname global localhostname global domain + global tmppwd if {[info exists hostname] && [info exists localhostname]} { return 1 } - set setup [setup_runtime_env] - - catch "exec $RESOLVE -q >tmpdir/hostname" exec_output + envstack_push + setup_runtime_env + catch "exec $RESOLVE -q >$tmppwd/hostname" exec_output + envstack_pop if ![string match "" $exec_output] { - send_log "$exec_output\n" - verbose $exec_output - send_error "ERROR: can't get hostname\n" - if {$setup == 0} restore_runtime_env + verbose -log $exec_output + perror "can't get hostname" return 0 } - set file [open tmpdir/hostname r] + set file [open $tmppwd/hostname r] if { [ gets $file hostname ] == -1 } { - send_error "ERROR: no output from hostname\n" - if {$setup == 0} restore_runtime_env + perror "no output from hostname" return 0 } close $file - catch "exec rm -f tmpdir/hostname" exec_output - regexp "^(\[^.\]*)\.(.*)$" $hostname foo localhostname domain + catch "exec rm -f $tmppwd/hostname" exec_output + regexp "^(\[^.\]*)\\.(.*)$" $hostname foo localhostname domain set hostname [string tolower $hostname] set localhostname [string tolower $localhostname] set domain [string tolower $domain] verbose "hostname: $hostname; localhostname: $localhostname; domain $domain" - if {$setup == 0} restore_runtime_env + return 1 +} + +# modify_principal name options... + +proc modify_principal { name args } { + global KADMIN_LOCAL + global REALMNAME + + spawn $KADMIN_LOCAL -r $REALMNAME + expect_after { + eof { + fail "modprinc (kadmin.local)" + return 0 + } + timeout { + fail "modprinc (kadmin.local)" + return 0 + } + } + expect "kadmin.local: " + send "modprinc $args $name\r" + expect -re "modprinc \[^\n\r\]* $name" + expect -re "Principal .* modified." + send "quit\r" + expect eof + catch expect_after + if ![check_exit_status "kadmin.local modprinc"] { + perror "kadmin.local modprinc exited abnormally" + } return 1 } @@ -301,40 +663,27 @@ proc setup_kerberos_files { } { global hostname global domain global tmppwd + global supported_enctypes + global kdc_supported_enctypes + global last_passname_conf + global multipass_name + global master_key_type if ![get_hostname] { return 0 } - # Create a krb5.conf file. - if ![file exists tmpdir/krb5.conf] { - set conffile [open tmpdir/krb5.conf w] - puts $conffile "\[libdefaults\]" - puts $conffile " default_realm = $REALMNAME" -# puts $conffile "default_tgs_enctypes = des-cbc-md5 des-cbc-crc" - puts $conffile "" - puts $conffile "\[realms\]" - puts $conffile " $REALMNAME = \{" - puts $conffile " kdc = $hostname:3088" - puts $conffile " admin_server = $hostname:3750" - puts $conffile " kpasswd_server = $hostname:3751" - puts $conffile " default_domain = $domain" - puts $conffile " \}" - puts $conffile "" - puts $conffile "\[domain_realm\]" - puts $conffile " .$domain = $REALMNAME" - puts $conffile " $domain = $REALMNAME" - puts $conffile "" - puts $conffile "\[logging\]" - puts $conffile " admin_server = FILE:$tmppwd/kadmind5.log" - puts $conffile " kdc = FILE:$tmppwd/kdc.log" - puts $conffile " default = FILE:$tmppwd/others.log" - close $conffile - } + setup_krb5_conf client + setup_krb5_conf server + setup_krb5_conf kdc # Create a kdc.conf file. - if ![file exists tmpdir/kdc.conf] { - set conffile [open tmpdir/kdc.conf w] + if { ![file exists $tmppwd/kdc.conf] \ + || $last_passname_conf != $multipass_name } { + if ![info exists master_key_type] { + set master_key_type des-cbc-md5 + } + set conffile [open $tmppwd/kdc.conf w] puts $conffile "\[kdcdefaults\]" puts $conffile " kdc_ports = 3085,3086,3087,3088,3089" puts $conffile "" @@ -350,34 +699,114 @@ proc setup_kerberos_files { } { puts $conffile " kpasswd_port = 3751" puts $conffile " max_life = 1:00:00" puts $conffile " max_renewable_life = 3:00:00" - puts $conffile " master_key_type = des-cbc-md5" + puts $conffile " master_key_type = $master_key_type" puts $conffile " master_key_name = master/key" -# des3-cbc-sha1:normal - puts $conffile " supported_enctypes = des-cbc-crc:normal des-cbc-md5:normal des-cbc-crc:v4 des-cbc-md5:norealm" - puts $conffile " kdc_supported_enctypes = des3-cbc-sha1:normal des-cbc-crc:normal des-cbc-md5:normal des-cbc-crc:v4 des-cbc-md5:norealm" + puts $conffile " supported_enctypes = $supported_enctypes" + puts $conffile " kdc_supported_enctypes = $kdc_supported_enctypes" puts $conffile " kdc_ports = 3088" puts $conffile " default_principal_expiration = 2037.12.31.23.59.59" puts $conffile " default_principal_flags = -postdateable forwardable" + puts $conffile " dict_file = $tmppwd/dictfile" puts $conffile " \}" puts $conffile "" close $conffile } # Create ACL file. - if ![file exists tmpdir/acl] { - set aclfile [open tmpdir/acl w] + if ![file exists $tmppwd/acl] { + set aclfile [open $tmppwd/acl w] puts $aclfile "krbtest/admin@$REALMNAME *" close $aclfile } + # Create krb.conf file + if ![file exists $tmppwd/krb.conf] { + set conffile [open $tmppwd/krb.conf w] + puts $conffile "$REALMNAME" + puts $conffile "$REALMNAME $hostname:3088 admin server" + close $conffile + } + + # Create krb.realms file + if ![file exists $tmppwd/krb.realms] { + set conffile [open $tmppwd/krb.realms w] + puts $conffile ".[string toupper $domain] $REALMNAME" + puts $conffile "[string toupper $domain]. $REALMNAME" + close $conffile + } + + # Create dictfile file. + if ![file exists $tmppwd/dictfile] { + set dictfile [open $tmppwd/dictfile w] + puts $dictfile "weak_password" + close $dictfile + } + + set last_passname_conf $multipass_name return 1 } +proc setup_krb5_conf { {type client} } { + global tmppwd + global hostname + global domain + global REALMNAME + global last_passname_conf + global multipass_name + global default_tgs_enctypes + global default_tkt_enctypes + global permitted_enctypes + + # Create a krb5.conf file. + if { ![file exists $tmppwd/krb5.$type.conf] \ + || $last_passname_conf != $multipass_name } { + set conffile [open $tmppwd/krb5.$type.conf w] + puts $conffile "\[libdefaults\]" + puts $conffile " default_realm = $REALMNAME" + if [info exists default_tgs_enctypes($type)] { + puts $conffile \ + " default_tgs_enctypes = $default_tgs_enctypes($type)" + } + if [info exists default_tkt_enctypes($type)] { + puts $conffile \ + " default_tkt_enctypes = $default_tkt_enctypes($type)" + } + if [info exists permitted_enctypes($type)] { + puts $conffile \ + " permitted_enctypes = $permitted_enctypes($type)" + } + puts $conffile " krb4_config = $tmppwd/krb.conf" + puts $conffile " krb4_realms = $tmppwd/krb.realms" + puts $conffile " krb4_srvtab = $tmppwd/v4srvtab" + puts $conffile "" + puts $conffile "\[realms\]" + puts $conffile " $REALMNAME = \{" + puts $conffile " kdc = $hostname:3088" + puts $conffile " admin_server = $hostname:3750" + puts $conffile " kpasswd_server = $hostname:3751" + puts $conffile " default_domain = $domain" + puts $conffile " krb524_server = $hostname:3752" + puts $conffile " \}" + puts $conffile "" + puts $conffile "\[domain_realm\]" + puts $conffile " .$domain = $REALMNAME" + puts $conffile " $domain = $REALMNAME" + puts $conffile "" + puts $conffile "\[logging\]" + puts $conffile " admin_server = FILE:$tmppwd/kadmind5.log" + puts $conffile " kdc = FILE:$tmppwd/kdc.log" + puts $conffile " default = FILE:$tmppwd/others.log" + close $conffile + } +} + # Save the original values of the environment variables we are going # to muck with. +# XXX deal with envstack later. + if [info exists env(KRB5_CONFIG)] { - set orig_krb_conf $env(KRB5_CONFIG) + set orig_krb5_conf $env(KRB5_CONFIG) } else { catch "unset orig_krb5_config" } @@ -403,7 +832,7 @@ if [ info exists env(KERBEROS_SERVER)] { # setup_kerberos_env # Set the environment variables needed to run Kerberos programs. -proc setup_kerberos_env { } { +proc setup_kerberos_env { {type client} } { global REALMNAME global env global tmppwd @@ -413,13 +842,17 @@ proc setup_kerberos_env { } { # Set the environment variable KRB5_CONFIG to point to our krb5.conf file. # All the Kerberos tools check KRB5_CONFIG. # Actually, V5 doesn't currently use this. - set env(KRB5_CONFIG) $tmppwd/krb5.conf + set env(KRB5_CONFIG) $tmppwd/krb5.$type.conf verbose "KRB5_CONFIG=$env(KRB5_CONFIG)" # Direct the Kerberos programs at a local ticket file. set env(KRB5CCNAME) $tmppwd/tkt verbose "KRB5CCNAME=$env(KRB5CCNAME)" + # Direct the Kerberos programs at a local ticket file. + set env(KRBTKFILE) $tmppwd/tktv4 + verbose "KRBTKFILE=$env(KRBTKFILE)" + # Direct the Kerberos server at a cache file stored in the # temporary directory. set env(KRB5RCACHEDIR) $tmppwd @@ -437,8 +870,8 @@ proc setup_kerberos_env { } { verbose "KRB5_KDC_PROFILE=$env(KRB5_KDC_PROFILE)" # Create an environment setup script. (For convenience) - if ![file exists tmpdir/env.sh] { - set envfile [open tmpdir/env.sh w] + if ![file exists $tmppwd/env.sh] { + set envfile [open $tmppwd/env.sh w] puts $envfile "KRB5_CONFIG=$env(KRB5_CONFIG)" puts $envfile "KRB5CCNAME=$env(KRB5CCNAME)" puts $envfile "KRB5RCACHEDIR=$env(KRB5RCACHEDIR)" @@ -453,8 +886,8 @@ proc setup_kerberos_env { } { } close $envfile } - if ![file exists tmpdir/env.csh] { - set envfile [open tmpdir/env.csh w] + if ![file exists $tmppwd/env.csh] { + set envfile [open $tmppwd/env.csh w] puts $envfile "setenv KRB5_CONFIG $env(KRB5_CONFIG)" puts $envfile "setenv KRB5CCNAME $env(KRB5CCNAME)" puts $envfile "setenv KRB5RCACHEDIR $env(KRB5RCACHEDIR)" @@ -503,7 +936,6 @@ proc restore_kerberos_env { } { catch "unset env(KERBEROS_SERVER)" } - restore_runtime_env } # setup_kadmind_srvtab @@ -516,58 +948,69 @@ proc setup_kadmind_srvtab { } { global KEY global tmppwd - catch "exec rm -f tmpdir/admin-keytab" + catch "exec rm -f $tmppwd/admin-keytab" + envstack_push + setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME + envstack_pop + catch expect_after expect_after { + -re "(.*)\r\nkadmin.local: " { + fail "kadmin.local admin-keytab (unmatched output: $expect_out(1,string)" + catch "exec rm -f $tmppwd/admin-keytab" + catch "expect_after" + return 0 + } timeout { fail "kadmin.local admin-keytab (timeout)" - catch "exec rm -f tmpdir/admin-keytab" + catch "exec rm -f $tmppwd/admin-keytab" catch "expect_after" return 0 } eof { fail "kadmin.local admin-keytab (eof)" - catch "exec rm -f tmpdir/admin-keytab" + catch "exec rm -f $tmppwd/admin-keytab" catch "expect_after" return 0 } } expect "kadmin.local: " send "xst -k admin-new-srvtab kadmin/admin\r" + expect "xst -k admin-new-srvtab kadmin/admin\r\n" expect -re ".*Entry for principal kadmin/admin.* added to keytab WRFILE:admin-new-srvtab." expect "kadmin.local: " catch "exec mv -f admin-new-srvtab changepw-new-srvtab" exec_output if ![string match "" $exec_output] { - send_log "$exec_output\n" - verbose $exec_output - send_error "ERROR: can't mv admin-new-srvtab\n" + verbose -log "$exec_output" + perror "can't mv admin-new-srvtab" + catch expect_after return 0 } send "xst -k changepw-new-srvtab kadmin/changepw\r" + expect "xst -k changepw-new-srvtab kadmin/changepw\r\n" expect -re ".*Entry for principal kadmin/changepw.* added to keytab WRFILE:changepw-new-srvtab." expect "kadmin.local: " send "quit\r" - expect "\r" - expect_after + expect eof + catch expect_after if ![check_exit_status "kadmin.local admin-keytab"] { - catch "exec rm -f tmpdir/admin-keytab" - send_error "ERROR: kadmin.local admin-keytab exited abnormally\n" + catch "exec rm -f $tmppwd/admin-keytab" + perror "kadmin.local admin-keytab exited abnormally" return 0 } - catch "exec mv -f changepw-new-srvtab tmpdir/admin-keytab" exec_output + catch "exec mv -f changepw-new-srvtab $tmppwd/admin-keytab" exec_output if ![string match "" $exec_output] { - send_log "$exec_output\n" - verbose $exec_output - send_error "ERROR: can't mv new admin-keytab\n" + verbose -log "$exec_output" + perror "can't mv new admin-keytab" return 0 } # Make the srvtab file globally readable in case we are using a # root shell and the srvtab is NFS mounted. - catch "exec chmod a+r tmpdir/admin-keytab" + catch "exec chmod a+r $tmppwd/admin-keytab" return 1 } @@ -584,208 +1027,260 @@ proc setup_kerberos_db { standalone } { global tmppwd global spawn_id global des3_krbtgt + global tgt_support_desmd5 + global multipass_name + global last_passname_db + + set failall 0 - if {!$standalone && [file exists tmpdir/db.ok]} { + if {!$standalone && [file exists $tmppwd/db.ok] \ + && $last_passname_db == $multipass_name} { return 1 } - catch "exec rm -f [glob -nocomplain tmpdir/db* tmpdir/adb*]" + catch "exec rm -f [glob -nocomplain $tmppwd/db* $tmppwd/adb*]" # Creating a new database means we need a new srvtab. - catch "exec rm -f tmpdir/srvtab" + catch "exec rm -f $tmppwd/srvtab" - if { ![setup_kerberos_files] || ![setup_kerberos_env] } { - return 0 + envstack_push + if { ![setup_kerberos_files] || ![setup_kerberos_env kdc] } { + set failall 1 } - spawn $KDB5_UTIL -r $REALMNAME create - - expect { - "Enter KDC database master key:" { - verbose "kdb5_util started" - } + # Set up a common expect_after for use in multiple places. + set def_exp_after { timeout { - fail "kdb5_util - create" - return 0 + set test "$test (timeout)" + break } eof { - fail "kdb5_util - create" - return 0 + set test "$test (eof)" + break } } - send "masterkey$KEY\r" - set failed 0 - expect { - "Re-enter KDC database master key to verify:" { } - timeout { - fail "kdb5_util create - verify" - return 0 - } - eof { - fail "kdb5_util create - verify" - return 0 + + set test "kdb5_util create" + set body { + if $failall { + break } - } - send "masterkey$KEY\r" - expect { - -re "\[Cc\]ouldn't" { - fail "kdb5_util - create" - return 0 + #exec xterm + verbose "starting $test" + spawn $KDB5_UTIL -r $REALMNAME create + expect_after $def_exp_after + + expect "Enter KDC database master key:" + + set test "kdb5_util create (verify)" + send "masterkey$KEY\r" + expect "Re-enter KDC database master key to verify:" + + set test "kdb5_util create" + send "masterkey$KEY\r" + expect { + -re "\[Cc\]ouldn't" { + expect eof + break + } + "Cannot find/read stored" exp_continue + "Warning: proceeding without master key" exp_continue + eof { } } - "Cannot find/read stored" { - exp_continue + catch expect_after + if ![check_exit_status kdb5_util] { + break } - "Warning: proceeding without master key" { - exp_continue + } + set ret [catch $body] + catch expect_after + if $ret { + set failall 1 + if $standalone { + fail $test } - timeout { - fail "kdb5_util - create" - return 0 + } else { + if $standalone { + pass $test } - eof { } - } - if ![check_exit_status kdb5_util] { - return 0 - } - - if {$standalone} { - pass "kdb5_util - create" } # Stash the master key in a file. - spawn $KDB5_UTIL -r $REALMNAME stash - expect { - "Enter KDC database master key:" { - verbose "kdb5_util stash started" + set test "kdb5_util stash" + set body { + if $failall { + break } - timeout { - fail "kdb5_util stash" - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" - } - return 0 - } - eof { - fail "kdb5_util stash" - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" - } - return 0 + spawn $KDB5_UTIL -r $REALMNAME stash + verbose "starting $test" + expect_after $def_exp_after + expect "Enter KDC database master key:" + send "masterkey$KEY\r" + expect eof + catch expect_after + if ![check_exit_status kdb5_util] { + break } } - send "masterkey$KEY\r" - expect { - eof { } - timeout { - fail "kdb5_util stash" - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" - } - return 0 + set ret [catch $body] + catch "expect eof" + catch expect_after + if $ret { + set failall 1 + if $standalone { + fail $test + } else { + catch "exec rm -f $tmppwd/db.ok $tmppwd/adb.db" + } + } else { + if $standalone { + pass $test } - } - if ![check_exit_status kdb5_util] { - return 0 - } - - if {$standalone} { - pass "kdb5_util stash" } # Add an admin user. - spawn $KADMIN_LOCAL -r $REALMNAME - expect_after { - timeout { - catch "expect_after" - fail "kadmin.local (timeout)" - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" - } - return 0 +#send_user "will run: $KADMIN_LOCAL -r $REALMNAME\n" +#exec xterm + set test "kadmin.local ank krbtest/admin" + set body { + if $failall { + break } - eof { - catch "expect_after" - fail "kadmin.local (eof)" - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" - } - return 0 + spawn $KADMIN_LOCAL -r $REALMNAME + verbose "starting $test" + expect_after $def_exp_after + + expect "kadmin.local: " + send "ank krbtest/admin@$REALMNAME\r" + # It echos... + expect "ank krbtest/admin@$REALMNAME\r" + expect "Enter password for principal \"krbtest/admin@$REALMNAME\":" + send "adminpass$KEY\r" + expect "Re-enter password for principal \"krbtest/admin@$REALMNAME\":" + send "adminpass$KEY\r" + expect { + "Principal \"krbtest/admin@$REALMNAME\" created" { } + "Principal or policy already exists while creating*" { } + } + expect "kadmin.local: " + send "quit\r" + expect eof + catch expect_after + if ![check_exit_status kadmin_local] { + break } } - expect "kadmin.local: " - send "ank krbtest/admin@$REALMNAME\r" - # It echos... - expect "ank krbtest/admin@$REALMNAME\r" - expect "Enter password for principal \"krbtest/admin@$REALMNAME\":" - send "adminpass$KEY\r" - expect "Re-enter password for principal \"krbtest/admin@$REALMNAME\":" - send "adminpass$KEY\r" - expect { - "Principal \"krbtest/admin@$REALMNAME\" created" { } - "Principal or policy already exists while creating*" { expect eof } - } - expect "kadmin.local: " - send "quit\r" - expect "\r" - expect_after - if ![check_exit_status kadmin_local] { - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" + set ret [catch $body] + catch "expect eof" + catch expect_after + if $ret { + set failall 1 + if $standalone { + fail $test + } else { + catch "exec rm -f $tmppwd/db.ok $tmppwd/adb.db" + } + } else { + if $standalone { + pass $test } - return 0 } if $des3_krbtgt { # Set the TGT key to DES3. - spawn $KADMIN_LOCAL -r $REALMNAME -e des3-cbc-sha1:normal - expect_after { - timeout { - catch "expect_after" - fail "kadmin.local (timeout)" - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" - } - return 0 + set test "kadmin.local TGT to DES3" + set body { + if $failall { + break } - eof { - catch "expect_after" - fail "kadmin.local (eof)" - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" - } - return 0 + spawn $KADMIN_LOCAL -r $REALMNAME -e des3-cbc-sha1:normal + verbose "starting $test" + expect_after $def_exp_after + + expect "kadmin.local: " + send "cpw -randkey krbtgt/$REALMNAME@$REALMNAME\r" + # It echos... + expect "cpw -randkey krbtgt/$REALMNAME@$REALMNAME\r" + expect { + "Key for \"krbtgt/$REALMNAME@$REALMNAME\" randomized." { } + } + expect "kadmin.local: " + send "quit\r" + expect eof + catch expect_after + if ![check_exit_status kadmin_local] { + break } } - expect "kadmin.local: " - send "cpw -randkey krbtgt/$REALMNAME@$REALMNAME\r" - # It echos... - expect "cpw -randkey krbtgt/$REALMNAME@$REALMNAME\r" - expect { - "Key for \"krbtgt/$REALMNAME@$REALMNAME\" randomized." { } + set ret [catch $body] + catch "expect eof" + catch expect_after + if $ret { + set failall 1 + if $standalone { + fail $test + } else { + catch "exec rm -f $tmppwd/db.ok $tmppwd/adb.db" + } + } else { + if $standalone { + pass $test + } } - expect "kadmin.local: " - send "quit\r" - expect "\r" - expect_after - if ![check_exit_status kadmin_local] { - if {!$standalone} { - catch "exec rm -f tmpdir/db.ok tmpdir/adb.db" + } + if $tgt_support_desmd5 { + # Make TGT support des-cbc-md5 + set test "kadmin.local TGT to SUPPORT_DESMD5" + set body { + if $failall { + break + } + spawn $KADMIN_LOCAL -r $REALMNAME + verbose "starting $test" + expect_after $def_exp_after + + expect "kadmin.local: " + send "modprinc +support_desmd5 krbtgt/$REALMNAME@$REALMNAME\r" + # It echos... + expect "modprinc +support_desmd5 krbtgt/$REALMNAME@$REALMNAME\r" + expect { + "Principal \"krbtgt/$REALMNAME@$REALMNAME\" modified.\r\n" { } + } + expect "kadmin.local: " + send "quit\r" + expect eof + catch expect_after + if ![check_exit_status kadmin_local] { + break + } + } + set ret [catch $body] + catch "expect eof" + catch expect_after + if $ret { + set failall 1 + if $standalone { + fail $test + } else { + catch "exec rm -f $tmppwd/db.ok $tmppwd/adb.db" + } + } else { + if $standalone { + pass $test } - return 0 } } - - if ![setup_kadmind_srvtab] { + # XXX should deal with envstack inside setup_kadmind_srvtab too + set ret [setup_kadmind_srvtab] + envstack_pop + if !$ret { return 0 } # create the admin database lock file - catch "exec touch tmpdir/adb.lock" - - if {$standalone} { - pass "kadmin_local" - } + catch "exec touch $tmppwd/adb.lock" + set last_passname_db $multipass_name return 1 } @@ -815,8 +1310,9 @@ proc start_kerberos_daemons { standalone } { } if {$standalone} { - catch "exec rm -f tmpdir/krb.log" - catch "exec rm -f tmpdir/kadmind.log" + catch "exec rm -f $tmppwd/krb.log" + catch "exec rm -f $tmppwd/kadmind.log" + catch "exec rm -f $tmppwd/krb5kdc_rcache" } # Start up the kerberos daemon @@ -829,43 +1325,72 @@ proc start_kerberos_daemons { standalone } { # The same thing is done a little later for the kadmind set kdc_lfile $tmppwd/kdc.log set kadmind_lfile $tmppwd/kadmind5.log - set retry 30 if ![file exists $kdc_lfile] then { catch [touch $kdc_lfile] } - sleep 2 - set kdc_start [file mtime $kdc_lfile] - spawn $KRB5KDC -r $REALMNAME -n - set kdc_pid [exp_pid] - set kdc_spawn_id $spawn_id + spawn tail -f $kdc_lfile + set tailf_spawn_id $spawn_id + set tailf_pid [exp_pid] - for {set count 0} {$count < $retry} {incr count} { - if { [file mtime $kdc_lfile] != $kdc_start } then { - break; - } - sleep 2 - } + set markstr "===MARK $tailf_pid [exec date] ===" + set f [open $kdc_lfile a] + puts $f $markstr + close $f - if {$count >= $retry} { - fail "krb5kdc" - stop_kerberos_daemons - return 0 + expect { + -i $tailf_spawn_id + -ex "$markstr\r\n" { } + timeout { + if {$standalone} { + verbose -log "tail -f timed out looking for mark" + fail "krb5kdc" + } else { + perror "krbkdc tail -f timed out looking for mark" + } + stop_kerberos_daemons + exec kill $tailf_pid + expect -i $tailf_spawn_id eof + wait -i $tailf_spawn_id + return 0 + } } - if ![regexp "commencing operation" [tail1 $kdc_lfile]] { - fail "krb5kdc" - stop_kerberos_daemons - return 0 + envstack_push + setup_kerberos_env kdc + spawn $KRB5KDC -r $REALMNAME -n + envstack_pop + set kdc_pid [exp_pid] + set kdc_spawn_id $spawn_id + + expect { + -i $tailf_spawn_id + -re "commencing operation\r\n" { } + timeout { + if {$standalone} { + verbose -log "krb5kdc startup timed out" + fail "krb5kdc" + } else { + perror "krb5kdc startup timed out" + } + stop_kerberos_daemons + exec kill $tailf_pid + expect -i $tailf_spawn_id eof + wait -i $tailf_spawn_id + return 0 + } } + exec kill $tailf_pid + expect -i $tailf_spawn_id eof + wait -i $tailf_spawn_id if {$standalone} { pass "krb5kdc" } # Give the kerberos daemon a few seconds to get set up. - sleep 2 +# sleep 2 # @@ -880,66 +1405,107 @@ proc start_kerberos_daemons { standalone } { if ![file exists $kadmind_lfile] then { catch [touch $kadmind_lfile] - sleep 1 } - set kadmind_start [file mtime $kadmind_lfile] + spawn tail -f $kadmind_lfile + set tailf_spawn_id $spawn_id + set tailf_pid [exp_pid] + + set markstr "===MARK $tailf_pid [exec date] ===" + set f [open $kadmind_lfile a] + puts $f $markstr + close $f + + expect { + -i $tailf_spawn_id + -ex "$markstr\r\n" { } + timeout { + if {$standalone} { + verbose -log "tail -f timed out looking for mark" + fail "kadmind" + } else { + perror "kadmind tail -f timed out looking for mark" + } + stop_kerberos_daemons + exec kill $tailf_pid + expect -i $tailf_spawn_id eof + wait -i $tailf_spawn_id + return 0 + } + } # Start up the kadmind daemon # XXXX kadmind uses stderr a lot. the sh -c and redirect can be - # removed when this is fixed + # removed when this is fixed + envstack_push + setup_kerberos_env kdc spawn $BINSH -c "exec $KADMIND -r $REALMNAME -nofork 2>>$kadmind_lfile" + envstack_pop set kadmind_pid [exp_pid] set kadmind_spawn_id $spawn_id - for {set count 0} {$count < $retry} {incr count} { - if { [file mtime $kadmind_lfile] != $kadmind_start } then { - break; - } - sleep 1 - } - - if {$count >= $retry} { - fail "kadmin5 (starting)" - if [info exists start_save_ktname] { - set env(KRB5_KTNAME) $start_save_ktname - unset start_save_ktname - } - stop_kerberos_daemons - return 0 - } - # Restore KRB5_KTNAME if [info exists start_save_ktname] { set env(KRB5_KTNAME) $start_save_ktname unset start_save_ktname } - switch -regexp [tail1 $kadmind_lfile] { - "cannot initialize network" { - fail "kadmind (network init)" + expect { + -i $tailf_spawn_id + "Seeding random number" exp_continue + "cannont initialize network" { + if {$standalone} { + verbose -log "kadmind failed network init" + fail "kadmind" + } else { + perror "kadmind failed network init" + } stop_kerberos_daemons + exec kill $tailf_pid + expect -i $tailf_spawn_id eof + wait -i $tailf_spawn_id return 0 } "cannot bind to network address" { - fail "kadmind (bind)" + if {$standalone} { + verbose -log "kadmind failed to bind socket" + fail "kadmind" + } else { + perror "kadmind failed to bind socket" + } stop_kerberos_daemons + exec kill $tailf_pid + expect -i $tailf_spawn_id eof + wait -i $tailf_spawn_id return 0 } "starting" { } - default { - fail "kadmind (startup)" + timeout { + if {$standalone} { + verbose -log "kadmind failed to start" + fail "kadmind" + } else { + verbose -log "kadmind failed to start" + perror "kadmind failed to start" + } +#sleep 10 stop_kerberos_daemons + exec kill $tailf_pid + expect -i $tailf_spawn_id eof + wait -i $tailf_spawn_id return 0 } } + exec kill $tailf_pid + expect -i $tailf_spawn_id eof + wait -i $tailf_spawn_id if {$standalone} { pass "kadmind" } # Give the kadmind daemon a few seconds to get set up. - sleep 2 +# sleep 2 return 1 } @@ -953,9 +1519,15 @@ proc stop_kerberos_daemons { } { global kadmind_pid global kadmind_spawn_id + verbose "entered stop_kerberos_daemons" + if [info exists kdc_pid] { - catch "close -i $kdc_spawn_id" - catch "exec kill $kdc_pid" + if [catch "exec kill $kdc_pid" msg] { + verbose "kill kdc: $msg" + } + if [catch "expect -i $kdc_spawn_id eof" msg] { + verbose "expect kdc eof: $msg" + } set kdc_list [wait -i $kdc_spawn_id] verbose "wait -i $kdc_spawn_id returned $kdc_list (kdc)" unset kdc_pid @@ -963,14 +1535,20 @@ proc stop_kerberos_daemons { } { } if [info exists kadmind_pid] { - catch "close -i $kadmind_spawn_id" - catch "exec kill $kadmind_pid" + if [catch "exec kill $kadmind_pid" msg] { + verbose "kill kadmind: $msg" + } + if [catch "expect -i $kadmind_spawn_id eof" msg] { + verbose "expect kadmind eof: $msg" + } set kadmind_list [wait -i $kadmind_spawn_id] verbose "wait -i $kadmind_spawn_id returned $kadmind_list (kadmind5)" unset kadmind_pid unset kadmind_list } + verbose "exiting stop_kerberos_daemons" + return 1 } @@ -987,45 +1565,58 @@ proc add_kerberos_key { kkey standalone } { global spawn_id # Use kadmin to add an key. - spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank $kkey@$REALMNAME" - expect_after { - "Cannot contact any KDC" { - fail "kadmin interactive add $kkey lost KDC" - catch "expect_after" - return 0 + set test "kadmin ank $kkey" + set body { + envstack_push + setup_kerberos_env client + spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank $kkey@$REALMNAME" + envstack_pop + verbose "starting $test" + expect_after { + "Cannot contact any KDC" { + set test "$test (lost KDC)" + break + } + timeout { + set test "$test (timeout)" + break + } + eof { + set test "$test (eof)" + break + } } - timeout { - fail "kadmin $kkey" - catch "expect_after" - return 0 + expect "Enter password:" + send "adminpass$KEY\r" + expect "Enter password for principal \"$kkey@$REALMNAME\":" + send "$kkey" + send "$KEY\r" + expect "Re-enter password for principal \"$kkey@$REALMNAME\":" + send "$kkey" + send "$KEY\r" + expect { + "Principal \"$kkey@$REALMNAME\" created" { } + "Principal or policy already exists while creating*" { } } - eof { - fail "kadmin $kkey" - return 0 + expect eof + if ![check_exit_status kadmin] { + break } } - expect "Enter password:" - send "adminpass$KEY\r" - expect "Enter password for principal \"$kkey@$REALMNAME\":" - send "$kkey" - send "$KEY\r" - expect "Re-enter password for principal \"$kkey@$REALMNAME\":" - send "$kkey" - send "$KEY\r" - expect { - "Principal \"$kkey@$REALMNAME\" created" { } - "Principal or policy already exists while creating*" { expect eof } - } - catch "expect_after" - if ![check_exit_status kadmin] { + set ret [catch $body] + catch "expect eof" + catch expect_after + if $ret { + if $standalone { + fail $test + } return 0 + } else { + if $standalone { + pass $test + } + return 1 } - - if {$standalone} { - pass "kadmin $kkey" - } - - return 1 } # add_random_key @@ -1041,35 +1632,46 @@ proc add_random_key { kkey standalone } { global spawn_id # Use kadmin to add an key. - spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank -randkey $kkey@$REALMNAME" - expect_after { - timeout { - fail "kadmin $kkey" - catch "expect_after" - return 0 + set test "kadmin ark $kkey" + set body { + envstack_push + setup_kerberos_env client + spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank -randkey $kkey@$REALMNAME" + envstack_pop + expect_after { + timeout { + set test "$test (timeout)" + break + } + eof { + set test "$test (eof)" + break + } } - eof { - fail "kadmin $kkey" - catch "expect_after" - return 0 + expect "Enter password:" + send "adminpass$KEY\r" + expect { + "Principal \"$kkey@$REALMNAME\" created" { } + "Principal or policy already exists while creating*" { } + } + expect eof + if ![check_exit_status kadmin] { + break } } - expect "Enter password:" - send "adminpass$KEY\r" - expect { - "Principal \"$kkey@$REALMNAME\" created" { } - "Principal or policy already exists while creating*" { expect eof} - } - catch "expect_after" - if ![check_exit_status kadmin] { + if [catch $body] { + catch expect_after + if $standalone { + fail $test + } return 0 + } else { + catch expect_after + if $standalone { + pass $test + } + return 1 } - - if {$standalone} { - pass "kadmin $kkey" - } - - return 1 } # setup_srvtab @@ -1087,11 +1689,11 @@ proc setup_srvtab { standalone {id host} } { global spawn_id global last_service - if {!$standalone && [file exists tmpdir/srvtab] && $last_service == $id} { + if {!$standalone && [file exists $tmppwd/srvtab] && $last_service == $id} { return 1 } - catch "exec rm -f tmpdir/srvtab tmpdir/srvtab.old" + catch "exec rm -f $tmppwd/srvtab $tmppwd/srvtab.old" if ![get_hostname] { return 0 @@ -1099,12 +1701,23 @@ proc setup_srvtab { standalone {id host} } { catch "exec rm -f $hostname-new-srvtab" + envstack_push + setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME + envstack_pop expect_after { + -re "(.*)\r\nkadmin.local: " { + fail "kadmin.local srvtab (unmatched output: $expect_out(1,string))" + if {!$standalone} { + catch "exec rm -f $tmppwd/srvtab" + } + catch "expect_after" + return 0 + } timeout { fail "kadmin.local srvtab" if {!$standalone} { - catch "exec rm -f tmpdir/srvtab" + catch "exec rm -f $tmppwd/srvtab" } catch "expect_after" return 0 @@ -1112,7 +1725,7 @@ proc setup_srvtab { standalone {id host} } { eof { fail "kadmin.local srvtab" if {!$standalone} { - catch "exec rm -f tmpdir/srvtab" + catch "exec rm -f $tmppwd/srvtab" } catch "expect_after" return 0 @@ -1120,23 +1733,34 @@ proc setup_srvtab { standalone {id host} } { } expect "kadmin.local: " send "xst -k $hostname-new-srvtab $id/$hostname\r" - expect -re ".*Entry for principal $id/$hostname.* added to keytab WRFILE:$hostname-new-srvtab." + expect "xst -k $hostname-new-srvtab $id/$hostname\r\n" + expect { + -re ".*Entry for principal $id/$hostname.* added to keytab WRFILE:$hostname-new-srvtab." { } + -re "\r\nkadmin.local: " { + if {$standalone} { + fail "kadmin.local srvtab" + } else { + catch "exec rm -f $tmppwd/srvtab" + } + catch expect_after + return 0 + } + } expect "kadmin.local: " send "quit\r" - expect "\r" - expect_after + expect eof + catch expect_after if ![check_exit_status "kadmin.local srvtab"] { if {!$standalone} { - catch "exec rm -f tmpdir/srvtab" + catch "exec rm -f $tmppwd/srvtab" } return 0 } - catch "exec mv -f $hostname-new-srvtab tmpdir/srvtab" exec_output + catch "exec mv -f $hostname-new-srvtab $tmppwd/srvtab" exec_output if ![string match "" $exec_output] { - send_log "$exec_output\n" - verbose $exec_output - send_error "ERROR: can't mv new srvtab\n" + verbose -log "$exec_output" + perror "can't mv new srvtab" return 0 } @@ -1146,7 +1770,7 @@ proc setup_srvtab { standalone {id host} } { # Make the srvtab file globally readable in case we are using a # root shell and the srvtab is NFS mounted. - catch "exec chmod a+r tmpdir/srvtab" + catch "exec chmod a+r $tmppwd/srvtab" # Remember what we just extracted set last_service $id @@ -1184,22 +1808,378 @@ proc kinit { name pass standalone } { } } send "$pass\r" - # This last expect seems useless, but without it the test hangs on - # AIX. + expect eof + if ![check_exit_status kinit] { + return 0 + } + + if {$standalone} { + pass "kinit" + } + + return 1 +} + +proc kinit_kt { name keytab standalone testname } { + global REALMNAME + global KINIT + global spawn_id + + # Use kinit to get a ticket. + # + # For now always get forwardable tickets. Later when we need to make + # tests that distiguish between forwardable tickets and otherwise + # we should but another option to this proc. --proven + # + spawn $KINIT -5 -f -k -t $keytab $name@$REALMNAME + expect { + timeout { + fail "kinit $testname" + return 0 + } + eof { } + } + if ![check_exit_status "kinit $testname"] { + return 0 + } + + if {$standalone} { + pass "kinit $testname" + } + + return 1 +} + +# List tickets. Requires client and server names, and test name. +# Checks that klist exist status is zero. +# Records pass or fail, and returns 1 or 0. +proc do_klist { myname servname testname } { + global KLIST + global tmppwd + + spawn $KLIST -5 -e + expect { + -re "Ticket cache:\[ \]*(.+:)?$tmppwd/tkt.*Default principal:\[ \]*$myname.*$servname\r\n" { + verbose "klist started" + } + timeout { + fail $testname + return 0 + } + eof { + fail $testname + return 0 + } + } + + expect eof + + if ![check_exit_status $testname] { + return 0 + } + pass $testname + return 1 +} + +proc do_klist_kt { keytab testname } { + global KLIST + global tmppwd + + spawn $KLIST -5 -e -k $keytab expect { - "\r" { } + -re "Keytab name:\[ \]*(.+:)?.*KVNO Principal\r\n---- -*\r\n" { + verbose "klist started" + } + timeout { + fail $testname + return 0 + } + eof { + fail $testname + return 0 + } + } + set more 1 + while {$more} { + expect { + -re { *[0-9][0-9]* *[a-zA-Z/@.-]* \([/a-zA-Z 0-9-]*\) *\r\n} { + verbose -log "key: $expect_out(buffer)" + } + eof { set more 0 } + } + } + + if ![check_exit_status $testname] { + return 0 + } + pass $testname + return 1 +} + +proc do_klist_err { testname } { + global KLIST + global spawn_id + + spawn $KLIST -5 + expect { + -re "klist: No credentials cache found.*\r\n" { + verbose "klist started" + } + timeout { + fail $testname + return 0 + } + eof { + fail $testname + return 0 + } + } + # We can't use check_exit_status, because we expect an exit status + # of 1. + catch "expect eof" + set status_list [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $status_list ($testname)" + if { [lindex $status_list 2] != 0 } { + fail "$testname (bad exit status) $status_list" + return 0 + } else { if { [lindex $status_list 3] != 1 } { + fail "$testname (bad exit status) $status_list" + return 0 + } else { + pass $testname + } } + return 1 +} + +proc do_kdestroy { testname } { + global KDESTROY + spawn $KDESTROY -5 + if ![check_exit_status $testname] { + fail $testname + return 0 } + pass $testname + return 1 +} + +proc xst { keytab name } { + global KADMIN_LOCAL + global REALMNAME + + envstack_push + setup_kerberos_env kdc + spawn $KADMIN_LOCAL -r $REALMNAME + envstack_pop + catch expect_after + expect_after { + -re "(.*)\r\nkadmin.local: " { + fail "kadmin.local xst $keytab (unmatched output: $expect_out(1,string)" + catch "expect_after" + return 0 + } + timeout { + fail "kadmin.local xst $keytab (timeout)" + catch "expect_after" + return 0 + } + eof { + fail "kadmin.local xst $keytab (eof)" + catch "expect_after" + return 0 + } + } + expect "kadmin.local: " + send "xst -k $keytab $name\r" + expect -re "xst -k \[^\r\n\]*\r\n.*Entry for principal .* added to keytab WRFILE:.*\r\nkadmin.local: " + send "quit\r" + expect eof + catch expect_after + if ![check_exit_status "kadmin.local $keytab"] { + perror "kadmin.local xst $keytab exited abnormally" + return 0 + } + return 1 +} + +# v4_compatible_enctype +# Returns 1 if v4 testing is enabled this passes encryption types are compatable with kerberos 4 work +proc v4_compatible_enctype {} { + global supported_enctypes + global KRBIV + + if ![info exists KRBIV] { + return 0; + } + + if { $KRBIV && [string first des-cbc-crc:v4 "$supported_enctypes"] >= 0} { + return 1 + } else { + return 0 + } +} + +# kinit +# Use kinit to get a ticket. If the argument is non-zero, call pass +# at relevant points. Returns 1 on success, 0 on failure. + +proc v4kinit { name pass standalone } { + global REALMNAME + global KINIT + global spawn_id + global des3_krbtgt + # Use kinit to get a ticket. + # + # For now always get forwardable tickets. Later when we need to make + # tests that distiguish between forwardable tickets and otherwise + # we should but another option to this proc. --proven + # + spawn $KINIT -4 $name@$REALMNAME + expect { + "Password for $name@$REALMNAME:" { + verbose "v4kinit started" + } + timeout { + fail "v4kinit" + return 0 + } + eof { + fail "v4kinit" + return 0 + } + } + send "$pass\r" expect eof + if {$des3_krbtgt == 0} { + if ![check_exit_status v4kinit] { + return 0 + } + } else { + # Fail if kinit is successful with a des3 TGT. + set status_list [wait -i $spawn_id] + set testname v4kinit + verbose "wait -i $spawn_id returned $status_list ($testname)" + if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 1 } { + verbose -log "exit status: $status_list" + fail "$testname (exit status)" + } + } + if {$standalone} { + pass "v4kinit" + } + return 1 +} + +proc v4kinit_kt { name keytab standalone } { + global REALMNAME + global KINIT + global spawn_id + + # Use kinit to get a ticket. + # + # For now always get forwardable tickets. Later when we need to make + # tests that distiguish between forwardable tickets and otherwise + # we should but another option to this proc. --proven + # + spawn $KINIT -4 -k -t $keytab $name@$REALMNAME + expect { + timeout { + fail "v4kinit" + return 0 + } + eof { } + } if ![check_exit_status kinit] { return 0 } if {$standalone} { - pass "kinit" + pass "v4kinit" + } + + return 1 +} + +# List v4 tickets. +# Client and server are regular expressions. +proc v4klist { client server testname } { + global KLIST + global tmppwd + + spawn $KLIST -4 + expect { + -re "Kerberos 4 ticket cache:\[ \]*(.+:)?$tmppwd/tkt.*Principal:\[ \]*$client.*$server\r\n" { + verbose "klist started" + } + timeout { + fail $testname + return 0 + } + eof { + fail $testname + return 0 + } } + expect eof + + if ![check_exit_status $testname] { + return 0 + } + pass $testname + return 1 +} + +# Destroy tickets. +proc v4kdestroy { testname } { + global KDESTROY + spawn $KDESTROY -4 + if ![check_exit_status $testname] { + return 0 + } + pass $testname + return 1 +} + +# Try to list the krb4 tickets -- there shouldn't be any ticket file. +proc v4klist_none { testname } { + global KLIST + global tmppwd + + # Double check that the ticket was destroyed. + spawn $KLIST -4 + expect { + -re "Kerberos 4 ticket cache:\[ \]*(.+:)?$tmppwd/tkt.*klist: You have no tickets cached.*\r\n" { + verbose "v4klist started" + pass "$testname (output)" + } + timeout { + fail "$testname (output)" + # Skip the 'wait' below, if it's taking too long. + untested "$testname (exit status)" + return 0 + } + eof { + fail "$testname (output)" + } + } + # We can't use check_exit_status, because we expect an exit status + # of 1. + expect eof + set status_list [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $status_list (v4klist)" + if { [lindex $status_list 2] != 0 } { + fail "$testname (exit status)" + return 0 + } else { + if { [lindex $status_list 3] != 1 } { + fail "$testname (exit status)" + return 0 + } else { + pass "$testname (exit status)" + } + } return 1 } @@ -1217,6 +2197,8 @@ proc setup_root_shell { testname } { global BINSH global ROOT_PROMPT global KEY + global RLOGIN + global RLOGIN_FLAGS global hostname global rlogin_spawn_id global rlogin_pid @@ -1224,15 +2206,22 @@ proc setup_root_shell { testname } { global env global krb5_init_vars + global timeout # Make sure we are using the original values of the environment # variables. This means that the caller must call # setup_kerberos_env after calling this procedure. + # XXX fixme to deal with envstack restore_kerberos_env setup_runtime_env + set me [exec whoami] + if [string match root $me] { + return [setup_root_shell_noremote $testname] + } + if ![get_hostname] { return 0 } @@ -1248,45 +2237,50 @@ proc setup_root_shell { testname } { # send "rootpassword\r" # exp_continue - spawn rlogin $hostname -l root + eval spawn $RLOGIN $hostname -l root $RLOGIN_FLAGS set rlogin_spawn_id $spawn_id set rlogin_pid [exp_pid] + set old_timeout $timeout + set timeout 300 + expect { - "word:" { - untested "$testname test requires ability to rlogin as root" + -re "word:|erberos rlogin failed|ection refused|ection reset by peer" { + note "$testname test requires ability to rlogin as root" + unsupported "$testname" + set timeout $old_timeout stop_root_shell return 0 } - "Kerberos rlogin failed" { - untested "$testname test requires ability to rlogin as root" + -re "$ROOT_PROMPT" { } + timeout { + perror "timeout from rlogin $hostname -l root" + perror "If you have an unusual root prompt," + perror "try running with ROOT_PROMPT=\"regexp\"" + set timeout $old_timeout stop_root_shell return 0 } eof { - untested "$testname test requires ability to rlogin as root" - stop_root_shell - return 0 - } - -re "$ROOT_PROMPT" { } - timeout { - send_error "ERROR: timeout from rlogin $hostname -l root\n" - send_error "ERROR: If you have an unusual root prompt,\n" - send_error "ERROR: try running with ROOT_PROMPT=\"regexp\"\n" + perror "eof from rlogin $hostname -l root" stop_root_shell + set timeout $old_timeout + catch "expect_after" return 0 } } expect_after { timeout { - send_error "ERROR: timeout from rlogin $hostname -l root\n" + perror "timeout from rlogin $hostname -l root" stop_root_shell + set timeout $old_timeout catch "expect_after" return 0 } eof { - send_error "ERROR: eof from rlogin $hostname -l root\n" + perror "eof from rlogin $hostname -l root" stop_root_shell + set timeout $old_timeout catch "expect_after" return 0 } @@ -1308,7 +2302,7 @@ proc setup_root_shell { testname } { } # Set up our krb5.conf - send "KRB5_CONFIG=$tmppwd/krb5.conf\r" + send "KRB5_CONFIG=$tmppwd/krb5.server.conf\r" expect { -re "$ROOT_PROMPT" { } } @@ -1337,13 +2331,96 @@ proc setup_root_shell { testname } { expect { -re "$ROOT_PROMPT" { } "$dir:" { - send_error "ERROR: root shell can not cd to $dir\n" + perror "root shell can not cd to $dir" + set timeout $old_timeout stop_root_shell return 0 } } - restore_runtime_env + expect_after + set timeout $old_timeout + + return 1 +} + +proc setup_root_shell_noremote { testname } { + global BINSH + global ROOT_PROMPT + global KEY + global hostname + global rlogin_spawn_id + global rlogin_pid + global tmppwd + global env + global krb5_init_vars + + eval spawn $BINSH + set rlogin_spawn_id $spawn_id + set rlogin_pid [exp_pid] + + expect_after { + timeout { + perror "timeout from root shell" + stop_root_shell + catch "expect_after" + return 0 + } + eof { + perror "eof from root shell" + stop_root_shell + catch "expect_after" + return 0 + } + } + expect { + -re "$ROOT_PROMPT" { } + } + + # Set up a shell variable tmppwd. The callers use this to keep + # command line lengths down. The command line length is important + # because we are feeding input to a shell via a pty. On some + # systems a pty will only accept 255 characters. + send "tmppwd=$tmppwd\r" + expect { + -re "$ROOT_PROMPT" { } + } + + # Set up our krb5.conf + send "KRB5_CONFIG=$tmppwd/krb5.server.conf\r" + expect { + -re "$ROOT_PROMPT" { } + } + send "export KRB5_CONFIG\r" + expect { + -re "$ROOT_PROMPT" { } + } + + # For all of our runtime environment variables - send them over... + foreach i $krb5_init_vars { + regexp "^(\[^=\]*)=(.*)" $i foo evar evalue + send "$evar=$env($evar)\r" + expect { + -re "$ROOT_PROMPT" { } + } + + send "export $evar\r" + expect { + -re "$ROOT_PROMPT" { } + } + } + + # Move over to the right directory. + set dir [pwd] + send "cd $dir\r" + expect { + -re "$ROOT_PROMPT" { } + "$dir:" { + perror "root shell can not cd to $dir" + stop_root_shell + return 0 + } + } expect_after @@ -1377,8 +2454,7 @@ proc check_date { date } { scan $date "%s %s %d %d:%d:%d %s %d" adow amon adom ahr amn asc atz ayr scan $ndate "%s %s %d %d:%d:%d %s %d" ndow nmon ndom nhr nmn nsc ntz nyr if { $atz != $ntz } { - verbose "date check failed: $atz != $ntz" - send_log "date check failed: $atz != $ntz\n" + verbose -log "date check failed: $atz != $ntz" return 0 } return 1 @@ -1421,5 +2497,17 @@ proc setup_wrapper { file command } { return 1 } - +proc krb_exit { } { + stop_kerberos_daemons +} + +# helpful sometimes for debugging the test suite +proc spawn_xterm { } { + global env + foreach i {KDB5_UTIL KRB5KDC KADMIND KADMIN KADMIN_LOCAL KINIT KTUTIL KLIST} { + global $i + set env($i) [set $i] + } + exec "xterm" +} diff --git a/src/tests/dejagnu/krb-root/ChangeLog b/src/tests/dejagnu/krb-root/ChangeLog index 3744efd..81ec954 100644 --- a/src/tests/dejagnu/krb-root/ChangeLog +++ b/src/tests/dejagnu/krb-root/ChangeLog @@ -1,3 +1,9 @@ +Wed Jan 31 12:32:37 2001 Ezra Peisach <epeisach@mit.edu> + + * rlogin.exp: Use the build tree's version of krlogin instead of + using the one found in the users path that might have been used in the + root login. + Thu Nov 14 15:20:19 1996 Barry Jaspan <bjaspan@mit.edu> * telnet.exp: telnet may output fqdn in upper-case diff --git a/src/tests/dejagnu/krb-root/rlogin.exp b/src/tests/dejagnu/krb-root/rlogin.exp index 4e84970..ac39520 100644 --- a/src/tests/dejagnu/krb-root/rlogin.exp +++ b/src/tests/dejagnu/krb-root/rlogin.exp @@ -7,8 +7,8 @@ # if they exist. If they do not, then they must be in PATH. We # expect $objdir to be .../kerberos/src. -if ![info exists RLOGIN] { - set RLOGIN [findfile $objdir/../../appl/bsd/rlogin] +if ![info exists KRLOGIN] { + set KRLOGIN [findfile $objdir/../../appl/bsd/rlogin] } if ![info exists KRLOGIND] { @@ -119,7 +119,7 @@ proc stop_rlogin_daemon { } { proc rlogin_test { } { global REALMNAME - global RLOGIN + global KRLOGIN global BINSH global SHELL_PROMPT global KEY @@ -141,7 +141,7 @@ proc rlogin_test { } { start_rlogin_daemon -k # Make an rlogin connection. - spawn $RLOGIN $hostname -k $REALMNAME -D 3543 + spawn $KRLOGIN $hostname -k $REALMNAME -D 3543 expect_after { timeout { @@ -215,7 +215,7 @@ proc rlogin_test { } { # Try an encrypted connection. start_rlogin_daemon -e - spawn $RLOGIN $hostname -x -k $REALMNAME -D 3543 + spawn $KRLOGIN $hostname -x -k $REALMNAME -D 3543 expect_after { timeout { diff --git a/src/tests/dejagnu/krb-standalone/ChangeLog b/src/tests/dejagnu/krb-standalone/ChangeLog index 649fb43..e8b10f1 100644 --- a/src/tests/dejagnu/krb-standalone/ChangeLog +++ b/src/tests/dejagnu/krb-standalone/ChangeLog @@ -1,3 +1,207 @@ +2003-03-26 Tom Yu <tlyu@mit.edu> + + * v4gssftp.exp (v4ftp_test): Return early if $des3_krbtgt set. + + * v4krb524d.exp (doit): Return early if $des3_krbtgt set. + + * v4standalone.exp (check_and_destroy_v4_tix): Return early if + $des3_krbtgt set. + +2002-11-03 Tom Yu <tlyu@mit.edu> + + * rsh.exp (rsh_test): Explicitly call stop_rsh_daemon upon pass + for "encrypted rsh" test, to avoid zombies. + [pullup from trunk] + +2002-02-06 Ken Raeburn <raeburn@mit.edu> + + * standalone.exp (doit): Don't use "file delete", it isn't in Tcl + version 7. + +2002-02-05 Ken Raeburn <raeburn@mit.edu> + + * standalone.exp: Move setting of KLIST and KDESTROY into + default.exp. + (doit): Call do_klist instead of implementing it here. Add a new + principal to the database, and test getting tickets using a + keytab, with multiple kvnos starting at 253 and going up past + 256; if first supported enctype supports v4, convert the keytab to + a srvtab and try getting tickets using it too. Verify that + kadmin.local can read the high kvno correctly. + + * v4standalone.exp: Move setting of KLIST and KDESTROY into + default.exp. Print correct filename in top-level error message. + (check_and_destroy_v4_tix): New proc. + (doit): Call v4kinit and check_and_destroy_v4_tix. + + * gssftp.exp (ftp_test): Bump kvno past 256, with multiple entries + in the keytab, before running test. + +2001-11-06 Tom Yu <tlyu@mit.edu> + + * rsh.exp: Fix date-grabbing regexp to deal with older versions of + expect/tcl that have limited regexp capabilities. + +2001-11-02 Tom Yu <tlyu@mit.edu> + + * rsh.exp: Fix date grabbing code so we don't try to parse the + timezone-less date out of of a syslog message. expect eof in + places to drain pty buffers and avoid deadlock. + +2001-11-02 Tom Yu <tlyu@mit.edu> + + * gssftp.exp: Remove -U flag from ftpd invocation for now, since + 1.2.x won't have it. + +2001-11-02 Tom Yu <tlyu@mit.edu> + + * v4gssftp.exp: Calling send_error from within a dejagnu test is + wrong. So is calling exit. Fix to not do these things. Expect + eof rather than "\r" so as to drain pty buffers and avoid + deadlock. + +2001-11-02 Tom Yu <tlyu@mit.edu> + + * gssftp.exp: Calling send_error from within a dejagnu test is + wrong. So is calling exit. Fix to not do these things. Expect + eof rather than "\r" so as to drain pty buffers and avoid + deadlock. + +2001-10-30 Tom Yu <tlyu@mit.edu> + + * standalone.exp: Change check for missing ccache to look for "No + credentials cache found" instead of "No credentials cache file + found" due to change in message text. + + * v4gssftp.exp: Remove -U flag frmo ftpd invocation for now, since + 1.2.x won't have it. Change check for missing ccache to look for + "No credentials cache found" instead of "No credentials cache file + found" due to change in message text. + + * v4krb524d.exp: Remove -p flag from krb524d invocation for now, + since 1.2.x won't have it. + +2001-10-26 Ezra Peisach <epeisach@mit.edu> + + * rcp.exp, rsh_exp (stop_rsh_daemon): Do not close a process and + then look for eof. Some versions of expect go through a full + timeout in this scenario and others return immediately. New order: + kill process, expect eof, close, and then wait. + [pullup from trunk] + +2001-10-25 Ezra Peisach <epeisach@mit.edu> + + * rsh.exp (rsh_test): Add stop_rsh_daemon before invoking + start_rsh_daemon again to prevent running out of ptys. + [pullup from trunk] + +2001-10-24 Mitchell Berger <mitchb@mit.edu> + + * kadmin.exp: Corrected a couple of unimportant typos. Added procedures + kadmin_addpol, kadmin_delpol, kadmin_listpols, kadmin_modpol, and + kadmin_showpol, which provide the tools with which to perform policy + tests. Added some basic policy operations to the tests of basic + kadmin functions. Added a test case to exercise the kadmind crash + that used to occur when the history number of a policy was decreased. + [pullup from trunk] + +2001-10-24 Tom Yu <tlyu@mit.edu> + + * rcp.exp (stop_rsh_daemon): Call "expect eof" to drain pty buffer + and avoid deadlock. + + * rsh.exp (stop_rsh_daemon, rsh_test): Call "expect eof" to drain + pty buffer and avoid deadlock. + [pullups from trunk] + +2001-07-04 Ezra Peisach <epeisach@mit.edu> + + * v4gssftp.exp, gssftp.exp: Test transfering a file > 1MB to + exercise PBSZ failure. + [pullup from trunk] + +2001-06-22 Tom Yu <tlyu@mit.edu> + + * gssftp.exp: Use $tmppwd rather than hardcoding tmpdir. + + * kadmin.exp: Use $tmppwd rather than hardcoding tmpdir. + + * rcp.exp: Use $tmppwd rather than hardcoding tmpdir. + + * rsh.exp: Rearrange ordering of environment setup slightly. + + * standalone.exp: Use $KLIST -5 -e so as to better debug enctype + problems. + + * v4gssftp.exp: Do check_klogin as well as check_k5login. Use + $tmppwd rather than hardcoding tmpdir. + [pullups from trunk] + +2001-06-17 Ezra Peisach <epeisach@mit.edu> + + * v4krb524d.exp: New tests for the krb524d and k524init programs. + [pullup from trunk] + +2001-06-08 Ezra Peisach <epeisach@mit.edu> + + * v4gssftp.exp: During test, set KRB5CCNAME to a non-existant + cache. Restore at end to previous setting. This prevents failures + caused when the krb5 cache contains valid information - as in the + case of this test being run immediately after the gssftp.exp test. + [pullup from trunk] + +2001-06-08 Mitchell Berger <mitchb@mit.edu> + + * gssftp.exp: Invocation of ftpd changed to use -U /dev/null and + -a so that the test may successfully be run by root without failing + (i.e. root is granted ftp access) and without opening the running + ftpd to a password attack (i.e. authorization is required). + Check for successful login messages added. + + * v4gssftp.exp: Same changes. + [pullups from trunk] + +2001-06-06 Ezra Peisach <epeisach@mit.edu> + + * v4gssftp.exp: Allow for "decrypt integrity check failed" error + minor code from GSSAPI as well. + [pullup from trunk] + +2001-04-26 Tom Yu <tlyu@mit.edu> + + * v4gssftp.exp: Allow for "no credentials cache found" error minor + code from GSSAPI. + [pullup from trunk] + +2000-11-08 Tom Yu <tlyu@mit.edu> + + * v4gssftp.exp: Fix to handle some cases of krb4 failure prior to + timing out. + [pullup from trunk] + +Tue Aug 22 11:43:14 2000 Ezra Peisach <epeisach@mit.edu> + + * v4gssftp.exp: New tests for the krb4 compatible interface to gssftp. + [pullup from trunk] + +2000-08-08 Ezra Peisach <epeisach@engrailed.mit.edu> + + * v4standalone.exp: New set of tests for basic V4 functionality. + [pullup from trunk] + +2000-07-04 Tom Yu <tlyu@mit.edu> + + * rsh.exp: Drain buffers on klist test to avoid wedging rsh on + exit under HP/UX. + [pullup from trunk] + + * gssapi.exp: Rework significantly to deal with HP/UX lossage that + probably resulted from when either the client or the server wound + up blocking on tty output. Abstract things a little more. Remove + dead duplicate code that used to deal with "-v2". Should figure + out why the "-v2" stuff disappeared mysteriously. + [pullup from trunk] + 2000-02-07 Tom Yu <tlyu@mit.edu> * kadmin.exp: Use $KDESTROY -5 to deal with changed behavior. diff --git a/src/tests/dejagnu/krb-standalone/gssapi.exp b/src/tests/dejagnu/krb-standalone/gssapi.exp index 8f932cb..fa71728 100644 --- a/src/tests/dejagnu/krb-standalone/gssapi.exp +++ b/src/tests/dejagnu/krb-standalone/gssapi.exp @@ -113,6 +113,81 @@ proc gss_restore_env { } { } } +proc run_client {test tkfile client} { + global env + global hostname + global GSSCLIENT + global spawn_id + global gss_server_spawn_id + global REALMNAME + + set env(KRB5CCNAME) $tkfile + verbose "KRB5CCNAME=$env(KRB5CCNAME)" + verbose "spawning gssclient, identity=$client" + spawn $GSSCLIENT -port 5556 $hostname gssservice@$hostname "message from $client" + set got_client 0 + set got_server 0 + expect_after { + -i $spawn_id + timeout { + if {!$got_client} { + verbose -log "client timeout" + fail $test + catch "expect_after" + return + } + } + eof { + if {!$got_client} { + verbose -log "client eof" + fail $test + catch "expect_after" + return + } + } + -i $gss_server_spawn_id + timeout { + if {!$got_server} { + verbose -log "server timeout" + fail $test + catch "expect_after" + return + } + } + eof { + if {!$got_server} { + verbose -log "server eof" + fail $test + catch "expect_after" + return + } + } + } + expect { + -i $gss_server_spawn_id + "Accepted connection: \"$client@$REALMNAME\"" exp_continue + "Received message: \"message from $client\"" { + set got_server 1 + if {!$got_client} { + exp_continue + } + } + -i $spawn_id + "Signature verified" { + set got_client 1 + if {!$got_server} { + exp_continue + } + } + } + catch "expect_after" + if ![check_exit_status $test] { + # check_exit_staus already calls fail for us + return + } + pass $test +} + proc doit { } { global REALMNAME global env @@ -133,70 +208,59 @@ proc doit { } { # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 0] { - fail gsstest - return + perror "failed to start kerberos daemons" } # Use kadmin to add a key for us. if ![add_kerberos_key gsstest0 0] { - fail gsstest - return + perror "failed to set up gsstest0 key" } # Use kadmin to add a key for us. if ![add_kerberos_key gsstest1 0] { - fail gsstest - return + perror "failed to set up gsstest1 key" } # Use kadmin to add a key for us. if ![add_kerberos_key gsstest2 0] { - fail gsstest - return + perror "failed to set up gsstest2 key" } # Use kadmin to add a key for us. if ![add_kerberos_key gsstest3 0] { - fail gsstest - return + perror "faild to set up gsstest3 key" } # Use kadmin to add a service key for us. if ![add_random_key gssservice/$hostname 0] { - fail gsstest - return + perror "failed to set up gssservice/$hostname key" } # Use kdb5_edit to create a srvtab entry for gssservice if ![setup_srvtab 0 gssservice] { - fail gsstest - return + perror "failed to set up gssservice srvtab" } catch "exec rm -f $tmppwd/gss_tk_0 $tmppwd/gss_tk_1 $tmppwd/gss_tk_2 $tmppwd/gss_tk_3" # Use kinit to get a ticket. if ![our_kinit gsstest0 gsstest0$KEY $tmppwd/gss_tk_0] { - fail gsstest - return + perror "failed to kinit gsstest0" } # Use kinit to get a ticket. if ![our_kinit gsstest1 gsstest1$KEY $tmppwd/gss_tk_1] { - fail gsstest - return + perror "failed to kinit gsstest1" } # Use kinit to get a ticket. if ![our_kinit gsstest2 gsstest2$KEY $tmppwd/gss_tk_2] { - fail gsstest - return + perror "failed to kinit gsstest2" } # Use kinit to get a ticket. if ![our_kinit gsstest3 gsstest3$KEY $tmppwd/gss_tk_3] { - fail gsstest - return + perror "failed to kinit gsstest3" } # @@ -219,377 +283,30 @@ proc doit { } { spawn $GSSSERVER -port 5556 gssservice@$hostname set gss_server_pid [exp_pid] set gss_server_spawn_id $spawn_id - catch "exec sleep 4" - - # Start the client with client identity 0 - set env(KRB5CCNAME) $tmppwd/gss_tk_0 - verbose "KRB5CCNAME=$env(KRB5CCNAME)" - spawn $GSSCLIENT -port 5556 $hostname gssservice@$hostname "message from gsstest0" - expect_after { - -i $spawn_id - timeout { - fail gssclient0 - catch "expect_after" - return - } - eof { - fail gssclient0 - catch "expect_after" - return - } - } - expect -i $spawn_id "Signature verified" - catch "expect_after" - expect_after { - -i $gss_server_spawn_id - timeout { - fail gssclient0 - catch "expect_after" - return - } - eof { - fail gssclient0 - catch "expect_after" - return - } - } - expect -i $gss_server_spawn_id "Accepted connection: \"gsstest0@$REALMNAME\"" - expect -i $gss_server_spawn_id "Received message: \"message from gsstest0\"" - catch "expect_after" - if ![check_exit_status gssclient0] { - fail gssclient0 - return - } - pass gssclient0 - - # Start the client with client identity 1 - set env(KRB5CCNAME) $tmppwd/gss_tk_1 - verbose "KRB5CCNAME=$env(KRB5CCNAME)" - spawn $GSSCLIENT -port 5556 $hostname gssservice@$hostname "message from gsstest1" - expect_after { - -i $spawn_id - timeout { - fail gssclient1 - catch "expect_after" - return - } - eof { - fail gssclient1 - catch "expect_after" - return - } - } - expect -i $spawn_id "Signature verified" - catch "expect_after" - expect_after { - -i $gss_server_spawn_id - timeout { - fail gssclient1 - catch "expect_after" - return - } - eof { - fail gssclient1 - catch "expect_after" - return - } - } - expect -i $gss_server_spawn_id "Accepted connection: \"gsstest1@$REALMNAME\"" - expect -i $gss_server_spawn_id "Received message: \"message from gsstest1\"" - catch "expect_after" - if ![check_exit_status gssclient1] { - fail gssclient1 - return - } - pass gssclient1 - - # Start the client with client identity 2 - set env(KRB5CCNAME) $tmppwd/gss_tk_2 - verbose "KRB5CCNAME=$env(KRB5CCNAME)" - spawn $GSSCLIENT -port 5556 $hostname gssservice@$hostname "message from gsstest2" - expect_after { - -i $spawn_id - timeout { - fail gssclient2 - catch "expect_after" - return - } - eof { - fail gssclient2 - catch "expect_after" - return - } - } - expect -i $spawn_id "Signature verified" - catch "expect_after" - expect_after { - -i $gss_server_spawn_id - timeout { - fail gssclient2 - catch "expect_after" - return - } - eof { - fail gssclient2 - catch "expect_after" - return - } - } - expect -i $gss_server_spawn_id "Accepted connection: \"gsstest2@$REALMNAME\"" - expect -i $gss_server_spawn_id "Received message: \"message from gsstest2\"" - catch "expect_after" - if ![check_exit_status gssclient2] { - fail gssclient2 - return - } - pass gssclient2 - - # Start the client with client identity 3 - set env(KRB5CCNAME) $tmppwd/gss_tk_3 - verbose "KRB5CCNAME=$env(KRB5CCNAME)" - spawn $GSSCLIENT -port 5556 $hostname gssservice@$hostname "message from gsstest3" - expect_after { - -i $gss_server_spawn_id - timeout { - fail "gssclient3 (server timeout)" - catch "expect_after" - return - } - eof { - fail "gssclient3 (server eof)" - catch "expect_after" - return - } - } - expect -i $gss_server_spawn_id "Accepted connection: \"gsstest3@$REALMNAME\"" - # Drain some output from the verbose client side. Otherwise, this - # test sometimes fails under HP-UX. - expect -i $spawn_id "\"gsstest3@KRBTEST.COM\" to \"gssservice" - expect -i $spawn_id "Mechanism { * } supports * name" - - expect -i $gss_server_spawn_id "Received message: \"message from gsstest3\"" - catch "expect_after" - expect_after { - -i $spawn_id - timeout { - fail "gssclient3 (timeout)" - catch "expect_after" - return - } - eof { - fail "gssclient3 (eof)" - catch "expect_after" - return - } - } - expect -i $spawn_id "Signature verified" - catch "expect_after" - if ![check_exit_status gssclient3] { - fail "gssclient3 (exit status)" - return - } - pass gssclient3 - - stop_gss_server - - # Try some V2 services. - # Now start the gss-server. - spawn $GSSSERVER -port 5557 gssservice@$hostname - set gss_server_pid [exp_pid] - set gss_server_spawn_id $spawn_id - catch "exec sleep 4" + sleep 2 - # Start the client with client identity 0 - set env(KRB5CCNAME) $tmppwd/gss_tk_0 - verbose "KRB5CCNAME=$env(KRB5CCNAME)" - spawn $GSSCLIENT -port 5557 $hostname gssservice@$hostname "message from gsstest0" - expect_after { - -i $spawn_id - timeout { - fail gssclient0 - catch "expect_after" - return - } - eof { - fail gssclient0 - catch "expect_after" - return - } - } - expect -i $spawn_id "Signature verified" - catch "expect_after" - expect_after { - -i $gss_server_spawn_id - timeout { - fail gssclient0 - catch "expect_after" - return - } - eof { - fail gssclient0 - catch "expect_after" - return - } - } - expect -i $gss_server_spawn_id "Accepted connection: \"gsstest0@$REALMNAME\"" - expect -i $gss_server_spawn_id "Received message: \"message from gsstest0\"" - catch "expect_after" - if ![check_exit_status gssclient0] { - fail gssclient0 - return - } - pass gssclient0 - - # Start the client with client identity 1 - set env(KRB5CCNAME) $tmppwd/gss_tk_1 - verbose "KRB5CCNAME=$env(KRB5CCNAME)" - spawn $GSSCLIENT -port 5557 $hostname gssservice@$hostname "message from gsstest1" - expect_after { - -i $spawn_id - timeout { - fail gssclient1 - catch "expect_after" - return - } - eof { - fail gssclient1 - catch "expect_after" - return - } - } - expect -i $spawn_id "Signature verified" - catch "expect_after" - expect_after { - -i $gss_server_spawn_id - timeout { - fail gssclient1 - catch "expect_after" - return - } - eof { - fail gssclient1 - catch "expect_after" - return - } - } - expect -i $gss_server_spawn_id "Accepted connection: \"gsstest1@$REALMNAME\"" - expect -i $gss_server_spawn_id "Received message: \"message from gsstest1\"" - catch "expect_after" - if ![check_exit_status gssclient1] { - fail gssclient1 - return - } - pass gssclient1 - - # Start the client with client identity 2 - set env(KRB5CCNAME) $tmppwd/gss_tk_2 - verbose "KRB5CCNAME=$env(KRB5CCNAME)" - spawn $GSSCLIENT -port 5557 $hostname gssservice@$hostname "message from gsstest2" - expect_after { - -i $spawn_id - timeout { - fail gssclient2 - catch "expect_after" - return - } - eof { - fail gssclient2 - catch "expect_after" - return - } - } - expect -i $spawn_id "Signature verified" - catch "expect_after" - expect_after { - -i $gss_server_spawn_id - timeout { - fail gssclient2 - catch "expect_after" - return - } - eof { - fail gssclient2 - catch "expect_after" - return - } - } - expect -i $gss_server_spawn_id "Accepted connection: \"gsstest2@$REALMNAME\"" - expect -i $gss_server_spawn_id "Received message: \"message from gsstest2\"" - catch "expect_after" - if ![check_exit_status gssclient2] { - fail gssclient2 - return - } - pass gssclient2 - - # Start the client with client identity 3 - set env(KRB5CCNAME) $tmppwd/gss_tk_3 - verbose "KRB5CCNAME=$env(KRB5CCNAME)" - spawn $GSSCLIENT -port 5557 $hostname gssservice@$hostname "message from gsstest3" - expect_after { - -i $gss_server_spawn_id - timeout { - fail gssclient3 - catch "expect_after" - return - } - eof { - fail gssclient3 - catch "expect_after" - return - } - } - expect -i $gss_server_spawn_id "Accepted connection: \"gsstest3@$REALMNAME\"" - - # Drain some output from the verbose client side. Otherwise, this - # test sometimes fails under HP-UX. - expect -i $spawn_id "\"gsstest3@KRBTEST.COM\" to \"gssservice" - expect -i $spawn_id "Mechanism { * } supports * name" - - expect -i $gss_server_spawn_id "Received message: \"message from gsstest3\"" - catch "expect_after" - expect_after { - -i $spawn_id - timeout { - fail gssclient3 - catch "expect_after" - return - } - eof { - fail gssclient3 - catch "expect_after" - return - } - } - expect -i $spawn_id "Signature verified" - catch "expect_after" - if ![check_exit_status gssclient3] { - fail gssclient3 - return - } - pass gssclient3 + run_client gssclient0 $tmppwd/gss_tk_0 gssclient0 + run_client gssclient1 $tmppwd/gss_tk_1 gssclient1 + run_client gssclient2 $tmppwd/gss_tk_2 gssclient2 + run_client gssclient3 $tmppwd/gss_tk_3 gssclient3 stop_gss_server gss_restore_env if ![our_kdestroy $tmppwd/gss_tk_0] { - fail gsstest - return + perror "failed kdestroy gss_tk_0" 0 } if ![our_kdestroy $tmppwd/gss_tk_1] { - fail gsstest - return + perror "failed kdestroy gss_tk_1" 0 } if ![our_kdestroy $tmppwd/gss_tk_2] { - fail gsstest - return + perror "failed kdestroy gss_tk_2" 0 } if ![our_kdestroy $tmppwd/gss_tk_3] { - fail gsstest - return + perror "failed kdestroy gss_tk_3" 0 } catch "exec rm -f $tmppwd/gss_tk_0 $tmppwd/gss_tk_1 $tmppwd/gss_tk_2 $tmppwd/gss_tk_3" @@ -604,7 +321,6 @@ gss_restore_env stop_kerberos_daemons if { $status != 0 } { - send_error "ERROR: error in gssapi.exp\n" - send_error "$msg\n" - exit 1 + perror "error in gssapi.exp" 0 + perror $msg 0 } diff --git a/src/tests/dejagnu/krb-standalone/gssftp.exp b/src/tests/dejagnu/krb-standalone/gssftp.exp index 2dea3a5..bda1d12 100644 --- a/src/tests/dejagnu/krb-standalone/gssftp.exp +++ b/src/tests/dejagnu/krb-standalone/gssftp.exp @@ -41,7 +41,9 @@ proc start_ftp_daemon { } { # don't need to use inetd. The 3021 is the port to listen at. # We rely on KRB5_KTNAME being set to the proper keyfile as there is # no way to cleanly set it with the gssapi API. - spawn $FTPD -p 3021 -r $tmppwd/krb5.conf + # The -a argument requires authorization, to mitigate any + # vulnerability introduced by circumventing ftpusers. + spawn $FTPD -p 3021 -a -r $tmppwd/krb5.conf set ftpd_spawn_id $spawn_id set ftpd_pid [exp_pid] @@ -64,12 +66,21 @@ proc stop_ftp_daemon { } { } # Create a file to use for ftp testing. -set file [open tmpdir/ftp-test w] +set file [open $tmppwd/ftp-test w] puts $file "This file is used for ftp testing." close $file +# Create a large file to use for ftp testing. File needs to be +# larger that 2^20 or 1MB for PBSZ testing. +set file [open $tmppwd/bigftp-test w] +puts $file "This file is used for ftp testing.\n" +seek $file 1048576 current +puts $file "This file is used for ftp testing." +close $file + + # Test that a file was copied correctly. -proc check_file { filename } { +proc check_file { filename {bigfile 0}} { if ![file exists $filename] { verbose "$filename does not exist" send_log "$filename does not exist\n" @@ -91,6 +102,24 @@ proc check_file { filename } { return 0 } + if {$bigfile} { + # + 1 for the newline + seek $file 1048577 current + if { [gets $file line] == -1 } { + verbose "$filename is truncated" + send_log "$filename is truncated\n" + close $file + return 0 + } + + if ![string match "This file is used for ftp testing." $line] { + verbose "$filename contains $line" + send_log "$filename contains $line\n" + close $file + return 0 + } + } + if { [gets $file line] != -1} { verbose "$filename is too long ($line)" send_log "$filename is too long ($line)\n" @@ -123,6 +152,7 @@ proc ftp_restore_env { } { proc ftp_test { } { global FTP global KEY + global REALMNAME global hostname global localhostname global env @@ -136,7 +166,12 @@ proc ftp_test { } { # ticket file. if {![start_kerberos_daemons 0] \ || ![add_random_key ftp/$hostname 0] \ + || ![modify_principal ftp/$hostname -kvno 254] \ || ![setup_srvtab 0 ftp] \ + || ![xst $tmppwd/srvtab ftp/$hostname] + || ![xst $tmppwd/srvtab ftp/$hostname] + || ![xst $tmppwd/srvtab ftp/$hostname] + || ![do_klist_kt $tmppwd/srvtab "gssftp keytab list"] || ![add_kerberos_key $env(USER) 0] \ || ![kinit $env(USER) $env(USER)$KEY 0]} { return @@ -185,9 +220,9 @@ proc ftp_test { } { } expect -nocase "name ($hostname:$env(USER)): " send "$env(USER)\r" -# expect "User $env(USER) logged in." -# expect "Remote system type is UNIX." -# expect "Using binary mode to transfer files." + expect "GSSAPI user $env(USER)@$REALMNAME is authorized as $env(USER)" + expect "Remote system type is UNIX." + expect "Using binary mode to transfer files." expect "ftp> " { pass $testname } @@ -236,26 +271,26 @@ proc ftp_test { } { set testname "get" - catch "exec rm -f tmpdir/copy" + catch "exec rm -f $tmppwd/copy" send "get $tmppwd/ftp-test $tmppwd/copy\r" expect "Opening BINARY mode data connection for $tmppwd/ftp-test" expect "Transfer complete" expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds" expect "ftp> " - if [check_file tmpdir/copy] { + if [check_file $tmppwd/copy] { pass $testname } else { fail $testname } set testname "put" - catch "exec rm -f tmpdir/copy" + catch "exec rm -f $tmppwd/copy" send "put $tmppwd/ftp-test $tmppwd/copy\r" expect "Opening BINARY mode data connection for $tmppwd/copy" expect "Transfer complete" expect -re "\[0-9\]+ bytes sent in \[0-9.e-\]+ seconds" expect "ftp> " - if [check_file tmpdir/copy] { + if [check_file $tmppwd/copy] { pass $testname } else { fail $testname @@ -269,20 +304,33 @@ proc ftp_test { } { } set testname "lcd" - send "lcd tmpdir\r" + send "lcd $tmppwd\r" expect "Local directory now $tmppwd" expect "ftp> " { pass $testname } set testname "local get" - catch "exec rm -f tmpdir/copy" + catch "exec rm -f $tmppwd/copy" send "get ftp-test copy\r" expect "Opening BINARY mode data connection for ftp-test" expect "Transfer complete" expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds" expect "ftp> " - if [check_file tmpdir/copy] { + if [check_file $tmppwd/copy] { + pass $testname + } else { + fail $testname + } + + set testname "big local get" + catch "exec rm -f $tmppwd/copy" + send "get bigftp-test copy\r" + expect "Opening BINARY mode data connection for bigftp-test" + expect "Transfer complete" + expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds" + expect "ftp> " + if [check_file $tmppwd/copy 1] { pass $testname } else { fail $testname @@ -303,18 +351,38 @@ proc ftp_test { } { } set testname "encrypted get" - catch "exec rm -f tmpdir/copy" + catch "exec rm -f $tmppwd/copy" send "get ftp-test copy\r" expect "Opening BINARY mode data connection for ftp-test" expect "Transfer complete" expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds" expect "ftp> " - if [check_file tmpdir/copy] { + if [check_file $tmppwd/copy] { pass $testname } else { fail $testname } + set testname "big encrypted get" + catch "exec rm -f $tmppwd/copy" + send "get bigftp-test copy\r" + expect "Opening BINARY mode data connection for bigftp-test" + expect { + -timeout 300 + "Transfer complete" {} + -re "Length .* of PROT buffer > PBSZ" { + fail "$testname (PBSZ)" + return 0 + } + } + expect -re "\[0-9\]+ bytes received in \[0-9.e+-\]+ seconds" + expect "ftp> " + if [check_file $tmppwd/copy 1] { + pass $testname + } else { + fail $testname + } + set testname "close" send "close\r" expect "Goodbye." @@ -333,7 +401,8 @@ proc ftp_test { } { set testname "quit" send "quit\r" - expect "\r" + expect_after + expect eof if [check_exit_status $testname] { pass $testname } @@ -371,7 +440,5 @@ if [info exists home] { } if { $status != 0 } { - send_error "ERROR: error in ftp.exp\n" - send_error "$msg\n" - exit 1 + perror "error in gssftp.exp: $msg" } diff --git a/src/tests/dejagnu/krb-standalone/kadmin.exp b/src/tests/dejagnu/krb-standalone/kadmin.exp index 8167b02..d4754e4 100644 --- a/src/tests/dejagnu/krb-standalone/kadmin.exp +++ b/src/tests/dejagnu/krb-standalone/kadmin.exp @@ -37,7 +37,7 @@ proc kadmin_add { pname password } { spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank $pname" expect_after { "Cannot contact any KDC" { - fail "kadmin add$pname lost KDC" + fail "kadmin add $pname lost KDC" catch "expect_after" return 0 } @@ -162,7 +162,7 @@ proc kadmin_add_rnd { pname } { expect_after expect eof set k_stat [wait -i $spawn_id] - verbose "wait -i $spawn_id returned $k_stat (kadmin add_rnt)" + verbose "wait -i $spawn_id returned $k_stat (kadmin add_rnd)" catch "close -i $spawn_id" if { $good == 1 } { # @@ -437,10 +437,11 @@ proc kadmin_extract { instance name } { global KADMIN global KEY global spawn_id + global tmppwd - catch "exec rm -f tmpdir/keytab" + catch "exec rm -f $tmppwd/keytab" - spawn $KADMIN -p krbtest/admin@$REALMNAME -q "xst -k tmpdir/keytab $name/$instance" + spawn $KADMIN -p krbtest/admin@$REALMNAME -q "xst -k $tmppwd/keytab $name/$instance" expect_after { "Cannot contact any KDC" { fail "kadmin xst $instance $name lost KDC" @@ -461,7 +462,7 @@ proc kadmin_extract { instance name } { expect "Enter password:" { send "adminpass$KEY\r" } -# expect -re "kadmin: Entry for principal $name/$instance with kvno [0-9], encryption type .* added to keytab WRFILE:tmpdir/keytab." +# expect -re "kadmin: Entry for principal $name/$instance with kvno [0-9], encryption type .* added to keytab WRFILE:$tmppwd/keytab." expect_after expect eof set k_stat [wait -i $spawn_id] @@ -644,6 +645,292 @@ proc kpasswd_cpw { princ opw npw } { } #++ +# kadmin_addpol - Test add new policy function of kadmin. +# +# Adds policy $pname. Returns 1 on success. +#-- +proc kadmin_addpol { pname } { + global REALMNAME + global KADMIN + global KADMIN_LOCAL + global KEY + global spawn_id + global tmppwd + + set good 0 + spawn $KADMIN -p krbtest/admin@$REALMNAME -q "addpol $pname" + expect_after { + "Cannot contact any KDC" { + fail "kadmin addpol $pname lost KDC" + catch "expect_after" + return 0 + } + timeout { + fail "kadmin addpol $pname" + catch "expect_after" + return 0 + } + eof { + fail "kadmin addpol $pname" + catch "expect_after" + return 0 + } + } + expect "Enter password:" { + send "adminpass$KEY\r" + } + expect_after + expect eof + set k_stat [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $k_stat (kadmin addpol)" + catch "close -i $spawn_id" + # + # use kadmin.local to verify that a policy was created + # + spawn $KADMIN_LOCAL -r $REALMNAME + expect_after { + -i $spawn_id + timeout { + fail "kadmin addpol $pname" + catch "expect_after" + return 0 + } + eof { + fail "kadmin addpol $pname" + catch "expect_after" + return 0 + } + } + set good 0 + expect "kadmin.local: " { send "getpol $pname\r" } + expect "Policy: $pname" { set good 1 } + expect "Maximum password life:" { verbose "got max pw life" } + expect "Minimum password life:" { verbose "got min pw life" } + expect "Minimum password length:" { verbose "got min pw length" } + expect "Minimum number of password character classes:" { + verbose "got min pw character classes" } + expect "Number of old keys kept:" { verbose "got num old keys kept" } + expect "Reference count:" { verbose "got refcount" } + expect "kadmin.local: " { send "q\r" } + + expect_after + expect eof + set k_stat [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $k_stat (kadmin.local showpol)" + catch "close -i $spawn_id" + if { $good == 1 } { + pass "kadmin addpol $pname" + return 1 + } + else { + fail "kadmin addpol $pname" + return 0 + } +} + +#++ +# kadmin_delpol - Test delete policy function of kadmin. +# +# Deletes policy $pname. Returns 1 on success. +#-- +proc kadmin_delpol { pname } { + global REALMNAME + global KADMIN + global KADMIN_LOCAL + global KEY + global spawn_id + global tmppwd + + spawn $KADMIN -p krbtest/admin@$REALMNAME -q "delpol -force $pname" + expect_after { + "Cannot contact any KDC" { + fail "kadmin_delpol $pname lost KDC" + catch "expect_after" + return 0 + } + timeout { + fail "kadmin delpol $pname" + catch "expect_after" + return 0 + } + eof { + fail "kadmin delpol $pname" + catch "expect_after" + return 0 + } + } + expect "Enter password:" { + send "adminpass$KEY\r" + } + expect_after + expect eof + set k_stat [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $k_stat (kadmin delpol)" + catch "close -i $spawn_id" + # + # use kadmin.local to verify that the old policy is not present. + # + spawn $KADMIN_LOCAL -r $REALMNAME + expect_after { + -i $spawn_id + timeout { + fail "kadmin delpol $pname" + catch "expect_after" + return 0 + } + eof { + fail "kadmin delpol $pname" + catch "expect_after" + return 0 + } + } + set good 0 + expect "kadmin.local: " { send "getpol $pname\r" } + expect "Policy does not exist while retrieving policy \"$pname\"." { + set good 1 + } + expect "kadmin.local: " { send "quit\r" } + expect_after + expect eof + set k_stat [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $k_stat (kadmin.local showpol)" + catch "close -i $spawn_id" + if { $good == 1 } { + pass "kadmin delpol $pname" + return 1 + } + else { + fail "kadmin delpol $pname" + return 0 + } +} + +#++ +# kadmin_listpols - Test list policy database function of kadmin. +# +# Lists the policies. Returns 1 on success. +#-- +proc kadmin_listpols { } { + global REALMNAME + global KADMIN + global KEY + global spawn_id + + spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_policies *" + expect_after { + "Cannot contact any KDC" { + fail "kadmin lpols lost KDC" + catch "expect_after" + return 0 + } + timeout { + fail "kadmin lpols" + catch "expect_after" + return 0 + } + eof { + fail "kadmin lpols" + catch "expect_after" + return 0 + } + } + expect "Enter password:" { + send "adminpass$KEY\r" + } + expect_after + expect eof + set k_stat [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $k_stat (kadmin listpols)" + catch "close -i $spawn_id" + pass "kadmin lpols" + return 1 +} + +#++ +# kadmin_modpol - Test modify policy function of kadmin. +# +# Modifies policy $pname with flags $flags. Returns 1 on success. +#-- +proc kadmin_modpol { pname flags } { + global REALMNAME + global KADMIN + global KEY + global spawn_id + + spawn $KADMIN -p krbtest/admin@$REALMNAME -q "modpol $flags $pname" + expect_after { + "Cannot contact any KDC" { + fail "kadmin modpol $pname ($flags) lost KDC" + catch "expect_after" + return 0 + } + timeout { + fail "kadmin modpol $pname" + catch "expect_after" + return 0 + } + eof { + fail "kadmin modpol $pname" + catch "expect_after" + return 0 + } + } + expect "Enter password:" + send "adminpass$KEY\r" + # When in doubt, jam one of these in there. + expect "\r" + # Sadly, kadmin doesn't print a confirmation message for policy operations. + expect_after + expect eof + set k_stat [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $k_stat (kadmin modpol)" + catch "close -i $spawn_id" + pass "kadmin modpol $pname" + return 1 +} + +#++ +# kadmin_showpol - Test show policy function of kadmin. +# +# Retrieves entry for $pname. Returns 1 on success. +#-- +proc kadmin_showpol { pname } { + global REALMNAME + global KADMIN + global KEY + global spawn_id + + spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_policy $pname" + expect_after { + "Cannot contact any KDC" { + fail "kadmin showpol $pname lost KDC" + catch "expect_after" + return 0 + } + timeout { + fail "kadmin showpol $pname" + catch "expect_after" + return 0 + } + eof { + fail "kadmin showpol $pname" + catch "expect_after" + return 0 + } + } + expect "Enter password:" + send "adminpass$KEY\r" + expect -re "\r.*Policy: $pname.*Number of old keys kept: .*Reference count: .*\r" + expect_after + expect eof + set k_stat [wait -i $spawn_id] + verbose "wait -i $spawn_id returned $k_stat (kadmin showpol)" + catch "close -i $spawn_id" + pass "kadmin showpol $pname" + return 1 +} + +#++ # kdestroy #-- proc kdestroy { } { @@ -668,6 +955,10 @@ proc kadmin_test { } { # Test basic kadmin functions. if {![kadmin_add v5principal/instance1 v5principal] \ + || ![kadmin_addpol standardpol] \ + || ![kadmin_showpol standardpol] \ + || ![kadmin_listpols] \ + || ![kadmin_modpol standardpol "-minlength 5"] \ || ![kadmin_add v4principal/instance2 v4principal] \ || ![kadmin_add_rnd v5random] \ || ![kadmin_show v5principal/instance1] \ @@ -678,11 +969,13 @@ proc kadmin_test { } { || ![kadmin_cpw_rnd v5random] \ || ![kadmin_modify v5random -allow_tix] \ || ![kadmin_modify v5random +allow_tix] \ + || ![kadmin_modify v5random "-policy standardpol"] \ || ![kadmin_list] \ || ![kadmin_extract instance1 v5principal] \ || ![kadmin_delete v5random] \ || ![kadmin_delete v4principal/instance2] \ - || ![kadmin_delete v5principal/instance1]} { + || ![kadmin_delete v5principal/instance1] \ + || ![kadmin_delpol standardpol]} { return } @@ -713,9 +1006,10 @@ proc kadmin_test { } { || ![kadmin_delete testprinc1/instance]} { return } + # now test modify changes. if {![kadmin_add testuser longtestpw] \ - || ![kinit testuser longtestpw 0] \ + || ![kinit testuser longtestpw 0] \ || ![kdestroy] \ || ![kadmin_modify testuser "-maxlife \"2500 seconds\""] \ || ![kinit testuser longtestpw 0] \ @@ -724,6 +1018,21 @@ proc kadmin_test { } { return } + # now test that reducing the history number doesn't make kadmind vulnerable. + if {![kadmin_addpol crashpol] \ + || ![kadmin_modpol crashpol "-history 5"] \ + || ![kadmin_add crash first] \ + || ![kadmin_modify crash "-policy crashpol"] \ + || ![kadmin_cpw crash second] \ + || ![kadmin_cpw crash third] \ + || ![kadmin_cpw crash fourth] \ + || ![kadmin_modpol crashpol "-history 3"] \ + || ![kadmin_cpw crash fifth] \ + || ![kadmin_delete crash] \ + || ![kadmin_delpol crashpol]} { + return + } + verbose "kadmin_test succeeded" } diff --git a/src/tests/dejagnu/krb-standalone/rcp.exp b/src/tests/dejagnu/krb-standalone/rcp.exp index a51196c..3367b3a 100644 --- a/src/tests/dejagnu/krb-standalone/rcp.exp +++ b/src/tests/dejagnu/krb-standalone/rcp.exp @@ -72,15 +72,16 @@ proc stop_rsh_daemon { } { global krshd_pid if [info exists krshd_pid] { - catch "close -i $krshd_spawn_id" 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 } } # Create a file to use for rcp testing. -set file [open tmpdir/rcp-test w] +set file [open $tmppwd/rcp-test w] puts $file "This file is used for rcp testing." close $file @@ -125,9 +126,9 @@ proc rcp_one_test { testname options frompref topref } { global RCP global tmppwd - send_log "rm -f tmpdir/copy\n" - verbose "exec rm -f tmpdir/copy" - catch "exec rm -f tmpdir/copy" + send_log "rm -f $tmppwd/copy\n" + verbose "exec rm -f $tmppwd/copy" + catch "exec rm -f $tmppwd/copy" set from [format "%s%s" $frompref $tmppwd/rcp-test] set to [format "%s%s" $topref $tmppwd/copy] @@ -143,7 +144,7 @@ proc rcp_one_test { testname options frompref topref } { return 0 } - if ![check_file tmpdir/copy] { + if ![check_file $tmppwd/copy] { fail $testname return 0 } diff --git a/src/tests/dejagnu/krb-standalone/rsh.exp b/src/tests/dejagnu/krb-standalone/rsh.exp index 09b5222..2cd6802 100644 --- a/src/tests/dejagnu/krb-standalone/rsh.exp +++ b/src/tests/dejagnu/krb-standalone/rsh.exp @@ -27,7 +27,6 @@ if ![check_k5login rsh] { # Set up the kerberos database. if {![get_hostname] \ || ![setup_kerberos_files] \ - || ![setup_kerberos_env] \ || ![setup_kerberos_db 0]} { return } @@ -58,8 +57,9 @@ proc stop_rsh_daemon { } { global krshd_pid if [info exists krshd_pid] { - catch "close -i $krshd_spawn_id" 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 } @@ -85,6 +85,7 @@ proc rsh_test { } { || ![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 } @@ -96,7 +97,7 @@ proc rsh_test { } { set testname "date" spawn $RSH $hostname -k $REALMNAME -D 3544 -A date expect { - -re "\[A-Za-z0-9 :\]+\[\r\n\]+$" { + -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 { @@ -129,7 +130,7 @@ proc rsh_test { } { set testname "encrypted rsh" spawn $RSH $hostname -x -k $REALMNAME -D 3544 -A echo hello expect { - "hello" { } + "hello" { expect eof } timeout { fail "$testname (timeout)" set failed yes @@ -140,11 +141,13 @@ proc rsh_test { } { } } + 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" @@ -162,7 +165,9 @@ proc rsh_test { } { spawn $RSH $hostname -f -k $REALMNAME -D 3544 -A $BINSH -c $tmppwd/klist.wrap expect { - "Ticket cache:" { } + "Ticket cache:*\r" { + expect eof + } "klist: No credentials cache file found" { fail "$testname (not forwarded)" return @@ -191,7 +196,9 @@ proc rsh_test { } { set testname "encrypted rsh forwarding tickets" spawn $RSH $hostname -x -f -k $REALMNAME -D 3544 -A $BINSH -c $tmppwd/klist.wrap expect { - "Ticket cache:" { } + "Ticket cache:*\r" { + expect eof + } "klist: No credentials cache file found" { fail "$testname (not forwarded)" return @@ -214,13 +221,12 @@ proc rsh_test { } { 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" { } + "hello" { expect eof } timeout { fail "$testname (timeout)" return @@ -237,11 +243,13 @@ proc rsh_test { } { 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" { } + "hello" { expect eof } timeout { fail "$testname (timeout)" return diff --git a/src/tests/dejagnu/krb-standalone/standalone.exp b/src/tests/dejagnu/krb-standalone/standalone.exp index e925b53..e493b65 100644 --- a/src/tests/dejagnu/krb-standalone/standalone.exp +++ b/src/tests/dejagnu/krb-standalone/standalone.exp @@ -4,14 +4,6 @@ # This mostly just calls procedures in testsuite/config/default.exp. -if ![info exists KLIST] { - set KLIST [findfile $objdir/../../clients/klist/klist] -} - -if ![info exists KDESTROY] { - set KDESTROY [findfile $objdir/../../clients/kdestroy/kdestroy] -} - # Set up the Kerberos files and environment. if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { return @@ -32,9 +24,12 @@ proc doit { } { global KLIST global KDESTROY global KEY + global KADMIN_LOCAL + global KTUTIL global hostname global tmppwd global spawn_id + global supported_enctypes # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 1] { @@ -57,30 +52,9 @@ proc doit { } { } # Make sure that klist can see the ticket. - spawn $KLIST -5 - expect { - -re "Ticket cache:\[ \]*(.+:)?$tmppwd/tkt.*Default principal:\[ \]*krbtest/admin@$REALMNAME.*krbtgt/$REALMNAME@$REALMNAME\r\n" { - verbose "klist started" - } - timeout { - fail "klist" - return - } - eof { - fail "klist" - return - } - } - - expect { - "\r" { } - eof { } - } - - if ![check_exit_status "klist"] { + if ![do_klist "krbtest/admin@$REALMNAME" "krbtgt/$REALMNAME@$REALMNAME" "klist"] { return } - pass "klist" # Destroy the ticket. spawn $KDESTROY -5 @@ -90,33 +64,83 @@ proc doit { } { pass "kdestroy" # Double check that the ticket was destroyed. - spawn $KLIST -5 - expect { - -re "klist: No credentials cache file found.*\r\n" { - verbose "klist started" - } - timeout { - fail "klist after kdestroy" - return + if ![do_klist_err "klist after destroy"] { return } + + if ![add_random_key foo/bar 1] { + return + } + + set keytab $tmppwd/fookeytab + catch "exec rm -f $keytab" + + modify_principal foo/bar -kvno 252 + foreach vno {253 254 255 256 257 258} { + xst $tmppwd/fookeytab foo/bar + do_klist_kt $tmppwd/fookeytab "klist keytab foo/bar vno $vno" + kinit_kt "foo/bar" $tmppwd/fookeytab 1 "kt kvno $vno" + do_klist "foo/bar" "krbtgt/$REALMNAME@$REALMNAME" "klist kt foo/bar vno $vno" + do_kdestroy "kdestroy foo/bar vno $vno" + + if [regexp {des-cbc-[a-z0-9-]*:v4} [lindex $supported_enctypes 0]] { + catch "exec rm -f $tmppwd/foosrvtab" + spawn $KTUTIL + expect_after { + timeout { fail "ktutil converting keytab to srvtab" ; set ok 0 } + eof { fail "ktutil converting keytab to srvtab" ; set ok 0 } + } + expect "ktutil: " + send "rkt $tmppwd/fookeytab\r" + expect -ex "rkt $tmppwd/fookeytab\r" + expect "ktutil: " +# for debugging, just log this +# send "list\r" +# expect "ktutil: " + # + send "wst $tmppwd/foosrvtab\r" + expect -ex "wst $tmppwd/foosrvtab\r" + expect "ktutil: " +# for debugging, just log this +# send "clear\r" +# expect "ktutil: " +# send "rst $tmppwd/foosrvtab\r" +# expect "ktutil: " +# send "list\r" +# expect "ktutil: " + # okay, now quit and finish testing + send "quit\r" + expect eof + catch expect_after + if [check_exit_status "ktutil converting keytab to srvtab (vno $vno)"] { + pass "ktutil converting keytab to srvtab (vno $vno)" + do_klist_kt $tmppwd/fookeytab "klist srvtab foo/bar vno $vno" + kinit_kt "foo/bar" "SRVTAB:$tmppwd/foosrvtab" 1 "st kvno $vno" + do_klist "foo/bar" "krbtgt/$REALMNAME@$REALMNAME" "klist st foo/bar vno $vno" + do_kdestroy "kdestroy st foo/bar vno $vno" + } + } else { + verbose "skipping v5kinit/srvtab tests because of non-v4 enctype" } - eof { - fail "klist after kdestroy" - return + } + catch "exec rm -f $keytab" + # Check that kadmin.local can actually read the correct kvno, even + # if we don't expect kadmin to be able to. + spawn $KADMIN_LOCAL -r $REALMNAME + set ok 1 + expect_after { + timeout { fail "kadmin.local correct high kvno" ; set ok 0 } + eof { fail "kadmin.local correct high kvno" ; set ok 0 } + } + expect "kadmin.local: " + send "getprinc foo/bar\r" +# exec sleep 10 + expect "Key: vno $vno," + send "quit\r" + expect eof + if [check_exit_status "kadmin.local examine foo/bar for high kvno"] { + if $ok { + pass "kadmin.local correct high kvno" } } - # We can't use check_exit_status, because we expect an exit status - # of 1. - set status_list [wait -i $spawn_id] - verbose "wait -i $spawn_id returned $status_list (klist)" - if { [lindex $status_list 2] != 0 } { - fail "klist (bad exit status) $status_list" - return - } else { if { [lindex $status_list 3] != 1 } { - fail "klist (bad exit status) $status_list" - return - } else { - pass klist - } } } set status [catch doit msg] diff --git a/src/tests/dejagnu/krb-standalone/v4gssftp.exp b/src/tests/dejagnu/krb-standalone/v4gssftp.exp new file mode 100644 index 0000000..1e90b2a --- /dev/null +++ b/src/tests/dejagnu/krb-standalone/v4gssftp.exp @@ -0,0 +1,501 @@ +# Kerberos ftp test. +# This is a DejaGnu test script. +# This script tests Kerberos ftp. +# Originally written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>. +# Modified bye Ezra Peisach for GSSAPI support. + +# 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/build/tests/dejagnu + +if ![info exists FTP] { + set FTP [findfile $objdir/../../appl/gssftp/ftp/ftp] +} + +if ![info exists FTPD] { + set FTPD [findfile $objdir/../../appl/gssftp/ftpd/ftpd] +} + +# If we do not have what is for a V4 test - return +if ![v4_compatible_enctype] { + return +} + +# Make sure .klogin is reasonable. +if ![check_k5login ftp] { + return +} + +if ![check_klogin ftp] { + return +} + +# Set up the kerberos database. +if {![get_hostname] \ + || ![setup_kerberos_files] \ + || ![setup_kerberos_env] \ + || ![setup_kerberos_db 0]} { + return +} + +# A procedure to start up the ftp daemon. + +proc start_ftp_daemon { } { + global FTPD + global tmppwd + global ftpd_spawn_id + global ftpd_pid + + # The -p argument tells it to accept a single connection, so we + # don't need to use inetd. The 3021 is the port to listen at. + # We rely on KRB5_KTNAME being set to the proper keyfile as there is + # no way to cleanly set it with the gssapi API. + # The -a argument requires authorization, to mitigate any + # vulnerability introduced by circumventing ftpusers. + spawn $FTPD -p 3021 -a -r $tmppwd/krb.conf + set ftpd_spawn_id $spawn_id + set ftpd_pid [exp_pid] + + # Give the ftp daemon a few seconds to get set up. + catch "exec sleep 2" +} + +# A procedure to stop the ftp daemon. + +proc stop_ftp_daemon { } { + global ftpd_spawn_id + global ftpd_pid + + if [info exists ftpd_pid] { + catch "close -i $ftpd_spawn_id" + catch "exec kill $ftpd_pid" + catch "wait -i $ftpd_spawn_id" + unset ftpd_pid + } +} + +# Create a file to use for ftp testing. +set file [open $tmppwd/ftp-test w] +puts $file "This file is used for ftp testing." +close $file + +# Create a large file to use for ftp testing. File needs to be +# larger that 2^20 or 1MB for PBSZ testing. +set file [open $tmppwd/bigftp-test w] +puts $file "This file is used for ftp testing.\n" +seek $file 1048576 current +puts $file "This file is used for ftp testing." +close $file + +# Test that a file was copied correctly. +proc check_file { filename {bigfile 0}} { + if ![file exists $filename] { + verbose "$filename does not exist" + send_log "$filename does not exist\n" + return 0 + } + + set file [open $filename r] + if { [gets $file line] == -1 } { + verbose "$filename is empty" + send_log "$filename is empty\n" + close $file + return 0 + } + + if ![string match "This file is used for ftp testing." $line] { + verbose "$filename contains $line" + send_log "$filename contains $line\n" + close $file + return 0 + } + + if {$bigfile} { + # + 1 for the newline + seek $file 1048577 current + if { [gets $file line] == -1 } { + verbose "$filename is truncated" + send_log "$filename is truncated\n" + close $file + return 0 + } + + if ![string match "This file is used for ftp testing." $line] { + verbose "$filename contains $line" + send_log "$filename contains $line\n" + close $file + return 0 + } + } + + if { [gets $file line] != -1} { + verbose "$filename is too long ($line)" + send_log "$filename is too long ($line)\n" + close $file + return 0 + } + + close $file + + return 1 +} + +# +# Restore environment variables possibly set. +# +proc ftp_restore_env { } { + global env + global ftp_save_ktname + global ftp_save_ccname + + catch "unset env(KRB5_KTNAME)" + if [info exists ftp_save_ktname] { + set env(KRB5_KTNAME) $ftp_save_ktname + unset ftp_save_ktname + } + + catch "unset env(KRB5CCNAME)" + if [info exists ftp_save_ccname] { + set env(KRB5CCNAME) $ftp_save_ccname + unset ftp_save_ccname + } +} + +# Wrap the tests in a procedure, so that we can kill the daemons if +# we get some sort of error. + +proc v4ftp_test { } { + global FTP + global KEY + global REALMNAME + global hostname + global localhostname + global env + global ftpd_spawn_id + global ftpd_pid + global spawn_id + global tmppwd + global ftp_save_ktname + global ftp_save_ccname + global des3_krbtgt + + if {$des3_krbtgt} { + return + } + # Start up the kerberos and kadmind daemons and get a srvtab and a + # ticket file. + if {![start_kerberos_daemons 0] \ + || ![add_random_key ftp/$hostname 0] \ + || ![setup_srvtab 0 ftp] \ + || ![add_kerberos_key $env(USER) 0] \ + || ![v4kinit $env(USER) $env(USER)$KEY 0]} { + return + } + + # + # Save settings of KRB5_KTNAME + # + if [info exists env(KRB5_KTNAME)] { + set ftp_save_ktname $env(KRB5_KTNAME) + } + + # + # set KRB5_KTNAME + # + set env(KRB5_KTNAME) FILE:$tmppwd/srvtab + verbose "KRB5_KTNAME=$env(KRB5_KTNAME)" + + # + # Save settings of KRB5CCNAME + # These tests fail if the krb5 cache happens to have a valid credential + # which can result from running the gssftp.exp test immediately + # preceeding these tests. + # + if [info exists env(KRB5CCNAME)] { + set ftp_save_ccname $env(KRB5CCNAME) + } + + # + # set KRB5_KTNAME + # + set env(KRB5CCNAME) FILE:$tmppwd/non-existant-cache + verbose "KRB5CCNAME=$env(KRB5CCNAME)" + + # Start the ftp daemon. + start_ftp_daemon + + # Make an ftp client connection to it. + spawn $FTP $hostname 3021 + + expect_after { + timeout { + fail "$testname (timeout)" + catch "expect_after" + return + } + eof { + fail "$testname (eof)" + catch "expect_after" + return + } + } + + set testname "ftp connection(v4)" + expect -nocase "connected to $hostname" + expect -nocase -re "$localhostname.*ftp server .version \[0-9.\]*. ready." + expect -re "Using authentication type GSSAPI; ADAT must follow" + expect "GSSAPI accepted as authentication type" + expect "GSSAPI error major: Miscellaneous failure" + expect { + "GSSAPI error minor: Unsupported credentials cache format version number" {} + "GSSAPI error minor: No credentials cache found" {} + "GSSAPI error minor: Decrypt integrity check failed" {} + } + expect "GSSAPI error: initializing context" + expect "GSSAPI authentication failed" + expect -re "Using authentication type KERBEROS_V4; ADAT must follow" + expect { + "Kerberos V4 authentication succeeded" { pass "ftp authentication" } + eof { fail "ftp authentication" ; catch "expect_after" ; return } + -re "Kerberos V4 .* failed.*\r" { + fail "ftp authentication"; + send "quit\r"; catch "expect_after"; + return + } + } + expect -nocase "name ($hostname:$env(USER)): " + send "$env(USER)\r" + expect "Kerberos user $env(USER)@$REALMNAME is authorized as $env(USER)" + expect "Remote system type is UNIX." + expect "Using binary mode to transfer files." + expect "ftp> " { + pass $testname + } + + set testname "binary(v4)" + send "binary\r" + expect "ftp> " { + pass $testname + } + + set testname "status(v4)" + send "status\r" + expect -nocase "connected to $hostname." + expect "Authentication type: KERBEROS_V4" + expect "ftp> " { + pass $testname + } + + set testname "ls(v4)" + send "ls $tmppwd/ftp-test\r" + expect -re "Opening ASCII mode data connection for .*ls." + expect -re ".* $tmppwd/ftp-test" + expect "ftp> " { + pass $testname + } + + set testname "nlist(v4)" + send "nlist $tmppwd/ftp-test\r" + expect -re "Opening ASCII mode data connection for file list." + expect -re "$tmppwd/ftp-test" + expect -re ".* Transfer complete." + expect "ftp> " { + pass $testname + } + + set testname "ls missing(v4)" + send "ls $tmppwd/ftp-testmiss\r" + expect -re "Opening ASCII mode data connection for .*ls." + expect { + -re "$tmppwd/ftp-testmiss not found" {} + -re "$tmppwd/ftp-testmiss: No such file or directory" + } + expect "ftp> " { + pass $testname + } + + + set testname "get(v4)" + catch "exec rm -f $tmppwd/copy" + send "get $tmppwd/ftp-test $tmppwd/copy\r" + expect "Opening BINARY mode data connection for $tmppwd/ftp-test" + expect "Transfer complete" + expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds" + expect "ftp> " + if [check_file $tmppwd/copy] { + pass $testname + } else { + fail $testname + } + + set testname "put(v4)" + catch "exec rm -f $tmppwd/copy" + send "put $tmppwd/ftp-test $tmppwd/copy\r" + expect "Opening BINARY mode data connection for $tmppwd/copy" + expect "Transfer complete" + expect -re "\[0-9\]+ bytes sent in \[0-9.e-\]+ seconds" + expect "ftp> " + if [check_file $tmppwd/copy] { + pass $testname + } else { + fail $testname + } + + set testname "cd(v4)" + send "cd $tmppwd\r" + expect "CWD command successful." + expect "ftp> " { + pass $testname + } + + set testname "lcd(v4)" + send "lcd $tmppwd\r" + expect "Local directory now $tmppwd" + expect "ftp> " { + pass $testname + } + + set testname "local get(v4)" + catch "exec rm -f $tmppwd/copy" + send "get ftp-test copy\r" + expect "Opening BINARY mode data connection for ftp-test" + expect "Transfer complete" + expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds" + expect "ftp> " + if [check_file $tmppwd/copy] { + pass $testname + } else { + fail $testname + } + + set testname "big local get(v4)" + catch "exec rm -f $tmppwd/copy" + send "get bigftp-test copy\r" + expect "Opening BINARY mode data connection for bigftp-test" + expect "Transfer complete" + expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds" + expect "ftp> " + if [check_file $tmppwd/copy 1] { + pass $testname + } else { + fail $testname + } + + set testname "start encryption(v4)" + send "private\r" + expect "Data channel protection level set to private" + expect "ftp> " { + pass $testname + } + + set testname "status(v4)" + send "status\r" + expect "Protection Level: private" + expect "ftp> " { + pass $testname + } + + set testname "encrypted get(v4)" + catch "exec rm -f $tmppwd/copy" + send "get ftp-test copy\r" + expect "Opening BINARY mode data connection for ftp-test" + expect "Transfer complete" + expect { + -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds" {} + -re "krb_rd_priv failed for KERBEROS_V4" { + fail $testname + send "quit\r" + catch "expect_after" + return + } + } + expect "ftp> " + if [check_file $tmppwd/copy] { + pass $testname + } else { + fail $testname + } + + + # Test a large file that will overflow PBSZ size + set testname "big encrypted get(v4)" + catch "exec rm -f $tmppwd/copy" + send "get bigftp-test copy\r" + expect "Opening BINARY mode data connection for bigftp-test" + expect "Transfer complete" + expect { + -re "\[0-9\]+ bytes received in \[0-9.e+-\]+ seconds" {} + -re "krb_rd_priv failed for KERBEROS_V4" { + fail $testname + send "quit\r" + catch "expect_after" + return + } + } + expect "ftp> " + if [check_file $tmppwd/copy 1] { + pass $testname + } else { + fail $testname + } + + set testname "close(v4)" + send "close\r" + expect "Goodbye." + expect "ftp> " + set status_list [wait -i $ftpd_spawn_id] + verbose "wait -i $ftpd_spawn_id returned $status_list ($testname)" + catch "close -i $ftpd_spawn_id" + if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 0 } { + send_log "exit status: $status_list\n" + verbose "exit status: $status_list" + fail $testname + } else { + pass $testname + unset ftpd_pid + } + + set testname "quit(v4)" + send "quit\r" + expect_after + expect eof + if [check_exit_status $testname] { + pass $testname + } + +} + +# The ftp client will look in $HOME/.netrc for the user name to use. +# To avoid confusing the testsuite, point $HOME at a directory where +# we know there is no .netrc file. +if [info exists env(HOME)] { + set home $env(HOME) +} elseif [info exists home] { + unset home +} +set env(HOME) $tmppwd + +# Run the test. Logging in sometimes takes a while, so increase the +# timeout. +set oldtimeout $timeout +set timeout 60 +set status [catch v4ftp_test msg] +set timeout $oldtimeout + +# Shut down the kerberos daemons and the ftp daemon. +stop_kerberos_daemons + +stop_ftp_daemon + +ftp_restore_env + +# Reset $HOME, for safety in case we are going to run more tests. +if [info exists home] { + set env(HOME) $home +} else { + unset env(HOME) +} + +if { $status != 0 } { + perror "error in gssftp.exp: $msg" +} diff --git a/src/tests/dejagnu/krb-standalone/v4krb524d.exp b/src/tests/dejagnu/krb-standalone/v4krb524d.exp new file mode 100644 index 0000000..2e17020 --- /dev/null +++ b/src/tests/dejagnu/krb-standalone/v4krb524d.exp @@ -0,0 +1,167 @@ +# Standalone Kerberos test. +# This is a DejaGnu test script. +# This script tests that the Kerberos tools can talk to each other. + +# This mostly just calls procedures in testsuite/config/default.exp. + +if ![info exists K524INIT] { + set K524INIT [findfile $objdir/../../krb524/k524init] +} + +if ![info exists KRB524D] { + set KRB524D [findfile $objdir/../../krb524/krb524d] +} + +if ![info exists KLIST] { + set KLIST [findfile $objdir/../../clients/klist/klist] +} + +if ![info exists KDESTROY] { + set KDESTROY [findfile $objdir/../../clients/kdestroy/kdestroy] +} + +# Set up the Kerberos files and environment. +if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { + return +} + +# If we do not have what is for a V4 test - return +if ![v4_compatible_enctype] { + return +} + +# Initialize the Kerberos database. The argument tells +# setup_kerberos_db that it is being called from here. +if ![setup_kerberos_db 1] { + return +} + +# A procedure to stop the krb524 daemon. +proc start_k524_daemon { } { + global KRB524D + global k524d_spawn_id + global k524d_pid + global REALMNAME + + spawn $KRB524D -m -r $REALMNAME -nofork + set k524d_spawn_id $spawn_id + set k524d_pid [exp_pid] + + # Give the krb524d daemon a few seconds to get set up. + catch "exec sleep 2" +} + +# A procedure to stop the krb524 daemon. +proc stop_k524_daemon { } { + global k524d_spawn_id + global k524d_pid + + if [info exists k524d_pid] { + catch "close -i $k524d_spawn_id" + catch "exec kill $k524d_pid" + catch "wait -i $k524d_spawn_id" + unset k524d_pid + } +} + +# We are about to start up a couple of daemon processes. We do all +# the rest of the tests inside a proc, so that we can easily kill the +# processes when the procedure ends. + +proc doit { } { + global env + global KEY + global K524INIT + # To pass spawn_id to the wait process + global spawn_id + global KLIST + global KDESTROY + global tmppwd + global REALMNAME + global des3_krbtgt + + if {$des3_krbtgt} { + return + } + # Start up the kerberos and kadmind daemons. + if ![start_kerberos_daemons 1] { + return + } + + # Add a user key and get a V5 ticket + if {![add_kerberos_key $env(USER) 0] \ + || ![kinit $env(USER) $env(USER)$KEY 0]} { + return + } + + # Start the krb524d daemon. + start_k524_daemon + + # The k524init program does not advertise anything on success - + #only failure. + spawn $K524INIT + expect { + -timeout 10 + -re "k524init: .*\r" { + fail "k524init" + return + } + eof {} + timeout {} + } + + + if ![check_exit_status "k524init"] { + return + } + pass "k524init" + + # Make sure that klist can see the ticket. + spawn $KLIST -4 + expect { + -re "Kerberos 4 ticket cache:\[ \]*(.+:)?$tmppwd/tkt.*Principal:\[ \]*$env(USER)@$REALMNAME.*krbtgt\.$REALMNAME@$REALMNAME\r\n" { + verbose "klist started" + } + timeout { + fail "v4klist" + return + } + eof { + fail "v4klist" + return + } + } + + expect { + "\r" { } + eof { } + } + + if ![check_exit_status "klist"] { + return + } + pass "krb524d: v4klist" + + # Destroy the ticket. + spawn $KDESTROY -4 + if ![check_exit_status "kdestroy"] { + return + } + pass "krb524d: v4kdestroy" + + pass "krb524d: krb524d" +} + +set status [catch doit msg] + +stop_kerberos_daemons + +stop_k524_daemon + +if { $status != 0 } { + send_error "ERROR: error in v4krb524d.exp\n" + send_error "$msg\n" + exit 1 +} + + diff --git a/src/tests/dejagnu/krb-standalone/v4standalone.exp b/src/tests/dejagnu/krb-standalone/v4standalone.exp new file mode 100644 index 0000000..cc42e8d --- /dev/null +++ b/src/tests/dejagnu/krb-standalone/v4standalone.exp @@ -0,0 +1,95 @@ +# Standalone Kerberos test. +# This is a DejaGnu test script. +# This script tests that the Kerberos tools can talk to each other. + +# This mostly just calls procedures in testsuite/config/default.exp. + +# Set up the Kerberos files and environment. +if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { + return +} + +# If we do not have what is for a V4 test - return +if ![v4_compatible_enctype] { + return +} + +# Initialize the Kerberos database. The argument tells +# setup_kerberos_db that it is being called from here. +if ![setup_kerberos_db 1] { + return +} + +# We are about to start up a couple of daemon processes. We do all +# the rest of the tests inside a proc, so that we can easily kill the +# processes when the procedure ends. + +proc check_and_destroy_v4_tix { client server } { + global REALMNAME + global des3_krbtgt + + # Skip this if we're using a des3 TGT, since that's supposed to fail. + if {$des3_krbtgt} { + return + } + # Make sure that klist can see the ticket. + if ![v4klist "$client" "$server" "v4klist"] { + return + } + + # Destroy the ticket. + if ![v4kdestroy "v4kdestroy"] { + return + } + + if ![v4klist_none "v4klist no tix 1"] { + return + } +} + +proc doit { } { + global REALMNAME + global KLIST + global KDESTROY + global KEY + global hostname + global spawn_id + global tmppwd + + # Start up the kerberos and kadmind daemons. + if ![start_kerberos_daemons 1] { + return + } + + # Use kadmin to add an host key. + if ![add_random_key host/$hostname 1] { + return + } + + # Use ksrvutil to create a srvtab entry. + if ![setup_srvtab 1] { + return + } + + # Use kinit to get a ticket. + if [v4kinit krbtest.admin adminpass$KEY 1] { + check_and_destroy_v4_tix krbtest.admin@$REALMNAME krbtgt.$REALMNAME@$REALMNAME + } + + # Use kinit with srvtab to get a ticket. + # XXX - Currently kinit doesn't support "-4 -k"! +# set shorthost [string range $hostname 0 [expr [string first . $hostname] - 1]] +# if [v4kinit_kt host.$shorthost SRVTAB:$tmppwd/srvtab 1] { +# check_and_destroy_v4_tix host.$shorthost@$REALMNAME krbtgt.$REALMNAME@$REALMNAME +# } +} + +set status [catch doit msg] + +stop_kerberos_daemons + +if { $status != 0 } { + send_error "ERROR: error in v4standalone.exp\n" + send_error "$msg\n" + exit 1 +} |