Commit d1b4bfe5 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Refactor .ssh/ssh into shared libs

parent cb3d87e9
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
test "${SOURCED_CONSTANTS-}" && return
SOURCED_CONSTANTS=yes

KERNEL=`uname -s`
case $KERNEL in
	Linux*) KERNEL=linux ;;
	Darwin*) KERNEL=xnu PLATFORM=darwin ;;
	NT*) KERNEL=nt ;;
esac

PLATFORM=`uname -o 2>/dev/null || uname`
case $PLATFORM in
	GNU*) PLATFORM=gnu ;;
	CYGWIN*) PLATFORM=gnu ;;
	MING*) PLATFORM=windows ;;
	Darwin*) PLATFORM=xnu ;;
esac

export SOURCED_CONSTANTS KERNEL PLATFORM

.shell/lib/shared.sh

0 → 100644
+19 −0
Original line number Diff line number Diff line
SCRIPT_NAME=`basename $0`

BOLD=`tput bold`
UNBOLD=`tput sgr0`

if [ -n "${ZSH_NAME:-}" ]; then
	CURRENT_SHELL=zsh
elif [ -n "${BASH:-}" ]; then
	CURRENT_SHELL=bash
else
	CURRENT_SHELL=sh
fi


die() {
	[ ${CODE:=$?} -gt 1 ] || CODE=2
	echo >&2 "${BOLD}${SCRIPT_NAME}:${UNBOLD} $*"
	exit $CODE
}

.shell/lib/ssh.sh

0 → 100644
+94 −0
Original line number Diff line number Diff line
. ~/.shell/lib/constants.sh
. ~/.shell/lib/shared.sh

: ${SSH_BIN:=`which ssh`}; export SSH_BIN

if [ $PLATFORM = windows ]; then
	if ! has sed; then
		die "This script requires 'sed'"
	fi
	# Hope it's GNU sed?
	PLATFORM=gnu
fi


ssh_version() {
	eval `${SSH_BIN} -V 2>&1 | sed -n \
		's/OpenSSH_\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*/SSH_MAJOR="\1" SSH_MINOR="\2"/p'`
}

config_sed() {
	case $PLATFORM in
		darwin|bsd) SED_WORD_START='[[:<:]]' SED_WORD_END='[[:>:]]' ;;
		gnu) case "$CURRENT_SHELL" in
			bash) SED_WORD_START='\b' SED_WORD_END='\b' ;;
			zsh|sh) SED_WORD_START='\\b' SED_WORD_END='\\b' ;;
		esac ;;
	esac
}

runtime() {
	if [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -d "$XDG_RUNTIME_DIR" ]; then
		RUNTIME="$XDG_RUNTIME_DIR/ssh"
	elif [ -d /tmp ]; then
		RUNTIME=/tmp/user/`id -u`/ssh
	else
		RUNTIME=$HOME/.ssh/.runtime
	fi

	if ! [ -d "$RUNTIME" ]; then
		mkdir -p "$RUNTIME"
		chmod 0750 `dirname $RUNTIME`
	fi >&2
}

make_config() {
	[ -z "${SSH_CONFIG-}" ] || return 0

	ssh_version && runtime && config_sed

	PLATFORM_UNIQ="$PLATFORM:$KERNEL:`hostname -f 2>/dev/null || hostname`:$SSH_MAJOR.$SSH_MINOR"
	PLATFORM_ID=`echo "$PLATFORM_UNIQ" | md5sum | cut -f1 -d' '`
	SSH_CONFIG="$RUNTIME/config-$PLATFORM_ID"

	if [ -f "$SSH_CONFIG" ] &&
		[ "$SSH_CONFIG" -nt ~/.ssh/config ] &&
		[ "$SSH_CONFIG" -nt $0 ] &&
		(! [ -r ~/.ssh/config.local ] || [ "$SSH_CONFIG" -nt ~/.ssh/config.local ])
	then
		return
	fi

	cat ~/.ssh/config ~/.ssh/config.local 2>/dev/null |
		sed >"$SSH_CONFIG" "
			`rule_unix_sockets`
			`rule_canonisation`
			`rule_runtime`
		"
}


# Filter rules

rule_unix_sockets() {
	# Windows has no unix sockets so disable shared connections
	# (Control* settings)
	if [ $KERNEL = nt ]; then
		echo '/^\s*Control.*/d;'
	fi
}

rule_canonisation() {
	# OpenSSH < 6.6 does not have name canonisation
	# (Canonical* settings)
	if [ $SSH_MAJOR -gt 6 ]; then return; fi
	if [ $SSH_MAJOR -lt 6 ] || [ $SSH_MINOR -lt 6 ]; then
		echo '/Canonical/d;'
	fi
}

