started preparing tests to work under loosely-permissioned temporary directories.
[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
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 SSHD_PID=
94
95 ## setup trap
96 trap failed_cleanup EXIT
97
98
99 ######################################################################
100 ### SETUP VARIABLES
101
102 ## set up some variables to ensure that we're operating strictly in
103 ## the tests, not system-wide:
104
105 # set up temp dir
106
107 # NOTE: /tmp can not be used as the temp dir here, since the
108 # permissions on /tmp are usually such that they will not pass the
109 # monkeysphere/ssh path permission checking.  If you need to use a
110 # different location than the current source, please set $TMPDIR
111 # somewhere with tighter permissions.
112
113 mkdir -p "$TESTDIR"/tmp
114 TEMPDIR=$(mktemp -d "${TMPDIR:-$TESTDIR/tmp}/monkeyspheretest.XXXXXXX")
115
116 # Use the local copy of executables first, instead of system ones.
117 # This should help us test without installing.
118 export PATH="$TESTDIR"/../src:"$PATH"
119
120 export MONKEYSPHERE_SYSDATADIR="$TEMPDIR"
121 export MONKEYSPHERE_SYSCONFIGDIR="$TEMPDIR"
122 export MONKEYSPHERE_SYSSHAREDIR="$TESTDIR"/../src/share
123 export MONKEYSPHERE_MONKEYSPHERE_USER=$(whoami)
124
125 export MONKEYSPHERE_CHECK_KEYSERVER=false
126 # example.org does not respond to the HKP port, so this should cause
127 # any keyserver connection attempts that do happen (they shouldn't!)
128 # to hang, so we'll notice them:
129 export MONKEYSPHERE_KEYSERVER=example.org
130
131 export MONKEYSPHERE_LOG_LEVEL=DEBUG
132 export MONKEYSPHERE_CORE_KEYLENGTH=1024
133 export MONKEYSPHERE_PROMPT=false
134
135 # unset SUBKEYS_FOR_AGENT variable which, if set, would confuse the
136 # into trying to use the user's key, instead of the testuser's key
137 unset MONKEYSPHERE_SUBKEYS_FOR_AGENT
138
139 export SSHD_CONFIG="$TEMPDIR"/sshd_config
140 export SOCKET="$TEMPDIR"/ssh-socket
141
142 # Make sure $DISPLAY is set to convince ssh and monkeysphere to fall
143 # back on $SSH_ASKPASS.  Make sure it's not set to the current actual
144 # $DISPLAY (if one exists) because this test suite should not be doing
145 # *anything* with any running X11 session.
146 export DISPLAY=monkeys
147
148
149 ## we cannot do proper directory permissions checking if the current
150 ## working directory has unsatisfactory permissions:
151 if ( . "$MONKEYSPHERE_SYSSHAREDIR"/common && check_key_file_permissions $(whoami) "$TEMPDIR" ) ; then 
152     echo "Permissions on temporary directory '$TEMPDIR' are OK for permissions checks."
153     TEMPDIR_PERMISSIONS_SAFE=yes
154 else
155     cat <<EOF
156
157 !!!WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING!!!
158  Permissions on testing directory '$TEMPDIR' are
159  too loose to do proper strict permissions checking.  Some tests 
160  will be disabled or ignored.
161
162  To avoid this warning (and to make sure that all tests are run
163  properly), please run these tests within a directory that meets
164  sshd's standards for "StrictModes yes" -- the directory (and every
165  one of its parents) should be owned only be the user running this
166  test or root, and should not be writable by group or other.
167 !!!WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING!!!
168
169 EOF
170
171     # FIXME: what should we do with this knowledge to make sure that
172     # the appropriate tests are handled properly?
173     TEMPDIR_PERMISSIONS_SAFE=no
174 fi
175
176
177
178 ######################################################################
179 ### CONFIGURE ENVIRONMENTS
180
181 # copy in admin and testuser home to tmp
182 echo
183 echo "##################################################"
184 echo "### configuring testuser home..."
185 (cd "$TESTDIR"/home && find testuser | cpio -pdu "$TEMPDIR")
186
187 # set up environment for testuser
188 export TESTHOME="$TEMPDIR"/testuser
189 export GNUPGHOME="$TESTHOME"/.gnupg
190 chmod 0700 "$GNUPGHOME"
191 export SSH_ASKPASS="$TESTHOME"/.ssh/askpass
192 export MONKEYSPHERE_HOME="$TESTHOME"/.monkeysphere
193 cat <<EOF >> "$TESTHOME"/.ssh/config
194 UserKnownHostsFile $TESTHOME/.ssh/known_hosts
195 IdentityFile $TESTHOME/.ssh/no-such-identity
196 ProxyCommand $TESTHOME/.ssh/proxy-command %h %p $SOCKET
197 EOF
198 cat <<EOF >> "$MONKEYSPHERE_HOME"/monkeysphere.conf
199 KNOWN_HOSTS=$TESTHOME/.ssh/known_hosts
200 EOF
201 get_gpg_prng_arg >> "$GNUPGHOME"/gpg.conf
202
203 echo
204 echo "##################################################"
205 echo "### configuring admin home..."
206 (cd "$TESTDIR"/home && find admin | cpio -pdu "$TEMPDIR")
207
208 # set up sshd
209 echo
210 echo "##################################################"
211 echo "### configuring sshd..."
212 cp "$TESTDIR"/etc/ssh/sshd_config "$SSHD_CONFIG"
213 # write the sshd_config
214 cat <<EOF >> "$SSHD_CONFIG"
215 HostKey ${MONKEYSPHERE_SYSDATADIR}/ssh_host_rsa_key
216 AuthorizedKeysFile ${MONKEYSPHERE_SYSDATADIR}/authorized_keys/%u
217 EOF
218
219 # disable sshd's strict permissions settings so that some tests can
220 # complete when running under a dubious path:
221 if [ "$TEMPDIR_PERMISSIONS_SAFE" != yes ] ; then
222     cat <<EOF >> "$SSHD_CONFIG"
223 StrictModes no
224 EOF
225 fi
226
227
228 ######################################################################
229 ### SERVER HOST SETUP
230
231 # import host key
232 echo
233 echo "##################################################"
234 echo "### import host key..."
235 ssh-keygen -b 1024 -t rsa -N '' -f "$TEMPDIR"/ssh_host_rsa_key
236 monkeysphere-host import-key "$TEMPDIR"/ssh_host_rsa_key testhost
237
238 echo
239 echo "##################################################"
240 echo "### getting host key fingerprint..."
241 HOSTKEYID=$( monkeysphere-host show-key | grep '^OpenPGP fingerprint: ' | cut -f3 -d\  )
242 echo "$HOSTKEYID"
243
244 # change host key expiration
245 echo
246 echo "##################################################"
247 echo "### setting host key expiration..."
248 monkeysphere-host set-expire 1
249 # FIXME: how do we check that the expiration has really been set?
250
251 # certify host key with the "Admin's Key".
252 # (this would normally be done via keyservers)
253 echo
254 echo "##################################################"
255 echo "### certifying server host key..."
256 < "$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg gpgadmin --import
257 echo y | gpgadmin --command-fd 0 --sign-key "$HOSTKEYID"
258
259 # FIXME: add revoker?
260
261 # FIXME: how can we test publish-key without flooding junk into the
262 # keyservers?
263
264 # FIXME: should we run "diagnostics" here to test setup?
265
266
267 ######################################################################
268 ### SERVER AUTHENTICATION SETUP
269
270 # set up monkeysphere authentication
271 echo
272 echo "##################################################"
273 echo "### setup monkeysphere authentication..."
274 cp "$TESTDIR"/etc/monkeysphere/monkeysphere-authentication.conf "$TEMPDIR"/
275 cat <<EOF >> "$TEMPDIR"/monkeysphere-authentication.conf
276 AUTHORIZED_USER_IDS="$MONKEYSPHERE_HOME/authorized_user_ids"
277 EOF
278 monkeysphere-authentication setup
279 get_gpg_prng_arg >> "$MONKEYSPHERE_SYSDATADIR"/authentication/sphere/gpg.conf
280
281 # add admin as identity certifier for testhost
282 echo
283 echo "##################################################"
284 echo "### adding admin as certifier..."
285 monkeysphere-authentication add-id-certifier "$TEMPDIR"/admin/.gnupg/pubkey.gpg
286
287 echo
288 echo "##################################################"
289 echo "### list certifiers..."
290 monkeysphere-authentication list-certifiers
291
292 # FIXME: should we run "diagnostics" here to test setup?
293
294 ######################################################################
295 ### TESTUSER SETUP
296
297 # generate an auth subkey for the test user that expires in 2 days
298 echo
299 echo "##################################################"
300 echo "### generating key for testuser..."
301 monkeysphere gen-subkey
302
303 # add server key to testuser keychain
304 echo
305 echo "##################################################"
306 echo "### export server key to testuser..."
307 gpgadmin --armor --export "$HOSTKEYID" | gpg --import
308
309 # teach the "server" about the testuser's key
310 echo
311 echo "##################################################"
312 echo "### export testuser key to server..."
313 gpg --export testuser | monkeysphere-authentication gpg-cmd --import
314
315 # update authorized_keys for user
316 echo
317 echo "##################################################"
318 echo "### update server authorized_keys file for this testuser..."
319 monkeysphere-authentication update-users $(whoami)
320 # FIXME: this is maybe not failing properly for:
321 # ms: improper group or other writability on path '/tmp'.
322
323 ######################################################################
324 ### TESTS
325
326 # connect to test sshd, using monkeysphere ssh-proxycommand to verify
327 # the identity before connection.  This should work in both directions!
328 echo
329 echo "##################################################"
330 echo "### ssh connection test for success..."
331 ssh_test
332
333 # remove the testuser's authorized_user_ids file, update, and make
334 # sure that the ssh authentication FAILS
335 echo
336 echo "##################################################"
337 echo "### removing testuser authorized_user_ids and updating..."
338 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{,.bak}
339 monkeysphere-authentication update-users $(whoami)
340 echo
341 echo "##################################################"
342 echo "### ssh connection test for failure..."
343 ssh_test 255
344 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{.bak,}
345
346 # put improper permissions on authorized_user_ids file, update, and
347 # make sure ssh authentication FAILS
348 echo
349 echo "##################################################"
350 echo "### setting group writability on authorized_user_ids and updating..."
351 chmod g+w "$TESTHOME"/.monkeysphere/authorized_user_ids
352 monkeysphere-authentication update-users $(whoami)
353 echo
354 echo "##################################################"
355 echo "### ssh connection test for failure..."
356 ssh_test 255
357 chmod g-w "$TESTHOME"/.monkeysphere/authorized_user_ids
358 echo
359 echo "##################################################"
360 echo "### setting other writability on authorized_user_ids and updating..."
361 chmod o+w "$TESTHOME"/.monkeysphere/authorized_user_ids
362 monkeysphere-authentication update-users $(whoami)
363 echo
364 echo "##################################################"
365 echo "### ssh connection test for failure..."
366 ssh_test 255
367 chmod o-w "$TESTHOME"/.monkeysphere/authorized_user_ids
368 monkeysphere-authentication update-users $(whoami)
369
370 # test symlinks
371 echo
372 echo "##################################################"
373 echo "### setup for symlink tests..."
374 cp -a "$TESTHOME"/.monkeysphere{,.linktest}
375
376 echo
377 echo "##################################################"
378 echo "### make authorized_user_ids an absolute symlink and updating..."
379 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{,.bak}
380 ln -s "$TESTHOME"/.monkeysphere{.linktest,}/authorized_user_ids
381 monkeysphere-authentication update-users $(whoami)
382 echo
383 echo "##################################################"
384 echo "### ssh connection test for success..."
385 ssh_test
386 echo
387 echo "##################################################"
388 echo "### create bad permissions on link dir and updating..."
389 chmod o+w "$TESTHOME"/.monkeysphere.linktest
390 monkeysphere-authentication update-users $(whoami)
391 echo
392 echo "##################################################"
393 echo "### ssh connection test for failure..."
394 ssh_test 255
395 chmod o-w "$TESTHOME"/.monkeysphere.linktest
396 echo
397 echo "##################################################"
398 echo "### make authorized_user_ids a relative symlink and updating..."
399 ln -sf ../.monkeysphere.linktest/authorized_user_ids "$TESTHOME"/.monkeysphere/authorized_user_ids
400 monkeysphere-authentication update-users $(whoami)
401 echo
402 echo "##################################################"
403 echo "### ssh connection test for success..."
404 ssh_test
405 echo
406 echo "##################################################"
407 echo "### create bad permissions on link dir updating..."
408 chmod o+w "$TESTHOME"/.monkeysphere.linktest
409 monkeysphere-authentication update-users $(whoami)
410 echo
411 echo "##################################################"
412 echo "### ssh connection test for failure..."
413 ssh_test 255
414 chmod o-w "$TESTHOME"/.monkeysphere.linktest
415 # FIXME: implement check of link path, and uncomment this test
416 # echo
417 # echo "##################################################"
418 # echo "### create bad permissions on link dir and updating..."
419 # chmod o+w "$TESTHOME"/.monkeysphere
420 # monkeysphere-authentication update-users $(whoami)
421 # echo
422 # echo "##################################################"
423 # echo "### ssh connection test for failure..."
424 # ssh_test 255
425 # chmod o-w "$TESTHOME"/.monkeysphere
426 rm "$TESTHOME"/.monkeysphere/authorized_user_ids
427 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{.bak,}
428
429 echo
430 echo "##################################################"
431 echo "### make .monkeysphere directory an absolute symlink and updating..."
432 mv "$TESTHOME"/.monkeysphere{,.bak}
433 ln -s "$TESTHOME"/.monkeysphere{.linktest,}
434 monkeysphere-authentication update-users $(whoami)
435 echo
436 echo "##################################################"
437 echo "### ssh connection test for success..."
438 ssh_test
439 echo
440 echo "##################################################"
441 echo "### create bad permissions on link dir and updating..."
442 chmod o+w "$TESTHOME"/.monkeysphere.linktest
443 monkeysphere-authentication update-users $(whoami)
444 echo
445 echo "##################################################"
446 echo "### ssh connection test for failure..."
447 ssh_test 255
448 chmod o-w "$TESTHOME"/.monkeysphere.linktest
449 echo
450 echo "##################################################"
451 echo "### make .monkeysphere directory a relative symlink and updating..."
452 ln -sfn .monkeysphere{.linktest,}
453 monkeysphere-authentication update-users $(whoami)
454 echo
455 echo "##################################################"
456 echo "### ssh connection test for success..."
457 ssh_test
458 echo
459 echo "##################################################"
460 echo "### create bad permissions on link dir updating..."
461 chmod o+w "$TESTHOME"/.monkeysphere.linktest
462 monkeysphere-authentication update-users $(whoami)
463 echo
464 echo "##################################################"
465 echo "### ssh connection test for failure..."
466 ssh_test 255
467 chmod o-w "$TESTHOME"/.monkeysphere.linktest
468 rm "$TESTHOME"/.monkeysphere
469 mv "$TESTHOME"/.monkeysphere{.bak,}
470
471 # ensure we're back to normal:
472 echo
473 echo "##################################################"
474 echo "### making sure we are back to normal..."
475 monkeysphere-authentication update-users $(whoami)
476 ssh_test
477
478
479 echo
480 echo "##################################################"
481 echo "### ssh connection test directly to 'testhost2' without new name..."
482 target_hostname=testhost2 ssh_test 255
483 echo
484 echo "##################################################"
485 echo "### add hostname, certify by admin, import by user..."
486 monkeysphere-host add-hostname testhost2
487 < "$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg gpgadmin --import
488 printf "y\ny\n" | gpgadmin --command-fd 0 --sign-key "$HOSTKEYID"
489
490 echo
491 echo "##################################################"
492 echo "### ssh connection test with hostname 'testhost2' added..."
493 gpgadmin --export "$HOSTKEYID" | gpg --import
494 gpg --check-trustdb
495 ssh_test
496
497 echo
498 echo "##################################################"
499 echo "### ssh connection test directly to 'testhost2' ..."
500 gpg --import <"$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg 
501 gpg --check-trustdb
502 target_hostname=testhost2 ssh_test
503
504 echo
505 echo "##################################################"
506 echo "### ssh connection test for failure with 'testhost2' revoked..."
507 monkeysphere-host revoke-hostname testhost2
508 gpg --import <"$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg
509 gpg --check-trustdb
510 target_hostname=testhost2 ssh_test 255
511
512 # FIXME: addtest: remove admin as id-certifier and check ssh failure
513
514 # FIXME: addtest: how do we test that set-expire makes sense after new
515 # hostnames have been added?
516
517 # FIXME: addtest: revoke the host key and check ssh failure
518
519 # test to make sure things are OK after the previous tests:
520 echo
521 echo "##################################################"
522 echo "### settings reset, updating..."
523 monkeysphere-authentication update-users $(whoami)
524 echo
525 echo "##################################################"
526 echo "### ssh connection test for success..."
527 ssh_test
528
529 echo
530 echo "##################################################"
531 echo "### revoking host key..."
532 # generate the revocation certificate and feed it directly to the test
533 # user's keyring (we're not publishing to the keyservers)
534 monkeysphere-host revoke-key | gpg --import
535 echo
536 echo "##################################################"
537 echo "### ssh connection test for failure..."
538 ssh_test 255
539
540
541 ######################################################################
542
543 trap - EXIT
544
545 echo
546 echo "##################################################"
547 echo " Monkeysphere basic tests completed successfully!"
548 echo "##################################################"
549
550 cleanup