#!/usr/bin/env bash

# Copyright (C) 2013-2018:
# This file is part of Shinken Enterprise, all rights reserved.

# Set default umask to avoid problems when creating Shinken files
umask 0022

source /var/lib/shinken/libexec/libs/shinken_protected_fields.sh
source ../libexec/libs/shinken_protected_fields.sh 2>/dev/null   # For PyCharm

function usage()
{
    printf "\nUsage: $(basename $0) [options]\n\n"
    printf "This command enables protected fields encryption in the Synchronizer.\n"
    printf "If the key does not exist, it will also generate one.\n"
    printf "The key can be changed at a later stage, assuming this one is still available.\n"
    printf "\nOptions :\n"
    printf "  -h  : Shows this help text\n"
    printf "  -q  : Reduce the verbosity\n"
    printf "  -y  : Force the "YES" answer to all questions asked by this command\n"
    printf "\nExample :\n"
    printf "$(basename $0)\n\n"
    exit 1
}

if ! shinken-daemons-has synchronizer > /dev/null 2> /dev/null ;then
    printf "\n\n$(show_critical_info "The Synchronizer is not installed on this server ; this tool is not relevant.")\n\n"
    exit 1
fi

force_yes=0
quiet=0
while [ $# -gt 0 ]; do
    case $1 in
        -h|-H|--help)
            usage
            ;;
         -y)
            force_yes=1
            ;;
         -q)
            quiet=1
            ;;
         *)
            usage
            ;;
    esac
    shift
done

spf_check_mongo_connexion "synchronizer"
synchronizer_is_started
is_started=$?
SYNCHRONIZER_CFG=/etc/shinken/synchronizer.cfg
key_file=$(spf_get_keyfile_name_from_synchronizer_cfg)

if [ $quiet -eq 0 ] ; then
    printf "\n\n$(show_important_info "This command will enable encryption")"

    if [ $is_started -eq 0 ] ; then
        printf  "$(show_important_info " and restart the synchronizer to encrypt the protected fields.")\n\n"
    else
        printf "$(show_important_info ". Then you have to start up your synchronizer to encrypt the protected fields.")\n\n"
    fi
fi

printf "\n$(show_important_info "Checking consistency between the synchronizer configuration file and the currently running configuration...") "
spf_check_consistency_config_db

if [ $? -ne 0 ]; then
    printf "\n\n$(show_critical_info "Consistency check failed ; make sure you restore the correct configuration file before anything else.")\n\n"
    printf "\n$(show_info "Here are some hints for this :")\n"
    printf "\n\t * If you have an export of the key from the database, you can use the command $(show_command "shinken-protected-fields-keyfile-restore" "")\n"
    printf "\n\t * If you don't have an export, but you have a backup made after the encryption, you can use the command :\n"
    printf "\n\t\t$(show_command "/var/lib/shinken/libexec/tools/shinken-protected-fields-keyfile-rescue-from-backup" "<your backup directory>")\n"
    printf "\n"
    exit 1
else
    printf "$(show_success "DONE")\n\n"
fi

if [ -z "$key_file" ]; then
    key_file=/etc/shinken/secrets/protected_fields_key
fi

if grep -q 'protect_fields__activate_encryption=1' ${SYNCHRONIZER_CFG} ; then
    activated=1
else
    activated=0
fi

if [ -f "$key_file" ] ; then
    keyfile_present=1
else
    keyfile_present=0
fi

if [ ${activated} -eq 1 ] && [ ${keyfile_present} -eq 1 ] ; then
    printf "$(show_important_info "Encryption already enabled with the key named $(show_data "$(spf_get_key_name_from_db)" )")\n"
    printf "\n$(show_info "Nothing to do.")\n\n"
    printf "\n$(show_important_info "However if you want to encrypt your protected fields with a new key, please use the following command :")\n"
    printf "\n\t$(show_command shinken-protected-fields-keyfile-migrate "")\n\n"
    exit 1
fi

if [ $quiet -eq 0 ] ; then
    printf "$(show_info "You can review the list of Shinken properties which will be protected using the following command :")\n"
    printf "\n\t$(show_command shinken-protected-fields-data-manage "")\n\n"
    printf "$(show_info "You can remove or add substrings to that list and review which Shinken properties would become protected or unprotected")\n"
    printf "$(show_info "before committing using the following commands  or a combination :")\n"
    printf "\n\t$(show_command shinken-protected-fields-data-manage "--add substring1 --add substring2 ..." )\n"
    printf "\n\t$(show_command shinken-protected-fields-data-manage "--remove substring1 --remove substring2 ...")\n\n"
