Commit | Line | Data |
---|---|---|
5d85da1c MW |
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 | |
13 | ### it under the terms of the GNU General Public License as published by | |
14 | ### the Free Software Foundation; either version 2 of the License, or | |
15 | ### (at your option) any later version. | |
16 | ### | |
17 | ### TrIPE is distributed in the hope that it will be useful, | |
18 | ### but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ### GNU General Public License for more details. | |
21 | ### | |
22 | ### You should have received a copy of the GNU General Public License | |
23 | ### along with TrIPE; if not, write to the Free Software Foundation, | |
24 | ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25 | ||
26 | m4_define([nl], [ | |
27 | ]) | |
28 | ||
29 | ## Configure a directory ready for use by tripe. | |
30 | m4_define([SETUPDIR], [ | |
31 | cp $abs_top_srcdir/t/keyring-$1 ./keyring | |
32 | key extract -f-secret keyring.pub | |
33 | ]) | |
34 | ||
35 | ## Running standard programs with useful options. | |
36 | m4_define([TRIPE], | |
37 | [$abs_top_builddir/server/tripe -F -d. -aadmin -p0 -b127.0.0.1 -talice]) | |
38 | m4_define([TRIPECTL], [$abs_top_builddir/client/tripectl -d. -aadmin]) | |
39 | m4_define([USLIP], [$abs_top_builddir/uslip/tripe-uslip]) | |
40 | ||
41 | ## Sequences. (These are used for testing the replay protection machinery.) | |
42 | m4_define([R32], [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dnl | |
43 | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]) | |
44 | m4_define([P32], [21 26 14 12 25 18 2 27 10 31 24 29 0 20 17 11 dnl | |
45 | 8 3 7 23 19 1 13 30 6 9 5 22 15 28 16 4]) | |
46 | ||
47 | ###-------------------------------------------------------------------------- | |
48 | ### Scaffolding for running a TrIPE server. | |
49 | ||
50 | m4_define([WITH_TRIPEX], [ | |
51 | ||
52 | ## Remove the status file. This is how we notice that the server's died. | |
53 | rm -f $1/server-status | |
54 | > $1/expected-server-output | |
55 | > $1/expected-server-errors | |
56 | ||
57 | ## Keep Autotest writes crap to standard output, which we don't want going to | |
58 | ## the server. So keep a copy of the standard output, do the pipe, and | |
59 | ## recover the old stdout inside the group. | |
60 | exec 3>&1 | |
61 | { ( | |
62 | exec 1>&3 3>&- | |
63 | ||
64 | ## Wait for the socket to appear. Watch for the server crashing during | |
65 | ## initialization. Busy waiting is evil, but it's the best I can do and | |
66 | ## not sleep for ages. (Yes, a second on each test group is a long time.) | |
67 | while test ! -r $1//server-status && test ! -S $1/admin; do :; done | |
68 | ||
69 | ## Test body... | |
70 | $3 | |
71 | ||
72 | ## End of the test, now run the server. | |
73 | ) && :; } | { | |
74 | cd $1 | |
75 | echo TRIPE $2 >&2 | |
76 | strace -f -o tripe.trace TRIPE $2 >server-output 2>server-errors | |
77 | stat=$? | |
78 | echo $stat >server-status | |
79 | if test $stat -ne 0; then | |
80 | echo "exit status: $stat" >>server-errors | |
81 | fi | |
82 | } | |
83 | exec 3>&- | |
84 | ||
85 | ## Now check that the server's output matches our expectations. | |
86 | mv $1/expected-server-output expout | |
87 | mv $1/expected-server-errors experr | |
88 | AT_CHECK([cat $1/server-output; cat >&2 $1/server-errors],, | |
89 | [expout], [experr]) | |
90 | ]) | |
91 | ||
92 | m4_define([WITH_TRIPE], [WITH_TRIPEX([.], [$1], [$2])]) | |
93 | ||
94 | m4_define([WITH_2TRIPES], | |
95 | [WITH_TRIPEX([$1], [$3 $4], [WITH_TRIPEX([$2], [$3 $5], [$6])])]) | |
96 | ||
97 | ###-------------------------------------------------------------------------- | |
98 | ### Very unpleasant coprocess handling. | |
99 | ||
100 | ## COPROCESSES(TAG, PROC-A, PROC-B) | |
101 | m4_define([COPROCESSES], [dnl | |
102 | rm -f pipe-$1; mknod pipe-$1 p | |
103 | { { $2 nl } <pipe-$1 | { $3 nl } >pipe-$1; } dnl | |
104 | ]) | |
105 | ||
106 | ## TRIPECTL_INTERACT(ARGS, SHELLSTUFF) | |
107 | m4_define([TRIPECTL_INTERACT], [ | |
108 | exec 3<&1 | |
109 | COPROCESSES([client], [exec 4>&1 1>&3 $2], [TRIPECTL $1]) | |
110 | ]) | |
111 | ||
112 | ## TRIPECTL_COMMAND(CMD, EXPECT) | |
113 | m4_define([TRIPECTL_COMMAND], [ | |
114 | AT_CHECK([ | |
115 | m4_if([$1], [!], [:], [echo "$1" >&4]) | |
116 | read line | |
117 | case "$line" in | |
118 | "$2") ;; | |
119 | *) echo 2>&1 "submitted $1: expected $2, found $line"; exit 1 ;; | |
120 | esac | |
121 | ]) | |
122 | exec 3>&- | |
123 | ]) | |
124 | ||
125 | ###-------------------------------------------------------------------------- | |
126 | ### Make sure the thing basically works. | |
127 | ||
128 | AT_SETUP([server basics]) | |
129 | SETUPDIR([ec]) | |
130 | AT_CHECK([echo port | TRIPE -p54321],, [INFO 54321[]nl[]OK[]nl]) | |
131 | AT_CLEANUP | |
132 | ||
133 | ###-------------------------------------------------------------------------- | |
134 | ### Challenges. | |
135 | ||
136 | AT_SETUP([server challenges]) | |
137 | AT_KEYWORDS([chal]) | |
138 | SETUPDIR([ec]) | |
139 | ||
140 | WITH_TRIPE(, [ | |
141 | ## A simple test. | |
142 | AT_CHECK([chal=$(TRIPECTL GETCHAL); TRIPECTL checkchal $chal]) | |
143 | ||
144 | ## A wrong challenge. (This was valid once, but the probablity that the | |
145 | ## server chose the same key is negligible.) | |
146 | AT_CHECK([TRIPECTL checkchal AAAAAHyoOL+HMaE0Y9B3ivuszt0], [1],, | |
147 | [tripectl: invalid-challenge[]nl]) | |
148 | echo WARN CHAL incorrect-tag >>expected-server-output | |
149 | ||
150 | ## A duplicated challenge. | |
151 | AT_CHECK([ | |
152 | chal=$(TRIPECTL GETCHAL) | |
153 | TRIPECTL CHECKCHAL $chal | |
154 | TRIPECTL CHECKCHAL $chal | |
155 | ], [1],, [tripectl: invalid-challenge[]nl]) | |
156 | echo WARN CHAL replay duplicated-sequence >>expected-server-output | |
157 | ||
158 | ## Out-of-order reception. There should be a window of 32 challenges; we | |
159 | ## make 33 and check them in a strange order. | |
160 | rm -f experr | |
161 | echo "tripectl: invalid-challenge" >>experr | |
162 | echo "WARN CHAL replay old-sequence" >>expected-server-output | |
163 | for i in P32; do | |
164 | echo "tripectl: invalid-challenge" >>experr | |
165 | echo "WARN CHAL replay duplicated-sequence" >>expected-server-output | |
166 | done | |
167 | AT_CHECK([ | |
168 | ||
169 | ## Make the challenges. | |
170 | for i in old R32; do TRIPECTL GETCHAL >chal-$i || exit 2; done | |
171 | ||
172 | ## Now check them back. | |
173 | for i in P32; do TRIPECTL CHECKCHAL $(cat chal-$i) || exit 3; done | |
174 | ||
175 | ## Check the one which should have fallen off the front. | |
176 | TRIPECTL CHECKCHAL $(cat chal-old) && exit 4 | |
177 | ||
178 | ## And make sure that the others are now considered duplicates. | |
179 | for i in R32; do TRIPECTL CHECKCHAL $(cat chal-$i) && exit 5; done | |
180 | ||
181 | ## All done: tidy cruft away. | |
182 | rm -f chal-* | |
183 | exit 0 | |
184 | ], [0],, [experr]) | |
185 | ]) | |
186 | ||
187 | AT_CLEANUP | |
188 | ||
189 | ###-------------------------------------------------------------------------- | |
190 | ### Communication. | |
191 | ||
192 | AT_SETUP([server communication]) | |
193 | AT_KEYWORDS([comm]) | |
194 | export TRIPE_SLIPIF=USLIP | |
195 | ||
196 | for i in alice bob; do (mkdir $i; cd $i; SETUPDIR([ec])); done | |
197 | ||
198 | WITH_2TRIPES([alice], [bob], [-nslip], [-talice], [-tbob], [ | |
199 | ||
200 | AT_CHECK([TRIPECTL -dalice PORT],, [stdout]) | |
201 | mv stdout alice/port | |
202 | ||
203 | AT_CHECK([TRIPECTL -dbob PORT],, [stdout]) | |
204 | mv stdout bob/port | |
205 | ||
206 | ## Watch for the key-exchange completion announcement, and then exit. | |
207 | COPROCESSES([wait], [ | |
208 | echo WATCH +n | |
209 | while read line; do | |
210 | case "$line" in | |
211 | OK) ;; | |
212 | "NOTE KXDONE "*) break ;; | |
213 | NOTE*) ;; | |
214 | *) exit 63 ;; | |
215 | esac | |
216 | done | |
217 | ], [ | |
218 | TRIPECTL -dalice | |
219 | ]) & | |
220 | ||
221 | ## Don't panic if you don't see the unexpected-source warning. It happens | |
222 | ## for me, but it's not important either way. | |
223 | AT_CHECK([TRIPECTL -dalice ADD bob INET 127.0.0.1 $(cat bob/port)]) | |
224 | echo >>bob/expected-server-output \ | |
225 | "WARN PEER - unexpected-source INET 127.0.0.1 $(cat alice/port)" | |
226 | AT_CHECK([TRIPECTL -dbob ADD alice INET 127.0.0.1 $(cat alice/port)]) | |
227 | ||
228 | ## Check transport pinging. | |
229 | AT_CHECK([TRIPECTL -dalice PING bob],, [ignore]) | |
230 | AT_CHECK([TRIPECTL -dbob PING alice],, [ignore]) | |
231 | ||
232 | ## Wait for the completion announcement. | |
233 | wait | |
234 | ||
235 | ## Check encrypted pinging. | |
236 | AT_CHECK([TRIPECTL -dalice EPING bob],, [ignore]) | |
237 | AT_CHECK([TRIPECTL -dbob EPING alice],, [ignore]) | |
238 | ||
239 | ## Check that packets can flow from one to the other. | |
240 | AT_CHECK([echo "from alice" | USLIP -p alice/bob]) | |
241 | AT_CHECK([USLIP -g bob/alice],, [from alice[]nl]) | |
242 | ||
243 | AT_CHECK([echo "from bob" | USLIP -p bob/alice]) | |
244 | AT_CHECK([USLIP -g alice/bob],, [from bob[]nl]) | |
245 | ]) | |
246 | ||
247 | AT_CLEANUP | |
248 | ||
249 | ###-------------------------------------------------------------------------- | |
250 | ### Services. | |
251 | ||
252 | AT_SETUP([server services]) | |
253 | AT_KEYWORDS([svc]) | |
254 | SETUPDIR([ec]) | |
255 | ||
256 | WITH_TRIPE(, [ | |
257 | ||
258 | ## Make sure it's not running yet. | |
259 | AT_CHECK([TRIPECTL SVCENSURE test], [1],, | |
260 | [tripectl: unknown-service test[]nl]) | |
261 | ||
262 | ## Run a simple service. | |
263 | rm -f svc-test-running tripectl-status | |
264 | COPROCESSES([svc], [ | |
265 | echo SVCCLAIM test 1.0.0 | |
266 | read line | |
267 | case "$line" in | |
268 | OK) | |
269 | ;; | |
270 | *) | |
271 | echo >&2 "SVCCLAIM failed: $line" | |
272 | exit 1 | |
273 | ;; | |
274 | esac | |
275 | echo ok >svc-test-running | |
276 | while read line; do | |
277 | set -- $line | |
278 | case "$[]1,$[]3,$[]4" in | |
279 | SVCJOB,test,HELP) | |
280 | echo SVCINFO try not to use this service for anything useful | |
281 | echo SVCOK $[]2 | |
282 | ;; | |
283 | SVCJOB,test,GOOD) | |
284 | echo SVCOK $[]2 | |
285 | ;; | |
286 | SVCJOB,test,BAD) | |
287 | echo SVCFAIL $[]2 this-command-always-fails | |
288 | ;; | |
289 | SVCJOB,test,UGLY) | |
290 | tag=$2 | |
291 | while read line; do | |
292 | set -- $line | |
293 | case "$[]1,$[]2,$[]3,$[]4" in | |
294 | SVCCANCEL,$tag,,) break ;; | |
295 | SVCJOB,*,test,ESCAPE) | |
296 | echo >&2 "attempt to escape from alkatraz" | |
297 | exit 1 | |
298 | ;; | |
299 | esac | |
300 | done | |
301 | ;; | |
302 | SVCJOB,test,FIRST) | |
303 | firsttag=$[]2 | |
304 | ;; | |
305 | SVCJOB,test,SECOND) | |
306 | echo SVCOK $firsttag | |
307 | echo SVCOK $[]2 | |
308 | ;; | |
309 | SVCJOB,*) | |
310 | echo SVCFAIL $[]2 unknown-svc-command $[]4 | |
311 | ;; | |
312 | SVCCLAIM,*) | |
313 | break | |
314 | ;; | |
315 | OK,* | INFO,*) | |
316 | ;; | |
317 | FAIL,*) | |
318 | echo "failure in service: $line" >&2 | |
319 | ;; | |
320 | esac | |
321 | done | |
322 | ], [ | |
323 | TRIPECTL; echo $? >tripectl-status | |
324 | ]) 2>tripectl-errors & | |
325 | ||
326 | ## Wait until it starts up. | |
327 | while test ! -r svc-test-running && test ! -r tripectl-status; do :; done | |
328 | ||
329 | ## Make sure it's running. | |
330 | AT_CHECK([TRIPECTL SVCQUERY test],, [name=test version=1.0.0[]nl]) | |
331 | ||
332 | ## Try some simple commands. | |
333 | AT_CHECK([TRIPECTL SVCSUBMIT test GOOD]) | |
334 | AT_CHECK([TRIPECTL SVCSUBMIT test BAD], [1],, | |
335 | [tripectl: this-command-always-fails[]nl]) | |
336 | ||
337 | ## And now with commands in the background. | |
338 | TRIPECTL_INTERACT([ | |
339 | TRIPECTL_COMMAND([SVCSUBMIT test GOOD], [OK]) | |
340 | TRIPECTL_COMMAND([SVCSUBMIT -background foo test UGLY], [BGDETACH foo]) | |
341 | TRIPECTL_COMMAND([BGCANCEL foo], [OK]) | |
342 | TRIPECTL_COMMAND([SVCSUBMIT test ESCAPE], | |
343 | [FAIL unknown-svc-command ESCAPE]) | |
344 | ]) | |
345 | ||
346 | ## Out-of-order completion. | |
347 | TRIPECTL_INTERACT([ | |
348 | TRIPECTL_COMMAND([SVCSUBMIT -background one test FIRST], [BGDETACH one]) | |
349 | TRIPECTL_COMMAND([SVCSUBMIT -background two test SECOND], [BGDETACH two]) | |
350 | TRIPECTL_COMMAND([!], [BGOK one]) | |
351 | TRIPECTL_COMMAND([!], [BGOK two]) | |
352 | ]) | |
353 | ||
354 | ## All done. | |
355 | exit 0 | |
356 | ]) | |
357 | ||
358 | AT_CLEANUP | |
359 | ||
360 | ###----- That's all, folks -------------------------------------------------- |