#!/usr/bin/env bash

# Usage:       ./chkh [hostname | -h | --help | -?] [known_hosts]
#                or
#              bash [hostname | -h | --help | -?] [known_hosts]
# Examples:    ~$ ./chkh                          (localhost in own known_hosts)
#              ~$ bash chkh                       (localhost in own known_hosts)
#              ~# ./chkh www.ncfi.no    (www.ncfi.no in own [roots] known_hosts)
#              ~# bash chkh www.ncfi.no (www.ncfi.no in own [roots] known_hosts)
#              ~$ sudo ./chkh www.ncfi.no /home/user/.ssh/known_hosts
#              ~$ sudo bash chkh www.ncfi.no /home/user/.ssh/known_hosts
# Description: Search for hashed known_hosts like "ssh-keygen -F hostname"
# Author:      Patrick Neumann (patrick@neumannsland.de)
# Version:     1.0
# Date:        09.01.2020
# License:     GPL3
# Warranty:    This program is distributed WITHOUT ANY WARRANTY

# config:
readonly DEFAULT_H="localhost"
readonly DEFAULT_K="${HOME}/.ssh/known_hosts"

# display help:
if [ "${1}" = "-h" -o "${1}" = "--help" -o "${1}" = "-?" ] ; then
  echo "Usage: ${0} [hostname | -h | --help | -?] [known_hosts]"
  echo "  Default hostname:   ${DEFAULT_H}"
  echo "  Default known_host: ${DEFAULT_K}"
  exit 0
fi

# set and check hostname:
if [ -n "${1}" ] ; then
  readonly HOSTNAME="${1}"
else
  readonly HOSTNAME="${DEFAULT_H}"
fi
if ! echo "${HOSTNAME}" | grep -E "^[[:alnum:]]+.*" 2>&1 > /dev/null ; then
  echo "Please specify a valid hostname!"
  exit 1
fi

# set and check known_hosts:
if [ -n "${2}" ] ; then
  readonly KNOWN_HOSTS="${2}"
else
  readonly KNOWN_HOSTS="${DEFAULT_K}"
fi
[ -f "${KNOWN_HOSTS}" ] || { echo "file not found!" ;exit 2; }

# walk through known_hosts...
while IFS= read -r line
do
  # the "second" field (the file is starting with the separator!)
  #   is the salt in base64:
  SALT="$( echo "${line}" \
           | cut -d "|" -f 3 \
           | base64 --decode \
           | xxd -p )"  
  # the "third" field is the "hmaced" hash:
  SHA1="$( echo -n "${HOSTNAME}" \
           | openssl dgst -sha1 -mac HMAC -macopt hexkey:"${SALT}" \
           | cut -d " " -f 2 \
           | xxd -r -p \
           | base64 )"
  # grep to get the hole line:
  grep -F "${SHA1}" "${KNOWN_HOSTS}"
done < "${KNOWN_HOSTS}"

exit 0