chiark / gitweb /
server/keymgmt.c: Track and find keys by their 32-bit IDs.
[tripe] / server / tests.at
1 ### -*-autotest-*-
2 ###
3 ### Test script for the main server
4 ###
5 ### (c) 2008 Straylight/Edgeware
6 ###
7
8 ###----- Licensing notice ---------------------------------------------------
9 ###
10 ### This file is part of Trivial IP Encryption (TrIPE).
11 ###
12 ### TrIPE is free software: you can redistribute it and/or modify it under
13 ### the terms of the GNU General Public License as published by the Free
14 ### Software Foundation; either version 3 of the License, or (at your
15 ### option) any later version.
16 ###
17 ### TrIPE is distributed in the hope that it will be useful, but WITHOUT
18 ### ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 ### FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 ### for more details.
21 ###
22 ### You should have received a copy of the GNU General Public License
23 ### along with TrIPE.  If not, see <https://www.gnu.org/licenses/>.
24
25 m4_define([nl], [
26 ])
27
28 ## Configure a directory ready for use by tripe.
29 m4_define([SETUPDIR], [
30   cp $abs_top_srcdir/t/keyring-$1 ./keyring
31   key extract -f-secret keyring.pub
32 ])
33
34 ## Running standard programs with useful options.
35 m4_define([TRIPE],
36   [env TRIPE_PRIVHELPER=$abs_top_builddir/priv/tripe-privhelper \
37      $abs_top_builddir/server/tripe -F -d. -aadmin -p0 -b127.0.0.1 \
38         ${TRIPE_TEST_TRACEOPTS+-T$TRIPE_TEST_TRACEOPTS}])
39 m4_define([TRIPECTL], [$abs_top_builddir/client/tripectl -d. -aadmin])
40 m4_define([USLIP], [$abs_top_builddir/uslip/tripe-uslip])
41 m4_define([MITM], [$abs_top_builddir/proxy/tripe-mitm])
42
43 ## WITH_STRACE(tag, cmd)
44 ##
45 ## There's an awful hack here.  If a process running under strace exits with
46 ## a signal, then strace will kill itself with the same signal -- and
47 ## therefore clobber the original process's core file.  So we arrange to run
48 ## strace in one directory and have the child process run in another.
49 m4_define([WITH_STRACE],
50 [case "${TRIPE_TEST_STRACE-nil}" in
51   nil)
52     $2
53     ;;
54   *)
55     mkdir -p strace-hack.$1/
56     (ulimit -c hard >/dev/null 2>&1
57      sh -c 'cd strace-hack.$1; exec "$[]@"' - \
58         strace -ff -tt -v -s1024 -o../$1.trace \
59         sh -c 'cd ..; exec "$[]@"' - \
60         $2)
61     ;;
62  esac])
63
64 ## Sequences.  (These are used for testing the replay protection machinery.)
65 m4_define([R32], [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   dnl
66                   16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31])
67 m4_define([P32], [21 26 14 12 25 18  2 27 10 31 24 29  0 20 17 11   dnl
68                    8  3  7 23 19  1 13 30  6  9  5 22 15 28 16  4])
69
70 ###--------------------------------------------------------------------------
71 ### Scaffolding for running a TrIPE server.
72
73 ## WITH_TRIPEX(dir, args, body)
74 m4_define([WITH_TRIPEX], [
75
76 ## If this directory doesn't exist then Bad Things will happen.
77 if test ! -d $1; then
78   echo >&2 "server directory \`$1' doesn't exist"
79   exit 99
80 fi
81
82 ## Remove the status file.  This is how we notice that the server's died.
83 rm -f $1/server-status
84 > $1/expected-server-output
85 > $1/expected-server-errors
86
87 ## Autotest writes crap to standard output, which we don't want going to the
88 ## server.  So keep a copy of the standard output, do the pipe, and recover
89 ## the old stdout inside the group.
90 exec 3>&1
91 { (
92 exec 1>&3 3>&-
93
94 ## Wait for the socket to appear.  Watch for the server crashing during
95 ## initialization.  Busy waiting is evil, but it's the best I can do and
96 ## not sleep for ages.  (Yes, a second on each test group is a long time.)
97 while test ! -r $1/server-status && test ! -S $1/admin; do :; done
98
99 ## Make the port number availale.
100 AT_CHECK([TRIPECTL -d$1 PORT],, [stdout])
101 mv stdout $1/port
102
103 ## Test body...
104 $3
105
106 ## End of the test, now run the server.
107 ) && :; } | {
108   cd $1
109   echo TRIPE $2 >&2
110   WITH_STRACE([tripe], [TRIPE $2 >server-output.full 2>server-errors.full])
111   stat=$?
112   echo $stat >server-status
113   if test $stat -ne 0; then
114     echo "exit status: $stat" >>server-errors.full
115   fi
116   grep -v '^+ tripe: ' server-errors.full >server-errors
117
118   ## We interrupt this relatively sensible macro for an especially awful
119   ## hack.  The tripe server emits warnings which are often caused by lack of
120   ## synchronization between two peers.  These are harmless and shouldn't
121   ## cause test failures.  But we shouldn't just trim out all messages that
122   ## look like the spurious ones: if they appear when we're not expecting
123   ## them, that's bad and they should properly cause a test failure.
124   ##
125   ## So we use the WARN command to insert magic directives into the server's
126   ## message stream.  The directives begin with `WARN USER test'; remaining
127   ## tokens may be as follows.
128   ##
129   ## PUSH               Introduce a new layer of nesting.  Settings between
130   ##                    this PUSH and the matching POP will be forgotten
131   ##                    following the POP.
132   ##
133   ## POP                End a layer of nesting.  See PUSH above.
134   ##
135   ## IGNORE tokens      Ignore lines which begin with the tokens.
136   ##
137   ## Token comparison isn't done very well, but it's good enough for these
138   ## purposes.
139   ##
140   ## We also trim out trace lines here, since it's useful to produce them for
141   ## debugging purposes and changing or introducing more of them shouldn't
142   ## cause failures.
143   awk '
144         BEGIN {
145           sp = 0;
146           npat = 0;
147         }
148         $[]1 == "TRACE" { next; }
149         $[]1 == "WARN" && $[]2 == "USER" && $[]3 == "test" {
150           if ($[]4 == "PUSH")
151             npatstk[[sp++]] = npat;
152           else if ($[]4 == "IGNORE") {
153             s = "";
154             p = "";
155             for (i = 5; i <= NF; i++) {
156               p = p s $[]i;
157               s = " ";
158             }
159             pat[[npat++]] = p;
160           } else if ($[]4 == "POP")
161             npat = npatstk[[--sp]];
162           next;
163         }
164         {
165           for (i = 0; i < npat; i++) {
166             n = length(pat[[i]]);
167             if (substr($[]0, 1, n) == pat[[i]])
168               next;
169           }
170           print $[]0;
171         }
172   ' server-output.full >server-output
173 }
174 exec 3>&-
175
176 ## Now check that the server's output matches our expectations.
177 mv $1/expected-server-output expout
178 mv $1/expected-server-errors experr
179 AT_CHECK([cat $1/server-output; cat >&2 $1/server-errors],,
180          [expout], [experr])
181 ])
182
183 ## WITH_TRIPE(args, body)
184 m4_define([WITH_TRIPE], [WITH_TRIPEX([.], [$1], [$2])])
185
186 ## WITH_2TRIPES(adir, bdir, bothargs, aargs, bargs, body)
187 m4_define([WITH_2TRIPES],
188           [WITH_TRIPEX([$1], [$3 $4], [WITH_TRIPEX([$2], [$3 $5], [$6])])])
189
190 ## WITH_3TRIPES(adir, bdir, cdir, allargs, aargs, bargs, cargs, body)
191 m4_define([WITH_3TRIPES],
192           [WITH_TRIPEX([$1], [$4 $5],
193           [WITH_TRIPEX([$2], [$4 $6],
194           [WITH_TRIPEX([$3], [$4 $7],
195           [$8])])])])
196
197 ## RETRY(n, body)
198 m4_define([RETRY], [
199   n=0 rc=1
200   while test $n -lt $1; do
201     if $2
202     then rc=0; break
203     fi
204     n=$(( $n + 1 ))
205   done
206   exit $rc
207 ])
208
209 ## COMMS_EPING(adir, aname, bdir, bname, [n])
210 m4_define([COMMS_EPING], [
211   AT_CHECK([RETRY([m4_default([$5], [1])],
212     [TRIPECTL -d$1 EPING $4])],, [ignore])
213   AT_CHECK([RETRY([m4_default([$5], [1])],
214     [TRIPECTL -d$3 EPING $2])],, [ignore])
215 ])
216
217 ## COMMS_SLIP(adir, aname, bdir, bname)
218 m4_define([COMMS_SLIP], [
219   AT_CHECK([echo "from $1" | USLIP -p $1/$4])
220   AT_CHECK([USLIP -g $3/$2],, [from $1[]nl])
221   AT_CHECK([echo "from $3" | USLIP -p $3/$2])
222   AT_CHECK([USLIP -g $1/$4],, [from $3[]nl])
223 ])
224
225 ## AWAIT_KXDONE(adir, aname, bdir, bname, body)
226 m4_define([AWAIT_KXDONE], [
227
228   ## Ignore some reports caused by races.
229   for i in $1!$4 $3!$2; do
230     d=${i%!*} o=${i#*!}
231     TRIPECTL -d$d WARN test PUSH
232     TRIPECTL -d$d WARN test IGNORE WARN KX $o incorrect cookie
233     TRIPECTL -d$d WARN test IGNORE WARN KX $o unexpected pre-challenge
234     TRIPECTL -d$d WARN test IGNORE WARN KX $o unexpected challenge
235   done
236
237   ## Watch for the key-exchange completion announcement in the background.
238   COPROCESSES([wait-$1], [
239     echo WATCH +n
240     while read line; do
241       set x $line; shift
242       echo >&2 ">>> $line"
243       case "$[]1:$[]2:$[]3" in
244         OK::) ;;
245         NOTE:KXDONE:$4) break ;;
246         NOTE:* | TRACE:* | WARN:*) ;;
247         *) exit 63 ;;
248       esac
249     done
250   ], [
251     TRIPECTL -d$1
252   ]) & waiter_$1=$!
253
254   $5
255
256   ## Collect the completion announcement.
257   wait $waiter_$1; waitrc=$?
258   AT_CHECK([echo $waitrc],, [0[]nl])
259
260   ## Be interested in key-exchange warnings again.
261   for d in $1 $3; do TRIPECTL -d$d WARN test POP; done
262 ])
263
264 ## ESTABLISH(adir, aname, aopts, bdir, bname, bopts, [aport], [bport])
265 m4_define([ESTABLISH], [
266
267   ## Set up the establishment.
268   AWAIT_KXDONE([$1], [$2], [$4], [$5], [
269     AT_CHECK([TRIPECTL -d$1 ADD -cork $6 $5 INET 127.0.0.1 \
270       m4_if([$8], [], [$(cat $4/port)], [$8])])
271     AT_CHECK([TRIPECTL -d$4 ADD $3 $2 INET 127.0.0.1 \
272       m4_if([$7], [], [$(cat $1/port)], [$7])])
273   ])
274
275   ## Check transport pinging.
276   AT_CHECK([TRIPECTL -d$1 PING $5],, [ignore])
277   AT_CHECK([TRIPECTL -d$4 PING $2],, [ignore])
278
279   ## Check communication works.
280   COMMS_EPING([$1], [$2], [$4], [$5])
281   COMMS_SLIP([$1], [$2], [$4], [$5])
282 ])
283
284 ###--------------------------------------------------------------------------
285 ### Very unpleasant coprocess handling.
286
287 ## COPROCESSES(TAG, PROC-A, PROC-B)
288 m4_define([COPROCESSES], [dnl
289 rm -f pipe-$1; mknod pipe-$1 p
290 { { $2 nl } <pipe-$1 | { $3 nl } >pipe-$1; } dnl
291 ])
292
293 ## TRIPECTL_INTERACT(ARGS, SHELLSTUFF)
294 m4_define([TRIPECTL_INTERACT], [
295   exec 3>&1
296   COPROCESSES([client], [exec 4>&1 1>&3 $1], [TRIPECTL $2])
297 ])
298
299 ## TRIPECTL_COMMAND(CMD, EXPECT)
300 m4_define([TRIPECTL_COMMAND], [
301   AT_CHECK([
302     m4_if([$1], [!], [:], [echo "$1" >&4])
303     read line
304     case "$line" in
305       "$2") ;;
306       *) echo 2>&1 "submitted $1: expected $2, found $line"; exit 1 ;;
307     esac
308   ])
309   exec 3>&-
310 ])
311
312 ###--------------------------------------------------------------------------
313 ### Make sure the thing basically works.
314
315 AT_SETUP([server basics])
316 SETUPDIR([alpha])
317 AT_CHECK([echo port | TRIPE -p54321],, [INFO 54321[]nl[]OK[]nl])
318 AT_CLEANUP
319
320 ###--------------------------------------------------------------------------
321 ### Challenges.
322
323 AT_SETUP([server challenges])
324 AT_KEYWORDS([chal])
325 SETUPDIR([alpha])
326
327 WITH_TRIPE(, [
328   ## A simple test.
329   AT_CHECK([chal=$(TRIPECTL GETCHAL); TRIPECTL checkchal $chal])
330
331   ## A wrong challenge.  (This was valid once, but the probablity that the
332   ## server chose the same key is negligible.)
333   AT_CHECK([TRIPECTL checkchal AAAAAHyoOL+HMaE0Y9B3ivuszt0], [1],,
334            [tripectl: invalid-challenge[]nl])
335   echo WARN CHAL incorrect-tag >>expected-server-output
336
337   ## A duplicated challenge.
338   AT_CHECK([
339     chal=$(TRIPECTL GETCHAL)
340     TRIPECTL CHECKCHAL $chal
341     TRIPECTL CHECKCHAL $chal
342   ], [1],, [tripectl: invalid-challenge[]nl])
343   echo WARN CHAL replay duplicated-sequence >>expected-server-output
344
345   ## Out-of-order reception.  There should be a window of 32 challenges; we
346   ## make 33 and check them in a strange order.
347   rm -f experr
348   echo "tripectl: invalid-challenge" >>experr
349   echo "WARN CHAL replay old-sequence" >>expected-server-output
350   for i in P32; do
351     echo "tripectl: invalid-challenge" >>experr
352     echo "WARN CHAL replay duplicated-sequence" >>expected-server-output
353   done
354   AT_CHECK([
355
356     ## Make the challenges.
357     for i in old R32; do TRIPECTL GETCHAL >chal-$i || exit 2; done
358
359     ## Now check them back.
360     for i in P32; do TRIPECTL CHECKCHAL $(cat chal-$i) || exit 3; done
361
362     ## Check the one which should have fallen off the front.
363     TRIPECTL CHECKCHAL $(cat chal-old) && exit 4
364
365     ## And make sure that the others are now considered duplicates.
366     for i in R32; do TRIPECTL CHECKCHAL $(cat chal-$i) && exit 5; done
367
368     ## All done: tidy cruft away.
369     rm -f chal-*
370     exit 0
371   ], [0],, [experr])
372 ])
373
374 AT_CLEANUP
375
376 ###--------------------------------------------------------------------------
377 ### Communication.
378
379 AT_SETUP([server communication])
380 AT_KEYWORDS([comm])
381 export TRIPE_SLIPIF=USLIP
382
383 for k in alpha beta-new; do
384   for p in alice bob; do (
385     rm -rf $p; mkdir $p; cd $p; SETUPDIR([$k])
386   ); done
387   WITH_2TRIPES([alice], [bob], [-nslip], [-talice], [-tbob], [
388     ESTABLISH([alice], [not-alice], [-key alice],
389               [bob], [bob], [])
390   ])
391   for p in alice bob; do rm -rf $p.$k; mv $p $p.$k; done
392 done
393
394 AT_CLEANUP
395
396 ###--------------------------------------------------------------------------
397 ### Mobile peer tracking.
398
399 AT_SETUP([peer tracking])
400 AT_KEYWORDS([mobile])
401 export TRIPE_SLIPIF=USLIP
402
403 for p in alice bob carol; do (mkdir $p; cd $p; SETUPDIR([alpha])); done
404
405 ## WITH_MITM(adir, aport, bdir, bport, body)
406 m4_define([WITH_MITM], [
407   echo >&2 "mitm: $1 <--> :$2 <-mitm-> :$4 <--> $3"
408   MITM -k$1/keyring.pub \
409         peer:$1:$2:127.0.0.1:$(cat $1/port) \
410         peer:$3:$4:127.0.0.1:$(cat $3/port) \
411         filt:send& mitmpid_$1_$3=$!
412   trap 'kill $mitmpid_$1_$3; exit 127' EXIT INT QUIT TERM HUP
413   sleep 1
414   $5
415   kill $mitmpid_$1_$3; trap - EXIT INT QUIT TERM HUP
416 ])
417
418 WITH_3TRIPES([alice], [bob], [carol], [-nslip],
419              [-talice], [-tbob], [-tcarol], [
420
421   ## We need an indirection layer between the two peers so that we can
422   ## simulate the effects of NAT remapping.  The nearest thing we have to
423   ## this is the mitm proxy, so we may as well use that.
424   ##
425   ## alice <--> :5311 <-mitm-> :5312 <--> bob
426   ## alice <--> :5321 <-mitm-> :5322 <--> carol
427
428   WITH_MITM([alice], [5311], [bob], [5312], [
429     ESTABLISH([alice], [alice], [], [bob], [bob], [-mobile], [5312], [5311])
430   ])
431
432   WITH_MITM([alice], [5319], [bob], [5312], [
433     COMMS_EPING([bob], [bob], [alice], [alice])
434     COMMS_SLIP([bob], [bob], [alice], [alice])
435   ])
436
437   WITH_MITM([alice], [5321], [carol], [5322], [
438     ESTABLISH([alice], [alice], [], [carol], [carol], [-mobile],
439         [5322], [5321])
440   ])
441
442   WITH_MITM([alice], [5311], [bob], [5312], [
443   WITH_MITM([alice], [5321], [carol], [5322], [
444     COMMS_EPING([bob], [bob], [alice], [alice])
445     COMMS_EPING([carol], [carol], [alice], [alice])
446     COMMS_SLIP([bob], [bob], [alice], [alice])
447     COMMS_SLIP([carol], [carol], [alice], [alice])
448   ])])
449
450   WITH_MITM([alice], [5321], [bob], [5312], [
451   WITH_MITM([alice], [5311], [carol], [5322], [
452     COMMS_EPING([bob], [bob], [alice], [alice])
453     COMMS_EPING([carol], [carol], [alice], [alice])
454     COMMS_SLIP([bob], [bob], [alice], [alice])
455     COMMS_SLIP([carol], [carol], [alice], [alice])
456   ])])
457   wait
458 ])
459
460 AT_CLEANUP
461
462 ###--------------------------------------------------------------------------
463 ### Adverse communication.
464
465 AT_SETUP([server retry])
466 AT_KEYWORDS([backoff])
467 export TRIPE_SLIPIF=USLIP
468
469 for i in alice bob; do (mkdir $i; cd $i; SETUPDIR([beta])); done
470
471 WITH_2TRIPES([alice], [bob], [-nslip], [-talice], [-tbob], [
472
473   ## Set up the evil proxy.
474   alicemitm=24516 bobmitm=14016
475   mknod pipe-mitmpid p
476   WITH_STRACE([mitm],
477               [sh -c 'echo $$ >pipe-mitmpid; exec "$@"' - \
478                MITM -kalice/keyring.pub >mitm.out 2>mitm.err \
479                  peer:alice:$alicemitm:127.0.0.1:$(cat alice/port) \
480                  peer:bob:$bobmitm:127.0.0.1:$(cat bob/port) \
481                  filt:drop:5 filt:send])&
482   read mitmpid <pipe-mitmpid
483   trap 'kill $mitmpid; exit 127' EXIT INT QUIT TERM HUP
484   exec 3>&-
485
486   ## Try to establish keys anyway.
487   AWAIT_KXDONE([alice], [alice], [bob], [bob], [
488     AT_CHECK([TRIPECTL -dalice ADD -cork bob   INET 127.0.0.1 $alicemitm])
489     AT_CHECK([TRIPECTL -dbob   ADD       alice INET 127.0.0.1 $bobmitm])
490   ])
491
492   ## Check pinging.
493   COMMS_EPING([alice], [alice], [bob], [bob], [10])
494   COMMS_EPING([bob], [bob], [alice], [alice], [10])
495
496   ## Tear down the MITM proxy.
497   kill $mitmpid
498 ])
499
500 AT_CLEANUP
501
502 ###--------------------------------------------------------------------------
503 ### Key management.
504
505 AT_SETUP([server key-management])
506 AT_KEYWORDS([keymgmt])
507 export TRIPE_SLIPIF=USLIP
508
509 ## Determine all of the nets and the principals.
510 princs=""
511 nets=" "
512 while read princ pnets; do
513   princs="$princs $princ"
514   for n in $pnets; do
515     case " $nets " in *" $n "*) ;; *) nets="$nets$n " ;; esac
516   done
517 done <<PRINC
518 alice   alpha   beta
519 bob     alpha   beta
520 carol   beta
521 PRINC
522
523 ## Build the master keyring.  All key tags here are of the form PRINC/NET.
524 for n in $nets; do
525   key -k$abs_top_srcdir/t/keyring-$n extract keyring-$n $princs
526   for p in $princs; do key -kkeyring-$n tag $p $p/$n; done
527   key merge keyring-$n
528   rm keyring-$n
529 done
530 key extract -f-secret keyring.pub
531
532 ## Set up the principals' directories.
533 for p in $princs; do
534   mkdir $p
535   cp keyring keyring.pub $p/
536 done
537
538 WITH_3TRIPES([alice], [bob], [carol], [-nslip -Tmx],
539         [-talice/alpha], [-tbob/alpha], [-tcarol/beta], [
540
541   ## Establish this little merry-go-round.
542   ESTABLISH([alice], [alice], [-key alice/alpha],
543         [bob], [bob], [-key bob/alpha])
544   ESTABLISH([alice], [alice], [-key alice/beta],
545         [carol], [carol], [-priv alice/beta -key carol/beta])
546   ESTABLISH([bob], [bob], [-key bob/beta],
547         [carol], [carol], [-priv bob/beta -key carol/beta])
548
549   ## Tweak Bob's alpha key.
550   for p in $princs; do
551     TRIPECTL -d$p WARN test COMMENT tweak bob/alpha
552   done
553
554   key -k$abs_top_srcdir/t/keyring-alpha extract keyring-bob-new bob-new
555   key merge keyring-bob-new
556   key tag -r bob-new bob/alpha
557   key extract -f-secret keyring.pub
558   for p in alice bob; do cp keyring keyring.pub $p/; done
559
560   ## Kick the peers to see whether they update.
561   AWAIT_KXDONE([alice], [alice], [bob], [bob], [
562     TRIPECTL -dalice RELOAD
563     TRIPECTL -dbob RELOAD
564     TRIPECTL -dalice FORCEKX bob
565     TRIPECTL -dbob FORCEKX alice
566   ])
567
568   COMMS_EPING([alice], [alice], [bob], [bob])
569   COMMS_EPING([bob], [bob], [alice], [alice])
570
571   ## Update the beta ring.
572   key merge $abs_top_srcdir/t/keyring-beta-new
573   for p in $princs; do key tag -r $p $p/beta; done
574   key extract -f-secret keyring.pub
575
576   ## Update alice's and carol's private keys, bob's public.  This should be
577   ## insufficient for them to switch, but the results could be interesting.
578   for p in $princs; do
579     TRIPECTL -d$p WARN test COMMENT tweak beta step 1
580   done
581
582   for p in alice carol; do cp keyring $p/; done
583   cp keyring.pub bob/
584   for p in $princs; do TRIPECTL -d$p RELOAD; done
585
586   AT_DATA([algs-alpha], [dnl
587 kx-group=curve25519 kx-group-order-bits=252 kx-group-elt-bits=255
588 hash=sha256 mgf=sha256-mgf hash-sz=32
589 bulk-transform=naclbox bulk-overhead=20
590 cipher=chacha20 cipher-keysz=32
591 mac=poly1305 mac-tagsz=16
592 cipher-data-limit=2147483648
593 ])
594
595   AT_DATA([algs-beta-old], [dnl
596 kx-group=prime kx-group-order-bits=160 kx-group-elt-bits=1023
597 hash=rmd160 mgf=rmd160-mgf hash-sz=20
598 bulk-transform=v0 bulk-overhead=22
599 cipher=blowfish-cbc cipher-keysz=20 cipher-blksz=8
600 mac=rmd160-hmac mac-keysz=20 mac-tagsz=10
601 cipher-data-limit=67108864
602 ])
603
604   AT_DATA([algs-beta-new], [dnl
605 kx-group=ec kx-group-order-bits=161 kx-group-elt-bits=320
606 hash=rmd160 mgf=rmd160-mgf hash-sz=20
607 bulk-transform=iiv bulk-overhead=14
608 cipher=blowfish-cbc cipher-keysz=20 cipher-blksz=8
609 mac=rmd160-hmac mac-keysz=20 mac-tagsz=10
610 blkc=blowfish blkc-keysz=20 blkc-blksz=8
611 cipher-data-limit=67108864
612 ])
613
614   cp algs-alpha expout;    AT_CHECK([TRIPECTL -dalice ALGS],,       [expout])
615   cp algs-beta-old expout; AT_CHECK([TRIPECTL -dalice ALGS carol],, [expout])
616   cp algs-beta-old expout; AT_CHECK([TRIPECTL -dbob   ALGS carol],, [expout])
617   cp algs-beta-new expout; AT_CHECK([TRIPECTL -dcarol ALGS],,       [expout])
618   cp algs-beta-old expout; AT_CHECK([TRIPECTL -dcarol ALGS alice],, [expout])
619
620   ## Now copy the full keys.  We expect this to provoke key exchange.
621   for p in $princs; do
622     TRIPECTL -d$p WARN test COMMENT tweak beta step 2
623   done
624
625   for p in $princs; do cp keyring keyring.pub $p/; done
626
627   AWAIT_KXDONE([alice], [alice], [carol], [carol], [
628     TRIPECTL -dalice RELOAD
629     AWAIT_KXDONE([bob], [bob], [carol], [carol], [
630       TRIPECTL -dbob RELOAD
631       TRIPECTL -dcarol RELOAD
632     ])
633   ])
634
635   cp algs-alpha expout;    AT_CHECK([TRIPECTL -dalice ALGS],,       [expout])
636   cp algs-beta-new expout; AT_CHECK([TRIPECTL -dalice ALGS carol],, [expout])
637   cp algs-beta-new expout; AT_CHECK([TRIPECTL -dbob   ALGS carol],, [expout])
638   cp algs-beta-new expout; AT_CHECK([TRIPECTL -dcarol ALGS],,       [expout])
639 ])
640
641 AT_CLEANUP
642
643 ###--------------------------------------------------------------------------
644 ### Services.
645
646 AT_SETUP([server services])
647 AT_KEYWORDS([svc])
648 SETUPDIR([alpha])
649
650 WITH_TRIPE(, [
651
652   ## Make sure it's not running yet.
653   AT_CHECK([TRIPECTL SVCENSURE test], [1],,
654            [tripectl: unknown-service test[]nl])
655
656   ## Run a simple service.
657   rm -f svc-test-running tripectl-status
658   COPROCESSES([svc], [
659     echo SVCCLAIM test 1.0.0
660     read line
661     case "$line" in
662       OK)
663         ;;
664       *)
665         echo >&2 "SVCCLAIM failed: $line"
666         exit 1
667         ;;
668     esac
669     echo ok >svc-test-running
670     while read line; do
671       set -- $line
672       case "$[]1,$[]3,$[]4" in
673         SVCJOB,test,HELP)
674           echo SVCINFO try not to use this service for anything useful
675           echo SVCOK $[]2
676           ;;
677         SVCJOB,test,GOOD)
678           echo SVCOK $[]2
679           ;;
680         SVCJOB,test,BAD)
681           echo SVCFAIL $[]2 this-command-always-fails
682           ;;
683         SVCJOB,test,UGLY)
684           tag=$2
685           while read line; do
686             set -- $line
687             case "$[]1,$[]2,$[]3,$[]4" in
688               SVCCANCEL,$tag,,) break ;;
689               SVCJOB,*,test,ESCAPE)
690                 echo >&2 "attempt to escape from alkatraz"
691                 exit 1
692                 ;;
693             esac
694           done
695           ;;
696         SVCJOB,test,FIRST)
697           firsttag=$[]2
698           ;;
699         SVCJOB,test,SECOND)
700           echo SVCOK $firsttag
701           echo SVCOK $[]2
702           ;;
703         SVCJOB,*)
704           echo SVCFAIL $[]2 unknown-svc-command $[]4
705           ;;
706         SVCCLAIM,*)
707           break
708           ;;
709         OK,* | INFO,*)
710           ;;
711         FAIL,*)
712           echo "failure in service: $line" >&2
713           ;;
714       esac
715     done
716   ], [
717     TRIPECTL; echo $? >tripectl-status
718   ]) 2>tripectl-errors &
719
720   ## Wait until it starts up.
721   while test ! -r svc-test-running && test ! -r tripectl-status; do :; done
722
723   ## Make sure it's running.
724   AT_CHECK([TRIPECTL SVCQUERY test],, [name=test version=1.0.0[]nl])
725
726   ## Try some simple commands.
727   AT_CHECK([TRIPECTL SVCSUBMIT test GOOD])
728   AT_CHECK([TRIPECTL SVCSUBMIT test BAD], [1],,
729            [tripectl: this-command-always-fails[]nl])
730
731   ## And now with commands in the background.
732   TRIPECTL_INTERACT([
733     TRIPECTL_COMMAND([SVCSUBMIT test GOOD], [OK])
734     TRIPECTL_COMMAND([SVCSUBMIT -background foo test UGLY], [BGDETACH foo])
735     TRIPECTL_COMMAND([BGCANCEL foo], [OK])
736     TRIPECTL_COMMAND([SVCSUBMIT test ESCAPE],
737                      [FAIL unknown-svc-command ESCAPE])
738   ])
739
740   ## Out-of-order completion.
741   TRIPECTL_INTERACT([
742     TRIPECTL_COMMAND([SVCSUBMIT -background one test FIRST], [BGDETACH one])
743     TRIPECTL_COMMAND([SVCSUBMIT -background two test SECOND], [BGDETACH two])
744     TRIPECTL_COMMAND([!], [BGOK one])
745     TRIPECTL_COMMAND([!], [BGOK two])
746   ])
747
748   ## All done.
749   exit 0
750 ])
751
752 AT_CLEANUP
753
754 ###----- That's all, folks --------------------------------------------------