#!/bin/bash [ "$UID" = 0 ] || exec sudo -- "$0" "$@" || exit help() { prefixU="Usage: $0 " prefix0=" $0 " prefix1=${prefix0//?/ } cat <...cryptonomic.net Synopsis: $prefix0 --remote-ip \\ $prefix1 --remote-name Usage: $prefix0 --remote-ip \\ $prefix1 --remote-name \\ $prefix1 [--remote-key-type rsa] \\ $prefix1 [--local-key ] Options: --remote-ip --remote-name Remote IP and NAME are MANDATORY. --remote-key Remote key, if specified, must be 'rsa'. --local-key The specified key must be an RSA key. The filename is considered relative to /etc/ssh if it has no slashes. The default is 'ssh_host_rsa_key'. EOF } die() { printf 'Error: %s\n' "$*"; exit 1; } REMOTE_IP=68.48.18.140 REMOTE_NAME=andy REMOTE_KEY_TYPE=rsa LOCAL_KEY=ssh_host_rsa_key LOCAL_KEY_DEST_BASENAME=ssh_host_rsa_key LOCAL_PRIVATE_KEY_DEST=/etc/swanctl/private/$LOCAL_KEY_DEST_BASENAME LOCAL_PUBLIC_KEY_DEST=/etc/swanctl/pubkey/$LOCAL_KEY_DEST_BASENAME.pub OPTS=$(getopt \ --options 'h' \ --longoptions 'help,remote-ip:,remote-name:,remote-key-type:,local-key:' \ -n connect-vpn \ -- "$@") eval set -- "$OPTS" unset OPTS while true do case "$1" in -h|--help) help; exit;; --remote-ip) REMOTE_IP=$2; shift 2;; --remote-name) REMOTE_NAME=$2; shift 2;; --remote-key-type) REMOTE_KEY_TYPE=$2; shift 2;; --local-key) LOCAL_KEY=$2; shift 2;; --) shift; break;; esac shift done if [ $# != 0 ] then help exit 1 fi [ "$REMOTE_IP" ] || die 'remote ip' # todo parse IP [ "$REMOTE_NAME" ] || die 'remote name' # todo parse valid hostname [ "$REMOTE_KEY_TYPE" = rsa ] case "$LOCAL_KEY" in */*) ;; *) LOCAL_KEY=/etc/ssh/$LOCAL_KEY ;; esac [ -f "$LOCAL_KEY" -a -r "$LOCAL_KEY" ] || die "local key ($LOCAL_KEY)" match_and_drop_first_word() { expect=$1 while read word rest do if [ "$word" = "$expect" ] then printf '%s\n' "$rest" return fi done false } keyscan() { if [ -e keyscan.cache ] then cat keyscan.cache else semi_quietly ssh-keyscan -t "${REMOTE_KEY_TYPE}" "$1" fi } write_successfully() { local f=$(mktemp) || return local out="$1" [ "$2" = -- ] || return shift 2 if "$@" > "$f" then if [ "$NO_ACT" ] then ( exec >&2 echo "Write $out:" case "$(file --mime-encoding "$f")" in *': binary') xxd "$f" ;; *) cat "$f" ;; esac | sed 's/^/ /' echo ) rm -f "$f" else mv "$f" "$out" fi else rm -f "$f" return 1 fi } semi_quietly() { local t=$(mktemp) if "$@" 2>"$t" then rm -f "$t" else cat "$t" >&2 fi } openssl() { semi_quietly command openssl "$@" } write_public_key() { openssl rsa -in "$1" -outform DER } write_private_key() { openssl rsa -in "$1" -outform DER -pubout } write_remote_key() { case "$REMOTE_KEY_TYPE" in rsa) ssh-keygen -e -f "$1" -m PEM | openssl rsa -RSAPublicKey_in -outform DER ;; *) echo "Unsupported key type." >&2; exit 1 ;; esac } keycopy() { private_key_tmp=$(mktemp) || return cp "$LOCAL_KEY" "$private_key_tmp" ssh-keygen -N '' -p -m PEM -f "$private_key_tmp" >/dev/null 2>&1 trap 'rm -f "$private_key_tmp"' EXIT write_successfully "$LOCAL_PRIVATE_KEY_DEST" -- write_private_key "$private_key_tmp" write_successfully "$LOCAL_PUBLIC_KEY_DEST" -- write_public_key "$private_key_tmp" trap - EXIT rm -f "$private_key_tmp" trap 'rm -f "$t"' EXIT t=$(mktemp) keyscan "$REMOTE_IP" | match_and_drop_first_word "$REMOTE_IP" > "$t" write_successfully /etc/swanctl/pubkey/"$REMOTE_NAME".pub -- write_remote_key "$t" trap - EXIT rm -f "$t" } nocomments() { sed 's/#.*//; /^ *$/d' } config() { local conn="$1" remote_addrs="$2" id="$3" local public_key_file="$4" private_key_file="$5" local remote_ts=0::0/0 vips=:: sed -e 's/^ //' <&1 set -e keycopy test_new_config