#!/usr/bin/bash


#
# Copyright 2014-2024 Senderek Web Security, Ireland. All rights reserved.
#                <https://senderek.ie/opensource/secureboot2>
#
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

#
# Author:       Ralf Senderek <innovation@senderek.ie>
#
# license:      GNU General Public License version 3 or later
# description:  changes the passphrase on a copy of an encrypted filesystem
# processname:  secureboot-encrypt $1
# config:       none
# date:         3/5/2024
#


ROOT=/usr/lib/secureboot
BASE=$ROOT
FILE=$ROOT/securefilesystem
SIZE=0
DEFAULTBLOCKS=50000   # 1 BLOCK = 1024 Bytes
RET=0

# old encrypted big files traditionally use ripemd160 to hash the passphrase in order to generate a AES key.
CREATE="/sbin/cryptsetup open -y --type plain --cipher="aes-cbc-essiv:sha256" --key-size=256 --hash=ripemd160"
# You can switch to sha256, if you create a new filesystem instead of using your old one.

NAME=secure
NEWDIR=$BASE/new-$NAME

if [ $# -gt 2 ]; then
     echo "usage: secureboot-encrypt [--default | --grow size]"; exit 2
else
     if [ $# -gt 0 ]; then
         if [ $1 = "--grow" ] ; then
              SIZE="$2"
	 else
	     if [ $1 = "--default" ]; then
                   dd if=/dev/urandom of=$ROOT/${NAME}.NEW bs=1k count=$DEFAULTBLOCKS
                   LOOP=$(/sbin/losetup -f)
                   if [ $? = 0 ]; then
                        echo $LOOP > $BASE/${NAME}NEW-loopdevice
                        /sbin/losetup $LOOP $ROOT/${NAME}.NEW
                        echo "Please enter the new passphrase for the encrypted filesystem."
                        ${CREATE} $LOOP ${NAME}NEW 
                        RET=$?
                        if [ $RET != 0 ]; then
                             # cryptsetup failed
                             echo "Error : Cannot create /dev/mapper/${NAME}NEW"
                        else
                             # create ext4 filesystema
                             echo
                             mkfs -t ext4 -c -c /dev/mapper/${NAME}NEW
			     if [ $? = 0 ]; then
			         echo
                                 ls -l $ROOT/${NAME}.NEW
				 echo
				 echo "Run /usr/lib/secureboot/secureboot-replace to activate the new filesystem."
			     fi
			     /sbin/cryptsetup remove /dev/mapper/${NAME}NEW
                        fi
                        /sbin/losetup -d $LOOP
                        rm $BASE/${NAME}NEW-loopdevice
	           fi		
                   exit 0
	     fi
         fi
     fi
fi


if [ ! -b /dev/mapper/$NAME ]; then
     /usr/lib/secureboot/secureboot2 start
     if [ $? != 0 ] ; then
          echo "Device $NAME is not available. Exiting ..."
          exit 3
     fi
fi

DIR=$(df | grep ${NAME}$)
DIR=${DIR##*\% }
echo "Using /dev/mapper/$NAME mounted on $DIR as the data source."

# determine size of the filesystem
OLDSIZE=$(du -L -k $FILE| cut -f1)
if [  $OLDSIZE  -gt $SIZE ]; then
     SIZE=$OLDSIZE
fi
BLOCKS=$(df -k .| grep dev)
BLOCKS=$(echo $BLOCKS | cut -f4 -d" ")
echo "$BLOCKS blocks available"

if [ $SIZE -gt $BLOCKS ]; then
     echo "Not enough space available to create a new filesystem."
     echo "$SIZE Kbytes needed. Exiting ..."
     exit 4
else
     echo "$SIZE blocks needed for new filesystem. If you want to grow a bigger filesystem use the option --grow size"
     echo -n "Continue ? [yes/no] : "
     read REPLY
     if [ $REPLY != "yes" ]; then
          echo "Aborting ..."
          # cleanup
          /usr/lib/secureboot/secureboot2 stop
          exit 1
     fi
     if [ -f ${NAME}.NEW ]; then
          echo "ERROR: file ${NAME}.NEW already exists. Please remove it first. Exiting ..."
          exit 3
     fi
     echo "Please wait ..."

     dd if=/dev/urandom of=$ROOT/${NAME}.NEW bs=1k count=$SIZE

     if [ $? != 0 ]; then
          echo "New file ${NAME}.NEW could not be created."
          exit 3
     else
          echo "New file ${NAME}.NEW filled with random data"
          echo
     fi
     LOOP=$(losetup -f)
     if [ $? = 0 ]; then
          echo $LOOP > $BASE/${NAME}NEW-loopdevice
          losetup $LOOP $ROOT/${NAME}.NEW
          echo "Please enter the new passphrase for the encrypted filesystem."
          ${CREATE} $LOOP ${NAME}NEW 
          RET=$?
          if [ $RET != 0 ]; then
               # cryptsetup failed
               echo "Error : Cannot create /dev/mapper/${NAME}NEW"
               losetup -d $LOOP
               rm $BASE/${NAME}NEW-loopdevice
               RET=4
          else
               # create ext4 filesystema
               echo
               mkfs -t ext4 -c /dev/mapper/${NAME}NEW
               # try to mount new filesystem
               mkdir ${NEWDIR} > /dev/null 2>&1
               mount /dev/mapper/${NAME}NEW ${NEWDIR}
               RET=$?
               if  [ $RET != 0 ]; then
                    echo "Mounting the new filesystem on ${NEWDIR} failed. Exiting ..."
                    rmdir ${NEWDIR}
                    exit 6
               fi
               echo
               echo "Ready to copy files from $DIR to ${NEWDIR}"
               echo
               if cd $DIR ; then
                    tar cpf - .  | (cd ${NEWDIR}; tar xpvf -)
                    echo
                    df | grep "${DIR}"
                    cd - >/dev/null 2>&1
                    echo
                    echo "Re-encryption finished"
                    echo
                    /usr/lib/secureboot/secureboot2 stop
		    
		    umount /dev/mapper/${NAME}NEW
		    cryptsetup remove /dev/mapper/${NAME}NEW
                    losetup -d $LOOP
                    rm $BASE/${NAME}NEW-loopdevice
                    rmdir ${NEWDIR}
		    echo
                    echo "You can now replace your encrypted filesystem with your new filesystem ${NAME}.NEW "
                    echo "Use the command: /usr/lib/secureboot/secureboot-replace"
		    echo

               fi
          fi
     fi
fi

exit $RET
#################################################################

