#!/bin/sh

# Copyright 2022  Dave Love, University of Manchester
# Licence: BSD-2-Clause <https://spdx.org/licenses/BSD-2-Clause>

# Use the modified sshpass and the pass otp extension to avoid typing
# 2-factor password and OTP, if that's required.

# Modify as appropriate
HOST=example.com                # default log in to here -- changeme!
LOGIN=$USER                     # default user
# These are for pam_sss.  For pam_duo it might be "Password:" and
# "Passcode or option"
PROMPT1="First Factor:"         # password prompt
PROMPT2="Second Factor:"        # prompt for an OTP

usage() {
cat <<EOF
Usage: $(basename $0) [argument]...
Run an SSH command under sshpass(1) with password and OTP value from pass(1).

Any arguments are used as the entire command (which should be an
invocation of either ssh, scp, or sftp.)  Otherwise a command is
constructed of the form:
  ssh -o ... $LOGIN@$HOST -- [argument]...
where -o ... specifies keyboard-interactive,password authentication.

The matched prompts for credentials are "$PROMPT1" and "$PROMPT2".
The pass "otp" extension is required, configured for the target under
the pass entry "$HOST/$LOGIN".  The modified sshpass from
https://github.com/dora38/sshpass is also required.

Modify this script if any of those are inappropriate.
EOF
}

case $1 in
    -h|--help) usage; exit ;;
esac

if ! sshpass --help 2>/dev/null | grep -q OTP; then
    printf '"sshpass" supporting OTP not found: see
https://github.com/dora38/sshpass\n' >&2
    exit 1
fi

# pass-extension-otp is packaged for Debian, at least
if ! pass otp --help >/dev/null 2>&1; then
    printf '"pass" with the "otp" extension not found; see
https://github.com/tadfisher/pass-otp\n' >&2
    exit 1
fi

# No command -- make one
if [ -z "$1" ]; then
    set ssh -o "PreferredAuthentications keyboard-interactive,password" "$LOGIN@$HOST"
fi

# Allow a complete command supplied as args, but insert the option to
# avoid trying to use other authN.  Otherwise use default login.
case $1 in
    ssh|scp|sftp)
        # We could just append -o ... for ssh, but not for scp or sftp
        cmd=$1; shift
        set "$cmd" -o "PreferredAuthentications keyboard-interactive,password" "$@" ;;
    *)
        set ssh -o "PreferredAuthentications keyboard-interactive,password" "$LOGIN@$HOST" -- "$@" ;;
esac

sshpass -P "$PROMPT1" -O "$PROMPT2" -d 4 -c "pass otp $HOST/$LOGIN" "$@" 4<<EOF
$(pass $HOST/$LOGIN|head -1)
EOF
