182 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/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.
 | 
						|
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
 | 
						|
        Spécifier l'exécutable à utiliser pour lancer ssh.
 | 
						|
    -R
 | 
						|
        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"
 | 
						|
}
 | 
						|
 | 
						|
source "$(dirname "$0")/ulib/ulib" &&
 | 
						|
urequire DEFAULTS ||
 | 
						|
exit 1
 | 
						|
 | 
						|
__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=
 | 
						|
login=
 | 
						|
options=()
 | 
						|
domain=
 | 
						|
ssh=
 | 
						|
parse_opts + "${PRETTYOPTS[@]}" \
 | 
						|
    --help '$exit_with display_help' \
 | 
						|
    -q,--quiet quiet=1 \
 | 
						|
    -t,--tty tty=1 \
 | 
						|
    -l:,--login: login= \
 | 
						|
    -o options \
 | 
						|
    -d:,--domain: domain= \
 | 
						|
    -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
 | 
						|
 | 
						|
    args=(${quiet:+-q} ${tty:+-t} ${login:+-l "$login"})
 | 
						|
    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
 | 
						|
        [ -n "$showtitle" ] && etitle "$host"
 | 
						|
        splituserhost "$host" user host
 | 
						|
        [[ "$host" == *.* ]] || host="$host${domain:+.$domain}"
 | 
						|
        "$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
 | 
						|
        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
 |