#!/bin/sh

set -u
set -e
set -x


# bashizm, won't work with POSIX shell
# exec > >(tee bestcrypt-install.log)
# exec 2>&1

GPG_KEY_ID="9720F6864823E840"


# empty for stable versions, _beta to install beta releases
BETA=""

#BASE_URL="ftp://file.jetico/packages/bcrypt-linux"
BASE_URL="https://www.jetico.com/packages${BETA}"


# script should be run either with 'root' privelegies
# or have 'sudo' configured for the user
if [ `id -u` = "0" ]; then
  # run as 'root' user, no need to use 'sudo'
  SUDO=""
else
  echo "Installer is not run as a 'root' user"
  if command -v sudo >/dev/null 2>&1 ; then
    echo "We will try to use 'sudo' to elevate privelegies"
    SUDO="sudo"
  else
    echo "and 'sudo' is not installed."
    echo "Please install and configure 'sudo' or"
    echo "run installation script as 'root' user"
    exit 1
  fi
fi


does_have_actual_kernel_headers()
{
  test -e /lib/modules/`uname -r`/build && return 0
  cat << EOF

Actual kernel headers were just installed. Reboot is required.
After you reboot your system please re-run this script by the same command.
If you'll get the same message then make sure your current kernel version 
 (uname -r) and kernel-* packages version (rpm -qa | grep kernel-) is the same.

EOF
  return 1
}

substitute_variables_in_template()
{
  local target="$1"

  $SUDO sed -i "s|#BASE_URL#|${BASE_URL}|"                "$target"
  $SUDO sed -i "s|#DISTNAME#|${DISTNAME}|"                "$target"
  $SUDO sed -i "s|#CODENAME#|${CODENAME}|"                "$target"
}

RELEASE_TYPE=""

# Debian, Ubuntu, LinuxMint
if [ -e "/etc/debian_version" ] ; then
  RELEASE_TYPE="DEBIAN"
# Fedora
elif [ -e "/etc/fedora-release" ] ; then
  RELEASE_TYPE="FEDORA"
# RHEL, CentOS, OracleLinux, Scientific Linux
elif [ -e "/etc/redhat-release" ] ; then
  RELEASE_TYPE="REDHAT"
# SLES
elif [ -e "/etc/SuSE-release" ]; then
  RELEASE_TYPE="SUSE"
elif [ -e "/etc/SUSE-brand" ]; then
  RELEASE_TYPE="SUSE"
elif [ -e "/etc/os-release" ]; then
  . /etc/os-release
  NAME=`echo "$NAME" | tr '[:upper:]' '[:lower:]'`
  # SLES
  if [ "${NAME/opensuse}" != "$NAME" ] || [ "${NAME/sle}" = "$NAME" ]; then
    RELEASE_TYPE="SUSE"
  fi
fi

# Debian, Ubuntu, LinuxMint
if [ $RELEASE_TYPE = "DEBIAN" ] ; then

  if ! command -v lsb_release >/dev/null 2>&1 ; then
    $SUDO apt-get install -y lsb-release
  fi

  if ! dpkg -l apt-transport-https >/dev/null 2>&1 ; then
    $SUDO apt-get install -y apt-transport-https
  fi

  DISTNAME=`lsb_release -is | tr 'A-Z' 'a-z'`
  CODENAME=`lsb_release -cs`

  if [ "$DISTNAME" = "linuxmint" ] ; then
    case "$CODENAME" in
    wilma)
      DISTNAME=ubuntu  CODENAME=noble ;;
    ulyana|ulyssa|uma|una)
      DISTNAME=ubuntu  CODENAME=focal ;;
    tara|tina|tricia)
      DISTNAME=ubuntu  CODENAME=bionic ;;
    sarah|serena|sonya|sylvia)
      DISTNAME=ubuntu  CODENAME=xenial ;;
    betsy)
      DISTNAME=debian  CODENAME=jessie ;;
    tessa)
      DISTNAME=debian  CODENAME=jessie ;;
    vanessa|vera|victoria|virginia)
      DISTNAME=ubuntu  CODENAME=jammy ;;
    faye)
      DISTNAME=debian  CODENAME=bookworm ;;
    *)
      echo "Error: Unsupported LinuxMint release '$CODENAME'"
      echo "Please contact Jetico support: mailto:support@jetico.com"
      exit 1
    esac
  fi

  if [ "$DISTNAME" = "elementary os" ] || [ "$DISTNAME" = "elementary" ]; then
    case "$CODENAME" in
    loki)
      DISTNAME=ubuntu  CODENAME=xenial ;;
    horus)
      DISTNAME=ubuntu  CODENAME=jammy ;;
    *)
      echo "Error: Unsupported Elementary OS release '$CODENAME'"
      echo "Please contact Jetico support: mailto:support@jetico.com"
      exit 1
    esac
  fi

  if [ "$DISTNAME" = "zorin" ] || [ "$DISTNAME" = "pop" ]; then
    DISTNAME=ubuntu
  fi

  if [ "$DISTNAME" = "ubuntu" ] ; then
    if ! apt-cache policy | grep -q universe ; then
      cat << EOF

