diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common | 185 | ||||
-rwxr-xr-x | src/monkeysphere | 34 | ||||
-rwxr-xr-x | src/monkeysphere-server | 100 | ||||
-rwxr-xr-x | src/monkeysphere-ssh-proxycommand | 2 | ||||
-rwxr-xr-x | src/seckey2sshagent | 15 |
5 files changed, 138 insertions, 198 deletions
@@ -18,10 +18,17 @@ ETC="/etc/monkeysphere" export ETC CACHE="/var/cache/monkeysphere" export CACHE +ERR=0 +export ERR ######################################################################## ### UTILITY FUNCTIONS +error() { + log "$1" + ERR=${2:-'1'} +} + failure() { echo "$1" >&2 exit ${2:-'1'} @@ -29,12 +36,12 @@ failure() { # write output to stderr log() { - echo -n "ms: " 1>&2 - echo "$@" 1>&2 + echo -n "ms: " >&2 + echo "$@" >&2 } loge() { - echo "$@" 1>&2 + echo "$@" >&2 } # cut out all comments(#) and blank lines from standard input @@ -85,6 +92,24 @@ remove_line() { fi } +# translate ssh-style path variables %h and %u +translate_ssh_variables() { + local uname + local home + + uname="$1" + path="$2" + + # get the user's home directory + userHome=$(getent passwd "$uname" | cut -d: -f6) + + # translate ssh-style path variables + path=${path/\%u/"$uname"} + path=${path/\%h/"$userHome"} + + echo "$path" +} + ### CONVERTION UTILITIES # output the ssh key for a given key ID @@ -351,110 +376,79 @@ process_user_id() { done } -# update the cache for userid, and prompt to add file to -# authorized_user_ids file if the userid is found in gpg -# and not already in file. -update_userid() { - local userID - - userID="$1" - - log "processing userid: '$userID'" - - # process the user ID to pull it from keyserver - process_user_id "$userID" | grep -q "^0 " - - # check if user ID is in the authorized_user_ids file - if ! grep -q "^${userID}\$" "$AUTHORIZED_USER_IDS" ; then - read -p "user ID not currently authorized. authorize? [Y|n]: " OK; OK=${OK:=Y} - if [ ${OK/y/Y} = 'Y' ] ; then - # add if specified - log -n " adding user ID to authorized_user_ids file... " - echo "$userID" >> "$AUTHORIZED_USER_IDS" - loge "done." - else - # else do nothing - log " authorized_user_ids file untouched." - fi - fi -} - -# remove a userid from the authorized_user_ids file -remove_userid() { - local userID - - userID="$1" - - log "processing userid: '$userID'" - - # check if user ID is in the authorized_user_ids file - if ! grep -q "^${userID}\$" "$AUTHORIZED_USER_IDS" ; then - log " user ID not currently authorized." - return 1 - fi - - # remove user ID from file - log -n " removing user ID '$userID'... " - remove_line "$AUTHORIZED_USER_IDS" "^${userID}$" - loge "done." -} - -# process a host in known_host file -process_host_known_hosts() { +# process hosts in the known_host file +process_hosts_known_hosts() { local host local userID local ok local keyid local tmpfile - host="$1" - userID="ssh://${host}" - - log "processing host: $host" - - process_user_id "ssh://${host}" | \ - while read -r ok keyid ; do - sshKey=$(gpg2ssh "$keyid") - # remove the old host key line - remove_line "$KNOWN_HOSTS" "$sshKey" - # if key OK, add new host line - if [ "$ok" -eq '0' ] ; then - # hash if specified - if [ "$HASH_KNOWN_HOSTS" = 'true' ] ; then - # FIXME: this is really hackish cause ssh-keygen won't - # hash from stdin to stdout - tmpfile=$(mktemp) - ssh2known_hosts "$host" "$sshKey" > "$tmpfile" - ssh-keygen -H -f "$tmpfile" 2> /dev/null - cat "$tmpfile" >> "$KNOWN_HOSTS" - rm -f "$tmpfile" "${tmpfile}.old" - else - ssh2known_hosts "$host" "$sshKey" >> "$KNOWN_HOSTS" + # create a lockfile on known_hosts + lockfile-create "$KNOWN_HOSTS" + + for host ; do + log "processing host: $host" + + userID="ssh://${host}" + + process_user_id "ssh://${host}" | \ + while read -r ok keyid ; do + sshKey=$(gpg2ssh "$keyid") + # remove the old host key line + remove_line "$KNOWN_HOSTS" "$sshKey" + # if key OK, add new host line + if [ "$ok" -eq '0' ] ; then + # hash if specified + if [ "$HASH_KNOWN_HOSTS" = 'true' ] ; then + # FIXME: this is really hackish cause ssh-keygen won't + # hash from stdin to stdout + tmpfile=$(mktemp) + ssh2known_hosts "$host" "$sshKey" > "$tmpfile" + ssh-keygen -H -f "$tmpfile" 2> /dev/null + cat "$tmpfile" >> "$KNOWN_HOSTS" + rm -f "$tmpfile" "${tmpfile}.old" + else + ssh2known_hosts "$host" "$sshKey" >> "$KNOWN_HOSTS" + fi fi - fi + done + # touch the lockfile, for good measure. + lockfile-touch --oneshot "$KNOWN_HOSTS" done + + # remove the lockfile + lockfile-remove "$KNOWN_HOSTS" } -# process a uid in an authorized_keys file -process_uid_authorized_keys() { +# process uids for the authorized_keys file +process_uids_authorized_keys() { local userID local ok local keyid - userID="$1" + # create a lockfile on authorized_keys + lockfile-create "$AUTHORIZED_KEYS" - log "processing user ID: $userID" + for userID ; do + log "processing user ID: $userID" - process_user_id "$userID" | \ - while read -r ok keyid ; do - sshKey=$(gpg2ssh "$keyid") - # remove the old host key line - remove_line "$AUTHORIZED_KEYS" "$sshKey" - # if key OK, add new host line - if [ "$ok" -eq '0' ] ; then - ssh2authorized_keys "$userID" "$sshKey" >> "$AUTHORIZED_KEYS" - fi + process_user_id "$userID" | \ + while read -r ok keyid ; do + sshKey=$(gpg2ssh "$keyid") + # remove the old host key line + remove_line "$AUTHORIZED_KEYS" "$sshKey" + # if key OK, add new host line + if [ "$ok" -eq '0' ] ; then + ssh2authorized_keys "$userID" "$sshKey" >> "$AUTHORIZED_KEYS" + fi + done + # touch the lockfile, for good measure. + lockfile-touch --oneshot "$AUTHORIZED_KEYS" done + + # remove the lockfile + lockfile-remove "$AUTHORIZED_KEYS" } # process known_hosts file @@ -469,10 +463,7 @@ process_known_hosts() { cat "$KNOWN_HOSTS" | meat | \ cut -d ' ' -f 1 | grep -v '^|.*$' | \ while IFS=, read -r -a hosts ; do - # and process each host - for host in ${hosts[*]} ; do - process_host_known_hosts "$host" - done + process_hosts_known_hosts ${hosts[@]} done } @@ -480,9 +471,11 @@ process_known_hosts() { process_authorized_user_ids() { local userid - cat "$AUTHORIZED_USER_IDS" | meat | \ + authorizedUserIDs="$1" + + cat "$authorizedUserIDs" | meat | \ while read -r userid ; do - process_uid_authorized_keys "$userid" + process_uids_authorized_keys "$userid" done } diff --git a/src/monkeysphere b/src/monkeysphere index a6cecfd..58f0fdc 100755 --- a/src/monkeysphere +++ b/src/monkeysphere @@ -35,8 +35,6 @@ MonkeySphere client tool. subcommands: update-known_hosts (k) [HOST]... update known_hosts file - update-userids (u) [USERID]... add/update user IDs - remove-userids (r) [USERID]... remove user IDs update-authorized_keys (a) update authorized_keys file gen-subkey (g) KEYID generate an 'a' capable subkey help (h,?) this help @@ -142,12 +140,9 @@ case $COMMAND in # if hosts are specified on the command line, process just # those hosts if [ "$1" ] ; then - for host ; do - process_host_known_hosts "$host" - done - log "known_hosts file updated." + process_hosts_known_hosts "$@" - # otherwise, if no hosts are specified, process every user + # otherwise, if no hosts are specified, process every host # in the user's known_hosts file else if [ ! -s "$KNOWN_HOSTS" ] ; then @@ -155,30 +150,9 @@ case $COMMAND in fi log "processing known_hosts file..." process_known_hosts - log "known_hosts file updated." fi - ;; - 'update-userids'|'update-userid'|'u') - if [ -z "$1" ] ; then - failure "you must specify at least one userid." - fi - for userID ; do - update_userid "$userID" - done - log "Run the following to update your monkeysphere authorized_keys file:" - log "$PGRM update-authorized_keys" - ;; - - 'remove-userids'|'remove-userid'|'r') - if [ -z "$1" ] ; then - failure "you must specify at least one userid." - fi - for userID ; do - remove_userid "$userID" - done - log "Run the following to update your monkeysphere authorized_keys file:" - log "$PGRM update-authorized_keys" + log "known_hosts file updated." ;; 'update-authorized_keys'|'update-authorized-keys'|'a') @@ -191,7 +165,7 @@ case $COMMAND in # process authorized_user_ids file log "processing authorized_user_ids file..." - process_authorized_user_ids + process_authorized_user_ids "$AUTHORIZED_USER_IDS" log "authorized_keys file updated." ;; diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 96a1070..693c062 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -31,14 +31,11 @@ usage: $PGRM <subcommand> [args] MonkeySphere server admin tool. subcommands: + update-users (s) [USER]... update users authorized_keys files gen-key (g) [HOSTNAME] generate gpg key for the server show-fingerprint (f) show server's host key fingerprint publish-key (p) publish server key to keyserver trust-keys (t) KEYID... mark keyids as trusted - - update-users (s) [USER]... update users authorized_keys files - update-user-userids (u) USER UID... add/update user IDs for a user - remove-user-userids (r) USER UID... remove user IDs for a user help (h,?) this help EOF @@ -139,6 +136,7 @@ GNUPGHOME=${GNUPGHOME:-"${MS_HOME}/gnupg"} KEYSERVER=${KEYSERVER:-"subkeys.pgp.net"} CHECK_KEYSERVER=${CHECK_KEYSERVER:="true"} REQUIRED_USER_KEY_CAPABILITY=${REQUIRED_USER_KEY_CAPABILITY:-"a"} +AUTHORIZED_USER_IDS=${AUTHORIZED_USER_IDS:-"%h/.config/monkeysphere/authorized_user_ids"} USER_CONTROLLED_AUTHORIZED_KEYS=${USER_CONTROLLED_AUTHORIZED_KEYS:-"%h/.ssh/authorized_keys"} export GNUPGHOME @@ -153,40 +151,50 @@ mkdir -p "${CACHE}/authorized_keys" case $COMMAND in 'update-users'|'update-user'|'s') if [ "$1" ] ; then + # get users from command line unames="$@" else - unames=$(ls -1 "${MS_HOME}/authorized_user_ids") + # or just look at all users if none specified + unames=$(getent passwd | cut -d: -f1) fi + # loop over users for uname in $unames ; do MODE="authorized_keys" + # check all specified users exist + if ! getent passwd "$uname" >/dev/null ; then + error "----- unknown user '$uname' -----" + continue + fi + + # set authorized_user_ids variable, + # translate ssh-style path variables + authorizedUserIDs=$(translate_ssh_variables "$uname" "$AUTHORIZED_USER_IDS") + + # skip user if authorized_user_ids file does not exist + if [ ! -f "$authorizedUserIDs" ] ; then + continue + fi + log "----- user: $uname -----" - # set variables for the user - AUTHORIZED_USER_IDS="${MS_HOME}/authorized_user_ids/${uname}" # temporary authorized_keys file - AUTHORIZED_KEYS="${CACHE}/authorized_keys/${uname}.tmp" - - # make sure user's authorized_user_ids file exists - touch "$AUTHORIZED_USER_IDS" - # make sure the authorized_keys file exists and is clear - > "$AUTHORIZED_KEYS" + AUTHORIZED_KEYS=$(mktemp) # skip if the user's authorized_user_ids file is empty - if [ ! -s "$AUTHORIZED_USER_IDS" ] ; then - log "authorized_user_ids file for '$uname' is empty." + if [ ! -s "$authorizedUserIDs" ] ; then + log "authorized_user_ids file '$authorizedUserIDs' is empty." continue fi # process authorized_user_ids file log "processing authorized_user_ids file..." - process_authorized_user_ids + process_authorized_user_ids "$authorizedUserIDs" # add user-controlled authorized_keys file path if specified if [ "$USER_CONTROLLED_AUTHORIZED_KEYS" != '-' ] ; then - userHome=$(getent passwd "$uname" | cut -d: -f6) - userAuthorizedKeys=${USER_CONTROLLED_AUTHORIZED_KEYS/\%h/"$userHome"} + userAuthorizedKeys=$(translate_ssh_variables "$uname" "$USER_CONTROLLED_AUTHORIZED_KEYS") if [ -f "$userAuthorizedKeys" ] ; then log -n "adding user's authorized_keys file... " cat "$userAuthorizedKeys" >> "$AUTHORIZED_KEYS" @@ -195,12 +203,10 @@ case $COMMAND in fi # move the temp authorized_keys file into place - mv -f "${CACHE}/authorized_keys/${uname}.tmp" "${CACHE}/authorized_keys/${uname}" + mv -f "$AUTHORIZED_KEYS" "${CACHE}/authorized_keys/${uname}" log "authorized_keys file updated." done - - log "----- done. -----" ;; 'gen-key'|'g') @@ -226,56 +232,6 @@ case $COMMAND in done ;; - 'update-user-userids'|'update-user-userid'|'u') - uname="$1" - shift - if [ -z "$uname" ] ; then - failure "You must specify user." - fi - if [ -z "$1" ] ; then - failure "You must specify at least one user ID." - fi - - # set variables for the user - AUTHORIZED_USER_IDS="$MS_HOME"/authorized_user_ids/"$uname" - - # make sure user's authorized_user_ids file exists - touch "$AUTHORIZED_USER_IDS" - - # process the user IDs - for userID ; do - update_userid "$userID" - done - - log "Run the following to update user's authorized_keys file:" - log "$PGRM update-users $uname" - ;; - - 'remove-user-userids'|'remove-user-userid'|'r') - uname="$1" - shift - if [ -z "$uname" ] ; then - failure "You must specify user." - fi - if [ -z "$1" ] ; then - failure "You must specify at least one user ID." - fi - - # set variables for the user - AUTHORIZED_USER_IDS="$MS_HOME"/authorized_user_ids/"$uname" - - # make sure user's authorized_user_ids file exists - touch "$AUTHORIZED_USER_IDS" - - # process the user IDs - for userID ; do - remove_userid "$userID" - done - - log "Run the following to update user's authorized_keys file:" - log "$PGRM update-users $uname" - ;; - 'help'|'h'|'?') usage ;; @@ -285,3 +241,5 @@ case $COMMAND in Type '$PGRM help' for usage." ;; esac + +exit "$ERR" diff --git a/src/monkeysphere-ssh-proxycommand b/src/monkeysphere-ssh-proxycommand index 4cbcd51..f4d4b0d 100755 --- a/src/monkeysphere-ssh-proxycommand +++ b/src/monkeysphere-ssh-proxycommand @@ -49,7 +49,7 @@ if [ "$PORT" != '22' ] ; then fi # if the host is in the gpg keyring... -if gpg --list-key ="${URI}" >/dev/null ; then +if gpg --list-key ="${URI}" 2>&1 >/dev/null ; then # do not check the keyserver CHECK_KEYSERVER="false" # if the host is NOT in the keyring... diff --git a/src/seckey2sshagent b/src/seckey2sshagent index 0e8d695..d8e9b79 100755 --- a/src/seckey2sshagent +++ b/src/seckey2sshagent @@ -1,5 +1,20 @@ #!/bin/sh +# seckey2sshagent: this is a hack of a script to cope with the fact +# that openpgp2ssh currently cannot support encrypted secret keys. + +# the basic operating principal is: + +# export the secret key in encrypted format to a new keyring + +# remove the passphrase in that keyring + +# use that keyring with openpgp2ssh + +# Authors: Daniel Kahn Gillmor <dkg@fifthhorseman.net>, +# Jameson Rollins <jrollins@fifthhorseman.net> + + cleanup() { echo -n "removing temp gpg home... " rm -rf $FOO |