zshlibs/zssh.funcs.zsh

228 lines
6.5 KiB
Bash
Raw Normal View History

2021-11-10 14:41:19 +00:00
function zssh_boot()
{
typeset -g zssh_ssh_dotdir="${HOME}/.ssh"
typeset -g zssh_private_keys="${zssh_ssh_dotdir}/keystore"
typeset -g zssh_private_configs="${zssh_ssh_dotdir}/config.d"
typeset -g zssh_global_configs=${globaldots_path}/config/ssh
typeset -g zssh_global_pubkeys=${globaldots_path}/keys/ssh
zssh_configure
zssh_process
}
function zssh_configure ()
{
if [[ -n "$zssh_host" ]]
then
zbootstrap_message zssh "zssh_host is set"
ztools_ensure -d $zssh_private_keys
ztools_ensure -d $zssh_private_configs
ztools_ensure -d ${zssh_global_configs}
ztools_ensure -d ${zssh_global_pubkeys}
zssh_enumeratenodes
if [[ ${#zssh_host_config_accesses} -gt 0 ]]
then
zbootstrap_message zssh "zssh_host_config_accesses is set"
typeset -g zssh_global_config_hostdir="${zssh_global_configs}/${zssh_host}"
typeset -g zssh_global_pubkey_hostdir="${zssh_global_pubkeys}/${zssh_host}"
ztools_ensure -d "${zssh_global_pubkey_hostdir}"
ztools_ensure -d "${zssh_global_config_hostdir}"
else
zbootstrap_message zssh "zssh_host_config_accesses is NOT set, not going to bother accepting keys"
fi
else
zbootstrap_message zssh "zssh_host is NOT set, which means we cannot neither publish keys nor accept them"
fi
}
function zssh_process()
{
if [[ -n "$zssh_host" ]]
then
if [[ ${#zssh_host_config_accesses} -gt 0 ]]
then
zbootstrap_message zssh "processing ssh server setup"
if [[ "${HOME}/.config/zsh/local.config.zsh" -nt "${zssh_global_config_hostdir}" ]]
then
zbootstrap_message zssh "publishing our configs …"
zssh_publish_configs
else
zbootstrap_message zssh "not publishing our configs …"
fi
fi
zbootstrap_message zssh "processing ssh client setup"
zssh_install_peers
zssh_publish_pubkeys
fi
}
function zssh_install_peers()
{
[[ -n $zssh_host ]] || return 63
zbootstrap_message zssh "installing peers"
for ssh_node in $zssh_nodes
do
zbootstrap_message zssh "installing peer $ssh_node"
zssh_generate_privkey4 $ssh_node
zssh_generate_config4 $ssh_node
done
}
function zssh_publish_pubkeys()
{
for ssh_node in $zssh_nodes
do
zssh_mail_pubkey2 $ssh_node
done
}
function zssh_mail_pubkey2()
{
[[ -n $zssh_host ]] || return 63
ssh_node="$1"
local targetspool="$zssh_global_pubkeys/$ssh_node"
local srcpk="$zssh_private_keys/$ssh_node.key.pub"
ztools_ensure -d "${targetspool}"
cp -t "$targetspool" "$srcpk"
}
function zssh_publish_configs()
{
[[ -n "$zssh_host_config_accesses" ]] || return 62
for sshmatch in ${(k)zssh_host_config_accesses}
do
hostaccessconfig_file="${zssh_global_config_hostdir}/${sshmatch}.sshconf"
zbootstrap_message zssh "generating our server access config '${hostaccessconfig_file}'"
zssh_generate_hostaccessconfig $sshmatch > "$hostaccessconfig_file"
done
zbootstrap_message zssh "updating mtime for ${zssh_global_config_hostdir}"
touch "${zssh_global_config_hostdir}"
}
function zssh_generate_hostaccessconfig()
{
sshmatch="${1}"
sshcontents=${zssh_host_config_accesses[$sshmatch]}
sshmatch_user=${sshmatch%%@*}
sshmatch_host=${sshmatch##*@}
if [[ "$sshmatch_host" == "$sshmatch_user" ]]
then
sshmatch_user=''
fi
<< HERE
Match ${sshmatch_host:+host $sshmatch_host,} ${sshmatch_user:+user $sshmatch_user,}
${sshcontents}
${zssh_host_config}
HERE
}
function zssh_generate_config4
{
ssh_node="$1"
dst="$zssh_private_configs/$ssh_node.sshconf"
srcs="$zssh_global_configs/$ssh_node"
zbootstrap_message zssh "checking configs for $ssh_node"
if [[ -d "$srcs" ]] && ! [[ $dst -nt $srcs ]]
then
sshkey="$zssh_private_keys/$ssh_node.key"
zbootstrap_message zssh "found fresh configs directory for $ssh_node"
zbootstrap_message zssh "config destination is '$dst'"
zbootstrap_message zssh "tied ssh key is '$sshkey'"
rm "$dst" 2> /dev/null
for src in "$srcs"/*.sshconf(N)
do
zbootstrap_message zssh "sourcing $src"
cat "$src" >> "$dst"
printf "\n IdentityFile %s\n\n" "$sshkey" >> "$dst"
done
fi
zbootstrap_message zssh "done with $ssh_node"
}
function zssh_generate_privkey4
{
ssh_node="$1"
zbootstrap_message zssh "checking keys for peer $ssh_node"
local newkey=$zssh_private_keys/$ssh_node.key
if ! [[ -s $newkey ]]
then
zbootstrap_message zssh "generate key for $ssh_node"
ssh-keygen -t ed25519 -N '' -C "$ssh_host($USER@$HOST) for $ssh_node" -f $newkey >> "${HOME}/.log/ssh-keygen.log"
if [[ "$ssh_node" == "$zssh_host" ]]
then
zbootstrap_message zssh "Self accepting key: $ssh_node"
cat "$newkey.pub" >> ${HOME}/.ssh/authorized_keys
fi
fi
}
function zssh_offer_all()
{
# offers keys for every node
if ! [[ -d $zssh_private_keys ]]
then
zbootstrap_message zssh "$zssh_private_keys not found"
return
fi
if [[ -n $zssh_thishost ]]
then
for ssh_node in $zssh_nodes
do
local node_directory=$zssh_global_configs/$ssh_node
local keytooffer=$node_directory/keyoffers/$zssh_thishost.pub
local keysource=$zssh_private_keys/$ssh_node.key
if ! [[ -s $keysource ]]
then
zbootstrap_message zssh "$ssh_node misses $keysource private key in keystore"
continue
fi
if ! [[ -d $node_directory ]]
then
zbootstrap_message zssh "$ssh_node misses its config directory '$node_directory'"
continue
fi
if ! [[ -d $node_directory/keyoffers ]]
then
zbootstrap_message zssh "creating keyoffer directory for $ssh_node"
mkdir $node_directory/keyoffers
fi
# offering ...
if ! [[ -s $keytooffer ]]
then
zbootstrap_message zssh "Offering public key for $ssh_node"
ssh-keygen -y -f $keysource -C "$zssh_thishost offered to ${ssh_node}" > $keytooffer
fi
done
else
zbootstrap_message zssh "no zssh_thishost defined, offering skipped"
fi
}
function zssh_accept_key()
{
local offered=$zssh_global_configs/$zssh_thishost/keyoffer/$1.pub
cat $offered
echo "do you accept key '$1'? :"
read
if [[ $REPLY == 'Y' ]]
then
echo "key $1 accepted"
cat $offered >> ${HOME}/.ssh/authorized_keys
else
echo "key $1 NOT accepted"
fi
}
function zssh_enumeratenodes()
{
typeset -g -a zssh_nodes;
zbootstrap_message zssh "enumerating nodes"
if [[ -d $zssh_global_configs ]]
then
for __ssh_node in ${zssh_global_configs}/*(/)
do
zssh_nodes+=($(basename $__ssh_node))
done
fi
zbootstrap_message zssh "got ${#zssh_nodes} nodes"
}