#!/usr/bin/bash

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

#***************************************************************************
# This file is part of the CRYPTO BONE
# File     : processmessage
# Version  : 1.6 (ALL-IN-ONE)
# License  : BSD
# Date     : 2 April 2023
# Contact  : Please send enquiries and bug-reports to innovation@senderek.ie
#
#
# Copyright (c) 2015-2023
#	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.
#
#****************************************************************************

SOCK=/usr/lib/cryptobone/secrets.sock
ALLOWED="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-@%"
RAM="/dev/shm/RAM"


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 [ x$1 != "x" ]
     then
          if [ x$2 != "x" ]
	  then
               LAST=$(/bin/ls $1/$3*.$2 2>/dev/null | /usr/bin/sort | /usr/bin/tail -1)
	       LAST=${LAST%.$2}
	  else
               LAST=$(/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="mail"
	  if [ x$3 != "x" ]; then
               PRE=$3
	  fi
          if [ ${NUM} -lt 10 ]
          then
               NAME="${PRE}.000"${NUM}
          else
               if [ ${NUM} -lt 100 ]
               then
                    NAME="${PRE}.00"${NUM}
               else
                    if [ ${NUM} -lt 1000 ]
                    then
                         NAME="${PRE}.0"${NUM}
                    else
                         NAME="${PRE}."${NUM}
                    fi
               fi
          fi
     fi
     if [ ${NUM} -eq 0 ]
     then
          NAME="${PRE}.0001" 
     fi
     if [ x$2 != "x" ]
     then
          NAME=${NAME}.$2
     fi
     echo ${NAME}
}

if [ $1x != "x" ]
then
     Success="false"
     Cleartextfile=${1%.asc}
     echo "processing $1" 
     Fromline=$(grep "From: "  $1)
     IFS=" "
     echo ${Fromline} |  while read PRE FROM POST; do
	  # found From email address
          # further processing, if Fromline is more complex !!
          
          if ! echo ${FROM} | /bin/grep "@"
          then
	       if ! echo ${FROM} | /bin/grep "%"
	       then
                    FROM=${POST#*<}
                    FROM=${FROM%>*}
	       fi 
          fi
          # chop off < and >
          FROM=${FROM#*<}
          FROM=${FROM%>*}
          RES=$(echo get-element key.${FROM}.key | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
          if [ ${RES}x != "x" ]
	  then
               # now try to decrypt mail file with key
	       /bin/rm ${Cleartextfile} 2> /dev/null
	       RES=$(echo decrypt $1 ${RES} | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
               NEXT=$(/usr/bin/tail -1 ${Cleartextfile})
               if [ ${#NEXT} -lt 20 ]
	       then
		    # decryption failed with key, try nextkey
		    RES=$(echo get-element key.${FROM}.nextkey | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                    if [ ${RES}x != "x" ]
		    then
	                 /bin/rm ${Cleartextfile} 2> /dev/null
	                 RES=$(echo decrypt $1 ${RES} | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                         NEXT=$(/usr/bin/tail -1 ${Cleartextfile})
                         if [ ${#NEXT} -lt 20 ]
			 then
                              # decryption failed with nextkey, try lastkey
		              RES=$(echo get-element key.${FROM}.lastkey | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                              if [ ${RES}x != "x" ]
			      then 
	                           /bin/rm ${Cleartextfile} 2> /dev/null
	                           RES=$(echo decrypt $1 ${RES} | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                                   NEXT=$(/usr/bin/tail -1 ${Cleartextfile})
                                   if [ ${#NEXT} -lt 20 ]
			           then
					# all decryption failed, move to FORENSIC
                                        Newname=$(new_name $RAM/FORENSIC "" "")
					/bin/mv $1 $RAM/FORENSIC/${Newname}
                                        Success="false"
				   else
					Success="true"
					# make sure the key database does not change
					NEXT=""

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

	       # update key table, if new key was found
	       if [ ${Success} = "true" ]
	       then
                    echo "update the key database"
                    if [ ${NEXT}x != "x" ]
		    then
			 # check if nextkey is "none"
		         RES=$(echo get-element key.${FROM}.nextkey | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                         if [ ${RES}x = "x" ]
			 then
			      # nextkey does not exist
			      # create a set of entries
			      echo write key.${FROM}.nextkey "none" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			      echo write key.${FROM}.lastkey "none" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			      echo write key.${FROM}.flag "false" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			 fi
		         RES=$(echo get-element key.${FROM}.nextkey | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
                         if [ ${RES}x != "nonex" ]
			 then
                              if [ ${RES}x != "${NEXT}x" ]
			      then
			           # key rollover 
			           echo replace key.${FROM}.key ${RES} | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			           echo replace key.${FROM}.nextkey ${NEXT} | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
                                   # reset the flag as there is a new nextkey to be used next time
			           echo replace key.${FROM}.flag "false" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
                              else
				   # do nothing, as the current nextkey has been re-used
				   echo > /dev/null
			      fi
			 else
                              # first message received, nothing sent yet
			      # do not change key, but update nextkey
			      echo replace key.${FROM}.nextkey ${NEXT} | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
			      echo replace key.${FROM}.flag "false" | 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=$(/bin/cat ${Cleartextfile} | /usr/bin/wc -l)
	            Newname=$(new_name $RAM/MESSAGES "" "${FROM}")
	            /usr/bin/head -n ${LINES} ${Cleartextfile} > $RAM/MESSAGES/${Newname}
	            /bin/chmod 600  $RAM/MESSAGES/${Newname}
	            /bin/chown root  $RAM/MESSAGES/${Newname}
	            /bin/rm ${Cleartextfile}
	       fi
	  fi
     done
fi



exit 0

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