fi

if [ ${force_yes} -eq 0 ] ; then
    printf "\n\n\t$(show_question "Are you sure you want to proceed and enable encryption (if you answer negatively you can still re-run this command later) ?") (y/N) "
    read -n 1 answer

    if [ "$answer" != "y" ] && [ "$answer" != "Y" ] ; then
        printf "\n$(show_critical_info "Aborting field protections enabling")\n"
        exit 0
    fi
fi

printf "\n\n"

if ! grep -q 'protect_fields__encryption_keyfile' "$SYNCHRONIZER_CFG" ; then
    sed -i "/sync_history_lifespan=1440/a \
    \
#==================================================================================\n\
#=============== Protected fields security ====================\n\
                                                       # Encryption for protected fields\n\
protect_fields__activate_encryption=1\n\
                                                       # File containing the encryption key\n\
protect_fields__encryption_keyfile=$key_file\n\
                                                       # List of words contained in protected fields names\n\
                                                       # Default values : PASSWORD,PASSPHRASE,PASSE,DOMAINUSER,MSSQLUSER,MYSQLUSER,ORACLE_USER,SSH_USER,LOGIN\n\
protect_fields__substrings_matching_fields=PASSWORD,PASSPHRASE,PASSE,DOMAINUSER,MSSQLUSER,MYSQLUSER,ORACLE_USER,SSH_USER,LOGIN\n\
#==================================================================================\n\n\
    " "$SYNCHRONIZER_CFG"
    if [ $? -ne 0 ] ; then
        spf_show_error "Error while updating $SYNCHRONIZER_CFG"
        exit 1
     fi

else
    sed -i -e "s/protect_fields__activate_encryption=0/protect_fields__activate_encryption=1/" ${SYNCHRONIZER_CFG}
    sed -i -e "s/protect_fields__activate_database_encryption=0/protect_fields__activate_database_encryption=1/" ${SYNCHRONIZER_CFG}
    sed -i -e "s/protect_fields__activate_interface_encryption=0/protect_fields__activate_interface_encryption=1/" ${SYNCHRONIZER_CFG}
fi

if [ $keyfile_present -eq 0 ] ; then
    printf "$(show_info "In order to enable encryption, an secret key is required.")\n"
    printf "$(show_info "It will be generated now, but it can be changed at a later stage, assuming this one is still available.")\n\n"
    printf "$(show_info "This key must have a name in order to identify it easily if you have several of them.")\n"
    key_name=""
    while [ -z "$key_name" ]; do
        read -p "Enter your key name: " key_name
    done

    shinken-protected-fields-keyfile-generate -q -n "$key_name"
else
    if [ $quiet -eq 0 ] ; then
        printf "$(show_important_info "A key named $(spf_get_key_name_from_key_file ${key_file}) is already present. I will use it.")\n"
    fi
fi

printf "\n$(show_important_info "Enabling encryption with key named '$(show_data "$(spf_get_key_name_from_key_file ${key_file})")'...")\n\n"

if [ $is_started -eq 0 ] ; then
    printf "\n$(show_info "Now stopping the Synchronizer... ")"

    stop_output=$(service shinken-synchronizer stop)
    if [ $? -eq 0 ] ; then
        printf " $(show_success OK)\n"
    else
        printf "$(show_info "Synchronizer already stopped").\n"
    fi
fi

printf "\n$(show_success "Encryption enabled")\n\n"

if [ $is_started -eq 0 ] ; then
    printf "$(show_info "Now restarting the Synchronizer... ")"

    start_output=$(service shinken-synchronizer start)
    if [ $? -eq 0 ]; then
        printf " $(show_success OK)\n"
    else
        printf "${start_output}\n"
        spf_show_error "An error occurred while starting the synchronizer ; please check the synchronizer logs.\n"
        exit 1
    fi
else
    printf "$(show_action "You now need to start the Synchronizer for the encryption to take effect.")\n\n"
fi

key_name=$(spf_get_key_name_from_key_file "${key_file}")
printf "\n$(show_important_info "Your protected data is now encrypted, using the key generated with the key name you provided :") "
printf "$(show_data "$key_name")\n\n"
printf " $(show_info "* You now need to make a backup of your key using the following command command :")\n\n"
printf "      $(show_command shinken-protected-fields-keyfile-export "")\n\n"
printf " * NOTE : $(show_critical_info "If you lose your key, you won't be able to restore a backup and you will have to contact your support.")\n\n"