Unable to continue: Your action is required.

BestCrypt for Linux depends on few packages from 'universe' repository.

Please make sure the universe repository is accessible on your system with apt utillity.
If your system support is discontinued then you should install all required packages manually
and re-run one-click-installer again.
(Packages list: qt5-default, libqt5x11extras5-dev, libudev1, libxss1, dkms, cpp)

EOF
      exit 1
    fi
  fi

  if [ "$DISTNAME" = "solydxk" ] ; then
    case "$CODENAME" in
    solydxk|*) # hope that build will work further
      DISTNAME=debian  CODENAME=jessie ;;
    esac
  fi

  # show current status
  dpkg -l '^bestcrypt*' || true

  $SUDO apt-key adv --recv-key --keyserver keyserver.ubuntu.com --recv-keys "$GPG_KEY_ID"

  # turn off beta repository when install release version
  if [ -z "$BETA" ] ; then
    $SUDO rm -f "/etc/apt/sources.list.d/bestcrypt_beta.list"
  fi

  repofile="/etc/apt/sources.list.d/bestcrypt${BETA}.list"
  $SUDO wget -O "$repofile" ${BASE_URL}/bestcrypt.list.template
  substitute_variables_in_template "$repofile"

  $SUDO apt-get update
  $SUDO apt-get install -y bestcrypt bestcrypt-panel bestcrypt-dkms

# Fedora
elif [ $RELEASE_TYPE = "FEDORA" ] ; then

  if ! command -v dnf >/dev/null 2>&1 ; then
    $SUDO yum install -y dnf
  fi

  if ! command -v lsb_release >/dev/null 2>&1 ; then
    $SUDO dnf install -y redhat-lsb-core
  fi

  DISTNAME="fedora"
  CODENAME=`lsb_release -rs | cut -d. -f1`

  # show current status
  rpm -qa | grep '^bestcrypt.*' || true

