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