# -*-shell-script-*-
# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)

# Monkeysphere authentication diagnostics subcommand
#
# The monkeysphere scripts are written by:
# Jameson Rollins <jrollins@finestructure.net>
# Jamie McClelland <jm@mayfirst.org>
# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
#
# They are Copyright 2008-2009, and are all released under the GPL,
# version 3 or later.

# check on the status and validity of the key and public certificates

diagnostics() {

local seckey
local keysfound
local curdate
local warnwindow
local warndate
local create
local expire
local uid
local fingerprint
local badhostkeys
local sshd_config
local problemsfound=0

report_cruft

if ! id monkeysphere >/dev/null ; then
    echo "! No monkeysphere user found!  Please create a monkeysphere system user with bash as its shell."
    problemsfound=$(($problemsfound+1))
fi

if ! [ -d "$SYSDATADIR" ] ; then
    echo "! no $SYSDATADIR directory found.  Please create it."
    problemsfound=$(($problemsfound+1))
fi

echo "Checking for authentication directory..."
if ! [ -d "$MADATADIR" ] ; then
    echo "! No authentication data directory found."
    echo " - Recommendation: run 'monkeysphere-authentication setup'"
    exit
fi    

# FIXME: what's the correct, cross-platform way to determine where
# sshd_config lives?
sshd_config=/etc/ssh/sshd_config

seckey=$(gpg_core --list-secret-keys --fingerprint --with-colons --fixed-list-mode)
keysfound=$(echo "$seckey" | grep -c ^sec:)
curdate=$(date +%s)
# warn when anything is 2 months away from expiration
warnwindow='2 months'
warndate=$(advance_date $warnwindow +%s)

echo "Checking core GPG key..."
if (( "$keysfound" < 1 )); then
    echo "! No core key found."
    echo " - Recommendation: run 'monkeysphere-authentication setup'"
    problemsfound=$(($problemsfound+1))
elif (( "$keysfound" > 1 )); then
    echo "! More than one core key found?"
    # FIXME: recommend a way to resolve this
    problemsfound=$(($problemsfound+1))
else
    create=$(echo "$seckey" | grep ^sec: | cut -f6 -d:)
    expire=$(echo "$seckey" | grep ^sec: | cut -f7 -d:)
    fingerprint=$(echo "$seckey" | grep ^fpr: | head -n1 | cut -f10 -d:)
    # check for key expiration:
    if [ "$expire" ]; then
	if (( "$expire"  < "$curdate" )); then
	    echo "! Core key is expired."
	    echo " - Recommendation: ???"
	    problemsfound=$(($problemsfound+1))
	elif (( "$expire" < "$warndate" )); then
	    echo "! Core key expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
	    echo " - Recommendation: ???"
	    problemsfound=$(($problemsfound+1))
	fi
    fi

    # and weirdnesses:
    if [ "$create" ] && (( "$create" > "$curdate" )); then
	echo "! Core key was created in the future(?!). Is your clock correct?"
	echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
	problemsfound=$(($problemsfound+1))
    fi
	    
fi

# FIXME: look at the ownership/privileges of the various keyrings,
#    directories housing them, etc (what should those values be?  can
#    we make them as minimal as possible?)

# FIXME: look to see that the ownertrust rules are set properly on the
#    sphere keyring

# make sure that at least one identity certifier exists
echo
echo "Checking for Identity Certifiers..."
if ! ( monkeysphere-authentication list-identity-certifiers | egrep '^[A-F0-9]{40}:' >/dev/null ) ; then
    echo "! No Identity Certifiers found!"
    echo " - Recommendation: once you know who should be able to certify the identities of 
     connecting users, you should add their key, with: 
      monkeysphere-authentication add-identity-certifier"
    problemsfound=$(($problemsfound+1))
fi

# FIXME: look at the timestamps on the monkeysphere-generated
# authorized_keys files -- warn if they seem out-of-date.

# FIXME: check for a cronjob that updates monkeysphere-generated
# authorized_keys?

echo
echo "Checking for Monkeysphere-enabled public-key authentication for users ..."
# Ensure that User ID authentication is enabled:
if ! grep -q "^AuthorizedKeysFile[[:space:]]\+${SYSDATADIR}/authorized_keys/%u$" "$sshd_config"; then
    echo "! $sshd_config does not point to monkeysphere authorized keys."
    echo " - Recommendation: add a line to $sshd_config: 'AuthorizedKeysFile ${SYSDATADIR}/authorized_keys/%u'"
    problemsfound=$(($problemsfound+1))
fi
if badauthorizedkeys=$(grep -i '^AuthorizedKeysFile' "$sshd_config" | grep -v "^AuthorizedKeysFile[[:space:]]\+${SYSDATADIR}/authorized_keys/%u$") ; then
    echo "! $sshd_config refers to non-monkeysphere authorized_keys files:"
    echo "$badauthorizedkeys"
    echo " - Recommendation: remove the above AuthorizedKeysFile lines from $sshd_config"
    problemsfound=$(($problemsfound+1))
fi

if [ "$problemsfound" -gt 0 ]; then
    echo "When the above $problemsfound issue"$(if [ "$problemsfound" -eq 1 ] ; then echo " is" ; else echo "s are" ; fi)" resolved, please re-run:"
    echo "  monkeysphere-authentication diagnostics"
else
    echo "Everything seems to be in order!"
fi

}