#!/bin/sh

# Prepare parameters
pkgtype="critical patch"
build=16950
serial=16950
service_pack=0
version="9.1"
PATCH1BUILD=1631

PS_CMD="ps -ef --width 1000"
product="InterScan(TM) Messaging Security Virtual Appliance (IMSVA)"
needReboot="0"

GREETING="Installing $product $version $pkgtype $serial"
IMSS_HOME="/opt/trend/imss"
WIDGET_PROXY_PATH="${IMSS_HOME}/UI/adminUI/ROOT/widget/repository/widgetPool/wp1/proxy"
WIDGET_CONF=${IMSS_HOME}/UI/php/conf/widget.conf
UpdateKernelDependency="kernel-firmware-2.6.32-696.18.7.el6.noarch.rpm"
UpdateKernel="kernel-2.6.32-696.18.7.el6.x86_64.rpm"

CheckInstalledIMSVA()
{
    IMSVAExist="0"
    rpm -q imsva > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
      IMSVAExist="1"
    fi
    master_ip=`grep master_ip= /opt/trend/imss/config/slave.nfo | awk -F '=' '{print $2}'`
    if [ "$master_ip" == "" ] ; then
      IsParent="1"
    fi
}

inst_dir=""
inst_version=""
GetInstallPath()
{   
    if [ "$IMSVAExist" = "1" ]; then
      rpm_check_name="imsva"
    fi
    
    if [ "$rpm_check_name" != "" ]; then
      inst_dir="/opt/trend/imss"
      inst_version=`rpm -q -i $rpm_check_name | grep Version | awk '{ print $3}'`
    fi
    
    if [ "$inst_version" != "$version" ] ; then
      echo "$product $version was not found."
      echo "Installation cancelled. No changes were made to your system."
      exit 1
    fi
}

# install/rollback check
PRE_CHECK()
{
  echo "===== Checking system condition ====="
  # if backup dir exist means the cp has already been installed
  if [ "$pkgtype" = "critical patch" ]; then
     if [ ! -d $back_dir ]; then
        # the cp hasn't installed, but if the latest hf build number is greater than cp, there is no need to install this cp
        if [ $build -le $exist_hf ]; then
          echo "Your system has already installed the solution in this $pkgtype.  There is no need to install this $pkgtype."
          echo "Installation cancelled. No changes were made to your system."
          echo
          exit 0
        #the cp hasn't installed, and the latest hf build number is not greater than cp, it should be installed.
        else    	
            #_found_require=0
            #_applied_patches=`grep "Applied=" $IMSS_HOME/patch/patch.ini| awk -F= '{ printf $2 }'`
            #for j in $_applied_patches
            #do
            #    if [ "$PATCH1BUILD" = "$j" ] ; then
            #        _found_require=1
            #    fi
            #done
            #if [ "$_found_require" = "0" ] ; then
            #    echo "Please install IMSVA 9.1 Patch 1 first"
            # 	exit 0               
            #fi
          echo "Start installing ..."
          is_install=1
       fi
     else
     # the cp has installed.
        if [ $exist_hf -ge $build ]; then
           echo "The current hot fix $exist_hf is more recent than this $pkgtype."
           echo "Rollback cancelled. No changes were made to your system."
           echo
           exit 0
        else           
           echo "All the files in this package are up to date."
           is_rollback=1
        fi
     fi
  fi
}

StopServices()
{
  echo
  echo "===== stop imsva services ====="
  ${inst_dir}/script/imssctl.sh stop 
}

StartServices()
{
  echo
  echo "===== start imsva services ====="
  ${inst_dir}/script/imssctl.sh start
}

