vern-web/en/recovery-challenge.cgi

147 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env -S bash
saveIFS=$IFS
IFS='=&'
parm=($POST_STRING)
IFS=$saveIFS
for ((i=0; i<${#parm[@]}; i+=2))
do
declare arg_${parm[i]}=${parm[i+1]}
done
runtime_dir=/var/log/challenges
gpg_home="$runtime_dir"/.gnupg
urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
sig="$(urldecode "$arg_signature" | sed 's/\r//g')"
key="$(urldecode "$arg_newkey")"
if [[ $arg_username ]]; then
keyid="$(gpg --import-options show-only --import "/vm/$arg_username/.pgp.asc" 2>&1 | grep '^ ' | xargs)"
fi
generate_challenge() {
if [[ -z "$arg_username" ]]; then
nouser=1
page=default
return
fi
if ! gpg --import-options show-only --import "/vm/$arg_username/.pgp.asc" &> /dev/null; then
nokey=1
page=default
return
fi
openssl rand -hex 32 > "$runtime_dir/$arg_username"
page=submit
return
}
submit_challenge() {
if [[ -z "$arg_username" ]]; then
nouser=1
page=submit
return
fi
if [[ -z "$key" ]]; then
nossh=1
page=submit
return
fi
if ! ssh-keygen -l -f /dev/stdin <<< "$key" &> /dev/null; then
badssh=1
page=submit
return
fi
if ! gpg --import-options show-only --import "/vm/$arg_username/.pgp.asc" &> /dev/null; then
nokey=1
page=submit
return
fi
if [[ -z "$sig" ]]; then
nosig=1
page=submit
return
fi
echo "$sig" > "$runtime_dir/$arg_username.gpg"
gpg --homedir "$gpg_home" --import "/vm/$arg_username/.pgp.asc" &> /dev/null
if gpg --homedir "$gpg_home" \
--trust-model always \
--verify "$runtime_dir/$arg_username.gpg" \
"$runtime_dir/$arg_username" &> /dev/null; then
if [[ "$(gpg --homedir $gpg_home \
--trust-model always \
--verify "$runtime_dir/$arg_username.gpg" \
"$runtime_dir/$arg_username" 2>&1 |
sed -n 's/.*using.*key \(.*\)/\1/p')" == \
"$keyid" ]]; then
echo "$key" >> "/vm/$arg_username/.ssh/authorized_keys"
rm "$runtime_dir/$arg_username"{,.pgp}
page=success
return
else
badsig=1
page=submit
return
fi
else
badsig=1
page=submit
return
fi
exit
}
page=default
nouser=0
nokey=0
nossh=0
badssh=0
nosig=0
badsig=0
case "$arg_method" in
generate)
generate_challenge
;;
submit)
submit_challenge
;;
esac
sedcmd=" -e 's/USERNAME/$arg_username/' -e 's/CHALLENGE/$(<$runtime_dir/$arg_username)/' -e 's/KEYID/$keyid/' -e 's\\NAV\\$(php $(dirname $0)/nav.php | sed 's/\&/\\\&/g')\\' -e 's\\FOOTER\\$($(dirname $0)/footer.cgi | sed '1,2d' | sed 's/\&lt;/</g')\\'"
sedcmd="$sedcmd $(if [[ $nokey == 1 ]]; then
printf '%s' '-e "s/NOKEY/This user has no <code>.pgp.asc</code> file/"'
else
printf '%s' '-e "s/NOKEY//"'
fi)"
sedcmd="$sedcmd $(if [[ $nouser == 1 ]]; then
printf '%s' '-e "s/NOUSER/No such user/"'
else
printf '%s' '-e "s/NOUSER//"'
fi)"
sedcmd="$sedcmd $(if [[ $nossh == 1 ]]; then
printf '%s' '-e "s/NOSSH/No SSH key(s) supplied/"'
else
printf '%s' '-e "s/NOSSH//"'
fi)"
sedcmd="$sedcmd $(if [[ $badssh == 1 ]]; then
printf '%s' '-e "s/BADSSH/Invalid SSH keyfile/"'
else
printf '%s' '-e "s/BADSSH//"'
fi)"
sedcmd="$sedcmd $(if [[ $nosig == 1 ]]; then
printf '%s' '-e "s/NOSIG/No signature supplied/"'
else
printf '%s' '-e "s/NOSIG//"'
fi)"
sedcmd="$sedcmd $(if [[ $badsig == 1 ]]; then
printf '%s' '-e "s/BADSIG/Bad signature/"'
else
printf '%s' '-e "s/BADSIG//"'
fi)"
sedcmd="${sedcmd:+sed$sedcmd}"
echo "Status: 200"
echo
eval ${sedcmd:-cat} $(dirname $0)/recovery-scripts/pgp/"$page".html