rule_runtime() {
	# Replace RUNTIME with the value of the RUNTIME variable
	[ -n "$RUNTIME" ] || die "RUNTIME not set"
	echo "s!${SED_WORD_START}RUNTIME${SED_WORD_END}!${RUNTIME-.}!g;"
}
+3 −108
Original line number Diff line number Diff line
#!/bin/sh
set -eu

: ${SSH_BIN:=`which ssh`}; export SSH_BIN


. ~/.shell/lib/ssh.sh
. ~/.shell/funcs


die() {
	[ ${CODE:=$?} -gt 1 ] || CODE=2
	echo >&2 "$*"
	exit $CODE
}

ssh_version() {
	eval `${SSH_BIN} -V 2>&1 | sed -n \
		's/OpenSSH_\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*/SSH_MAJOR="\1" SSH_MINOR="\2"/p'`
}

platform() {
	case `uname` in
		Linux*) PLATFORM=linux ;;
		CYGWIN*) PLATFORM=windows ;;
		MING*) PLATFORM=windows ;;
		Darwin*) PLATFORM=darwin ;;
		*) echo >&2 "Unrecognised platform: `uname`"; exit 2 ;;
	esac

	if [ -n "${ZSH_NAME:-}" ]; then
		SHELL=zsh
	elif [ -n "${BASH:-}" ]; then
		SHELL=bash
	else
		SHELL=sh
	fi
}

config_sed() {
	case $PLATFORM in
		darwin|bsd) SED_WORD_START='[[:<:]]' SED_WORD_END='[[:>:]]'; return ;;
	esac
	case "$SHELL" in
		bash) SED_WORD_START='\b' SED_WORD_END='\b' ;;
		zsh|sh) SED_WORD_START='\\b' SED_WORD_END='\\b' ;;
	esac
}

runtime() {
	if [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -d "$XDG_RUNTIME_DIR" ]; then
		RUNTIME="$XDG_RUNTIME_DIR/ssh"
	elif [ -d /tmp ]; then
		RUNTIME=/tmp/user/`id -u`/ssh
	else
		RUNTIME=$HOME/.ssh/.runtime
	fi

	if ! [ -d "$RUNTIME" ]; then
		mkdir -p "$RUNTIME"
		chmod 0750 `dirname $RUNTIME`
	fi >&2
}

rule_unix_sockets() {
	# Windows has no unix sockets so disable shared connections
	# (Control* settings)
	if [ $PLATFORM = windows ]; then
		echo '/^\s*Control.*/d;'
	fi
}

rule_canonisation() {
	# OpenSSH < 6.6 does not have name canonisation
	# (Canonical* settings)
	if [ $SSH_MAJOR -gt 6 ]; then return; fi
	if [ $SSH_MAJOR -lt 6 ] || [ $SSH_MINOR -lt 6 ]; then
		echo '/Canonical/d;'
	fi
}

rule_runtime() {
	# Replace RUNTIME with the value of the RUNTIME variable
	[ -n "$RUNTIME" ] || die "RUNTIME not set"
	echo "s!${SED_WORD_START}RUNTIME${SED_WORD_END}!${RUNTIME-.}!g;"
}

make_config() {
	[ -z "${CONFIG-}" ] || return 0

	platform && ssh_version && runtime && config_sed

	PLATFORM_UNIQ="$PLATFORM:`hostname -f 2>/dev/null || hostname`:$SSH_MAJOR.$SSH_MINOR"
	PLATFORM_ID=`echo "$PLATFORM_UNIQ" | md5sum | cut -f1 -d' '`
	CONFIG="$RUNTIME/config-$PLATFORM_ID"

	if [ -f "$CONFIG" ] &&
		[ "$CONFIG" -nt ~/.ssh/config ] &&
		[ "$CONFIG" -nt $0 ] &&
		(! [ -r ~/.ssh/config.local ] || [ "$CONFIG" -nt ~/.ssh/config.local ])
	then
		return
	fi

	cat ~/.ssh/config ~/.ssh/config.local 2>/dev/null |
		sed >"$CONFIG" "
			`rule_unix_sockets`
			`rule_canonisation`
			`rule_runtime`
		"
}

# Ensure the GPG agent is running if installed
if has gpg-agent; then
	gpg-connect-agent /bye
@@ -118,11 +13,11 @@ case " $*" in
	*' -F'*) exec ${SSH_BIN} "$@" ;;
	' --make-config'*) 
		make_config
		echo "$CONFIG"
		echo "$SSH_CONFIG"
		;;
	*)
		make_config
		PATH="`dirname $0`:$PATH"; export PATH
		exec ${SSH_BIN} -F "$CONFIG" "$@"
		exec ${SSH_BIN} -F "$SSH_CONFIG" "$@"
		;;
esac