#  rpm -q kernel      && $SUDO dnf update -y kernel
#  rpm -q kernel-core && $SUDO dnf update -y kernel-core
  $SUDO dnf install -y gcc dkms
  $SUDO dnf install -y --best kernel-devel kernel-headers

  if uname -r | grep -q PAE; then
    $SUDO dnf install -y kernel-PAE-devel
  fi

  does_have_actual_kernel_headers || exit 0
  
  if [ "$CODENAME" -gt "39" ] ; then
    $SUDO dnf install -y dkms systemd-sysvcompat insserv-compat || true
    # Secure Boot: fix and enroll DKMS key
    $SUDO openssl req -new -x509 -nodes -days 36500 -subj "/CN=DKMS module signing key" \
      -addext "extendedKeyUsage=codeSigning" \
      -newkey rsa:2048 -keyout /var/lib/dkms/mok.key \
      -outform DER -out /var/lib/dkms/mok.pub > /dev/null 2>&1
    if command -v mokutil >/dev/null 2>&1 ; then
      SB_ENABLED=`$SUDO mokutil --sb-state`
      if [ "$SB_ENABLED" = "SecureBoot enabled" ]; then
      echo "*** Please, enter your password for insert BestCrypt modules for SB, and reboot your system ***"
        $SUDO mokutil --import /var/lib/dkms/mok.pub
      fi
    fi
  fi


  # turn off beta repository when install release version
  if [ -z "$BETA" ] ; then
    $SUDO rm -f "/etc/yum.repos.d/bestcrypt_beta.repo"
  fi

  repofile="/etc/yum.repos.d/bestcrypt${BETA}.repo"
  $SUDO wget -O "$repofile" ${BASE_URL}/bestcrypt.repo.template
  substitute_variables_in_template "$repofile"

  $SUDO wget -O /etc/pki/rpm-gpg/RPM-GPG-KEY-Jetico ${BASE_URL}/jetico_packages.asc
  $SUDO gpg --import /etc/pki/rpm-gpg/RPM-GPG-KEY-Jetico

  rpm -q BestCrypt && $SUDO rpm -e BestCrypt    # previous version from .src.rpm

  $SUDO dnf -y makecache

  rpm -q bestcrypt \
    && $SUDO dnf update -y bestcrypt bestcrypt-panel bestcrypt-dkms \
    || $SUDO dnf install -y bestcrypt bestcrypt-panel bestcrypt-dkms

# RHEL, CentOS, OracleLinux, Scientific Linux
elif [ $RELEASE_TYPE = "REDHAT" ] ; then

  if [ `arch` != "x86_64" ]; then
    echo "platform `arch` isn't supported"
    exit 1
  fi

  if ! command -v lsb_release >/dev/null 2>&1 ; then
    $SUDO yum install -y redhat-lsb-core
  fi

  DISTNAME="el"
  CODENAME=`lsb_release -rs | cut -d. -f1`

  # show current status
  rpm -qa | grep '^bestcrypt.*' || true

#  $SUDO yum update -y kernel
  $SUDO yum install -y epel-release
  $SUDO yum install -y gcc dkms kernel-devel kernel-headers

  does_have_actual_kernel_headers || exit 0

  # turn off beta repository when install release version
  if [ -z "$BETA" ] ; then
    $SUDO rm -f "/etc/yum.repos.d/bestcrypt_beta.repo"
  fi

  repofile="/etc/yum.repos.d/bestcrypt${BETA}.repo"
  $SUDO curl -L --output "$repofile" ${BASE_URL}/bestcrypt.repo.template
  substitute_variables_in_template "$repofile"

  $SUDO wget -O /etc/pki/rpm-gpg/RPM-GPG-KEY-Jetico ${BASE_URL}/jetico_packages.asc

  rpm -q BestCrypt && $SUDO rpm -e BestCrypt    # previous version from .src.rpm

  rpm -q bestcrypt \
    && $SUDO yum update  -y bestcrypt bestcrypt-panel bestcrypt-dkms \
    || $SUDO yum install -y bestcrypt bestcrypt-panel bestcrypt-dkms

# SLES
elif [ $RELEASE_TYPE = "SUSE" ] ; then

  DISTNAME="suse"

  if ! command -v lsb_release >/dev/null 2>&1 ; then
    $SUDO zypper install -y lsb-release
  fi

  CODENAME=`lsb_release -rs | cut -d. -f1`

  # OpenSuSE 12
  if [ "$CODENAME" = "42" ] ; then
    CODENAME=12
  fi

