### -*-autotest-*- ### ### Test script for the main server ### ### (c) 2008 Straylight/Edgeware ### ###----- Licensing notice --------------------------------------------------- ### ### This file is part of Trivial IP Encryption (TrIPE). ### ### TrIPE is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### ### TrIPE is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with TrIPE; if not, write to the Free Software Foundation, ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. m4_define([nl], [ ]) ## Configure a directory ready for use by tripe. m4_define([SETUPDIR], [ cp $abs_top_srcdir/t/keyring-$1 ./keyring key extract -f-secret keyring.pub ]) ## Running standard programs with useful options. m4_define([TRIPE], [$abs_top_builddir/server/tripe -F -d. -aadmin -p0 -b127.0.0.1 -talice]) m4_define([TRIPECTL], [$abs_top_builddir/client/tripectl -d. -aadmin]) m4_define([USLIP], [$abs_top_builddir/uslip/tripe-uslip]) ## Sequences. (These are used for testing the replay protection machinery.) m4_define([R32], [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dnl 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]) m4_define([P32], [21 26 14 12 25 18 2 27 10 31 24 29 0 20 17 11 dnl 8 3 7 23 19 1 13 30 6 9 5 22 15 28 16 4]) ###-------------------------------------------------------------------------- ### Scaffolding for running a TrIPE server. m4_define([WITH_TRIPEX], [ ## Remove the status file. This is how we notice that the server's died. rm -f $1/server-status > $1/expected-server-output > $1/expected-server-errors ## Keep Autotest writes crap to standard output, which we don't want going to ## the server. So keep a copy of the standard output, do the pipe, and ## recover the old stdout inside the group. exec 3>&1 { ( exec 1>&3 3>&- ## Wait for the socket to appear. Watch for the server crashing during ## initialization. Busy waiting is evil, but it's the best I can do and ## not sleep for ages. (Yes, a second on each test group is a long time.) while test ! -r $1//server-status && test ! -S $1/admin; do :; done ## Test body... $3 ## End of the test, now run the server. ) && :; } | { cd $1 echo TRIPE $2 >&2 strace -f -o tripe.trace TRIPE $2 >server-output 2>server-errors stat=$? echo $stat >server-status if test $stat -ne 0; then echo "exit status: $stat" >>server-errors fi } exec 3>&- ## Now check that the server's output matches our expectations. mv $1/expected-server-output expout mv $1/expected-server-errors experr AT_CHECK([cat $1/server-output; cat >&2 $1/server-errors],, [expout], [experr]) ]) m4_define([WITH_TRIPE], [WITH_TRIPEX([.], [$1], [$2])]) m4_define([WITH_2TRIPES], [WITH_TRIPEX([$1], [$3 $4], [WITH_TRIPEX([$2], [$3 $5], [$6])])]) ###-------------------------------------------------------------------------- ### Very unpleasant coprocess handling. ## COPROCESSES(TAG, PROC-A, PROC-B) m4_define([COPROCESSES], [dnl rm -f pipe-$1; mknod pipe-$1 p { { $2 nl } pipe-$1; } dnl ]) ## TRIPECTL_INTERACT(ARGS, SHELLSTUFF) m4_define([TRIPECTL_INTERACT], [ exec 3<&1 COPROCESSES([client], [exec 4>&1 1>&3 $2], [TRIPECTL $1]) ]) ## TRIPECTL_COMMAND(CMD, EXPECT) m4_define([TRIPECTL_COMMAND], [ AT_CHECK([ m4_if([$1], [!], [:], [echo "$1" >&4]) read line case "$line" in "$2") ;; *) echo 2>&1 "submitted $1: expected $2, found $line"; exit 1 ;; esac ]) exec 3>&- ]) ###-------------------------------------------------------------------------- ### Make sure the thing basically works. AT_SETUP([server basics]) SETUPDIR([ec]) AT_CHECK([echo port | TRIPE -p54321],, [INFO 54321[]nl[]OK[]nl]) AT_CLEANUP ###-------------------------------------------------------------------------- ### Challenges. AT_SETUP([server challenges]) AT_KEYWORDS([chal]) SETUPDIR([ec]) WITH_TRIPE(, [ ## A simple test. AT_CHECK([chal=$(TRIPECTL GETCHAL); TRIPECTL checkchal $chal]) ## A wrong challenge. (This was valid once, but the probablity that the ## server chose the same key is negligible.) AT_CHECK([TRIPECTL checkchal AAAAAHyoOL+HMaE0Y9B3ivuszt0], [1],, [tripectl: invalid-challenge[]nl]) echo WARN CHAL incorrect-tag >>expected-server-output ## A duplicated challenge. AT_CHECK([ chal=$(TRIPECTL GETCHAL) TRIPECTL CHECKCHAL $chal TRIPECTL CHECKCHAL $chal ], [1],, [tripectl: invalid-challenge[]nl]) echo WARN CHAL replay duplicated-sequence >>expected-server-output ## Out-of-order reception. There should be a window of 32 challenges; we ## make 33 and check them in a strange order. rm -f experr echo "tripectl: invalid-challenge" >>experr echo "WARN CHAL replay old-sequence" >>expected-server-output for i in P32; do echo "tripectl: invalid-challenge" >>experr echo "WARN CHAL replay duplicated-sequence" >>expected-server-output done AT_CHECK([ ## Make the challenges. for i in old R32; do TRIPECTL GETCHAL >chal-$i || exit 2; done ## Now check them back. for i in P32; do TRIPECTL CHECKCHAL $(cat chal-$i) || exit 3; done ## Check the one which should have fallen off the front. TRIPECTL CHECKCHAL $(cat chal-old) && exit 4 ## And make sure that the others are now considered duplicates. for i in R32; do TRIPECTL CHECKCHAL $(cat chal-$i) && exit 5; done ## All done: tidy cruft away. rm -f chal-* exit 0 ], [0],, [experr]) ]) AT_CLEANUP ###-------------------------------------------------------------------------- ### Communication. AT_SETUP([server communication]) AT_KEYWORDS([comm]) export TRIPE_SLIPIF=USLIP for i in alice bob; do (mkdir $i; cd $i; SETUPDIR([ec])); done WITH_2TRIPES([alice], [bob], [-nslip], [-talice], [-tbob], [ AT_CHECK([TRIPECTL -dalice PORT],, [stdout]) mv stdout alice/port AT_CHECK([TRIPECTL -dbob PORT],, [stdout]) mv stdout bob/port ## Watch for the key-exchange completion announcement, and then exit. COPROCESSES([wait], [ echo WATCH +n while read line; do case "$line" in OK) ;; "NOTE KXDONE "*) break ;; NOTE*) ;; *) exit 63 ;; esac done ], [ TRIPECTL -dalice ]) & ## Don't panic if you don't see the unexpected-source warning. It happens ## for me, but it's not important either way. AT_CHECK([TRIPECTL -dalice ADD bob INET 127.0.0.1 $(cat bob/port)]) echo >>bob/expected-server-output \ "WARN PEER - unexpected-source INET 127.0.0.1 $(cat alice/port)" AT_CHECK([TRIPECTL -dbob ADD alice INET 127.0.0.1 $(cat alice/port)]) ## Check transport pinging. AT_CHECK([TRIPECTL -dalice PING bob],, [ignore]) AT_CHECK([TRIPECTL -dbob PING alice],, [ignore]) ## Wait for the completion announcement. wait ## Check encrypted pinging. AT_CHECK([TRIPECTL -dalice EPING bob],, [ignore]) AT_CHECK([TRIPECTL -dbob EPING alice],, [ignore]) ## Check that packets can flow from one to the other. AT_CHECK([echo "from alice" | USLIP -p alice/bob]) AT_CHECK([USLIP -g bob/alice],, [from alice[]nl]) AT_CHECK([echo "from bob" | USLIP -p bob/alice]) AT_CHECK([USLIP -g alice/bob],, [from bob[]nl]) ]) AT_CLEANUP ###-------------------------------------------------------------------------- ### Services. AT_SETUP([server services]) AT_KEYWORDS([svc]) SETUPDIR([ec]) WITH_TRIPE(, [ ## Make sure it's not running yet. AT_CHECK([TRIPECTL SVCENSURE test], [1],, [tripectl: unknown-service test[]nl]) ## Run a simple service. rm -f svc-test-running tripectl-status COPROCESSES([svc], [ echo SVCCLAIM test 1.0.0 read line case "$line" in OK) ;; *) echo >&2 "SVCCLAIM failed: $line" exit 1 ;; esac echo ok >svc-test-running while read line; do set -- $line case "$[]1,$[]3,$[]4" in SVCJOB,test,HELP) echo SVCINFO try not to use this service for anything useful echo SVCOK $[]2 ;; SVCJOB,test,GOOD) echo SVCOK $[]2 ;; SVCJOB,test,BAD) echo SVCFAIL $[]2 this-command-always-fails ;; SVCJOB,test,UGLY) tag=$2 while read line; do set -- $line case "$[]1,$[]2,$[]3,$[]4" in SVCCANCEL,$tag,,) break ;; SVCJOB,*,test,ESCAPE) echo >&2 "attempt to escape from alkatraz" exit 1 ;; esac done ;; SVCJOB,test,FIRST) firsttag=$[]2 ;; SVCJOB,test,SECOND) echo SVCOK $firsttag echo SVCOK $[]2 ;; SVCJOB,*) echo SVCFAIL $[]2 unknown-svc-command $[]4 ;; SVCCLAIM,*) break ;; OK,* | INFO,*) ;; FAIL,*) echo "failure in service: $line" >&2 ;; esac done ], [ TRIPECTL; echo $? >tripectl-status ]) 2>tripectl-errors & ## Wait until it starts up. while test ! -r svc-test-running && test ! -r tripectl-status; do :; done ## Make sure it's running. AT_CHECK([TRIPECTL SVCQUERY test],, [name=test version=1.0.0[]nl]) ## Try some simple commands. AT_CHECK([TRIPECTL SVCSUBMIT test GOOD]) AT_CHECK([TRIPECTL SVCSUBMIT test BAD], [1],, [tripectl: this-command-always-fails[]nl]) ## And now with commands in the background. TRIPECTL_INTERACT([ TRIPECTL_COMMAND([SVCSUBMIT test GOOD], [OK]) TRIPECTL_COMMAND([SVCSUBMIT -background foo test UGLY], [BGDETACH foo]) TRIPECTL_COMMAND([BGCANCEL foo], [OK]) TRIPECTL_COMMAND([SVCSUBMIT test ESCAPE], [FAIL unknown-svc-command ESCAPE]) ]) ## Out-of-order completion. TRIPECTL_INTERACT([ TRIPECTL_COMMAND([SVCSUBMIT -background one test FIRST], [BGDETACH one]) TRIPECTL_COMMAND([SVCSUBMIT -background two test SECOND], [BGDETACH two]) TRIPECTL_COMMAND([!], [BGOK one]) TRIPECTL_COMMAND([!], [BGOK two]) ]) ## All done. exit 0 ]) AT_CLEANUP ###----- That's all, folks --------------------------------------------------