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