#!/usr/bin/bash

##############################################################################
# This file is part of the CRYPTO BONE
# File     : safewebdropregistration (server) 
# Version  : 2.0 (ALL-IN-ONE)
# License  : BSD-3-Clause
# Date     : 19 Apr 2025
# Contact  : Please send enquiries and bug-reports to innovation@senderek.ie
#
# Copyright (c) 2015-2025
#	Ralf Senderek, Ireland.  All rights reserved. (https://senderek.ie)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#	   This product includes software developed by Ralf Senderek.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND  ANY EXPRESS OR 
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  IMPLIED WARRANTIES 
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
# POSSIBILITY OF SUCH DAMAGE.
##############################################################################

ADMINNAME=root
PUBKEY=""
ID=""
REQ=""
KEY=""

#----------------------------------------------------#
# load functions and global variables
. ./safewebdrop-functions
#----------------------------------------------------#

DEST="/home/safewebdrop/admin"
LOG=${DEST}/log

if [[ ! -d ${DEST} ]] ; then
     /usr/bin/echo "CONFIGURATION ERROR: the admin directory ${DEST} does not exist." | mail ${ADMINNAME}
     exit 3
fi

log "---- registration request  ----"

/usr/bin/echo Content-type: text/html
/usr/bin/echo

# extract ID and REQ (and KEY in phase 2) from QUERY_STRING
OLDIFS="${IFS}"
IFS=\&
set -- $QUERY_STRING 
ID=$1
REQ=$2
HASHSIG=$3
KEY=$4
IFS=${OLDIFS}

# get the IP
IP=$REMOTE_ADDR

if [[ ! ${ID} ]]; then
    # no user ID available
    log "No user ID in registration. Exiting ..."
    exit 2 
fi
if [[ ${ID} = admin* ]] ;then 
    exit 2
fi

FILE=${DEST}/${ID}.registration
log "using registration file $FILE"

# request = REGISTRATION or it consists of signed data
if [[ ${REQ} = "REGISTRATION" ]]; then
     # phase 1
     generate_challenge     

     /usr/bin/touch ${FILE} >/dev/null 2>/dev/null
     if [[ -r ${FILE} ]] ; then 
          /usr/bin/echo "ID=${ID}" > $FILE
	  /usr/bin/echo "ADDR=${IP}" >> $FILE   
          /usr/bin/echo "NONCE=${NONCE}" >> $FILE   
          /usr/bin/echo "CHALLENGE=${CHALLENGE}" >> $FILE   
	  log "providing a challenge for ${ID}"
	  /usr/bin/echo -n "${CHALLENGE}"
	  exit 0
     fi
fi

if [[ ${REQ} != "REGISTRATION" ]] ; then

     # phase 2
     log "phase 2 signed request ${#REQ} bytes received" 
     # load the stored credentials
     if [[ -r ${FILE} ]] ; then
          .  ${FILE}
     fi

     # check if the new request has the same ADDR
     if [[ ${IP} != ${ADDR}  ]] ; then
         # dismiss this request
	 clean
         log "different IP in phase 2 for user ${ID}"
         exit 4
     fi

     PUBKEY=${DEST}/${ID}.pubkey.pem
     # store the pubkey first
     /usr/bin/echo -n "${KEY}" | /usr/bin/base64 -d > ${PUBKEY}
     
     /usr/bin/ln -s ../tmp ${DEST}/${ID}
     verify_request
     rm -f ${DEST}/${ID}
     log "verification of signed request succeeded"

     # split the request
     OLDIFS="${IFS}"
     IFS=\:
     set -- ${REQ} 
     WID=$1
     WCHL=$2
     IFS=${OLDIFS}

     if [[ ${WID} != ${ID} ]] || [[  ${WCHL} != ${CHALLENGE} ]]  ; then
          # request failed
	  log "registration failed for user ${ID}"
	  /usr/bin/echo "none"
          cleansig
	  exit 3
     fi

     # create a registration code and store it
     REGCODE=$(/usr/bin/dd if=/dev/urandom bs=1 count=20 2>/dev/null | /usr/bin/base64 | /usr/bin/cut -c-20 )
     /usr/bin/echo "REGCODE=${REGCODE}" >> $FILE 
     log "registration succeeded for user ${ID}"
     log "--- registration end ---"
     /usr/bin/echo -n ${REGCODE}
fi     

cleansig
exit 0
