#!/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/\</.pgp.asc 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