diff --git a/lib/completion.d/nutools b/lib/completion.d/nutools index 527d07d..5cdc084 100644 --- a/lib/completion.d/nutools +++ b/lib/completion.d/nutools @@ -11,7 +11,7 @@ complete -F __nutools_host_completion -o default uinst ruinst runs rruns if __bash_completion_module_enabled ssh; then shopt -u hostcomplete - complete -F _ssh ussh cssh + complete -F _ssh ussh cssh mssh fi if __bash_completion_module_enabled umount; then diff --git a/lib/default/mssh b/lib/default/mssh new file mode 100644 index 0000000..84ca909 --- /dev/null +++ b/lib/default/mssh @@ -0,0 +1,22 @@ +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 + +# Réseaux +NETWORKS=( + ur # université de la réunion + ksct # ks.jclain.fr +) + +ur_INCLUDES=(10/8) +ur_EXCLUDES=(10.42/16) +ur_DOMAINS=(univ.run univ-reunion.fr) + +ksct_INCLUDES=(192.168.97/24) +ksct_EXCLUDES=() +ksct_DOMAINS=(ct) + +# Règles de la forme FROM:TO:SSH +RULES=( + :ksct:kssh + ur::ssh + :ur:fssh +) diff --git a/lib/profile.d/git-ssh.userconf b/lib/profile.d/git-ssh.userconf new file mode 100644 index 0000000..d887ff2 --- /dev/null +++ b/lib/profile.d/git-ssh.userconf @@ -0,0 +1,4 @@ +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 + +# Spécifier le client SSH à utiliser pour git +export GIT_SSH=mssh diff --git a/mssh b/mssh new file mode 100755 index 0000000..cd301e2 --- /dev/null +++ b/mssh @@ -0,0 +1,107 @@ +#!/bin/bash +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 +source "$(dirname "$0")/lib/ulib/ulib" +urequire DEFAULTS ipcalc + +if [ $# -eq 1 -a "$1" == "--help" ]; then + exit_with uecho "$scriptname: Faire une connexion ssh en utilisant l'exécutable approprié au réseau source et destination + +USAGE + $scriptname [user@]host" +fi + +# fonctions de support +function match_network() { + local ip="$1" network="$2" + local -a includes excludes domains + local spec + array_copy includes "${network}_INCLUDES" + array_copy excludes "${network}_EXCLUDES" + array_copy domains "${network}_DOMAINS" + + if ipcalc_checkip "$ip" >/dev/null; then + for spec in "${excludes[@]}"; do + if ipcalc_match "$ip" "$spec"; then + return 1 + fi + done + for spec in "${includes[@]}"; do + if ipcalc_match "$ip" "$spec"; then + return 0 + fi + done + else + for spec in "${domains[@]}"; do + [[ "$ip" == *."$spec" ]] && return 0 + done + fi + return 1 +} + +# paramètres de l'environnement +DO= +if [ "$1" == --debug ]; then + # Activer le mode DEBUG + shift + set_verbosity -D +elif [ "$1" == --trace ]; then + # Activer le mode DEBUG + shift + set_verbosity -D + TRACE=1 + DO=qvals +fi + +NETWORKS=() +RULES=() +set_defaults mssh + +# déterminer d'où l'on vient +from= +array_from_lines myips "$(ip addr | awk '$1 == "inet" { gsub(/\/.*/, "", $2); print $2 }')" +for network in "${NETWORKS[@]}"; do + for myip in "${myips[@]}"; do + if match_network "$myip" "$network"; then + from="$network" + break + fi + done + [ -n "$from" ] && break +done +edebug "FROM: ${from:-ANY} (${myips[*]})" + +# analyser la ligne de commande +vars="$("$scriptdir/ussh" --parse "$@")" || exit 1 + +[ -n "$TRACE" ] && echo "$vars" +eval "$vars" + +for userhost in "${hosts[@]}"; do + # déterminer où l'on veut aller + splituserhost "$userhost" user host + + to= + for network in "${NETWORKS[@]}"; do + if match_network "$host" "$network"; then + to="$network" + break + fi + done + edebug "TO: ${to:-ANY} ($host)" + + # Sélectionner la commande ssh à utiliser + found= + for rule in "${RULES[@]}"; do + splitfsep "$rule" : rfrom rule2 + splitfsep "$rule2" : rto rssh + if [ \( -z "$rfrom" -o "$from" == "$rfrom" \) -a \ + \( -z "$rto" -o "$to" == "$rto" \) ]; then + found=1 + $DO ${exec:+exec} "$rssh" "${options[@]}" "$userhost" "${args[@]}" + break + fi + done + if [ -z "$found" ]; then + $DO ${exec:+exec} "$ssh" "${options[@]}" "$userhost" "${args[@]}" + fi +done