#!/usr/bin/bash

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

# use the check only under Fedora, it fails under Ubuntu
if [ -L /etc/fedora-release ]
then
     . /usr/lib/cryptobone/check
fi

##############################################################################
# This file is part of the CRYPTO BONE
# File     : cbcontrol 
# Version  : 1.7 (ALL-IN-ONE)
# License  : BSD-3-Clause
# Date     : 14 Feb 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/cbcontrol.functions

#-------------------------------------------------------------#

if [ ! -d /dev/shm/RAM ]
then
    /usr/lib/cryptobone/rc.local
fi

date +%s > /dev/shm/RAM/GUI 2> /dev/null

if [ x$1 = "xUSEALLINONE" ]
then
     ln -s /usr/lib/cryptobone/version /usr/lib/cryptobone/ALLINONE
fi

if [ x$1 = "xUSECRYPTOBONE" ]
then
     /bin/rm -f /usr/lib/cryptobone/ALLINONE
fi

if [ x$1 = "xGETALLINONE" ]
then
     if [ -L /usr/lib/cryptobone/ALLINONE ]
     then
          echo "ALLINONE"
     else
          if [ -f /usr/lib/cryptobone/cbb.config ]
	  then
	       . /usr/lib/cryptobone/cbb.config
	       echo -n ${BONEIP}
	  else
               echo -n "EXTERNAL CRYPTO BONE"
	  fi
     fi
     exit 0
fi


