nutools/ussh

188 lines
5.9 KiB
Plaintext
Raw Normal View History

2013-08-27 15:14:44 +04:00
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
function display_help() {
uecho "$scriptname: se connecter par ssh à un ou plusieurs hôtes
USAGE
$scriptname host [options]
$scriptname @hostsfile [options]
$scriptname -R hosts...
OPTIONS
host
@hostsfile
Spécifier un hôte distant sur lequel faire la connexion. Plusieurs
hôtes peuvent être spécifiées, en les séparant par ':', e.g. host1:host2
La forme @hostsfile permet de lire la liste des hôtes depuis le fichier
hostsfile, à raison d'un hôte par ligne.
[options]
Les arguments et options de ssh doivent se trouver *APRES* host, pour
simplifier leur analyse.
2014-02-21 08:52:19 +04:00
Les options suivantes sont reconnues même quand elle sont spécifiées avant le
premier argument (les options longues ne sont reconnues qu'avant le premier
argument):
-q, --quiet
Mode non verbeux
-t, --tty
Forcer l'allocation d'un TTY
-l, --login USER
Spécifier le user avec lequel se connecter
-o OPTION
Ajouter une option de SSH
Les options suivantes *doivent* se trouver *AVANT* le premier argument:
-d, --domain DOMAIN
Spécifier un domaine par défaut pour les hôtes qui sont spécifiés sans
domaine.
-S, --ssh SSH
2013-08-27 15:14:44 +04:00
Spécifier l'exécutable à utiliser pour lancer ssh.
-R, --remove
2013-08-27 15:14:44 +04:00
Lancer 'ssh-keygen -R' pour chacun des hôtes spécifiés. Par exemple:
$scriptname -R host.tld
est équivalent à:
ssh-keygen -R host.tld
ssh-keygen -R host
ssh-keygen -R 10.10.1.5
si l'adresse ip de host.tld est 10.10.1.5
Quand cette option est spécifié, l'option -c est reconnue et permet de
se reconnecter à l'hôte juste après avoir nettoyé les clés."
2013-08-27 15:14:44 +04:00
}
source "$(dirname "$0")/ulib/ulib" || exit 1
urequire DEFAULTS
set_defaults nutools
2013-08-27 15:14:44 +04:00
__PARSED_HOSTS=()
__PARSED_FILES=()
function parse_hostsfile() {
# Lire chacun des fichiers $* et initialiser __PARSED_HOSTS avec la liste
# des hôtes mentionnés dans les fichiers.
local inputfile basedir inputs input
for inputfile in "$@"; do
inputfile="$(abspath "$inputfile")"
array_contains __PARSED_FILES "$inputfile" && {
ewarn "$(ppath "$inputfile"): inclusion récursive"
continue
}
array_add __PARSED_FILES "$inputfile"
basedir="$(dirname "$inputfile")"
array_from_lines inputs "$(<"$inputfile" filter_conf)" || {
ewarn "$inputfile: fichier ingnoré"
continue
}
for input in "${inputs[@]}"; do
if [ "${input#@}" != "$input" ]; then
# fichier inclus
parse_hostsfile "$(abspath "${input#@}" "$basedir")"
else
array_addu __PARSED_HOSTS "$input"
fi
done
done
}
function __dot_is_localhost() { [ "$1" == "." ] && echo "localhost" || echo "$1"; }
function fix_hosts() {
# Si hosts contient des éléments multiple, comme a:b, séparer ces
# éléments. i.e (a b:c) --> (a b c)
# Supporter la syntaxe @hostsfile qui permet de charger la liste des hôtes
# depuis un fichier.
# Remplacer aussi les '.' par 'localhost'
array_fix_paths hosts
local -a _hosts _tmphosts host
for host in "${hosts[@]}"; do
host="${host%/}"
if [ "${host#@}" != "$host" ]; then
__PARSED_HOSTS=()
parse_hostsfile "${host#@}"
array_fix_paths __PARSED_HOSTS
array_extendu _hosts __PARSED_HOSTS
else
array_addu _hosts "$host"
fi
done
array_copy hosts _hosts
array_map hosts __dot_is_localhost
}
action=ssh
quiet=
tty=
2014-02-21 08:52:19 +04:00
login=
2013-08-27 15:14:44 +04:00
options=()
domain="$USSH_DOMAIN"
2013-08-27 15:14:44 +04:00
ssh=
parse_opts + "${PRETTYOPTS[@]}" \
--help '$exit_with display_help' \
2014-02-21 08:52:19 +04:00
-q,--quiet quiet=1 \
-t,--tty tty=1 \
-l:,--login: login= \
2013-08-27 15:14:44 +04:00
-o options \
2014-02-21 08:52:19 +04:00
-d:,--domain: domain= \
2013-08-27 15:14:44 +04:00
-S:,--ssh ssh= \
-R,--remove action=remove \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ "$action" == "ssh" ]; then
[ -n "$1" ] || die "Vous devez spécifier l'hôte sur lequel faire la connexion"
hosts=("$1"); shift
fix_hosts
2014-02-21 08:52:19 +04:00
args=(${quiet:+-q} ${tty:+-t} ${login:+-l "$login"})
2013-08-27 15:14:44 +04:00
for option in "${options[@]}"; do
args=("${args[@]}" -o "$option")
done
args=("${args[@]}" "$@")
[ -n "$ssh" ] || ssh=ssh
[ "${#hosts[*]}" -gt 1 ] && showtitle=1 || showtitle=
for host in "${hosts[@]}"; do
splituserhost "$host" user host
2014-02-21 08:52:19 +04:00
[[ "$host" == *.* ]] || host="$host${domain:+.$domain}"
2014-02-21 08:53:18 +04:00
[ -n "$showtitle" ] && etitle "${user:+$user@}$host"
2013-08-27 15:14:44 +04:00
"$ssh" "${user:+$user@}$host" "${args[@]}"
[ -n "$showtitle" ] && eend
done
elif [ "$action" == "remove" ]; then
urequire ipcalc
function remove() {
estep "$1"
ssh-keygen -R "$1" >&/dev/null
}
[ -n "$1" ] || die "Vous devez spécifier les hôtes à supprimer de ~/.ssh/known_hosts"
hosts=("$@")
fix_hosts
etitle "Suppression des entrées dans ~/.ssh/known_hosts"
allhosts=("${hosts[@]}")
for host in "${allhosts[@]}"; do
2014-02-21 15:18:25 +04:00
splituserhost "$host" user host
[[ "$host" == *.* ]] || host="$host${domain:+.$domain}"
2013-08-27 15:14:44 +04:00
if ipcalc_checkip "$host" >/dev/null; then
ip="$host"
remove "$ip"
resolv_hosts hosts "$ip"
for host in "${hosts[@]}"; do
remove "$host"
hostname="${host%%.*}"
[ "$hostname" != "$host" ] && remove "$hostname"
done
else
remove "$host"
hostname="${host%%.*}"
[ "$hostname" != "$host" ] && remove "$hostname"
resolv_ips ips "$host"
for ip in "${ips[@]}"; do
remove "$ip"
done
fi
done
eend
fi