3 # Tests to ensure that the monkeysphere is working
5 # unset MONKEYSPHERE_TEST_NO_EXAMINE to get a prompt to examine the
6 # test state after failure.
9 # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
10 # Jameson Rollins <jrollins@fifthhorseman.net>
11 # Micah Anderson <micah@riseup.net>
13 # Copyright: © 2008-2010
14 # License: GPL v3 or later
16 # these tests should all be able to run as a non-privileged user.
18 # put all the test output to stdout
20 # all subcommands in this script should complete without failure:
22 # piped commands should return the code of the first non-zero return
25 # make sure the TESTDIR is an absolute path, not a relative one.
26 export TESTDIR=$(cd $(dirname "$0") && pwd)
28 source "$TESTDIR"/common
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; }
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; }
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; }
43 ## FIXME: other checks?
45 ######################################################################
48 # gpg command for test admin user
50 chmod 0700 "$TEMPDIR"/admin "$TEMPDIR"/admin/.gnupg
51 GNUPGHOME="$TEMPDIR"/admin/.gnupg gpg --no-tty "$@"
55 # first argument is expected return code from ssh connection
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 &
68 # wait until the socket is created before continuing
69 while [ ! -S "$SOCKET" ] ; do
73 # make a client connection to the socket
74 echo "##### starting ssh client..."
76 "monkeysphere subkey-to-ssh-agent && ssh -F $TEMPDIR/testuser/.ssh/config ${target_hostname:-testhost.example} true" \
79 # kill the sshd process if it's still running
80 kill "$SSHD_PID" || true
84 if [ "$RETURN" = "$CODE" ] ; then
85 echo "##### ssh connection test PASSED. returned: $RETURN"
88 echo "##### ssh connection test FAILED. returned: $RETURN, expected: $CODE"
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."
107 trap failed_cleanup EXIT
110 ######################################################################
113 ## set up some variables to ensure that we're operating strictly in
114 ## the tests, not system-wide:
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.
124 mkdir -p "$TESTDIR"/tmp
125 TEMPDIR=$(mktemp -d "${TMPDIR:-$TESTDIR/tmp}/monkeyspheretest.XXXXXXX")
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"
131 export MONKEYSPHERE_SYSDATADIR="$TEMPDIR"
132 export MONKEYSPHERE_SYSCONFIGDIR="$TEMPDIR"
133 export MONKEYSPHERE_SYSSHAREDIR="$TESTDIR"/../src/share
134 export MONKEYSPHERE_MONKEYSPHERE_USER=$(whoami)
136 HOST_KEY_FILE="$MONKEYSPHERE_SYSCONFIGDIR"/host_keys.pub.pgp
138 export MONKEYSPHERE_CHECK_KEYSERVER=false
139 # example.org does not respond to the HKP port, so this should cause
140 # any keyserver connection attempts that do happen (they shouldn't!)
141 # to hang, so we'll notice them:
142 export MONKEYSPHERE_KEYSERVER=example.org
144 export MONKEYSPHERE_LOG_LEVEL=DEBUG
145 export MONKEYSPHERE_CORE_KEYLENGTH=1024
146 export MONKEYSPHERE_PROMPT=false
148 # unset SUBKEYS_FOR_AGENT variable which, if set, would confuse the
149 # into trying to use the user's key, instead of the testuser's key
150 unset MONKEYSPHERE_SUBKEYS_FOR_AGENT
152 export SSHD_CONFIG="$TEMPDIR"/sshd_config
153 export SOCKET="$TEMPDIR"/ssh-socket
155 # Make sure $DISPLAY is set to convince ssh and monkeysphere to fall
156 # back on $SSH_ASKPASS. Make sure it's not set to the current actual
157 # $DISPLAY (if one exists) because this test suite should not be doing
158 # *anything* with any running X11 session.
159 export DISPLAY=monkeys
162 ## we cannot do proper directory permissions checking if the current
163 ## working directory has unsatisfactory permissions:
164 if "$MONKEYSPHERE_SYSSHAREDIR"/checkperms $(whoami) "$TEMPDIR"; then
165 echo "Permissions on temporary directory '$TEMPDIR' are OK for permissions checks."
166 TEMPDIR_PERMISSIONS_SAFE=yes
170 !!!WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING!!!
171 Permissions on testing directory '$TEMPDIR' are
172 too loose to do proper strict permissions checking. Some tests
173 will be disabled or ignored.
175 To avoid this warning (and to make sure that all tests are run
176 properly), please run these tests within a directory that meets
177 sshd's standards for "StrictModes yes" -- the directory (and every
178 one of its parents) should be owned only be the user running this
179 test or root, and should not be writable by group or other.
180 !!!WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING!!!
184 # FIXME: what else should we do with this knowledge to make sure
185 # that the appropriate tests are handled properly?
186 TEMPDIR_PERMISSIONS_SAFE=no
188 # this is a new option (as of 0.26) to disable filesystem
191 # it should operate by analogy with StrictModes from sshd_config(5)
192 export MONKEYSPHERE_STRICT_MODES=false
197 ######################################################################
198 ### CONFIGURE ENVIRONMENTS
200 # copy in admin and testuser home to tmp
202 echo "##################################################"
203 echo "### configuring testuser home..."
204 (cd "$TESTDIR"/home && find testuser | cpio -pdu "$TEMPDIR")
206 # set up environment for testuser
207 export TESTHOME="$TEMPDIR"/testuser
208 export GNUPGHOME="$TESTHOME"/.gnupg
209 chmod 0700 "$GNUPGHOME"
210 export SSH_ASKPASS="$TESTHOME"/.ssh/askpass
211 export MONKEYSPHERE_HOME="$TESTHOME"/.monkeysphere
212 cat <<EOF >> "$TESTHOME"/.ssh/config
213 UserKnownHostsFile $TESTHOME/.ssh/known_hosts
214 IdentityFile $TESTHOME/.ssh/no-such-identity
215 ProxyCommand $TESTHOME/.ssh/proxy-command %h %p $SOCKET
217 cat <<EOF >> "$MONKEYSPHERE_HOME"/monkeysphere.conf
218 KNOWN_HOSTS=$TESTHOME/.ssh/known_hosts
220 get_gpg_prng_arg >> "$GNUPGHOME"/gpg.conf
223 echo "##################################################"
224 echo "### configuring admin home..."
225 (cd "$TESTDIR"/home && find admin | cpio -pdu "$TEMPDIR")
229 echo "##################################################"
230 echo "### configuring sshd..."
231 cp "$TESTDIR"/etc/ssh/sshd_config "$SSHD_CONFIG"
232 # write the sshd_config
233 cat <<EOF >> "$SSHD_CONFIG"
234 HostKey ${MONKEYSPHERE_SYSDATADIR}/ssh_host_rsa_key
235 AuthorizedKeysFile ${MONKEYSPHERE_SYSDATADIR}/authorized_keys/%u
238 # disable sshd's strict permissions settings so that some tests can
239 # complete when running under a dubious path:
240 if [ "$TEMPDIR_PERMISSIONS_SAFE" != yes ] ; then
241 cat <<EOF >> "$SSHD_CONFIG"
247 ######################################################################
248 ### SERVER HOST SETUP
252 echo "##################################################"
253 echo "### import host key..."
254 ssh-keygen -b 1024 -t rsa -N '' -f "$TEMPDIR"/ssh_host_rsa_key
255 monkeysphere-host import-key "$TEMPDIR"/ssh_host_rsa_key ssh://testhost.example
258 echo "##################################################"
259 echo "### getting host key fingerprint..."
260 SSHHOSTKEYID=$( monkeysphere-host show-keys | grep '^OpenPGP fingerprint: ' | cut -f3 -d\ )
263 # change host key expiration
265 echo "##################################################"
266 echo "### setting host key expiration..."
267 monkeysphere-host set-expire 1
268 # FIXME: how do we check that the expiration has really been set?
270 # certify host key with the "Admin's Key".
271 # (this would normally be done via keyservers)
273 echo "##################################################"
274 echo "### certifying server host key..."
275 < "$HOST_KEY_FILE" gpgadmin --import
276 echo y | gpgadmin --command-fd 0 --sign-key "$SSHHOSTKEYID"
278 # FIXME: add revoker?
280 # FIXME: how can we test publish-key without flooding junk into the
283 # FIXME: should we run "diagnostics" here to test setup?
286 ######################################################################
287 ### SERVER AUTHENTICATION SETUP
289 # set up monkeysphere authentication
291 echo "##################################################"
292 echo "### setup monkeysphere authentication..."
293 cp "$TESTDIR"/etc/monkeysphere/monkeysphere-authentication.conf "$TEMPDIR"/
294 cat <<EOF >> "$TEMPDIR"/monkeysphere-authentication.conf
295 AUTHORIZED_USER_IDS="$MONKEYSPHERE_HOME/authorized_user_ids"
297 monkeysphere-authentication setup
298 get_gpg_prng_arg >> "$MONKEYSPHERE_SYSDATADIR"/authentication/sphere/gpg.conf
300 # add admin as identity certifier for testhost.example
302 echo "##################################################"
303 echo "### adding admin as certifier..."
304 monkeysphere-authentication add-id-certifier "$TEMPDIR"/admin/.gnupg/pubkey.gpg
307 echo "##################################################"
308 echo "### list certifiers..."
309 monkeysphere-authentication list-certifiers
311 # FIXME: should we run "diagnostics" here to test setup?
313 ######################################################################
316 # generate an auth subkey for the test user that expires in 2 days
318 echo "##################################################"
319 echo "### generating key for testuser..."
320 monkeysphere gen-subkey
322 # add server key to testuser keychain
324 echo "##################################################"
325 echo "### export server key to testuser..."
326 gpgadmin --armor --export "$SSHHOSTKEYID" | gpg --import
328 # teach the "server" about the testuser's key
330 echo "##################################################"
331 echo "### export testuser key to server..."
332 gpg --export testuser | monkeysphere-authentication gpg-cmd --import
334 # update authorized_keys for user
336 echo "##################################################"
337 echo "### update server authorized_keys file for this testuser..."
338 monkeysphere-authentication update-users $(whoami)
339 # FIXME: this is maybe not failing properly for:
340 # ms: improper group or other writability on path '/tmp'.
342 ######################################################################
345 ## see whether keys-for-userid works from the client's perspective:
347 echo "##################################################"
348 echo "### testing monkeysphere keys-for-userid ..."
349 diff -q <( monkeysphere keys-for-userid ssh://testhost.example ) <( cut -f1,2 -d' ' < "$TEMPDIR"/ssh_host_rsa_key.pub )
351 # connect to test sshd, using monkeysphere ssh-proxycommand to verify
352 # the identity before connection. This should work in both directions!
354 echo "##################################################"
355 echo "### ssh connection test for success..."
358 # remove the testuser's authorized_user_ids file, update, and make
359 # sure that the ssh authentication FAILS
361 echo "##################################################"
362 echo "### removing testuser authorized_user_ids and updating..."
363 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{,.bak}
364 monkeysphere-authentication update-users $(whoami)
366 echo "##################################################"
367 echo "### ssh connection test for failure..."
369 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{.bak,}
371 # put improper permissions on authorized_user_ids file, update, and
372 # make sure ssh authentication FAILS
374 echo "##################################################"
375 echo "### setting group writability on authorized_user_ids and updating..."
376 chmod g+w "$TESTHOME"/.monkeysphere/authorized_user_ids
377 monkeysphere-authentication update-users $(whoami)
379 echo "##################################################"
380 echo "### ssh connection test for failure..."
381 ssh_good_perm_test 255
382 chmod g-w "$TESTHOME"/.monkeysphere/authorized_user_ids
384 echo "##################################################"
385 echo "### setting other writability on authorized_user_ids and updating..."
386 chmod o+w "$TESTHOME"/.monkeysphere/authorized_user_ids
387 monkeysphere-authentication update-users $(whoami)
389 echo "##################################################"
390 echo "### ssh connection test for failure..."
391 ssh_good_perm_test 255
392 chmod o-w "$TESTHOME"/.monkeysphere/authorized_user_ids
393 monkeysphere-authentication update-users $(whoami)
397 echo "##################################################"
398 echo "### setup for symlink tests..."
399 cp -a "$TESTHOME"/.monkeysphere{,.linktest}
402 echo "##################################################"
403 echo "### make authorized_user_ids an absolute symlink and updating..."
404 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{,.bak}
405 ln -s "$TESTHOME"/.monkeysphere{.linktest,}/authorized_user_ids
406 monkeysphere-authentication update-users $(whoami)
408 echo "##################################################"
409 echo "### ssh connection test for success..."
412 echo "##################################################"
413 echo "### create bad permissions on link dir and updating..."
414 chmod o+w "$TESTHOME"/.monkeysphere.linktest
415 monkeysphere-authentication update-users $(whoami)
417 echo "##################################################"
418 echo "### ssh connection test for failure..."
419 ssh_good_perm_test 255
420 chmod o-w "$TESTHOME"/.monkeysphere.linktest
422 echo "##################################################"
423 echo "### make authorized_user_ids a relative symlink and updating..."
424 ln -sf ../.monkeysphere.linktest/authorized_user_ids "$TESTHOME"/.monkeysphere/authorized_user_ids
425 monkeysphere-authentication update-users $(whoami)
427 echo "##################################################"
428 echo "### ssh connection test for success..."
431 echo "##################################################"
432 echo "### create bad permissions on link dir updating..."
433 chmod o+w "$TESTHOME"/.monkeysphere.linktest
434 monkeysphere-authentication update-users $(whoami)
436 echo "##################################################"
437 echo "### ssh connection test for failure..."
438 ssh_good_perm_test 255
439 chmod o-w "$TESTHOME"/.monkeysphere.linktest
440 # FIXME: implement check of link path, and uncomment this test
442 # echo "##################################################"
443 # echo "### create bad permissions on link dir and updating..."
444 # chmod o+w "$TESTHOME"/.monkeysphere
445 # monkeysphere-authentication update-users $(whoami)
447 # echo "##################################################"
448 # echo "### ssh connection test for failure..."
449 # ssh_good_perm_test 255
450 # chmod o-w "$TESTHOME"/.monkeysphere
451 rm "$TESTHOME"/.monkeysphere/authorized_user_ids
452 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{.bak,}
455 echo "##################################################"
456 echo "### make .monkeysphere directory an absolute symlink and updating..."
457 mv "$TESTHOME"/.monkeysphere{,.bak}
458 ln -s "$TESTHOME"/.monkeysphere{.linktest,}
459 monkeysphere-authentication update-users $(whoami)
461 echo "##################################################"
462 echo "### ssh connection test for success..."
465 echo "##################################################"
466 echo "### create bad permissions on link dir and updating..."
467 chmod o+w "$TESTHOME"/.monkeysphere.linktest
468 monkeysphere-authentication update-users $(whoami)
470 echo "##################################################"
471 echo "### ssh connection test for failure..."
472 ssh_good_perm_test 255
473 chmod o-w "$TESTHOME"/.monkeysphere.linktest
475 echo "##################################################"
476 echo "### make .monkeysphere directory a relative symlink and updating..."
477 ln -sfn .monkeysphere.linktest "$TESTHOME"/.monkeysphere
478 monkeysphere-authentication update-users $(whoami)
480 echo "##################################################"
481 echo "### ssh connection test for success..."
484 echo "##################################################"
485 echo "### create bad permissions on link dir updating..."
486 chmod o+w "$TESTHOME"/.monkeysphere.linktest
487 monkeysphere-authentication update-users $(whoami)
489 echo "##################################################"
490 echo "### ssh connection test for failure..."
491 ssh_good_perm_test 255
492 chmod o-w "$TESTHOME"/.monkeysphere.linktest
493 rm "$TESTHOME"/.monkeysphere
494 mv "$TESTHOME"/.monkeysphere{.bak,}
496 # ensure we're back to normal:
498 echo "##################################################"
499 echo "### making sure we are back to normal..."
500 monkeysphere-authentication update-users $(whoami)
505 echo "##################################################"
506 echo "### ssh connection test directly to 'testhost2.example' without new name..."
507 target_hostname=testhost2.example ssh_test 255
509 echo "##################################################"
510 echo "### add servicename, certify by admin, import by user..."
511 monkeysphere-host add-servicename ssh://testhost2.example
512 <"$HOST_KEY_FILE" gpgadmin --import
513 printf "y\ny\n" | gpgadmin --command-fd 0 --sign-key "$SSHHOSTKEYID"
516 echo "##################################################"
517 echo "### ssh connection test with hostname 'testhost2.example' added..."
518 gpgadmin --export "$SSHHOSTKEYID" | gpg --import
523 echo "##################################################"
524 echo "### ssh connection test directly to 'testhost2.example' ..."
525 gpg --import <"$HOST_KEY_FILE"
527 target_hostname=testhost2.example ssh_test
530 echo "##################################################"
531 echo "### ssh connection test for failure with 'testhost2.example' revoked..."
532 monkeysphere-host revoke-servicename ssh://testhost2.example
533 gpg --import <"$HOST_KEY_FILE"
535 target_hostname=testhost2.example ssh_test 255
537 # FIXME: addtest: remove admin as id-certifier and check ssh failure
539 # FIXME: addtest: how do we test that set-expire makes sense after new
540 # servicenames have been added?
542 # test to make sure things are OK after the previous tests:
544 echo "##################################################"
545 echo "### settings reset, updating..."
546 monkeysphere-authentication update-users $(whoami)
548 echo "##################################################"
549 echo "### ssh connection test for success..."
553 echo "##################################################"
554 echo "### Testing TLS setup..."
556 openssl req -config "$TESTDIR"/openssl.cnf -x509 -newkey rsa:1024 -subj '/DC=example/DC=testhost/CN=testhost.example/' -days 3 -keyout "$TEMPDIR"/tls_key.pem -nodes >"$TEMPDIR"/tls_cert.pem
557 monkeysphere-host import-key "$TEMPDIR"/tls_key.pem https://testhost.example
559 # FIXME: how can we test this via an https client?
560 # We don't currently provide one.
562 # FIXME: should we test other monkeysphere-host operations somehow now
563 # that we have more than one key in the host keyring?
566 echo "##################################################"
567 echo "### revoking ssh host key..."
568 # generate the revocation certificate and feed it directly to the test
569 # user's keyring (we're not publishing to the keyservers)
570 monkeysphere-host revoke-key "$SSHHOSTKEYID" | gpg --import
572 echo "##################################################"
573 echo "### ssh connection test for failure..."
577 ######################################################################
582 echo "##################################################"
583 echo " Monkeysphere basic tests completed successfully!"
584 echo "##################################################"