summaryrefslogtreecommitdiff
path: root/src/monkeysphere-host
blob: bf586169bf5a259199e5b3ddd657e9db6c664e66 (plain)
  1. #!/usr/bin/env bash
  2. # monkeysphere-host: Monkeysphere host admin tool
  3. #
  4. # The monkeysphere scripts are written by:
  5. # Jameson Rollins <jrollins@fifthhorseman.net>
  6. # Jamie McClelland <jm@mayfirst.org>
  7. # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
  8. #
  9. # They are Copyright 2008, and are all released under the GPL, version 3
  10. # or later.
  11. ########################################################################
  12. PGRM=$(basename $0)
  13. SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
  14. export SYSSHAREDIR
  15. . "${SYSSHAREDIR}/common" || exit 1
  16. SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/lib/monkeysphere/host"}
  17. export SYSDATADIR
  18. # monkeysphere temp directory, in sysdatadir to enable atomic moves of
  19. # authorized_keys files
  20. MSTMPDIR="${SYSDATADIR}/tmp"
  21. export MSTMPDIR
  22. # UTC date in ISO 8601 format if needed
  23. DATE=$(date -u '+%FT%T')
  24. # unset some environment variables that could screw things up
  25. unset GREP_OPTIONS
  26. # default return code
  27. RETURN=0
  28. ########################################################################
  29. # FUNCTIONS
  30. ########################################################################
  31. usage() {
  32. cat <<EOF >&2
  33. usage: $PGRM <subcommand> [options] [args]
  34. Monkeysphere host admin tool.
  35. subcommands:
  36. show-key (s) output all host key information
  37. extend-key (e) EXPIRE extend host key expiration
  38. add-hostname (n+) NAME[:PORT] add hostname user ID to host key
  39. revoke-hostname (n-) NAME[:PORT] revoke hostname user ID
  40. add-revoker (o) FINGERPRINT add a revoker to the host key
  41. revoke-key (r) revoke host key
  42. publish-key (p) publish server host key to keyserver
  43. expert
  44. import-key (i) import existing ssh key to gpg
  45. --hostname (-h) NAME[:PORT] hostname for key user ID
  46. --keyfile (-f) FILE key file to import
  47. --expire (-e) EXPIRE date to expire
  48. gen-key (g) generate gpg key for the host
  49. --hostname (-h) NAME[:PORT] hostname for key user ID
  50. --length (-l) BITS key length in bits (2048)
  51. --expire (-e) EXPIRE date to expire
  52. --revoker (-r) FINGERPRINT add a revoker
  53. diagnostics (d) monkeysphere host status
  54. version (v) show version number
  55. help (h,?) this help
  56. EOF
  57. }
  58. # function to run command as monkeysphere user
  59. su_monkeysphere_user() {
  60. # if the current user is the monkeysphere user, then just eval
  61. # command
  62. if [ $(id -un) = "$MONKEYSPHERE_USER" ] ; then
  63. eval "$@"
  64. # otherwise su command as monkeysphere user
  65. else
  66. su "$MONKEYSPHERE_USER" -c "$@"
  67. fi
  68. }
  69. # function to interact with the host gnupg keyring
  70. gpg_host() {
  71. local returnCode
  72. GNUPGHOME="$GNUPGHOME_HOST"
  73. export GNUPGHOME
  74. # NOTE: we supress this warning because we need the monkeysphere
  75. # user to be able to read the host pubring. we realize this might
  76. # be problematic, but it's the simplest solution, without too much
  77. # loss of security.
  78. gpg --no-permission-warning "$@"
  79. returnCode="$?"
  80. # always reset the permissions on the host pubring so that the
  81. # monkeysphere user can read the trust signatures
  82. chgrp "$MONKEYSPHERE_USER" "${GNUPGHOME_HOST}/pubring.gpg"
  83. chmod g+r "${GNUPGHOME_HOST}/pubring.gpg"
  84. return "$returnCode"
  85. }
  86. # output just key fingerprint
  87. fingerprint_server_key() {
  88. # set the pipefail option so functions fails if can't read sec key
  89. set -o pipefail
  90. gpg_host --list-secret-keys --fingerprint \
  91. --with-colons --fixed-list-mode 2> /dev/null | \
  92. grep '^fpr:' | head -1 | cut -d: -f10 2>/dev/null
  93. }
  94. # function to check for host secret key
  95. check_host_keyring() {
  96. fingerprint_server_key >/dev/null \
  97. || failure "You don't appear to have a Monkeysphere host key on this server. Please run 'monkeysphere-server gen-key' first."
  98. }
  99. # output key information
  100. show_server_key() {
  101. local fingerprintPGP
  102. local fingerprintSSH
  103. local ret=0
  104. # FIXME: you shouldn't have to be root to see the host key fingerprint
  105. check_host_keyring
  106. fingerprintPGP=$(fingerprint_server_key)
  107. gpg_authentication "--fingerprint --list-key --list-options show-unusable-uids $fingerprintPGP" 2>/dev/null
  108. if [ $? -ne 0 ] ; then
  109. log info "You must be root to see host OpenPGP fingerprint."
  110. ret='1'
  111. else
  112. echo "OpenPGP fingerprint: $fingerprintPGP"
  113. fi
  114. if [ -f "${SYSDATADIR}/ssh_host_rsa_key.pub" ] ; then
  115. fingerprintSSH=$(ssh-keygen -l -f "${SYSDATADIR}/ssh_host_rsa_key.pub" | \
  116. awk '{ print $1, $2, $4 }')
  117. echo "ssh fingerprint: $fingerprintSSH"
  118. else
  119. log info "SSH host key not found."
  120. ret='1'
  121. fi
  122. return $ret
  123. }
  124. # import an existing ssh key to a gpg key
  125. import_key() {
  126. local hostName=$(hostname -f)
  127. local keyFile="/etc/ssh/ssh_host_rsa_key"
  128. local keyExpire
  129. local userID
  130. # check for presense of secret key
  131. # FIXME: is this the proper test to be doing here?
  132. fingerprint_server_key >/dev/null \
  133. && failure "An OpenPGP host key already exists."
  134. # get options
  135. while true ; do
  136. case "$1" in
  137. -h|--hostname)
  138. hostName="$2"
  139. shift 2
  140. ;;
  141. -f|--keyfile)
  142. keyFile="$2"
  143. shift 2
  144. ;;
  145. -e|--expire)
  146. keyExpire="$2"
  147. shift 2
  148. ;;
  149. *)
  150. if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
  151. failure "Unknown option '$1'.
  152. Type '$PGRM help' for usage."
  153. fi
  154. break
  155. ;;
  156. esac
  157. done
  158. if [ ! -f "$keyFile" ] ; then
  159. failure "SSH secret key file '$keyFile' not found."
  160. fi
  161. userID="ssh://${hostName}"
  162. # prompt about key expiration if not specified
  163. keyExpire=$(get_gpg_expiration "$keyExpire")
  164. echo "The following key parameters will be used for the host private key:"
  165. echo "Import: $keyFile"
  166. echo "Name-Real: $userID"
  167. echo "Expire-Date: $keyExpire"
  168. read -p "Import key? (Y/n) " OK; OK=${OK:=Y}
  169. if [ ${OK/y/Y} != 'Y' ] ; then
  170. failure "aborting."
  171. fi
  172. log verbose "importing ssh key..."
  173. # translate ssh key to a private key
  174. (umask 077 && \
  175. pem2openpgp "$userID" "$keyExpire" < "$sshKey" | gpg_host --import)
  176. # find the key fingerprint of the newly converted key
  177. fingerprint=$(fingerprint_server_key)
  178. # export host ownertrust to authentication keyring
  179. log verbose "setting ultimate owner trust for host key..."
  180. echo "${fingerprint}:6:" | gpg_host "--import-ownertrust"
  181. echo "${fingerprint}:6:" | gpg_authentication "--import-ownertrust"
  182. # export public key to file
  183. gpg_authentication "--export-options export-minimal --armor --export 0x${fingerprint}\!" > "${SYSDATADIR}/ssh_host_rsa_key.pub.gpg"
  184. log info "SSH host public key in OpenPGP form: ${SYSDATADIR}/ssh_host_rsa_key.pub.gpg"
  185. # show info about new key
  186. show_server_key
  187. }
  188. # generate server gpg key
  189. gen_key() {
  190. local keyType="RSA"
  191. local keyLength="2048"
  192. local keyUsage="auth"
  193. local keyExpire
  194. local revoker
  195. local hostName=$(hostname -f)
  196. local userID
  197. local keyParameters
  198. local fingerprint
  199. # check for presense of secret key
  200. # FIXME: is this the proper test to be doing here?
  201. fingerprint_server_key >/dev/null \
  202. && failure "An OpenPGP host key already exists."
  203. # get options
  204. while true ; do
  205. case "$1" in
  206. -l|--length)
  207. keyLength="$2"
  208. shift 2
  209. ;;
  210. -e|--expire)
  211. keyExpire="$2"
  212. shift 2
  213. ;;
  214. -r|--revoker)
  215. revoker="$2"
  216. shift 2
  217. ;;
  218. *)
  219. if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
  220. failure "Unknown option '$1'.
  221. Type '$PGRM help' for usage."
  222. fi
  223. hostName="$1"
  224. break
  225. ;;
  226. esac
  227. done
  228. userID="ssh://${hostName}"
  229. # prompt about key expiration if not specified
  230. keyExpire=$(get_gpg_expiration "$keyExpire")
  231. # set key parameters
  232. keyParameters=\
  233. "Key-Type: $keyType
  234. Key-Length: $keyLength
  235. Key-Usage: $keyUsage
  236. Name-Real: $userID
  237. Expire-Date: $keyExpire"
  238. # add the revoker field if specified
  239. # FIXME: the "1:" below assumes that $REVOKER's key is an RSA key.
  240. # FIXME: key is marked "sensitive"? is this appropriate?
  241. if [ "$revoker" ] ; then
  242. keyParameters=\
  243. "${keyParameters}
  244. Revoker: 1:${revoker} sensitive"
  245. fi
  246. echo "The following key parameters will be used for the host private key:"
  247. echo "$keyParameters"
  248. read -p "Generate key? (Y/n) " OK; OK=${OK:=Y}
  249. if [ ${OK/y/Y} != 'Y' ] ; then
  250. failure "aborting."
  251. fi
  252. # add commit command
  253. # must include blank line!
  254. keyParameters=\
  255. "${keyParameters}
  256. %commit
  257. %echo done"
  258. log verbose "generating host key..."
  259. echo "$keyParameters" | gpg_host --batch --gen-key
  260. # find the key fingerprint of the newly generated key
  261. fingerprint=$(fingerprint_server_key)
  262. # export host ownertrust to authentication keyring
  263. log verbose "setting ultimate owner trust for host key..."
  264. echo "${fingerprint}:6:" | gpg_authentication "--import-ownertrust"
  265. # translate the private key to ssh format, and export to a file
  266. # for sshs usage.
  267. # NOTE: assumes that the primary key is the proper key to use
  268. (umask 077 && \
  269. gpg_host --export-secret-key "$fingerprint" | \
  270. openpgp2ssh "$fingerprint" > "${SYSDATADIR}/ssh_host_rsa_key")
  271. log info "SSH host private key output to file: ${SYSDATADIR}/ssh_host_rsa_key"
  272. ssh-keygen -y -f "${SYSDATADIR}/ssh_host_rsa_key" > "${SYSDATADIR}/ssh_host_rsa_key.pub"
  273. log info "SSH host public key output to file: ${SYSDATADIR}/ssh_host_rsa_key.pub"
  274. gpg_authentication "--export-options export-minimal --armor --export 0x${fingerprint}\!" > "${SYSDATADIR}/ssh_host_rsa_key.pub.gpg"
  275. log info "SSH host public key in OpenPGP form: ${SYSDATADIR}/ssh_host_rsa_key.pub.gpg"
  276. # show info about new key
  277. show_server_key
  278. }
  279. # extend the lifetime of a host key:
  280. extend_key() {
  281. local fpr=$(fingerprint_server_key)
  282. local extendTo="$1"
  283. # get the new expiration date
  284. extendTo=$(get_gpg_expiration "$extendTo")
  285. gpg_host --quiet --command-fd 0 --edit-key "$fpr" <<EOF
  286. expire
  287. $extendTo
  288. save
  289. EOF
  290. echo
  291. echo "NOTE: Host key expiration date adjusted, but not yet published."
  292. echo "Run '$PGRM publish-key' to publish the new expiration date."
  293. }
  294. # add hostname user ID to server key
  295. add_hostname() {
  296. local userID
  297. local fingerprint
  298. local tmpuidMatch
  299. local line
  300. local adduidCommand
  301. if [ -z "$1" ] ; then
  302. failure "You must specify a hostname to add."
  303. fi
  304. userID="ssh://${1}"
  305. fingerprint=$(fingerprint_server_key)
  306. # match to only ultimately trusted user IDs
  307. tmpuidMatch="u:$(echo $userID | gpg_escape)"
  308. # find the index of the requsted user ID
  309. # NOTE: this is based on circumstantial evidence that the order of
  310. # this output is the appropriate index
  311. if line=$(gpg_host --list-keys --with-colons --fixed-list-mode "0x${fingerprint}!" \
  312. | egrep '^(uid|uat):' | cut -f2,10 -d: | grep -n -x -F "$tmpuidMatch") ; then
  313. failure "Host userID '$userID' already exists."
  314. fi
  315. echo "The following user ID will be added to the host key:"
  316. echo " $userID"
  317. read -p "Are you sure you would like to add this user ID? (y/N) " OK; OK=${OK:=N}
  318. if [ ${OK/y/Y} != 'Y' ] ; then
  319. failure "User ID not added."
  320. fi
  321. # edit-key script command to add user ID
  322. adduidCommand=$(cat <<EOF
  323. adduid
  324. $userID
  325. save
  326. EOF
  327. )
  328. # execute edit-key script
  329. if echo "$adduidCommand" | \
  330. gpg_host --quiet --command-fd 0 --edit-key "0x${fingerprint}!" ; then
  331. # update the trustdb for the authentication keyring
  332. gpg_authentication "--check-trustdb"
  333. show_server_key
  334. echo
  335. echo "NOTE: User ID added to key, but key not published."
  336. echo "Run '$PGRM publish-key' to publish the new user ID."
  337. else
  338. failure "Problem adding user ID."
  339. fi
  340. }
  341. # revoke hostname user ID to server key
  342. revoke_hostname() {
  343. local userID
  344. local fingerprint
  345. local tmpuidMatch
  346. local line
  347. local uidIndex
  348. local message
  349. local revuidCommand
  350. if [ -z "$1" ] ; then
  351. failure "You must specify a hostname to revoke."
  352. fi
  353. echo "WARNING: There is a known bug in this function."
  354. echo "This function has been known to occasionally revoke the wrong user ID."
  355. echo "Please see the following bug report for more information:"
  356. echo "http://web.monkeysphere.info/bugs/revoke-hostname-revoking-wrong-userid/"
  357. read -p "Are you sure you would like to proceed? (y/N) " OK; OK=${OK:=N}
  358. if [ ${OK/y/Y} != 'Y' ] ; then
  359. failure "aborting."
  360. fi
  361. userID="ssh://${1}"
  362. fingerprint=$(fingerprint_server_key)
  363. # match to only ultimately trusted user IDs
  364. tmpuidMatch="u:$(echo $userID | gpg_escape)"
  365. # find the index of the requsted user ID
  366. # NOTE: this is based on circumstantial evidence that the order of
  367. # this output is the appropriate index
  368. if line=$(gpg_host --list-keys --with-colons --fixed-list-mode "0x${fingerprint}!" \
  369. | egrep '^(uid|uat):' | cut -f2,10 -d: | grep -n -x -F "$tmpuidMatch") ; then
  370. uidIndex=${line%%:*}
  371. else
  372. failure "No non-revoked user ID '$userID' is found."
  373. fi
  374. echo "The following host key user ID will be revoked:"
  375. echo " $userID"
  376. read -p "Are you sure you would like to revoke this user ID? (y/N) " OK; OK=${OK:=N}
  377. if [ ${OK/y/Y} != 'Y' ] ; then
  378. failure "User ID not revoked."
  379. fi
  380. message="Hostname removed by monkeysphere-server $DATE"
  381. # edit-key script command to revoke user ID
  382. revuidCommand=$(cat <<EOF
  383. $uidIndex
  384. revuid
  385. y
  386. 4
  387. $message
  388. y
  389. save
  390. EOF
  391. )
  392. # execute edit-key script
  393. if echo "$revuidCommand" | \
  394. gpg_host --quiet --command-fd 0 --edit-key "0x${fingerprint}!" ; then
  395. # update the trustdb for the authentication keyring
  396. gpg_authentication "--check-trustdb"
  397. show_server_key
  398. echo
  399. echo "NOTE: User ID revoked, but revocation not published."
  400. echo "Run '$PGRM publish-key' to publish the revocation."
  401. else
  402. failure "Problem revoking user ID."
  403. fi
  404. }
  405. # add a revoker to the host key
  406. add_revoker() {
  407. # FIXME: implement!
  408. failure "not implemented yet!"
  409. }
  410. # revoke the host key
  411. revoke_key() {
  412. # FIXME: implement!
  413. failure "not implemented yet!"
  414. }
  415. # publish server key to keyserver
  416. publish_server_key() {
  417. read -p "Really publish host key to $KEYSERVER? (y/N) " OK; OK=${OK:=N}
  418. if [ ${OK/y/Y} != 'Y' ] ; then
  419. failure "key not published."
  420. fi
  421. # find the key fingerprint
  422. fingerprint=$(fingerprint_server_key)
  423. # publish host key
  424. gpg_authentication "--keyserver $KEYSERVER --send-keys '0x${fingerprint}!'"
  425. }
  426. diagnostics() {
  427. # * check on the status and validity of the key and public certificates
  428. local seckey
  429. local keysfound
  430. local curdate
  431. local warnwindow
  432. local warndate
  433. local create
  434. local expire
  435. local uid
  436. local fingerprint
  437. local badhostkeys
  438. local sshd_config
  439. local problemsfound=0
  440. # FIXME: what's the correct, cross-platform answer?
  441. sshd_config=/etc/ssh/sshd_config
  442. seckey=$(gpg_host --list-secret-keys --fingerprint --with-colons --fixed-list-mode)
  443. keysfound=$(echo "$seckey" | grep -c ^sec:)
  444. curdate=$(date +%s)
  445. # warn when anything is 2 months away from expiration
  446. warnwindow='2 months'
  447. warndate=$(advance_date $warnwindow +%s)
  448. if ! id monkeysphere >/dev/null ; then
  449. echo "! No monkeysphere user found! Please create a monkeysphere system user with bash as its shell."
  450. problemsfound=$(($problemsfound+1))
  451. fi
  452. if ! [ -d "$SYSDATADIR" ] ; then
  453. echo "! no $SYSDATADIR directory found. Please create it."
  454. problemsfound=$(($problemsfound+1))
  455. fi
  456. echo "Checking host GPG key..."
  457. if (( "$keysfound" < 1 )); then
  458. echo "! No host key found."
  459. echo " - Recommendation: run 'monkeysphere-server gen-key'"
  460. problemsfound=$(($problemsfound+1))
  461. elif (( "$keysfound" > 1 )); then
  462. echo "! More than one host key found?"
  463. # FIXME: recommend a way to resolve this
  464. problemsfound=$(($problemsfound+1))
  465. else
  466. create=$(echo "$seckey" | grep ^sec: | cut -f6 -d:)
  467. expire=$(echo "$seckey" | grep ^sec: | cut -f7 -d:)
  468. fingerprint=$(echo "$seckey" | grep ^fpr: | head -n1 | cut -f10 -d:)
  469. # check for key expiration:
  470. if [ "$expire" ]; then
  471. if (( "$expire" < "$curdate" )); then
  472. echo "! Host key is expired."
  473. echo " - Recommendation: extend lifetime of key with 'monkeysphere-server extend-key'"
  474. problemsfound=$(($problemsfound+1))
  475. elif (( "$expire" < "$warndate" )); then
  476. echo "! Host key expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
  477. echo " - Recommendation: extend lifetime of key with 'monkeysphere-server extend-key'"
  478. problemsfound=$(($problemsfound+1))
  479. fi
  480. fi
  481. # and weirdnesses:
  482. if [ "$create" ] && (( "$create" > "$curdate" )); then
  483. echo "! Host key was created in the future(?!). Is your clock correct?"
  484. echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
  485. problemsfound=$(($problemsfound+1))
  486. fi
  487. # check for UserID expiration:
  488. echo "$seckey" | grep ^uid: | cut -d: -f6,7,10 | \
  489. while IFS=: read create expire uid ; do
  490. # FIXME: should we be doing any checking on the form
  491. # of the User ID? Should we be unmangling it somehow?
  492. if [ "$create" ] && (( "$create" > "$curdate" )); then
  493. echo "! User ID '$uid' was created in the future(?!). Is your clock correct?"
  494. echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
  495. problemsfound=$(($problemsfound+1))
  496. fi
  497. if [ "$expire" ] ; then
  498. if (( "$expire" < "$curdate" )); then
  499. echo "! User ID '$uid' is expired."
  500. # FIXME: recommend a way to resolve this
  501. problemsfound=$(($problemsfound+1))
  502. elif (( "$expire" < "$warndate" )); then
  503. echo "! User ID '$uid' expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
  504. # FIXME: recommend a way to resolve this
  505. problemsfound=$(($problemsfound+1))
  506. fi
  507. fi
  508. done
  509. # FIXME: verify that the host key is properly published to the
  510. # keyservers (do this with the non-privileged user)
  511. # FIXME: check that there are valid, non-expired certifying signatures
  512. # attached to the host key after fetching from the public keyserver
  513. # (do this with the non-privileged user as well)
  514. # FIXME: propose adding a revoker to the host key if none exist (do we
  515. # have a way to do that after key generation?)
  516. # Ensure that the ssh_host_rsa_key file is present and non-empty:
  517. echo
  518. echo "Checking host SSH key..."
  519. if [ ! -s "${SYSDATADIR}/ssh_host_rsa_key" ] ; then
  520. echo "! The host key as prepared for SSH (${SYSDATADIR}/ssh_host_rsa_key) is missing or empty."
  521. problemsfound=$(($problemsfound+1))
  522. else
  523. if [ $(ls -l "${SYSDATADIR}/ssh_host_rsa_key" | cut -f1 -d\ ) != '-rw-------' ] ; then
  524. echo "! Permissions seem wrong for ${SYSDATADIR}/ssh_host_rsa_key -- should be 0600."
  525. problemsfound=$(($problemsfound+1))
  526. fi
  527. # propose changes needed for sshd_config (if any)
  528. if ! grep -q "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$" "$sshd_config"; then
  529. echo "! $sshd_config does not point to the monkeysphere host key (${SYSDATADIR}/ssh_host_rsa_key)."
  530. echo " - Recommendation: add a line to $sshd_config: 'HostKey ${SYSDATADIR}/ssh_host_rsa_key'"
  531. problemsfound=$(($problemsfound+1))
  532. fi
  533. if badhostkeys=$(grep -i '^HostKey' "$sshd_config" | grep -v "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$") ; then
  534. echo "! $sshd_config refers to some non-monkeysphere host keys:"
  535. echo "$badhostkeys"
  536. echo " - Recommendation: remove the above HostKey lines from $sshd_config"
  537. problemsfound=$(($problemsfound+1))
  538. fi
  539. # FIXME: test (with ssh-keyscan?) that the running ssh
  540. # daemon is actually offering the monkeysphere host key.
  541. fi
  542. fi
  543. # FIXME: look at the ownership/privileges of the various keyrings,
  544. # directories housing them, etc (what should those values be? can
  545. # we make them as minimal as possible?)
  546. # FIXME: look to see that the ownertrust rules are set properly on the
  547. # authentication keyring
  548. # FIXME: make sure that at least one identity certifier exists
  549. # FIXME: look at the timestamps on the monkeysphere-generated
  550. # authorized_keys files -- warn if they seem out-of-date.
  551. # FIXME: check for a cronjob that updates monkeysphere-generated
  552. # authorized_keys?
  553. echo
  554. echo "Checking for MonkeySphere-enabled public-key authentication for users ..."
  555. # Ensure that User ID authentication is enabled:
  556. if ! grep -q "^AuthorizedKeysFile[[:space:]]\+${SYSDATADIR}/authorized_keys/%u$" "$sshd_config"; then
  557. echo "! $sshd_config does not point to monkeysphere authorized keys."
  558. echo " - Recommendation: add a line to $sshd_config: 'AuthorizedKeysFile ${SYSDATADIR}/authorized_keys/%u'"
  559. problemsfound=$(($problemsfound+1))
  560. fi
  561. if badauthorizedkeys=$(grep -i '^AuthorizedKeysFile' "$sshd_config" | grep -v "^AuthorizedKeysFile[[:space:]]\+${SYSDATADIR}/authorized_keys/%u$") ; then
  562. echo "! $sshd_config refers to non-monkeysphere authorized_keys files:"
  563. echo "$badauthorizedkeys"
  564. echo " - Recommendation: remove the above AuthorizedKeysFile lines from $sshd_config"
  565. problemsfound=$(($problemsfound+1))
  566. fi
  567. if [ "$problemsfound" -gt 0 ]; then
  568. echo "When the above $problemsfound issue"$(if [ "$problemsfound" -eq 1 ] ; then echo " is" ; else echo "s are" ; fi)" resolved, please re-run:"
  569. echo " monkeysphere-server diagnostics"
  570. else
  571. echo "Everything seems to be in order!"
  572. fi
  573. }
  574. ########################################################################
  575. # MAIN
  576. ########################################################################
  577. # unset variables that should be defined only in config file
  578. unset KEYSERVER
  579. unset AUTHORIZED_USER_IDS
  580. unset RAW_AUTHORIZED_KEYS
  581. unset MONKEYSPHERE_USER
  582. # load configuration file
  583. [ -e ${MONKEYSPHERE_SERVER_CONFIG:="${SYSCONFIGDIR}/monkeysphere-server.conf"} ] && . "$MONKEYSPHERE_SERVER_CONFIG"
  584. # set empty config variable with ones from the environment, or with
  585. # defaults
  586. LOG_LEVEL=${MONKEYSPHERE_LOG_LEVEL:=${LOG_LEVEL:="INFO"}}
  587. KEYSERVER=${MONKEYSPHERE_KEYSERVER:=${KEYSERVER:="pool.sks-keyservers.net"}}
  588. AUTHORIZED_USER_IDS=${MONKEYSPHERE_AUTHORIZED_USER_IDS:=${AUTHORIZED_USER_IDS:="%h/.monkeysphere/authorized_user_ids"}}
  589. RAW_AUTHORIZED_KEYS=${MONKEYSPHERE_RAW_AUTHORIZED_KEYS:=${RAW_AUTHORIZED_KEYS:="%h/.ssh/authorized_keys"}}
  590. MONKEYSPHERE_USER=${MONKEYSPHERE_MONKEYSPHERE_USER:=${MONKEYSPHERE_USER:="monkeysphere"}}
  591. # other variables
  592. CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:="true"}
  593. REQUIRED_USER_KEY_CAPABILITY=${MONKEYSPHERE_REQUIRED_USER_KEY_CAPABILITY:="a"}
  594. GNUPGHOME_HOST=${MONKEYSPHERE_GNUPGHOME_HOST:="${SYSDATADIR}/gnupg-host"}
  595. GNUPGHOME_AUTHENTICATION=${MONKEYSPHERE_GNUPGHOME_AUTHENTICATION:="${SYSDATADIR}/gnupg-authentication"}
  596. # export variables needed in su invocation
  597. export DATE
  598. export MODE
  599. export MONKEYSPHERE_USER
  600. export LOG_LEVEL
  601. export KEYSERVER
  602. export CHECK_KEYSERVER
  603. export REQUIRED_USER_KEY_CAPABILITY
  604. export GNUPGHOME_HOST
  605. export GNUPGHOME_AUTHENTICATION
  606. export GNUPGHOME
  607. # get subcommand
  608. COMMAND="$1"
  609. [ "$COMMAND" ] || failure "Type '$PGRM help' for usage."
  610. shift
  611. case $COMMAND in
  612. 'show-key'|'show'|'s')
  613. show_server_key
  614. ;;
  615. 'extend-key'|'e')
  616. check_host_keyring
  617. extend_key "$@"
  618. ;;
  619. 'add-hostname'|'add-name'|'n+')
  620. check_host_keyring
  621. add_hostname "$@"
  622. ;;
  623. 'revoke-hostname'|'revoke-name'|'n-')
  624. check_host_keyring
  625. revoke_hostname "$@"
  626. ;;
  627. 'add-revoker'|'o')
  628. check_host_keyring
  629. add_revoker "$@"
  630. ;;
  631. 'revoke-key'|'r')
  632. check_host_keyring
  633. revoke_key "$@"
  634. ;;
  635. 'publish-key'|'publish'|'p')
  636. check_host_keyring
  637. publish_server_key
  638. ;;
  639. 'expert'|'e')
  640. check_user
  641. SUBCOMMAND="$1"
  642. shift
  643. case "$SUBCOMMAND" in
  644. 'import-key'|'i')
  645. import_key "$@"
  646. ;;
  647. 'gen-key'|'g')
  648. gen_key "$@"
  649. ;;
  650. 'diagnostics'|'d')
  651. diagnostics
  652. ;;
  653. *)
  654. failure "Unknown expert subcommand: '$COMMAND'
  655. Type '$PGRM help' for usage."
  656. ;;
  657. esac
  658. ;;
  659. 'version'|'v')
  660. echo "$VERSION"
  661. ;;
  662. '--help'|'help'|'-h'|'h'|'?')
  663. usage
  664. ;;
  665. *)
  666. failure "Unknown command: '$COMMAND'
  667. Type '$PGRM help' for usage."
  668. ;;
  669. esac
  670. exit "$RETURN"