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