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} 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 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
142 export MONKEYSPHERE_LOG_LEVEL=DEBUG
143 export MONKEYSPHERE_CORE_KEYLENGTH=1024
144 export MONKEYSPHERE_PROMPT=false
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
150 export SSHD_CONFIG="$TEMPDIR"/sshd_config
151 export SOCKET="$TEMPDIR"/ssh-socket
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
160 ## we cannot do proper directory permissions checking if the current
161 ## working directory has unsatisfactory permissions:
162 if "$MONKEYSPHERE_SYSSHAREDIR"/checkperms $(whoami) "$TEMPDIR"; then
163 echo "Permissions on temporary directory '$TEMPDIR' are OK for permissions checks."
164 TEMPDIR_PERMISSIONS_SAFE=yes
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.
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!!!
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
186 # this is a new option (as of 0.26) to disable filesystem
189 # it should operate by analogy with StrictModes from sshd_config(5)
190 export MONKEYSPHERE_STRICT_MODES=false
195 ######################################################################
196 ### CONFIGURE ENVIRONMENTS
198 # copy in admin and testuser home to tmp
200 echo "##################################################"
201 echo "### configuring testuser home..."
202 (cd "$TESTDIR"/home && find testuser | cpio -pdu "$TEMPDIR")
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
215 cat <<EOF >> "$MONKEYSPHERE_HOME"/monkeysphere.conf
216 KNOWN_HOSTS=$TESTHOME/.ssh/known_hosts
218 get_gpg_prng_arg >> "$GNUPGHOME"/gpg.conf
221 echo "##################################################"
222 echo "### configuring admin home..."
223 (cd "$TESTDIR"/home && find admin | cpio -pdu "$TEMPDIR")
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
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"
245 ######################################################################
246 ### SERVER HOST SETUP
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 ssh://testhost
256 echo "##################################################"
257 echo "### getting host key fingerprint..."
258 SSHHOSTKEYID=$( monkeysphere-host show-key | grep '^OpenPGP fingerprint: ' | cut -f3 -d\ )
261 # change host key expiration
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?
268 # certify host key with the "Admin's Key".
269 # (this would normally be done via keyservers)
271 echo "##################################################"
272 echo "### certifying server host key..."
273 < "$MONKEYSPHERE_SYSCONFIGDIR"/host_keys.pub.gpg gpgadmin --import
274 echo y | gpgadmin --command-fd 0 --sign-key "$SSHHOSTKEYID"
276 # FIXME: add revoker?
278 # FIXME: how can we test publish-key without flooding junk into the
281 # FIXME: should we run "diagnostics" here to test setup?
284 ######################################################################
285 ### SERVER AUTHENTICATION SETUP
287 # set up monkeysphere authentication
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"
295 monkeysphere-authentication setup
296 get_gpg_prng_arg >> "$MONKEYSPHERE_SYSDATADIR"/authentication/sphere/gpg.conf
298 # add admin as identity certifier for testhost
300 echo "##################################################"
301 echo "### adding admin as certifier..."
302 monkeysphere-authentication add-id-certifier "$TEMPDIR"/admin/.gnupg/pubkey.gpg
305 echo "##################################################"
306 echo "### list certifiers..."
307 monkeysphere-authentication list-certifiers
309 # FIXME: should we run "diagnostics" here to test setup?
311 ######################################################################
314 # generate an auth subkey for the test user that expires in 2 days
316 echo "##################################################"
317 echo "### generating key for testuser..."
318 monkeysphere gen-subkey
320 # add server key to testuser keychain
322 echo "##################################################"
323 echo "### export server key to testuser..."
324 gpgadmin --armor --export "$SSHHOSTKEYID" | gpg --import
326 # teach the "server" about the testuser's key
328 echo "##################################################"
329 echo "### export testuser key to server..."
330 gpg --export testuser | monkeysphere-authentication gpg-cmd --import
332 # update authorized_keys for user
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'.
340 ######################################################################
343 ## see whether keys-for-userid works from the client's perspective:
345 echo "##################################################"
346 echo "### testing monkeysphere keys-for-userid ..."
347 diff -q <( monkeysphere keys-for-userid ssh://testhost ) <( cut -f1,2 -d' ' < "$TEMPDIR"/ssh_host_rsa_key.pub )
349 # connect to test sshd, using monkeysphere ssh-proxycommand to verify
350 # the identity before connection. This should work in both directions!
352 echo "##################################################"
353 echo "### ssh connection test for success..."
356 # remove the testuser's authorized_user_ids file, update, and make
357 # sure that the ssh authentication FAILS
359 echo "##################################################"
360 echo "### removing testuser authorized_user_ids and updating..."
361 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{,.bak}
362 monkeysphere-authentication update-users $(whoami)
364 echo "##################################################"
365 echo "### ssh connection test for failure..."
367 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{.bak,}
369 # put improper permissions on authorized_user_ids file, update, and
370 # make sure ssh authentication FAILS
372 echo "##################################################"
373 echo "### setting group writability on authorized_user_ids and updating..."
374 chmod g+w "$TESTHOME"/.monkeysphere/authorized_user_ids
375 monkeysphere-authentication update-users $(whoami)
377 echo "##################################################"
378 echo "### ssh connection test for failure..."
379 ssh_good_perm_test 255
380 chmod g-w "$TESTHOME"/.monkeysphere/authorized_user_ids
382 echo "##################################################"
383 echo "### setting other writability on authorized_user_ids and updating..."
384 chmod o+w "$TESTHOME"/.monkeysphere/authorized_user_ids
385 monkeysphere-authentication update-users $(whoami)
387 echo "##################################################"
388 echo "### ssh connection test for failure..."
389 ssh_good_perm_test 255
390 chmod o-w "$TESTHOME"/.monkeysphere/authorized_user_ids
391 monkeysphere-authentication update-users $(whoami)
395 echo "##################################################"
396 echo "### setup for symlink tests..."
397 cp -a "$TESTHOME"/.monkeysphere{,.linktest}
400 echo "##################################################"
401 echo "### make authorized_user_ids an absolute symlink and updating..."
402 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{,.bak}
403 ln -s "$TESTHOME"/.monkeysphere{.linktest,}/authorized_user_ids
404 monkeysphere-authentication update-users $(whoami)
406 echo "##################################################"
407 echo "### ssh connection test for success..."
410 echo "##################################################"
411 echo "### create bad permissions on link dir and updating..."
412 chmod o+w "$TESTHOME"/.monkeysphere.linktest
413 monkeysphere-authentication update-users $(whoami)
415 echo "##################################################"
416 echo "### ssh connection test for failure..."
417 ssh_good_perm_test 255
418 chmod o-w "$TESTHOME"/.monkeysphere.linktest
420 echo "##################################################"
421 echo "### make authorized_user_ids a relative symlink and updating..."
422 ln -sf ../.monkeysphere.linktest/authorized_user_ids "$TESTHOME"/.monkeysphere/authorized_user_ids
423 monkeysphere-authentication update-users $(whoami)
425 echo "##################################################"
426 echo "### ssh connection test for success..."
429 echo "##################################################"
430 echo "### create bad permissions on link dir updating..."
431 chmod o+w "$TESTHOME"/.monkeysphere.linktest
432 monkeysphere-authentication update-users $(whoami)
434 echo "##################################################"
435 echo "### ssh connection test for failure..."
436 ssh_good_perm_test 255
437 chmod o-w "$TESTHOME"/.monkeysphere.linktest
438 # FIXME: implement check of link path, and uncomment this test
440 # echo "##################################################"
441 # echo "### create bad permissions on link dir and updating..."
442 # chmod o+w "$TESTHOME"/.monkeysphere
443 # monkeysphere-authentication update-users $(whoami)
445 # echo "##################################################"
446 # echo "### ssh connection test for failure..."
447 # ssh_good_perm_test 255
448 # chmod o-w "$TESTHOME"/.monkeysphere
449 rm "$TESTHOME"/.monkeysphere/authorized_user_ids
450 mv "$TESTHOME"/.monkeysphere/authorized_user_ids{.bak,}
453 echo "##################################################"
454 echo "### make .monkeysphere directory an absolute symlink and updating..."
455 mv "$TESTHOME"/.monkeysphere{,.bak}
456 ln -s "$TESTHOME"/.monkeysphere{.linktest,}
457 monkeysphere-authentication update-users $(whoami)
459 echo "##################################################"
460 echo "### ssh connection test for success..."
463 echo "##################################################"
464 echo "### create bad permissions on link dir and updating..."
465 chmod o+w "$TESTHOME"/.monkeysphere.linktest
466 monkeysphere-authentication update-users $(whoami)
468 echo "##################################################"
469 echo "### ssh connection test for failure..."
470 ssh_good_perm_test 255
471 chmod o-w "$TESTHOME"/.monkeysphere.linktest
473 echo "##################################################"
474 echo "### make .monkeysphere directory a relative symlink and updating..."
475 ln -sfn .monkeysphere.linktest "$TESTHOME"/.monkeysphere
476 monkeysphere-authentication update-users $(whoami)
478 echo "##################################################"
479 echo "### ssh connection test for success..."
482 echo "##################################################"
483 echo "### create bad permissions on link dir updating..."
484 chmod o+w "$TESTHOME"/.monkeysphere.linktest
485 monkeysphere-authentication update-users $(whoami)
487 echo "##################################################"
488 echo "### ssh connection test for failure..."
489 ssh_good_perm_test 255
490 chmod o-w "$TESTHOME"/.monkeysphere.linktest
491 rm "$TESTHOME"/.monkeysphere
492 mv "$TESTHOME"/.monkeysphere{.bak,}
494 # ensure we're back to normal:
496 echo "##################################################"
497 echo "### making sure we are back to normal..."
498 monkeysphere-authentication update-users $(whoami)
503 echo "##################################################"
504 echo "### ssh connection test directly to 'testhost2' without new name..."
505 target_hostname=testhost2 ssh_test 255
507 echo "##################################################"
508 echo "### add servicename, certify by admin, import by user..."
509 monkeysphere-host add-servicename ssh://testhost2
510 < "$MONKEYSPHERE_SYSCONFIGDIR"/host_keys.pub.gpg gpgadmin --import
511 printf "y\ny\n" | gpgadmin --command-fd 0 --sign-key "$SSHHOSTKEYID"
514 echo "##################################################"
515 echo "### ssh connection test with hostname 'testhost2' added..."
516 gpgadmin --export "$SSHHOSTKEYID" | gpg --import
521 echo "##################################################"
522 echo "### ssh connection test directly to 'testhost2' ..."
523 gpg --import <"$MONKEYSPHERE_SYSCONFIGDIR"/host_keys.pub.gpg
525 target_hostname=testhost2 ssh_test
528 echo "##################################################"
529 echo "### ssh connection test for failure with 'testhost2' revoked..."
530 monkeysphere-host revoke-servicename ssh://testhost2
531 gpg --import <"$MONKEYSPHERE_SYSCONFIGDIR"/host_keys.pub.gpg
533 target_hostname=testhost2 ssh_test 255
535 # FIXME: addtest: remove admin as id-certifier and check ssh failure
537 # FIXME: addtest: how do we test that set-expire makes sense after new
538 # servicenames have been added?
540 # test to make sure things are OK after the previous tests:
542 echo "##################################################"
543 echo "### settings reset, updating..."
544 monkeysphere-authentication update-users $(whoami)
546 echo "##################################################"
547 echo "### ssh connection test for success..."
551 echo "##################################################"
552 echo "### Testing TLS setup..."
554 openssl req -config "$TESTDIR"/openssl.cnf -x509 -newkey rsa:1024 -subj '/DC=net/DC=example/DC=testhost/CN=testhost.example.net/' -days 3 -keyout "$TEMPDIR"/tls_key.pem -nodes >"$TEMPDIR"/tls_cert.pem
555 monkeysphere-host import-key "$TEMPDIR"/tls_key.pem https://testhost
557 # FIXME: how can we test this via an https client?
558 # We don't currently provide one.
560 # FIXME: should we test other monkeysphere-host operations somehow now
561 # that we have more than one key in the host keyring?
564 echo "##################################################"
565 echo "### revoking ssh host key..."
566 # generate the revocation certificate and feed it directly to the test
567 # user's keyring (we're not publishing to the keyservers)
568 monkeysphere-host revoke-key | gpg --import
570 echo "##################################################"
571 echo "### ssh connection test for failure..."
575 ######################################################################
580 echo "##################################################"
581 echo " Monkeysphere basic tests completed successfully!"
582 echo "##################################################"