#  $SUDO zypper update -y kernel-default

  $SUDO zypper install -y kernel-default-devel

    if [ "$CODENAME" -lt "15" ] ; then
    # git clone https://github.com/dell-oss/dkms
    # cd dkms
    # patch -p0 < ~/bcrypt-3.0.0/contrib/rpm/suse/dkms.spec.patch
    # make
    # cp dist/dkms-2.2.1.0-1.sles11.4.noarch.rpm $BASE_URL/suse/11/
    DKMS_PKG_FN="dkms-2.2.1.0-1.sles11.4.noarch.rpm"  # works on SUSE 11 and SUSE 12
    rpm -q dkms || { wget "https://www.jetico.com/linux/3rdparty/${DKMS_PKG_FN}" ; $SUDO rpm -Uvh "${DKMS_PKG_FN}" ; rm "${DKMS_PKG_FN}" ; }
  else
    $SUDO zypper install -y dkms systemd-sysvcompat insserv-compat
    # Secure Boot: fix and enroll DKMS key
    $SUDO openssl req -new -x509 -nodes -days 36500 -subj "/CN=DKMS module signing key" \
      -addext "extendedKeyUsage=codeSigning" \
      -newkey rsa:2048 -keyout /var/lib/dkms/mok.key \
      -outform DER -out /var/lib/dkms/mok.pub > /dev/null 2>&1
    if command -v mokutil >/dev/null 2>&1 ; then
      SB_ENABLED=`$SUDO mokutil --sb-state`
      if [ "$SB_ENABLED" = "SecureBoot enabled" ]; then
        $SUDO mokutil --root-pw --import /var/lib/dkms/mok.pub
      fi
    fi
  fi

  does_have_actual_kernel_headers || exit 0

  # turn off beta repository when install release version
  if [ -z "$BETA" ] ; then
    $SUDO rm -f "/etc/zypp/repos.d/bestcrypt_beta.repo"
  fi

  repofile="/etc/zypp/repos.d/bestcrypt${BETA}.repo"
  $SUDO curl -L --output "$repofile" ${BASE_URL}/bestcrypt.repo.template
  substitute_variables_in_template "$repofile"

  $SUDO mkdir -p /etc/pki/rpm-gpg/
  $SUDO wget -O /etc/pki/rpm-gpg/RPM-GPG-KEY-Jetico ${BASE_URL}/jetico_packages.asc
  $SUDO gpg --import /etc/pki/rpm-gpg/RPM-GPG-KEY-Jetico
  echo "Note: if the next command fails look for a dialog that asks to accept new software source"
  $SUDO rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-Jetico

  $SUDO zypper ref -f "bestcrypt"

  rpm -q BestCrypt && $SUDO rpm -e BestCrypt    # previous version from .src.rpm

  # SLES 11
  test -f /etc/modprobe.d/unsupported-modules && \
    $SUDO sed -i 's/allow_unsupported_modules.*/allow_unsupported_modules 1/g' /etc/modprobe.d/unsupported-modules

  # SLES 12
  test -f /etc/modprobe.d/10-unsupported-modules && \
    $SUDO sed -i 's/allow_unsupported_modules.*/allow_unsupported_modules 1/g' /etc/modprobe.d/10-unsupported-modules

  if [ $CODENAME == "11" ] ; then
    rpm -q bestcrypt \
      && $SUDO zypper --non-interactive --gpg-auto-import-keys --no-gpg-check update  -y bestcrypt bestcrypt-panel bestcrypt-dkms \
      || $SUDO zypper --non-interactive --gpg-auto-import-keys --no-gpg-check install -y bestcrypt bestcrypt-panel
  else
    rpm -q bestcrypt \
      && $SUDO zypper --non-interactive update  -y bestcrypt bestcrypt-panel bestcrypt-dkms \
      || $SUDO zypper --non-interactive install -y bestcrypt bestcrypt-panel bestcrypt-dkms || true
  fi

else
  echo "Unfortunately, you distribution is currently is not supported."
  echo "Please contact mailto:support@jetico.com and tell as which distribution"
  echo "do you want to see in supported list."
  exit 1
fi


cat << EOF

        Congratulations!

Now you have BestCrypt for Linux installed in your system.

Execute 'bestcrypt-panel' command or use menu shortcut in your desktop
menu to run the program. Alternatively you may start using 'bctool'
command line tool (see 'man bctool' for details).

Updates to BestCrypt for Linux will be delivered by your system
updates mechanism (APT on Debian/Ubuntu, yum/dnf on Fedora, etc).

Any questions/suggestions are welcome!
mailto:support@jetico.com
We are glad to hear from you.

EOF

set +x

if [ "${SB_ENABLED:-}" = "SecureBoot enabled" ]; then
cat <<EOF
*** Please reboot your computer to add the module signing key for Secure Boot. ***
After the reboot please select "Enroll MOK" and use your system root password when asked.
EOF
fi
