X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=src%2Fcommon;h=5bb0b79fac779d08348721f2d3e5d6df0f29ed5a;hb=91bf57bac7bed32937c13595044158007e7b5812;hp=89efc46a4014dbcfedaec546018c09d066e3509b;hpb=15637a9ab9b4fe7ea537988f5cc145d35948d783;p=monkeysphere.git diff --git a/src/common b/src/common index 89efc46..5bb0b79 100644 --- a/src/common +++ b/src/common @@ -22,6 +22,11 @@ export CACHE ######################################################################## ### UTILITY FUNCTIONS +error() { + log "$1" + ERR=${2:-'1'} +} + failure() { echo "$1" >&2 exit ${2:-'1'} @@ -29,12 +34,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 @@ -96,14 +101,15 @@ translate_ssh_variables() { # get the user's home directory userHome=$(getent passwd "$uname" | cut -d: -f6) - # translate ssh-style path variables + # translate '%u' to user name path=${path/\%u/"$uname"} + # translate '%h' to user home directory path=${path/\%h/"$userHome"} echo "$path" } -### CONVERTION UTILITIES +### CONVERSION UTILITIES # output the ssh key for a given key ID gpg2ssh() { @@ -116,6 +122,17 @@ gpg2ssh() { gpg --export "$keyID" | openpgp2ssh "$keyID" 2> /dev/null } +# output the ssh key for a given secret key ID +gpgsecret2ssh() { + local keyID + + #keyID="$1" #TMP + # only use last 16 characters until openpgp2ssh can take all 40 #TMP + keyID=$(echo "$1" | cut -c 25-) #TMP + + gpg --export-secret-key "$keyID" | openpgp2ssh "$keyID" 2> /dev/null +} + # output known_hosts line from ssh key ssh2known_hosts() { local host @@ -199,8 +216,8 @@ get_key_fingerprint() { keyID="$1" gpg --list-key --with-colons --fixed-list-mode \ - --with-fingerprint "$keyID" | grep "$keyID" | \ - grep '^fpr:' | cut -d: -f10 + --with-fingerprint --with-fingerprint "$keyID" | \ + grep '^fpr:' | grep "$keyID" | cut -d: -f10 } ######################################################################## @@ -246,7 +263,7 @@ process_user_id() { fi requiredPubCapability=$(echo "$requiredCapability" | tr "[:lower:]" "[:upper:]") - # if CHECK_KEYSERVER variable set, check the keyserver + # if CHECK_KEYSERVER variable set to true, check the keyserver # for the user ID if [ "$CHECK_KEYSERVER" = "true" ] ; then gpg_fetch_userid "$userID" @@ -325,9 +342,9 @@ process_user_id() { # 0 = ok, 1 = bad if [ "$keyOK" -a "$uidOK" -a "$lastKeyOK" ] ; then log " * acceptable key found." - echo 0 "$fingerprint" + echo "0:${fingerprint}" else - echo 1 "$fingerprint" + echo "1:${fingerprint}" fi ;; 'sub') # sub keys @@ -360,80 +377,37 @@ process_user_id() { # 0 = ok, 1 = bad if [ "$keyOK" -a "$uidOK" -a "$lastKeyOK" ] ; then log " * acceptable key found." - echo 0 "$fingerprint" + echo "0:${fingerprint}" else - echo 1 "$fingerprint" + echo "1:${fingerprint}" fi ;; esac 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" - authorizedUserIDs="$2" - - 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}\$" "$authorizedUserIDs" ; 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" >> "$authorizedUserIDs" - 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" - authorizedUserIDs="$2" - - log "processing userid: '$userID'" - - # check if user ID is in the authorized_user_ids file - if ! grep -q "^${userID}\$" "$authorizedUserIDs" ; then - log " user ID not currently authorized." - return 1 - fi - - # remove user ID from file - log -n " removing user ID '$userID'... " - remove_line "$authorizedUserIDs" "^${userID}$" - loge "done." -} - -# process a host in known_host file +# process a single host in the known_host file process_host_known_hosts() { local host local userID local ok local keyid local tmpfile + local returnCode + + # default return code is 1, which assumes no key was found + returnCode=1 host="$1" - userID="ssh://${host}" log "processing host: $host" - process_user_id "ssh://${host}" | \ - while read -r ok keyid ; do + userID="ssh://${host}" + + for line in $(process_user_id "ssh://${host}") ; do + ok=$(echo "$line" | cut -d: -f1) + keyid=$(echo "$line" | cut -d: -f2) + sshKey=$(gpg2ssh "$keyid") # remove the old host key line remove_line "$KNOWN_HOSTS" "$sshKey" @@ -451,61 +425,151 @@ process_host_known_hosts() { else ssh2known_hosts "$host" "$sshKey" >> "$KNOWN_HOSTS" fi + # set return code to be 0, since a key was found + returnCode=0 fi + return "$returnCode" done + + return "$returnCode" } -# process a uid in an authorized_keys file +# update the known_hosts file for a set of hosts listed on command +# line +update_known_hosts() { + local host + local returnCode + + # default return code is 0, which assumes a key was found for + # every host. code will be set to 1 if a key is not found for at + # least one host + returnCode=0 + + # set the trap to remove any lockfiles on exit + trap "lockfile-remove $KNOWN_HOSTS" EXIT + + # create a lockfile on known_hosts + lockfile-create "$KNOWN_HOSTS" + + for host ; do + # process the host, change return code if host key not found + process_host_known_hosts "$host" || returnCode=1 + + # touch the lockfile, for good measure. + lockfile-touch --oneshot "$KNOWN_HOSTS" + done + + # remove the lockfile + lockfile-remove "$KNOWN_HOSTS" + + return "$returnCode" +} + +# process known_hosts file, going through line-by-line, extract each +# host, and process with the host processing function +process_known_hosts() { + local returnCode + + # default return code is 0, which assumes a key was found for + # every host. code will be set to 1 if a key is not found for at + # least one host + returnCode=0 + + # take all the hosts from the known_hosts file (first field), grep + # out all the hashed hosts (lines starting with '|')... + for line in $(cat "$KNOWN_HOSTS" | meat | cut -d ' ' -f 1 | grep -v '^|.*$') ; do + # break up hosts into separate words + update_known_hosts $(echo "$line" | tr , ' ') || returnCode=1 + done + + return "$returnCode" +} + +# process uids for the authorized_keys file process_uid_authorized_keys() { local userID local ok local keyid + local returnCode + + # default return code is 1, which assumes no key was found + returnCode=1 userID="$1" log "processing user ID: $userID" - process_user_id "$userID" | \ - while read -r ok keyid ; do + for line in $(process_user_id "$userID") ; do + ok=$(echo "$line" | cut -d: -f1) + keyid=$(echo "$line" | cut -d: -f2) + 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" + + # set return code to be 0, since a key was found + returnCode=0 fi done + + return "$returnCode" } -# process known_hosts file -# go through line-by-line, extract each host, and process with the -# host processing function -process_known_hosts() { - local hosts - local host +# update the authorized_keys files from a list of user IDs on command +# line +update_authorized_keys() { + local userID + local returnCode + + # default return code is 0, which assumes a key was found for + # every user ID. code will be set to 1 if a key is not found for + # at least one user ID + returnCode=0 + + # set the trap to remove any lockfiles on exit + trap "lockfile-remove $AUTHORIZED_KEYS" EXIT - # take all the hosts from the known_hosts file (first field), - # grep out all the hashed hosts (lines starting with '|')... - 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 + # create a lockfile on authorized_keys + lockfile-create "$AUTHORIZED_KEYS" + + for userID ; do + # process the user ID, change return code if key not found for + # user ID + process_uid_authorized_keys "$userID" || returnCode=1 + + # touch the lockfile, for good measure. + lockfile-touch --oneshot "$AUTHORIZED_KEYS" done + + # remove the lockfile + lockfile-remove "$AUTHORIZED_KEYS" + + return "$returnCode" } # process an authorized_user_ids file for authorized_keys process_authorized_user_ids() { local userid + local returnCode + + # default return code is 0, and is set to 1 if a key for a user ID + # is not found + returnCode=0 authorizedUserIDs="$1" - cat "$authorizedUserIDs" | meat | \ - while read -r userid ; do - process_uid_authorized_keys "$userid" + # set the IFS to be newline for parsing the authorized_user_ids + # file. can't find it in BASH(1) (found it on the net), but it + # works. + IFS=$'\n' + for userid in $(cat "$authorizedUserIDs" | meat) ; do + update_authorized_keys "$userid" || returnCode=1 done + + return "$returnCode" } # EXPERIMENTAL (unused) process userids found in authorized_keys file @@ -515,6 +579,11 @@ process_authorized_user_ids() { process_authorized_keys() { local authorizedKeys local userID + local returnCode + + # default return code is 0, and is set to 1 if a key for a user + # is not found + returnCode=0 authorizedKeys="$1" @@ -539,8 +608,10 @@ process_authorized_keys() { # process the userid log "processing userid: '$userID'" - process_user_id "$userID" > /dev/null + process_user_id "$userID" > /dev/null || returnCode=1 done + + return "$returnCode" } ################################################## @@ -549,26 +620,63 @@ process_authorized_keys() { # retrieve key from web of trust, and set owner trust to "full" # if key is found. trust_key() { + local keyID + local trustLevel + + keyID="$1" + trustLevel="$2" + + if [ -z "$keyID" ] ; then + failure "You must specify key to trust." + fi + # get the key from the key server if ! gpg --keyserver "$KEYSERVER" --recv-key "$keyID" ; then - log "could not retrieve key '$keyID'" - return 1 + failure "Could not retrieve key '$keyID'." fi # get key fingerprint fingerprint=$(get_key_fingerprint "$keyID") + echo "key found:" + gpg --fingerprint "$fingerprint" + + while [ -z "$trustLevel" ] ; do + cat <