#!/usr/bin/bash

if [[ $(/usr/bin/id -u) != 0 ]]; then /usr/bin/echo "only root can do that"; exit 2; fi

#***************************************************************************
# This file is part of the CRYPTO BONE
# File     : processmessage-safewebdrop
# Version  : 2.0 (EXTERNAL DEVICE)
# License  : BSD-3-Clause
# Date     : 26 Mar 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.
#
#****************************************************************************


. /usr/lib/cryptobone/safewebdrop.header

#----------------------------------------------------#
function log {
     if [[ $1 ]]; then
          echo "$(/usr/bin/date +'%x %X'): $1  " >> ${RAM}/log
          /usr/bin/chmod 600 ${RAM}/log > /dev/null 2>&1
     fi
}

function new_name
{
     # $1 : directory
     # $2 : extension that is appended, if $2 exists
     # $3 : PREFIX without number extension
     NAME=""
     LAST=""
     typeset -i NUM=1
     if [[ $1 ]]
     then
          if [[ $2 ]]
	  then
               LAST=$(/usr/bin/ls $1/$3*.$2 2>/dev/null | /usr/bin/sort | /usr/bin/tail -1)
	       LAST=${LAST%.$2}
	  else
               LAST=$(/usr/bin/ls $1/$3* 2> /dev/null | /usr/bin/sort | /usr/bin/tail -1)
	  fi
          LAST=${LAST##*.}
          LAST=${LAST#0}
          LAST=${LAST#0}
          LAST=${LAST#0}
	  NUM=${LAST}
	  NUM=${NUM}+1
	  PRE="message"
	  if [[ $3 ]]; then
               PRE=$3
	  fi
          if (( ${NUM} < 10 ))
          then
               NAME="${PRE}.000"${NUM}
          else
               if (( ${NUM} < 100 ))
               then
                    NAME="${PRE}.00"${NUM}
               else
                    if (( ${NUM} < 1000 ))
                    then
                         NAME="${PRE}.0"${NUM}
                    else
                         NAME="${PRE}."${NUM}
                    fi
               fi
          fi
     fi
     if (( ${NUM} == 0 )) 
     then
          NAME="${PRE}.0001" 
     fi
     if [[ $2 ]]
     then
          NAME=${NAME}.$2
     fi
     /usr/bin/echo ${NAME}
}

function decryptwebdrop {
     if [[ $1 != "none" ]] && [[ -r $1 ]] ; then
          log "trying to decrypt $1 with $3"
          /usr/bin/echo "$2" | /usr/lib/cryptobone/bin/claes -decrypt $1 
          if (( $? == 0 )) ; then
               log "success: webdrop $1 decrypted"
          else
               log "error: cannot decrypt webdrop $1"
          fi
     fi
}

function decryptfile {
     if [[ $1 != "none" ]] && [[ -r $1 ]] ; then
          log "trying to decrypt $1 with $3"
          /usr/bin/echo "$2" | /usr/lib/cryptobone/bin/claes -decrypt $1 
          if (( $? == 0 )) ; then
               /usr/bin/rm -f $1
               log "success: file $1 decrypted"
          else
               log "error: cannot decrypt $1"
          fi
     fi
}

# check if $1 seems to have an attachment
LASTLINE=$(/usr/bin/tail -1 $1)
log "$1 has $LASTLINE"
FILENAME="none"
if [[ ${LASTLINE} != "-----END PGP MESSAGE-----" ]] ; then
     FILENAME=${RAM}/FILES/${LASTLINE##*: }.asc
     if [[ -r ${FILENAME} ]] ; then
          log "$1 has an attachment ${FILENAME}"
     fi
fi

if [[ $1 ]]
then
     Success="false"
     Cleartextfile=${1%.asc}
     log "processing $1" 
     Fromline=$(/usr/bin/grep "From: "  $1)
     FROM=${Fromline##From: }

     # fetch the current message key
     RES=$(/usr/bin/echo get-element key.${FROM}.key | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
     if [[ ${RES} ]]
     then
          # there is a key for $FROM
          if (( ${#RES} >= 20 )); then
               # now try to decrypt attachment file with key
	       CLAES=$(decryptfile ${FILENAME} ${RES} "key")
               # now try to decrypt message file with key
	       CLAES=$(decryptwebdrop ${1} ${RES} "key")
               NEXT=$(/usr/bin/tail -1 ${Cleartextfile})
               if (( ${#NEXT} < 20 ))
	       then
		    # decryption failed with key, try nextkey
		    RES=$(/usr/bin/echo get-element key.${FROM}.nextkey | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                    if [[ ${RES} ]]
		    then
                         # now try to decrypt attachment file with nextkey
	                 CLAES=$(decryptfile ${FILENAME} ${RES} "nextkey")
                         # now try to decrypt message file with nextkey
	                 CLAES=$(decryptwebdrop ${1} ${RES} "nextkey")
                         NEXT=$(/usr/bin/tail -1 ${Cleartextfile})
                         if (( ${#NEXT} < 20 ))
			 then
                              # decryption failed with nextkey, try lastkey
		              RES=$(/usr/bin/echo get-element key.${FROM}.lastkey | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                              if [[ ${RES} ]]
			      then 
                                   # now try to decrypt attachment file with lastkey
	                           CLAES=$(decryptfile ${FILENAME} ${RES} "lastkey")
                                   # now try to decrypt message file with lastkey
	                           CLAES=$(decryptwebdrop ${1} ${RES} "lastkey")
                                   NEXT=$(/usr/bin/tail -1 ${Cleartextfile})
                                   if (( ${#NEXT} < 20 ))
			           then
					# all decryption failed, move to FORENSIC
                                        Newname=$(new_name $RAM/FORENSIC "" "")
					/usr/bin/mv $1 $RAM/FORENSIC/${Newname}
					/usr/bin/mv ${FILENAME} $RAM/FORENSIC/file-${Newname}
                                        Success="false"
				   else
					Success="true"
					# make sure the key database does not change
					NEXT=""

			           fi
			      fi
                         else
			      Success="true"
			 fi
	            else		 
	                 Success="true"
 	            fi
	       else
	            Success="true"
	       fi

	       # update key table, if new key was found
	       if [[ ${Success} = "true" ]]
	       then
                    echo "update the key database"
                    if [[ ${NEXT} ]]
		    then
			 # check if nextkey is "none"
		         RES=$(/usr/bin/echo get-element key.${FROM}.nextkey | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                         if [[ ${RES} ]]
			 then
			      # nextkey does not exist
			      # create a set of entries
			      /usr/bin/echo write key.${FROM}.nextkey "none" | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			      /usr/bin/echo write key.${FROM}.lastkey "none" | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			      /usr/bin/echo write key.${FROM}.flag "false" | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			 fi
		         RES=$(/usr/bin/echo get-element key.${FROM}.nextkey | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                         if [[ ${RES} != "none" ]]
			 then
                              if [[ ${RES} != "${NEXT}" ]]
			      then
			           # key rollover 
			           /usr/bin/echo replace key.${FROM}.key ${RES} | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			           /usr/bin/echo replace key.${FROM}.nextkey ${NEXT} | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null
                                   # reset the flag as there is a new nextkey to be used next time
			           /usr/bin/echo replace key.${FROM}.flag "false" | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null
                              else
				   # do nothing, as the current nextkey has been re-used
				   /usr/bin/echo > /dev/null
			      fi
			 else
                              # first message received, nothing sent yet
			      # do not change key, but update nextkey
			      /usr/bin/echo replace key.${FROM}.nextkey ${NEXT} | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			      /usr/bin/echo replace key.${FROM}.flag "false" | /usr/bin/socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			 fi
		    fi

	            # move clear text with a new number to MESSAGES
	            # destroy the last line in ${Cleartextfile}, as it contains the key
                    # count the lines, the last line does not count as it does not end in \n
	            typeset -i LINES=$(/usr/bin/cat ${Cleartextfile} | /usr/bin/wc -l)
	            Newname=$(new_name $RAM/MESSAGES "" "${FROM}")
	            /usr/bin/head -n ${LINES} ${Cleartextfile} > $RAM/MESSAGES/${Newname}
	            /usr/bin/chmod 600  $RAM/MESSAGES/${Newname}
	            /usr/bin/chown root  $RAM/MESSAGES/${Newname}
	            /usr/bin/rm -f ${Cleartextfile}
	       fi
          fi    	       
     fi
fi

exit 0

#****************************************************************************
