#!/bin/sh
# vim: set filetype=sh :
#        file: sshd2222
#   copyright: Bernd Schumacher <bernd.schumacher@hpe.com> (2007-2021)
#     license: GNU General Public License, version 3
# description: run non-root sshd on port 2222 for tests, to
#              do run "ssh -p 2222 localhost" without password.
#              Should work on real system and in pbuilder chroot
#              with additional hooks (see A10add_pbuilder_home and
#              A10add_ssh in sources)
#              This script will not modify configs for normal sshd.
#       usage: sshd2222 [-s] status|start|stop|options|should-work
#              -s          be silent
#              status      show status of sshd on port 2222
#              start       start sshd on port 2222
#              stop        stop sshd on port 2222
#              options     list options needed for ssh to use sshd2222
#              should-work exit 0 if sshd2222 should run in environment
#                          exit 1 if sshd2222 will not be able to run
#       files: $HOME/.ssh/id_rsa2222
#              $HOME/.ssh/id_rsa2222.pub
#              $HOME/sshd2222/sshd_config
#              $HOME/sshd2222/ssh_host_rsa_key,
#              $HOME/sshd2222/ssh_host_rsa_key.pub
#                          will be created with "sshd2222 start" and deleted
#                          with "sshd2222 stop"
#              $HOME/.ssh/authorized_keys:
#                          id_rsa2222.pub is added while sshd2222 is running

err()
{
  echo "ERROR: sshd2222: $1" >&2
  exit 1
}

info()
{
  [ "$SILENT" ] || echo "INFO: sshd2222: $1" >&2
}

status()
{
  local chroot pid
  [ "$MYHOME" ] || err "\"sshd2222 should-work\" returns 1"
  [ "$(ls -id /)" = "2 /" ] && chroot="no" || chroot="yes"
  pid="$(pgrep -f "/usr/sbin/sshd -f $MYHOME/sshd2222/sshd_config")"
  echo "sshd2222 chroot=<$chroot> pid=<$pid>"
}

stop()
{
  local pid
  pkill -f "/usr/sbin/sshd -f \S+/sshd2222/sshd_config"
  [ "$MYHOME" ] || err "stop: \"sshd2222 should-work\" returns 1"
  rm -rf $MYHOME/sshd2222
  rm -rf $MYHOME/.ssh/id_rsa2222 $MYHOME/.ssh/id_rsa2222.pub
  ssh-keygen -q -R "[localhost]:2222" >/dev/null 2>&1
  [ ! -f $MYHOME/.ssh/authorized_keys ] || sed -i "/shellia ssh tests/ d" $MYHOME/.ssh/authorized_keys
  pid="$(pgrep -f "/usr/sbin/sshd -f $MYHOME/sshd2222/sshd_config")"
  [ ! "$pid" ] || err "stop: could not kill $pid"
}

start()
{
  stop

  mkdir $MYHOME/sshd2222
  ssh-keygen -q -N "" -t rsa -b 4096 -f $MYHOME/sshd2222/ssh_host_rsa_key
  cat <<END >$MYHOME/sshd2222/sshd_config
Port 2222
HostKey $MYHOME/sshd2222/ssh_host_rsa_key
UsePAM no
END
  /usr/sbin/sshd -f $MYHOME/sshd2222/sshd_config
  mkdir -p $MYHOME/.ssh
  chmod 0700 $MYHOME/.ssh
  ssh-keyscan -p 2222 -t rsa localhost >> $MYHOME/.ssh/known_hosts
  ssh-keygen -q -t rsa -C "shellia ssh tests" -f $MYHOME/.ssh/id_rsa2222 -N ""
  touch $MYHOME/.ssh/authorized_keys
  chmod 0600 $MYHOME/.ssh/authorized_keys
  cat $MYHOME/.ssh/id_rsa2222.pub >> $MYHOME/.ssh/authorized_keys
  pid="$(pgrep -f "/usr/sbin/sshd -f $MYHOME/sshd2222/sshd_config")"
  [ "$pid" ] || err "start: did not work"
}

# set shell variable MYHOME to match /etc/passwd (HOME may be changed by debian/rules)
set_MYHOME()
{
  local PWDHOME
  MYHOME=""
  PWDHOME="$(sed -E -n -e "s|^$(whoami):[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):[^:]*$|\1|p" /etc/passwd)"
  if [ -d "$PWDHOME" ]; then
    MYHOME="$PWDHOME"
  fi
}

options()
{
  [ "$MYHOME" ] || err "options: \"sshd2222 should-work\" returns 1"
  echo "-p 2222 -i $MYHOME/.ssh/id_rsa2222 -o PreferredAuthentications=publickey \
-o NoHostAuthenticationForLocalhost=yes"
}

should_work()
{
  if [ ! -x /usr/bin/ssh ]; then
    info "ssh is not installed"
    return 1
  elif [ ! "$MYHOME" ]; then
    info "User has no home"
    return 1
  fi
}

[ "$(whoami)" != "root" -o -n "$FAKED_MODE" ] || err "do not run as root"

if [ "$1" = "-s" ]; then
  SILENT="$1"
  shift
fi

set_MYHOME

fun="status start stop options should-work"
[ $# -gt 0 ] || err "Usage: $0 [-s] $(echo "$fun" | sed "s/ /|/g")"
cmd="$1"
shift
[ "$(echo " $fun " | grep " $cmd ")" ] || err "bad <$cmd> must be in <$fun>"
cmd="$(echo "$cmd" | sed "s/-/_/g")"
$cmd "$@"
