#! /bin/bash # Copyright (c) 2007 Andrés J. Díaz # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Downloaded from https://launchpad.net/ssh-keysend ssh_keysend_db_keys=( ~/.ssh/*.pub ) ssh_keysend_db_host=( ~/.ssh/known_hosts ) log_level=0 fatal () { echo "fatal: $@" >&2 ; ${E:+exit $E}; } require () { type -p "$1" 2>&1 >/dev/null; } debug () { :; } list () { :; } help () { echo "$0 [options] ..." echo echo "ssh-keysend send a number of public ssh keys to a different" echo "machines over a network. user@host is the user in the hostname" echo "host who ssh-keysend will authorize in a list of remotehosts." echo echo "Options:" echo " -h display this help screen" echo " -v increase verbosity" echo " -p pretend. Do not do really" echo " -K file use file as key database" echo " -H file use file as host database" echo echo "Andrés J. Díaz " } verbose () { debug () { echo "debug::$@" >&2; } list () { for item in "$@"; do if [ "${item%% *}" != "${item## *}" ] then debug " [${item%% *}] ${item##* } " else debug " ${item}" fi done; } } # Parse options in command line using getopts. while getopts "hvpK:H:" option "$@"; do case $option in v) verbose ;; h) help && exit 0 ;; p) pretend=true ;; K) ssh_keysend_db_keys="$OPTARG" ;; H) ssh_keysend_db_host="$OPTARG" ;; esac done ; shift $((OPTIND -1)) # Check if pattern search argument exists, if not then exit with error code # one. If @ is not present in pattern search, add wildcard automatically. [ "$1" ] || E=1 fatal $"user@host not specified." user="$1"; shift [ "${user%@*}" = "${user}" ] && set -- "${user:-.*}@.*" "$@" debug "Found pattern keys is: $1" debug "Found pattern host is: ${2:-.*}" # Getting the keys which matching with pattern search into ssh-keysend # public keys database. keys="$( awk "/[ ]$1$/ { printf \"'%s'\n\",\$0 }" "${ssh_keysend_db_keys[@]}" )" eval keys=( $keys ) debug $"Found ${#keys[@]} key(s) for specified pattern matching." list "${keys[@]}" # Getting the hosts which we will send the specified keys via ssh-keysend. host="$( awk "/^${2:-.*}/ { gsub(\",.*\",\"\"); printf \"'%s'\n\",\$1 }" \ "${ssh_keysend_db_host[@]}" )" eval host=( $host ) debug $"Affected ${#host[@]} host(s) for current action." list "${host[@]}" # The keys() function return a short list of keys to be exported, including # the user@host and key type. keys () { oldIFS="$IFS" ; export IFS=$'\n' keys="${keys[*]}"; export IFS="$oldIFS" echo "${keys}" } # If running in pretend mode, then it's a good moment to exit. ${pretend:-false} && exit 0 # For each host try to put ssh key in respective authorized_keys file. for host in "${host[@]}" ; do [ "${host##*@}" = "${host}" ] && host="$user@$host" debug "Sending keys to $host..." keys | ssh "$host" "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" done # vim:foldmethod=syntax:foldenable: