make expectedout file during keytrans test in test directory, not in the cwd
[monkeysphere.git] / tests / basic
1 #!/usr/bin/env bash
2
3 # Tests to ensure that the monkeysphere is working
4 #
5 # unset MONKEYSPHERE_TEST_NO_EXAMINE to get a prompt to examine the
6 # test state after failure.
7
8 # Authors: 
9 #   Daniel Kahn Gillmor <dkg@fifthhorseman.net>
10 #   Jameson Rollins <jrollins@fifthhorseman.net>
11 #   Micah Anderson <micah@riseup.net> 
12 #
13 # Copyright: 2008-2009
14 # License: GPL v3 or later
15
16 # these tests should all be able to run as a non-privileged user.
17
18 # put all the test output to stdout
19 exec 2>&1
20 # all subcommands in this script should complete without failure:
21 set -e
22 # piped commands should return the code of the first non-zero return
23 set -o pipefail
24
25 # make sure the TESTDIR is an absolute path, not a relative one.
26 export TESTDIR=$(cd $(dirname "$0") && pwd)
27
28 source "$TESTDIR"/common
29
30 ## make sure that the right tools are installed to run the test.  the
31 ## test has *more* requirements than plain ol' monkeysphere:
32 [ -f /usr/sbin/sshd ] || { echo "You must have sshd installed to run this test." ; exit 1; }
33 which socat >/dev/null || { echo "You must have socat installed to run this test." ; exit 1; }
34
35 perl -MCrypt::OpenSSL::RSA -e 1 2>/dev/null || { echo "You must have the perl module Crypt::OpenSSL::RSA installed to run this test.  
36 On debian-derived systems, you can set this up with:
37   apt-get install libcrypt-openssl-rsa-perl" ; exit 1; }
38
39 perl -MDigest::SHA -e 1 2>/dev/null || { echo "You must have the perl module Digest::SHA installed to run this test.  
40 On debian-derived systems, you can set this up with:
41   apt-get install libdigest-sha-perl" ; exit 1; }
42
43 ## FIXME: other checks?
44
45 ######################################################################
46 ### FUNCTIONS
47
48 # gpg command for test admin user
49 gpgadmin() {
50     chmod 0700 "$TEMPDIR"/admin "$TEMPDIR"/admin/.gnupg
51     GNUPGHOME="$TEMPDIR"/admin/.gnupg gpg --no-tty "$@"
52 }
53
54 # test ssh connection
55 # first argument is expected return code from ssh connection
56 ssh_test() {
57     local RETURN=0
58
59     umask 0077
60
61     CODE=${1:-0}
62
63     # start the ssh daemon on the socket
64     echo "##### starting ssh server..."
65     socat EXEC:"/usr/sbin/sshd -f ${SSHD_CONFIG} -i -D -e" "UNIX-LISTEN:${SOCKET}" 2> "$TEMPDIR"/sshd.log &
66     SSHD_PID="$!"
67
68     # wait until the socket is created before continuing
69     while [ ! -S "$SOCKET" ] ; do
70         sleep 1
71     done
72
73     # make a client connection to the socket
74     echo "##### starting ssh client..."
75     ssh-agent bash -c \
76         "monkeysphere subkey-to-ssh-agent && ssh -F $TEMPDIR/testuser/.ssh/config ${target_hostname:-testhost} true" \
77         || RETURN="$?"
78
79     # kill the sshd process if it's still running
80     kill "$SSHD_PID" || true
81     wait
82     SSHD_PID=
83
84     if [ "$RETURN" = "$CODE" ] ; then
85         echo "##### ssh connection test PASSED. returned: $RETURN"
86         return 0
87     else
88         echo "##### ssh connection test FAILED. returned: $RETURN, expected: $CODE"
89         return 1
90     fi
91 }
92
93 # invoke this instead of ssh_test() if you want this test to be
94 # skipped when the working directory has bad permissions.
95 ssh_good_perm_test() {
96     if [ "$TEMPDIR_PERMISSIONS_SAFE" = no ] ; then
97         echo "WARNING!!! Test SKIPPED because we are running in an unsafe working directory."
98     else
99         ssh_test "$@"
100     fi
101 }
102
103
104 SSHD_PID=
105
106 ## setup trap
107 trap failed_cleanup EXIT
108
109
110 ######################################################################
111 ### SETUP VARIABLES
112
113 ## set up some variables to ensure that we're operating strictly in
114 ## the tests, not system-wide:
115
116 # set up temp dir
117
118 # NOTE: /tmp can not be used as the temp dir here, since the
119 # permissions on /tmp are usually such that they will not pass the
120 # monkeysphere/ssh path permission checking.  If you need to use a
121 # different location than the current source, please set $TMPDIR
122 # somewhere with tighter permissions.
123
124 mkdir -p "$TESTDIR"/tmp
125 TEMPDIR=$(mktemp -d "${TMPDIR:-$TESTDIR/tmp}/monkeyspheretest.XXXXXXX")
126
127 # Use the local copy of executables first, instead of system ones.
128 # This should help us test without installing.
129 export PATH="$TESTDIR"/../src:"$PATH"
130
131 export MONKEYSPHERE_SYSDATADIR="$TEMPDIR"
132 export MONKEYSPHERE_SYSCONFIGDIR="$TEMPDIR"
133 export MONKEYSPHERE_SYSSHAREDIR="$TESTDIR"/../src/share
134 export MONKEYSPHERE_MONKEYSPHERE_USER=$(whoami)
135
136 export MONKEYSPHERE_CHECK_KEYSERVER=false
137 # example.org does not respond to the HKP port, so this should cause
138 # any keyserver connection attempts that do happen (they shouldn't!)
139 # to hang, so we'll notice them:
140 export MONKEYSPHERE_KEYSERVER=example.org
141
142 export MONKEYSPHERE_LOG_LEVEL=DEBUG
143 export MONKEYSPHERE_CORE_KEYLENGTH=1024
144 export MONKEYSPHERE_PROMPT=false
145
146 # unset SUBKEYS_FOR_AGENT variable which, if set, would confuse the
147 # into trying to use the user's key, instead of the testuser's key
148 unset MONKEYSPHERE_SUBKEYS_FOR_AGENT
149
150 export SSHD_CONFIG="$TEMPDIR"/sshd_config
151 export SOCKET="$TEMPDIR"/ssh-socket
152
153 # Make sure $DISPLAY is set to convince ssh and monkeysphere to fall
154 # back on $SSH_ASKPASS.  Make sure it's not set to the current actual
155 # $DISPLAY (if one exists) because this test suite should not be doing
156 # *anything* with any running X11 session.
157 export DISPLAY=monkeys
158
159
160 ## we cannot do proper directory permissions checking if the current
161 ## working directory has unsatisfactory permissions:
162 if ( . "$MONKEYSPHERE_SYSSHAREDIR"/common && check_key_file_permissions $(whoami) "$TEMPDIR" ) ; then 
163     echo "Permissions on temporary directory '$TEMPDIR' are OK for permissions checks."
164     TEMPDIR_PERMISSIONS_SAFE=yes
165 else
166     cat <<EOF
167
168 !!!WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING!!!
169  Permissions on testing directory '$TEMPDIR' are
170  too loose to do proper strict permissions checking.  Some tests 
171  will be disabled or ignored.
172
173  To avoid this warning (and to make sure that all tests are run
174  properly), please run these tests within a directory that meets
175  sshd's standards for "StrictModes yes" -- the directory (and every
176  one of its parents) should be owned only be the user running this
177  test or root, and should not be writable by group or other.
178 !!!WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING!!!
179
180 EOF
181
182     # FIXME: what else should we do with this knowledge to make sure
183     # that the appropriate tests are handled properly?
184     TEMPDIR_PERMISSIONS_SAFE=no
185
186     # this is a new option (as of 0.26) to disable filesystem
187     # permission checks.
188
189     # it should operate by analogy with StrictModes from sshd_config(5)
190     export MONKEYSPHERE_STRICT_MODES=no
191 fi
192
193
194
195 ######################################################################
196 ### CONFIGURE ENVIRONMENTS
197
198 # copy in admin and testuser home to tmp
199 echo
200 echo "##################################################"
201 echo "### configuring testuser home..."
202 (cd "$TESTDIR"/home && find testuser | cpio -pdu "$TEMPDIR")
203
204 # set up environment for testuser
205 export TESTHOME="$TEMPDIR"/testuser
206 export GNUPGHOME="$TESTHOME"/.gnupg
207 chmod 0700 "$GNUPGHOME"
208 export SSH_ASKPASS="$TESTHOME"/.ssh/askpass
209 export MONKEYSPHERE_HOME="$TESTHOME"/.monkeysphere
210 cat <<EOF >> "$TESTHOME"/.ssh/config
211 UserKnownHostsFile $TESTHOME/.ssh/known_hosts
212 IdentityFile $TESTHOME/.ssh/no-such-identity
213 ProxyCommand $TESTHOME/.ssh/proxy-command %h %p $SOCKET
214 EOF
215 cat <<EOF >> "$MONKEYSPHERE_HOME"/monkeysphere.conf
216 KNOWN_HOSTS=$TESTHOME/.ssh/known_hosts
217 EOF
218 get_gpg_prng_arg >> "$GNUPGHOME"/gpg.conf
219
220 echo
221 echo "##################################################"
222 echo "### configuring admin home..."
223 (cd "$TESTDIR"/home && find admin | cpio -pdu "$TEMPDIR")
224
225 # set up sshd
226 echo
227 echo "##################################################"
228 echo "### configuring sshd..."
229 cp "$TESTDIR"/etc/ssh/sshd_config "$SSHD_CONFIG"
230 # write the sshd_config
231 cat <<EOF >> "$SSHD_CONFIG"
232 HostKey ${MONKEYSPHERE_SYSDATADIR}/ssh_host_rsa_key
233 AuthorizedKeysFile ${MONKEYSPHERE_SYSDATADIR}/authorized_keys/%u
234 EOF
235
236 # disable sshd's strict permissions settings so that some tests can
237 # complete when running under a dubious path:
238 if [ "$TEMPDIR_PERMISSIONS_SAFE" != yes ] ; then
239     cat <<EOF >> "$SSHD_CONFIG"
240 StrictModes no
241 EOF
242 fi
243
244
245 ######################################################################
246 ### SERVER HOST SETUP
247
248 # import host key
249 echo
250 echo "##################################################"
251 echo "### import host key..."
252 ssh-keygen -b 1024 -t rsa -N '' -f "$TEMPDIR"/ssh_host_rsa_key
253 monkeysphere-host import-key "$TEMPDIR"/ssh_host_rsa_key testhost
254
255 echo
256 echo "##################################################"
257 echo "### getting host key fingerprint..."
258 HOSTKEYID=$( monkeysphere-host show-key | grep '^OpenPGP fingerprint: ' | cut -f3 -d\  )
259 echo "$HOSTKEYID"
260
261 # change host key expiration
262 echo
263 echo "##################################################"
264 echo "### setting host key expiration..."
265 monkeysphere-host set-expire 1
266 # FIXME: how do we check that the expiration has really been set?
267
268 # certify host key with the "Admin's Key".
269 # (this would normally be done via keyservers)
270 echo
271 echo "##################################################"
272 echo "### certifying server host key..."
273 < "$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg gpgadmin --import
274 echo y | gpgadmin --command-fd 0 --sign-key "$HOSTKEYID"
275
276 # FIXME: add revoker?
277
278 # FIXME: how can we test publish-key without flooding junk into the
279 # keyservers?
280
281 # FIXME: should we run "diagnostics" here to test setup?
282
283
284 ######################################################################
285 ### SERVER AUTHENTICATION SETUP
286
287 # set up monkeysphere authentication
288 echo
289 echo "##################################################"
290 echo "### setup monkeysphere authentication..."
291 cp "$TESTDIR"/etc/monkeysphere/monkeysphere-authentication.conf "$TEMPDIR"/
292 cat <<EOF >> "$TEMPDIR"/monkeysphere-authentication.conf
293 AUTHORIZED_USER_IDS="$MONKEYSPHERE_HOME/authorized_user_ids"
294 EOF
295 monkeysphere-authentication setup
296 get_gpg_prng_arg >> "$MONKEYSPHERE_SYSDATADIR"/authentication/sphere/gpg.conf
297
298 # add admin as identity certifier for testhost
299 echo
300 echo "##################################################"
301 echo "### adding admin as certifier..."
302 monkeysphere-authentication add-id-certifier "$TEMPDIR"/admin/.gnupg/pubkey.gpg
303
304 echo
305 echo "##################################################"
306 echo "### list certifiers..."
307 monkeysphere-authentication list-certifiers
308
309 # FIXME: should we run "diagnostics" here to test setup?
310
311 ######################################################################
312 ### TESTUSER SETUP
313
314 # generate an auth subkey for the test user that expires in 2 days
315 echo
316 echo "##################################################"
317 echo "### generating key for testuser..."
318 monkeysphere gen-subkey
319
320 # add server key to testuser keychain
321 echo
322 echo "##################################################"
323 echo "### export server key to testuser..."
324 gpgadmin --armor --export "$HOSTKEYID" | gpg --import
325
326 # teach the "server" about the testuser's key
327 echo
328 echo "##################################################"
329 echo "### export testuser key to server..."
330 gpg --export testuser | monkeysphere-authentication gpg-cmd --import
331
332 # update authorized_keys for user
333 echo
334 echo "##################################################"
335 echo "### update server authorized_keys file for this testuser..."
336 monkeysphere-authentication update-users $(whoami)
337 # FIXME: this is maybe not failing properly for:
338 # ms: improper group or other writability on path '/tmp'.
339
340 ######################################################################
341 ### TESTS
342
343 # connect to test sshd, using monkeysphere ssh-proxycommand to verify
344 # the identity before connection.  This should work in both directions!
345 echo
346 echo "##################################################"
347 echo "### ssh connection test for success..."
348 ssh_test
349
350 # remove the testuser's authorized_user_ids file, update, and make
351 # sure that the ssh authentication FAILS
352 echo
353 echo "##################################################"
354 echo "### removing testuser authorized_user_ids and updating..."
355 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{,.bak}
356 monkeysphere-authentication update-users $(whoami)
357 echo
358 echo "##################################################"
359 echo "### ssh connection test for failure..."
360 ssh_test 255
361 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{.bak,}
362
363 # put improper permissions on authorized_user_ids file, update, and
364 # make sure ssh authentication FAILS
365 echo
366 echo "##################################################"
367 echo "### setting group writability on authorized_user_ids and updating..."
368 chmod g+w "$TESTHOME"/.monkeysphere/authorized_user_ids
369 monkeysphere-authentication update-users $(whoami)
370 echo
371 echo "##################################################"
372 echo "### ssh connection test for failure..."
373 ssh_good_perm_test 255
374 chmod g-w "$TESTHOME"/.monkeysphere/authorized_user_ids
375 echo
376 echo "##################################################"
377 echo "### setting other writability on authorized_user_ids and updating..."
378 chmod o+w "$TESTHOME"/.monkeysphere/authorized_user_ids
379 monkeysphere-authentication update-users $(whoami)
380 echo
381 echo "##################################################"
382 echo "### ssh connection test for failure..."
383 ssh_good_perm_test 255
384 chmod o-w "$TESTHOME"/.monkeysphere/authorized_user_ids
385 monkeysphere-authentication update-users $(whoami)
386
387 # test symlinks
388 echo
389 echo "##################################################"
390 echo "### setup for symlink tests..."
391 cp -a "$TESTHOME"/.monkeysphere{,.linktest}
392
393 echo
394 echo "##################################################"
395 echo "### make authorized_user_ids an absolute symlink and updating..."
396 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{,.bak}
397 ln -s "$TESTHOME"/.monkeysphere{.linktest,}/authorized_user_ids
398 monkeysphere-authentication update-users $(whoami)
399 echo
400 echo "##################################################"
401 echo "### ssh connection test for success..."
402 ssh_test
403 echo
404 echo "##################################################"
405 echo "### create bad permissions on link dir and updating..."
406 chmod o+w "$TESTHOME"/.monkeysphere.linktest
407 monkeysphere-authentication update-users $(whoami)
408 echo
409 echo "##################################################"
410 echo "### ssh connection test for failure..."
411 ssh_good_perm_test 255
412 chmod o-w "$TESTHOME"/.monkeysphere.linktest
413 echo
414 echo "##################################################"
415 echo "### make authorized_user_ids a relative symlink and updating..."
416 ln -sf ../.monkeysphere.linktest/authorized_user_ids "$TESTHOME"/.monkeysphere/authorized_user_ids
417 monkeysphere-authentication update-users $(whoami)
418 echo
419 echo "##################################################"
420 echo "### ssh connection test for success..."
421 ssh_test
422 echo
423 echo "##################################################"
424 echo "### create bad permissions on link dir updating..."
425 chmod o+w "$TESTHOME"/.monkeysphere.linktest
426 monkeysphere-authentication update-users $(whoami)
427 echo
428 echo "##################################################"
429 echo "### ssh connection test for failure..."
430 ssh_good_perm_test 255
431 chmod o-w "$TESTHOME"/.monkeysphere.linktest
432 # FIXME: implement check of link path, and uncomment this test
433 # echo
434 # echo "##################################################"
435 # echo "### create bad permissions on link dir and updating..."
436 # chmod o+w "$TESTHOME"/.monkeysphere
437 # monkeysphere-authentication update-users $(whoami)
438 # echo
439 # echo "##################################################"
440 # echo "### ssh connection test for failure..."
441 # ssh_good_perm_test 255
442 # chmod o-w "$TESTHOME"/.monkeysphere
443 rm "$TESTHOME"/.monkeysphere/authorized_user_ids
444 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{.bak,}
445
446 echo
447 echo "##################################################"
448 echo "### make .monkeysphere directory an absolute symlink and updating..."
449 mv "$TESTHOME"/.monkeysphere{,.bak}
450 ln -s "$TESTHOME"/.monkeysphere{.linktest,}
451 monkeysphere-authentication update-users $(whoami)
452 echo
453 echo "##################################################"
454 echo "### ssh connection test for success..."
455 ssh_test
456 echo
457 echo "##################################################"
458 echo "### create bad permissions on link dir and updating..."
459 chmod o+w "$TESTHOME"/.monkeysphere.linktest
460 monkeysphere-authentication update-users $(whoami)
461 echo
462 echo "##################################################"
463 echo "### ssh connection test for failure..."
464 ssh_good_perm_test 255
465 chmod o-w "$TESTHOME"/.monkeysphere.linktest
466 echo
467 echo "##################################################"
468 echo "### make .monkeysphere directory a relative symlink and updating..."
469 ln -sfn .monkeysphere.linktest "$TESTHOME"/.monkeysphere
470 monkeysphere-authentication update-users $(whoami)
471 echo
472 echo "##################################################"
473 echo "### ssh connection test for success..."
474 ssh_test
475 echo
476 echo "##################################################"
477 echo "### create bad permissions on link dir updating..."
478 chmod o+w "$TESTHOME"/.monkeysphere.linktest
479 monkeysphere-authentication update-users $(whoami)
480 echo
481 echo "##################################################"
482 echo "### ssh connection test for failure..."
483 ssh_good_perm_test 255
484 chmod o-w "$TESTHOME"/.monkeysphere.linktest
485 rm "$TESTHOME"/.monkeysphere
486 mv "$TESTHOME"/.monkeysphere{.bak,}
487
488 # ensure we're back to normal:
489 echo
490 echo "##################################################"
491 echo "### making sure we are back to normal..."
492 monkeysphere-authentication update-users $(whoami)
493 ssh_test
494
495
496 echo
497 echo "##################################################"
498 echo "### ssh connection test directly to 'testhost2' without new name..."
499 target_hostname=testhost2 ssh_test 255
500 echo
501 echo "##################################################"
502 echo "### add hostname, certify by admin, import by user..."
503 monkeysphere-host add-hostname testhost2
504 < "$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg gpgadmin --import
505 printf "y\ny\n" | gpgadmin --command-fd 0 --sign-key "$HOSTKEYID"
506
507 echo
508 echo "##################################################"
509 echo "### ssh connection test with hostname 'testhost2' added..."
510 gpgadmin --export "$HOSTKEYID" | gpg --import
511 gpg --check-trustdb
512 ssh_test
513
514 echo
515 echo "##################################################"
516 echo "### ssh connection test directly to 'testhost2' ..."
517 gpg --import <"$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg 
518 gpg --check-trustdb
519 target_hostname=testhost2 ssh_test
520
521 echo
522 echo "##################################################"
523 echo "### ssh connection test for failure with 'testhost2' revoked..."
524 monkeysphere-host revoke-hostname testhost2
525 gpg --import <"$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg
526 gpg --check-trustdb
527 target_hostname=testhost2 ssh_test 255
528
529 # FIXME: addtest: remove admin as id-certifier and check ssh failure
530
531 # FIXME: addtest: how do we test that set-expire makes sense after new
532 # hostnames have been added?
533
534 # FIXME: addtest: revoke the host key and check ssh failure
535
536 # test to make sure things are OK after the previous tests:
537 echo
538 echo "##################################################"
539 echo "### settings reset, updating..."
540 monkeysphere-authentication update-users $(whoami)
541 echo
542 echo "##################################################"
543 echo "### ssh connection test for success..."
544 ssh_test
545
546 echo
547 echo "##################################################"
548 echo "### revoking host key..."
549 # generate the revocation certificate and feed it directly to the test
550 # user's keyring (we're not publishing to the keyservers)
551 monkeysphere-host revoke-key | gpg --import
552 echo
553 echo "##################################################"
554 echo "### ssh connection test for failure..."
555 ssh_test 255
556
557
558 ######################################################################
559
560 trap - EXIT
561
562 echo
563 echo "##################################################"
564 echo " Monkeysphere basic tests completed successfully!"
565 echo "##################################################"
566
567 cleanup