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