if [ x$1 = "xCOPYSDCARD" ]
then
     if [ x$2 != "x" ]
     then
          DIR=$(df | grep $2 | cut -f2 -d%)
          if [ -f $DIR/master.key ]
	  then
	       # there are keys on the SD card
	       echo -n "replace EXTERN.OVERWRITE yes" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
               /bin/cp $DIR/local.key /usr/lib/cryptobone/keys/EXTERN.local.key 2>/dev/null
	       /bin/chown root /usr/lib/cryptobone/keys/EXTERN.local.key 2>/dev/null
	       /bin/chmod 600 /usr/lib/cryptobone/keys/EXTERN.local.key 2>/dev/null
	       if [ -f /usr/lib/cryptobone/keys/EXTERN.local.key ]; then
	            /usr/bin/sha256sum /usr/lib/cryptobone/keys/EXTERN.local.key | /usr/bin/cut -c-64 > /usr/lib/cryptobone/keys/EXTERN.local.key.sha256
	            /bin/chmod 600 /usr/lib/cryptobone/keys/EXTERN.local.key.sha256
	       else	    
	            echo -n "failed"
	            exit 2
               fi 

               # write 2 secrets directly to database 
	       LINE=$(/bin/cat $DIR/master.key | cut -c-40)
	       echo -n "replace EXTERN.real.key $LINE" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
         
               RES=$(echo  "get-element EXTERN.real.key" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
	       if [ x$RES != "x$LINE" ]
	       then
	            echo -n "failed"
	            exit 2
	       fi

	       # base64 encode cbb after it is decrypted to form one line          
	       /usr/bin/ssh-keygen -p -P $(/bin/cat $DIR/local.key) -N "" -f  $DIR/cbb 2> /dev/null > /dev/null
	       LINE=$(/bin/cat $DIR/cbb | base64 | tr -d "\n" )
	       echo "replace EXTERN.cbb $LINE" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null
               RES=$(echo "get-element EXTERN.cbb" | socat -t15 - UNIX-connect:$SOCK 2> /dev/null)
	       if [ x$RES != "x$LINE" ]
	       then
	            echo -n "failed"
	            exit 2
	       fi
	       # reaching this point, all secrets have been transferred correctly.
	       echo -n "success"
	       exit 0
	  fi
     fi
     echo -n "nokeys"
     exit 1
fi

if [ x$1 = "xDELETE" ]; then
     if [ x$2 = "xCONFIG" ]; then
          /bin/rm /usr/lib/cryptobone/cbb.config
	  echo -n "success"
	  exit 0
     fi
fi

if [ -L /usr/lib/cryptobone/ALLINONE ]
then
     if [ "x$1" = "xEXIT" ]
     then
          echo "Bye for now."
          exit 0
     fi


     # check if querying local.key works, compare with sha256 hashvalue
     # exit "failed", if local.key cannot be accessed (directly or via a second device)

     if [ ! -f /usr/lib/cryptobone/keys/local.key.sha256 ]
     then
          /usr/lib/cryptobone/rc.local
     fi

     TESTHASH=$(/bin/cat /usr/lib/cryptobone/keys/local.key.sha256 2>/dev/null | cut -c-64)
     HASH=$(/usr/lib/cryptobone/getlocalsecret | sha256sum | cut -c-64)
     
     if [ x$HASH != x$TESTHASH ]
     then
          echo "failed: local authentication"
          exit 1
     fi

     log  "170: $*"

     if [ $# -ge 1 ]
     then
          case $1 in

          ATTACHMENT)   case $2 in
	                      LIST)             attachmentlist
			                        ;;

			      MOVE)             move_attachment "$3"
			                        ;;
                        esac
			;;

	  CHECKEMAIL)   case $2 in
	                      IN) 	        /usr/lib/cryptobone/checkemail IN
	                                        ;;

 			      OUT) 	        /usr/lib/cryptobone/checkemail OUT "$3" "$4"
	                                        ;;
                        esac
			;;

          EMAIL) 	case $2 in
			     STATUS)	        case $3 in
				 	             IN)  /bin/cat /dev/shm/RAM/fetchmail.*
                                                     ;;
					             OUT) mailqueue 
	                                             ;;		      
                                                esac
                        esac
			;;

	  EXTERNAL)     case $2 in
	  		     STATUS)		 check_external
			                         ;;
			esac     
	                ;;

          FETCH)        /usr/lib/cryptobone/cron.fetchmail			
                        ;;

          KEY)          case $2 in

                              CHANGEEMAIL)	change_email_address "$3"  "$4"
			                        ;;

                              CONTACT)		contact_registered "$3"
			                        ;;

			      NEWSECRETS) 	get_new_secrets
			                        ;;

			      RECIPIENTLIST)	recipient_list	
			                        ;;

			      RESET)		reset_key_for_email "$3"
			                        ;;

		 	      USE) 	        register_new_key "$3"  "$4"
			                        ;;

                              *) 	        echo "unknown KEY command"
			                        ;;

                        esac
                        ;;

          NETWORK) 	case $2 in
			      STATUS)	case $3 in
                                            CONNECT)  /usr/bin/sudo /sbin/ifconfig  2>&1
						      ;;
					    FIREWALL) /usr/bin/sudo /usr/lib/cryptobone/firewall status
						      ;;
                                            PING)     /bin/ping -c1 -w1 $(cat /usr/lib/cryptobone/pinghost)
                                                      ;;
                                        esac
			esac
                        ;;

          POWEROFF)     echo "going down"
			/usr/lib/cryptobone/bin/cbb-poweroff 2>/dev/null
			;;
         
	  READ)	        case $2 in
			      DESTROY)		destroy_message $3
			                        ;;

			      MESSAGELIST)	get_message_list
			                        ;;
			      
			      EMAILLIST)	get_email_list
			                        ;;

                              MESSAGE)		read_message $3
			                        ;;
                              
			      EMAIL)		read_email $3
			                        ;;
                        esac
			;;


          RESET)	echo "reset the masterkey"
			;;

	  SETUP)        case $2 in
	                     ID) 	     get_id ;;
			     GETTRANSPORT)   get_transport;;
	                     SERVER)         setup_mailserver "$3" ;;
			     USER)           setup_mailuser "$3" ;;
			     PASSWORD)       setup_mailpassword "$3" ;;
			     SMTPSERVER)     setup_smtpserver "$3" ;;
			     SMTPPORT)       setup_smtpport "$3" ;;
			     SMTPTLS)        setup_smtptls "$3" ;;
			     TRANSPORT)      setup_transport "$3" ;;
			     SHOW)           show_setup ;;
			     WID)	     get_wid ;;
			     WEBDROP)        show_safewebdrop_setup ;;
			     WEBDROPSECRET)  setup_safewebdropsecret "$3" ;;
			     WEBDROPSERVER)  setup_safewebdropserver  "$3" ;;
			     WEBDROPUSER)    setup_safewebdropuser "$3" ;;
			     CLEARREG)       setup_clear_safewebdrop_registration ;;
			     REGISTER)       setup_register_safewebdrop ;;
			     REGISTRATION)   setup_get_safewebdrop_registration ;;
			esac
			;;

          SHOW)         echo "forbidden";
	                ;;

          STATUS)       if  echo "get-element cryptobone" | socat -t15 - UNIX-connect:$SOCK > /dev/null
		        then 
			     echo "active"
		        else 
			     echo "waiting"
		        fi
		        ;;

	  SYSTEM)       case $2 in
	                     SUSPEND)    cryptobonesuspend ;;
			     RESUME)     cryptoboneresume ;;
			     POWEROFF)   clear_RAM ;;
			     RESTART)    /usr/lib/cryptobone/rc.local ;;
			esac
			;;


          WRITE)        write_message "$2"  "$3"
			;;
          
	  WEBDROP)      safewebdrop_message "$2"  "$3" "$4"
			;;


          *)            echo "failed"
		        ;;
         esac
         exit 0
     fi
     echo "failed"
     exit 1

