summaryrefslogtreecommitdiff
path: root/src/monkeysphere-server
blob: ac7c1cbca3cac6b12e3303338a3cc4b6470f4aff (plain)
  1. #!/bin/bash
  2. # monkeysphere-server: MonkeySphere server admin tool
  3. #
  4. # The monkeysphere scripts are written by:
  5. # Jameson Rollins <jrollins@fifthhorseman.net>
  6. #
  7. # They are Copyright 2008, and are all released under the GPL, version 3
  8. # or later.
  9. ########################################################################
  10. PGRM=$(basename $0)
  11. SHARE=${SHARE:-"/usr/share/monkeysphere"}
  12. export SHARE
  13. . "${SHARE}/common"
  14. VARLIB="/var/lib/monkeysphere"
  15. export VARLIB
  16. # date in UTF format if needed
  17. DATE=$(date -u '+%FT%T')
  18. # unset some environment variables that could screw things up
  19. GREP_OPTIONS=
  20. # default return code
  21. ERR=0
  22. ########################################################################
  23. # FUNCTIONS
  24. ########################################################################
  25. usage() {
  26. cat <<EOF
  27. usage: $PGRM <subcommand> [args]
  28. MonkeySphere server admin tool.
  29. subcommands:
  30. update-users (u) [USER]... update users authorized_keys files
  31. gen-key (g) [HOSTNAME] generate gpg key for the server
  32. show-fingerprint (f) show server's host key fingerprint
  33. publish-key (p) publish server's host key to keyserver
  34. trust-key (t) KEYID [LEVEL] set owner trust for keyid
  35. help (h,?) this help
  36. EOF
  37. }
  38. # generate server gpg key
  39. gen_key() {
  40. local hostName
  41. hostName=${1:-$(hostname --fqdn)}
  42. SERVICE=${SERVICE:-"ssh"}
  43. userID="${SERVICE}://${hostName}"
  44. if gpg --list-key ="$userID" > /dev/null 2>&1 ; then
  45. failure "Key for '$userID' already exists"
  46. fi
  47. # set key defaults
  48. KEY_TYPE=${KEY_TYPE:-"RSA"}
  49. KEY_LENGTH=${KEY_LENGTH:-"2048"}
  50. KEY_USAGE=${KEY_USAGE:-"auth"}
  51. KEY_EXPIRE=${KEY_EXPIRE:-"0"}
  52. cat <<EOF
  53. Please specify how long the key should be valid.
  54. 0 = key does not expire
  55. <n> = key expires in n days
  56. <n>w = key expires in n weeks
  57. <n>m = key expires in n months
  58. <n>y = key expires in n years
  59. EOF
  60. read -p "Key is valid for? ($KEY_EXPIRE) " KEY_EXPIRE; KEY_EXPIRE=${KEY_EXPIRE:-"0"}
  61. # set key parameters
  62. keyParameters=$(cat <<EOF
  63. Key-Type: $KEY_TYPE
  64. Key-Length: $KEY_LENGTH
  65. Key-Usage: $KEY_USAGE
  66. Name-Real: $userID
  67. Expire-Date: $KEY_EXPIRE
  68. EOF
  69. )
  70. # add the revoker field if requested
  71. # FIXME: the "1:" below assumes that $REVOKER's key is an RSA key. why?
  72. # FIXME: why is this marked "sensitive"? how will this signature ever
  73. # be transmitted to the expected revoker?
  74. if [ "$REVOKER" ] ; then
  75. keyParameters="${keyParameters}"$(cat <<EOF
  76. Revoker: 1:$REVOKER sensitive
  77. EOF
  78. )
  79. fi
  80. echo "The following key parameters will be used:"
  81. echo "$keyParameters"
  82. read -p "Generate key? [Y|n]: " OK; OK=${OK:=Y}
  83. if [ ${OK/y/Y} != 'Y' ] ; then
  84. failure "aborting."
  85. fi
  86. # add commit command
  87. keyParameters="${keyParameters}"$(cat <<EOF
  88. %commit
  89. %echo done
  90. EOF
  91. )
  92. log "generating server key... "
  93. echo "$keyParameters" | gpg --batch --gen-key
  94. # output the server fingerprint
  95. fingerprint_server_key "=${userID}"
  96. # find the key fingerprint of the server primary key
  97. keyID=$(gpg --list-key --with-colons --with-fingerprint "=${userID}" | \
  98. grep '^fpr:' | head -1 | cut -d: -f10)
  99. # write the key to the file
  100. # NOTE: assumes that the primary key is the proper key to use
  101. (umask 077 && gpgsecret2ssh "$keyID" > "${VARLIB}/ssh_host_rsa_key")
  102. log "Private SSH host key output to file: ${VARLIB}/ssh_host_rsa_key"
  103. }
  104. # gpg output key fingerprint
  105. fingerprint_server_key() {
  106. local ID
  107. if [ -z "$1" ] ; then
  108. ID="$1"
  109. else
  110. ID="=ssh://$(hostname --fqdn)"
  111. fi
  112. gpg --fingerprint --list-secret-keys "$ID"
  113. }
  114. ########################################################################
  115. # MAIN
  116. ########################################################################
  117. COMMAND="$1"
  118. [ "$COMMAND" ] || failure "Type '$PGRM help' for usage."
  119. shift
  120. # set ms home directory
  121. MS_HOME=${MS_HOME:-"$ETC"}
  122. # load configuration file
  123. MS_CONF=${MS_CONF:-"$MS_HOME"/monkeysphere-server.conf}
  124. [ -e "$MS_CONF" ] && . "$MS_CONF"
  125. # set empty config variable with defaults
  126. MONKEYSPHERE_USER=${MONKEYSPHERE_USER:-"monkeysphere"}
  127. KEYSERVER=${KEYSERVER:-"subkeys.pgp.net"}
  128. CHECK_KEYSERVER=${CHECK_KEYSERVER:="true"}
  129. AUTHORIZED_USER_IDS=${AUTHORIZED_USER_IDS:-"%h/.config/monkeysphere/authorized_user_ids"}
  130. RAW_AUTHORIZED_KEYS=${RAW_AUTHORIZED_KEYS:-"%h/.ssh/authorized_keys"}
  131. # other variables
  132. REQUIRED_USER_KEY_CAPABILITY=${REQUIRED_USER_KEY_CAPABILITY:-"a"}
  133. GNUPGHOME_HOST=${GNUPGHOME_HOST:-"${VARLIB}/gnupg-host"}
  134. GNUPGHOME_AUTHENTICATION=${GNUPGHOME_AUTHENTICATION:-"${VARLIB}/gnupg-authentication"}
  135. # set default GNUPGHOME, and make sure the directory exists. this is
  136. # true for all functions expect user authentication
  137. # (ie. update-users).
  138. GNUPGHOME="$GNUPGHOME_HOST"
  139. export GNUPGHOME
  140. mkdir -p -m 0700 "$GNUPGHOME"
  141. case $COMMAND in
  142. 'update-users'|'update-user'|'u')
  143. if [ "$1" ] ; then
  144. # get users from command line
  145. unames="$@"
  146. else
  147. # or just look at all users if none specified
  148. unames=$(getent passwd | cut -d: -f1)
  149. fi
  150. # set mode
  151. MODE="authorized_keys"
  152. # make sure the authorized_keys directory exists
  153. mkdir -p "${VARLIB}/authorized_keys"
  154. # set GNUPGHOME, and make sure the directory exists
  155. GNUPGHOME="$GNUPGHOME_AUTHENTICATION"
  156. export GNUPGHOME
  157. mkdir -p -m 0700 "$GNUPGHOME"
  158. # loop over users
  159. for uname in $unames ; do
  160. # check all specified users exist
  161. if ! getent passwd "$uname" >/dev/null ; then
  162. error "----- unknown user '$uname' -----"
  163. continue
  164. fi
  165. # set authorized_user_ids and raw authorized_keys variables,
  166. # translating ssh-style path variables
  167. authorizedUserIDs=$(translate_ssh_variables "$uname" "$AUTHORIZED_USER_IDS")
  168. rawAuthorizedKeys=$(translate_ssh_variables "$uname" "$RAW_AUTHORIZED_KEYS")
  169. # if neither is found, skip user
  170. if [ ! -s "$authorizedUserIDs" -a ! -s "$rawAuthorizedKeys" ] ; then
  171. continue
  172. fi
  173. log "----- user: $uname -----"
  174. # temporary authorized_keys file
  175. AUTHORIZED_KEYS=$(mktemp)
  176. # trap to delete file on exit
  177. trap "rm -f $AUTHORIZE_KEYS" EXIT
  178. # process authorized_user_ids file
  179. if [ -s "$authorizedUserIDs" ] ; then
  180. log "processing authorized_user_ids file..."
  181. process_authorized_user_ids "$authorizedUserIDs"
  182. fi
  183. # add user-controlled authorized_keys file path if specified
  184. if [ "$RAW_AUTHORIZED_KEYS" != '-' ] ; then
  185. if [ -s "$rawAuthorizedKeys" ] ; then
  186. log -n "adding raw authorized_keys file... "
  187. cat "$rawAuthorizedKeys" >> "$AUTHORIZED_KEYS"
  188. loge "done."
  189. fi
  190. fi
  191. # if the resulting authorized_keys file is not empty, move
  192. # the temp authorized_keys file into place
  193. if [ -s "$AUTHORIZED_KEYS" ] ; then
  194. # openssh appears to check the contents of the
  195. # authorized_keys file as the user in question, so the
  196. # file must be readable by that user at least.
  197. # FIXME: is there a better way to do this?
  198. chgrp $(getent passwd "$uname" | cut -f4 -d:) "$AUTHORIZED_KEYS"
  199. chmod g+r "$AUTHORIZED_KEYS"
  200. mv -f "$AUTHORIZED_KEYS" "${VARLIB}/authorized_keys/${uname}"
  201. log "authorized_keys file updated."
  202. # else destroy it
  203. else
  204. rm -f "$AUTHORIZED_KEYS"
  205. fi
  206. done
  207. ;;
  208. 'gen-key'|'g')
  209. gen_key "$1"
  210. ;;
  211. 'show-fingerprint'|'f')
  212. fingerprint_server_key "$@"
  213. ;;
  214. 'publish-key'|'p')
  215. publish_server_key
  216. ;;
  217. 'trust-key'|'trust-key'|'t')
  218. trust_key "$@"
  219. ;;
  220. 'help'|'h'|'?')
  221. usage
  222. ;;
  223. *)
  224. failure "Unknown command: '$COMMAND'
  225. Type '$PGRM help' for usage."
  226. ;;
  227. esac
  228. exit "$ERR"