# Backup
# need modified.
BACKUP()
{
  local local_dir
  local local_file  
  echo 
  echo "===== backing up ====="  
  mkdir -p $back_dir
  echo "Backing up changed files to $back_dir"
  for file in `find . -type f ! \( -name "imssinst" -o -name "EULA.txt" -o -name '*.rpm' \)`
  do
    local_dir=`dirname $file`
    local_dir=${local_dir#./}
    local_file=`basename $file`
    [ ! -d $back_dir/$local_dir ] && mkdir -p $back_dir/$local_dir
    cp -pf $inst_dir/$file $back_dir/$local_dir
  done
  #cp -pf $WIDGET_CONF $back_dir/
  
}


# Replace
# need modified.
REPLACE()
{
  local local_dir
  local local_file
  echo 
  echo "===== replacing files ====="  
  fcount=0
  for file in `find . -type f ! \( -name "imssinst" -o -name "EULA.txt" -o -name '*.rpm' \)`
  do
    local_dir=`dirname $file`
    local_dir=${local_dir#./}
    local_file=`basename $file`
    echo "copy $local_file ---> $inst_dir/$local_dir"
    cp -fp $file $inst_dir/$local_dir
    fcount=$(( $fcount + 1 ))
  done
  echo "$fcount files copied"
}

# Change Settings ( ini, pni )
CH_SETTING()
{
  echo 
  echo "===== updating configure files ====="  
  
  
  # update ini setting  
  if [ "$pkgtype" = "critical patch" ] ; then
     if [ $is_install = "1" ]; then
        echo "Recording ${build} to $cp_ini_file"
        echo "${build}" >> $cp_ini_file
     fi
     if [ $is_rollback = "1" ]; then        
        echo "Removing ${build} from cphistory"
        cp_ini_bak=$inst_dir/patch/cphistory.bak
        cat $cp_ini_file |grep -v "${build}" > $cp_ini_bak
        mv -f $cp_ini_bak $cp_ini_file
     fi
  fi
  
}
RemoveUnusedFile()
{
   if [ -d ${WIDGET_PROXY_PATH}/modSimple ];then
       rm -rf ${WIDGET_PROXY_PATH}/modSimple
   fi
   if [ -d ${WIDGET_PROXY_PATH}/modTMCSS ];then
       rm -rf ${WIDGET_PROXY_PATH}/modTMCSS
   fi
   if [ -d ${WIDGET_PROXY_PATH}/modTMSPLX ];then
       rm -rf ${WIDGET_PROXY_PATH}/modTMSPLX
   fi
   if [ -d ${WIDGET_PROXY_PATH}/modZMultiple ];then
       rm -rf ${WIDGET_PROXY_PATH}/modZMultiple
   fi
   if [ -f ${IMSS_HOME}/UI/adminUI/ROOT/widget/repository/log/diagnostic.log ]; then
      rm -rf ${IMSS_HOME}/UI/adminUI/ROOT/widget/repository/log/diagnostic.log
   fi
}
APPLYSPECIALSETTING()
{
    #VRTS-1289 
    grep "/widget/repository/log/"  $WIDGET_CONF
    if [ $? -eq 1 ]; then
        echo " " >> $WIDGET_CONF
        echo "#Block access from UI" >>$WIDGET_CONF
        grep "^\s*LoadModule\sauthz_host_modul.*modules\/mod_authz_host.so"  $WIDGET_CONF
        if [ $? -eq 1 ];then
            echo "LoadModule authz_host_module modules/mod_authz_host.so" >>$WIDGET_CONF
        fi
        echo "<Directory  ~ \"/widget/repository/log/\">"  >>$WIDGET_CONF
        echo "    Order allow,deny" >>$WIDGET_CONF
        echo "    Deny from all"    >>$WIDGET_CONF
        echo "</Directory>"  >>$WIDGET_CONF
    else
         echo "NO need to update ${WIDGET_CONF}"
    fi
}

INSTALLKERNEL()
{
    #kernel                                       
	fixed=` rpm -qi kernel  --changelog  |grep -i CVE-2017-5754 |grep -v grep|wc -l`
    if [ $fixed -eq 0 ];then
        #mkdir -p $back_dir
        echo " Checking packages"
        rpm -K --nosignature  ${UpdateKernel}  
        if [ $? -eq 0 ]; then
            rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
            rpm -Uvh ${UpdateKernelDependency}
            rpm -ivh ${UpdateKernel}
            if  [ $? -eq 0 ];then
                echo "Updating for kernel succeed."
                needReboot=1
            fi
        else
             echo "Installation packages corrupted,Installation failed." 
        fi 
    else
       echo "Current kernel version has already fixed the CVE, No need to upgrade"
    fi
}
# Install
INSTALL()
{
   #StopServices
   BACKUP
   #REPLACE
   INSTALLKERNEL
   #APPLYSPECIALSETTING
   #RemoveUnusedFile
   CH_SETTING
   # for jsp
   rm -rf ${IMSS_HOME}/UI/adminUI/ROOT/work/*
   StartServices
   echo
   if [ "$needReboot" = "1" ];then
       echo "Installation is complete. The system must be rebooted for this update to take effect."
       echo 
   fi 
   exit 0
}

ROLLBACK()
{
   echo "Please select the option to boot from the old kernel"
   exit 0
   local local_dir
   local local_file
   echo
   echo "===== rolling back ====="
   StopServices
   fcount=0
   for file in `find . -type f ! \( -name "imssinst" -o -name "EULA.txt" -o -name '*.rpm' \)`
   do
     local_dir=`dirname $file`
     local_dir=${local_dir#./}
     local_file=`basename $file`
     echo "Rolling back $local_file"
     cp -pf $back_dir/$file $inst_dir/$local_dir
     fcount=$(( $fcount + 1 ))
   done
   #VRTS-1289
   cp -pf  $back_dir/widget.conf  $WIDGET_CONF
   echo "$fcount files rolled back"  
   CH_SETTING    
   rm -rf $back_dir
   # for jsp
   rm -rf ${IMSS_HOME}/UI/adminUI/ROOT/work/*
   StartServices
   echo
   echo "Rollback is complete and related services are started." 
   exit 0
}
GET_HFNUM()
{
    exist_hf=""
    [ ! -d ${inst_dir}/patch -o ! -f ${inst_dir}/patch/patch.ini ] && exist_hf="0" && return 0
    exist_hf=`cat ${inst_dir}/patch/patch.ini |grep BuildNum|tail -1`
    exist_hf=${exist_hf##*.}"0"
    return 0
}


############### MAIN ##############
umask 22
# require root permission
id | grep root > /dev/null 2>&1
if [ $? -ne 0 ] ; then
  echo "Please log on as a superuser (root) to run this script."
  exit 1
fi

# remember current directory
curr_dir=`pwd`
if [ ! -f $curr_dir/imssinst ]; then
   echo "Files required by the $pkgtype were not found. Installation exits."
   echo "Please go to the folder where $pkgtype files were extracted and run \"./imssinst\"."
   exit 1
fi
export curr_dir

CheckInstalledIMSVA
if [ "$IMSVAExist" = "0" ]; then
   echo "$product $version was not found."
   echo "Installation cancelled. No changes were made to your system."
   exit 1
fi

echo $GREETING
echo

# check scheduled update
$PS_CMD | grep imssausched | grep -v grep > /dev/null
if [ $? = 0 ]; then
   echo "Scheduled update is in progress. Please wait until it is finished."
   echo "Installation exits."
   exit 1
fi

# Check if installation path is correct
GetInstallPath

# Set up backup directory
back_dir=${inst_dir}/patch
if [ "$pkgtype" = "hotfix" ] ; then
  back_dir=${back_dir}/Hotfix_B${build}
elif [ "$pkgtype" = "patch" ] ; then
  back_dir=${back_dir}/Patch${serial}_B${build}
elif [ "$pkgtype" = "sp" ] ; then
  back_dir=${back_dir}/SP${serial}_B${build}
elif [ "$pkgtype" = "critical patch" ] ; then
  back_dir=${back_dir}/CP_B${build}
fi

# Get the lastest hf number
GET_HFNUM

cp_ini_file=${inst_dir}/patch/cphistory

# Check install/rollback precondition
is_install=0
is_rollback=0

PRE_CHECK

if [ $is_install -eq "1" ]; then
   INSTALL
fi

if [ $is_rollback -eq "1" ]; then
   ans="n"
   echo "Do you want to roll back $pkgtype $serial? [y/n]"
   read ans
   if [ "$ans" = "y" -o "$ans" = "Y" ]; then
      ROLLBACK
   fi     
fi

exit 0