else
     # real Crypto Bone
     export SSH_AUTH_SOCK=/usr/lib/cryptobone/ssh.sock	  
     if [ -f /usr/lib/cryptobone/cbb.config ]
     then
	  /bin/chmod 600 /usr/lib/cryptobone/cbb.config
          . /usr/lib/cryptobone/cbb.config 2> /dev/null
     else
          BONEIP="none"
     fi 
     
     # check if external system is active
     if [ -f /usr/lib/cryptobone/UPLOADED ]
     then 
	  # send the commands directly to the EXTERNAL Crypto Bone
          echo $(/usr/lib/cryptobone/getlocalsecret) $1 $2 $3 $4 | /usr/bin/ssh -l cryptobone  ${BONEIP} /cbb/cbcontrol      
          if [ $1 = "POWEROFF" ]
          then
               # shutdown of an active system has finished, record shutdown here.
               /bin/rm /usr/lib/cryptobone/UPLOADED 2> /dev/null
          fi	  
     else	  
          # external crypto bone is not yet active or unreachable
	  if [ $BONEIP != "none" ] 
	  then
	       # we have cbb.config, the external crypto bone may be reachable
	       if ping -c1 -w1 ${BONEIP} 2>/dev/null >/dev/null
	       then
	            if [ $1 = "POWEROFF" ]
		    then
	                 # shut down of an inactive system
                         echo $(/usr/lib/cryptobone/getlocalsecret) POWEROFF | /usr/bin/ssh -l cryptobone  ${BONEIP} /cbb/cbcontrol      
	                 echo "shutdown"
	            else		 
	                 echo "master key not available"
		    fi
               else
	            echo "offline"
	       fi
	       exit 0
          else
	       # we don't have any configuration yet
               # external crypto bone is not reachable
               # check if SSH key is active
	       if  /usr/bin/ssh-add -L | grep "ssh-rsa" > /dev/null 2> /dev/null
	       then
	            # find the external crypto bone
	            echo "LOOKING FOR A CRYPTO BONE"
                    /usr/lib/cryptobone/getIP 
                    if [ -f /usr/lib/cryptobone/cbb.config ]
                    then
	                 /bin/chmod 600 /usr/lib/cryptobone/cbb.config
                         . /usr/lib/cryptobone/cbb.config 2> /dev/null
		         echo "master key not available"
	            else
		         echo "boneless"
                    fi
	       else
	            echo "ssh key not available"
	       fi
	       exit 0
	  fi     
     fi	  
fi

#########################################################
