#!/bin/bash
set +x
source /opt/product/snas/script/inspect_mml/CheckItems

CurInspectNum="274"
CurInspectFun=`GetInspectType $CurInspectNum`
RESULTFILE="${G_TMP_INSPECT_PATH}tmpResult${CurInspectFun}"
>$RESULTFILE

isPass=0
AllNodeNeedPemList="/opt/product/snas/etc/sslcert.pem /opt/product/snas/etc/sslca.cer /opt/product/deploy/etc/Equipment_Root_CA.der /opt/product/deploy/etc/IT_Product_CA.cer /etc/softcert/HuaweiRootCA.der /opt/product/deploy/etc/cluster_ca.cer /opt/product/deploy/etc/cluster_cert.pem /opt/product/deploy/etc/toolkit_dep_ca.cer /opt/Runtime/tomcat7/conf/server.pem /opt/Runtime/tomcat7/conf/server.cer"
MayBeNonexistPemlist="/etc/ssl/private/server_cert.pem /opt/product/snas/etc/cert/alarm/cacert.pem /opt/product/snas/etc/cert/password/cacert.pem /opt/product/snas/etc/cert/emui/cacert.pem /etc/rsyslog-key/client_cert.pem /etc/rsyslog-key/ca.pem /opt/deviceManager/apache/conf/ca.crt"
viidPemList="/opt/product/viid/config/server/server.pem /opt/product/viid/config/server/server.cer"
DomainZeroPemList="/opt/product/deploy/etc/toolkit_dep_cert.pem /opt/deviceManager/apache/conf/cert_en.pem"
DominkeyStorelist="/opt/Runtime/tomcat7/cert/ToolKitDeploy.keystore /opt/Runtime/tomcat7/cert/IT_CA.keystore /opt/Runtime/tomcat7/conf/server.keystore" 
S3keyStorelist="/opt/obs/service/osc/etc/keystore /opt/obs/service/poe/etc/keystore /opt/obs/service/dcm/etc/keystore"
S3PemList="/var/uds/user/data_upf/server.crt"

#NoReplaceCertiList="/opt/product/deploy/etc/Equipment_Root_CA.der /opt/product/deploy/etc/IT_Product_CA.cer /etc/softcert/HuaweiRootCA.der /opt/product/deploy/etc/cluster_ca.cer /opt/product/deploy/etc/cluster_cert.pem /opt/product/deploy/etc/toolkit_dep_cert.pem /opt/deviceManager/apache/conf/cert_en.pem /opt/Runtime/tomcat7/cert/IT_CA.keystore"

#判断节点是否是UDS/S3节点,是的话,返回0,不是,返回1
function CheckNodeServiceType()
{
    local cfgfile="/opt/product/snas/etc/snas.ini"
    local UDS_Type="80"
    local DFS_Type="48"
    local DFS_ServiceType="1"
    if [ ! -f ${cfgfile} ];then
        echo "[ERR]INFO:The file ${cfgfile} does not exist.Cannot tell if the node belongs to the 0 subdomain." >>$RESULTFILE 2>&1
        echo "NULL"
        return
    fi
    local ProductType=$( grep productType ${cfgfile} |awk -F= '{print $2}' )
    if [ "X" == "X${ProductType}" ];then
        echo "[ERR]INFO:Get ProductType from ${cfgfile} failed." >>$RESULTFILE 2>&1
        echo "NULL"
        return
    fi
    if [ "X${UDS_Type}" == "X${ProductType}" ];then
        echo 0
        return
    fi
    if [ "X${DFS_Type}" == "X${ProductType}" ];then
        local nodeServiceType=$( grep node_service_type ${cfgfile} | awk -F"=" '{print $2}' )
        if [ "X" == "X${nodeServiceType}" ];then
            echo "[ERR]INFO:Get nodeServiceType from ${cfgfile} failed." >>$RESULTFILE 2>&1
            echo "NULL"
            return
        fi
        if [ "X${DFS_ServiceType}" != "X${nodeServiceType}" ];then
            echo 0
            return
        fi
    fi

   echo 1
}

function GetDomain()
{
    local cfgfile="/opt/product/snas/etc/cm.ini"
    if [ ! -f ${cfgfile} ];then
        echo "[ERR]INFO:The file ${cfgfile} does not exist.Cannot tell if the node belongs to the 0 subdomain" >>$RESULTFILE 2>&1
        echo "NULL"
        return
    fi
    local SubDomain=$( grep SubDomain ${cfgfile} | awk -F"=" '{print $2}' )
    if [ "X" == "X${SubDomain}" ];then
        echo "[ERR]INFO:Get  SubDomain from ${cfgfile} failed." >>$RESULTFILE 2>&1
        echo "NULL"
        return
    fi
    echo "${SubDomain}"
}

# 有些证书需要申请或者需要某些特性才能使用
function getMayBeNonexistPem()
{
    local iRet=""
    local iRet1=""
    local DeadLine=""
    local SHAkey=""

    for item in ${MayBeNonexistPemlist}
    do
        if [ ! -f ${item} ];then
            # 直接不用管。退出即可
            continue
        fi
        DeadLine=$( openssl x509 -enddate -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet=$?
        if [ 0 -ne ${iRet} ];then
             DeadLine="NA"
             echo "[ERR]INFO:Get ${item} deadline failed"  >>$RESULTFILE 2>&1
             continue
        fi
        if [ "X" == "X${DeadLine}" ];then
            DeadLine="NA"
            continue
        fi
        SHAkey=$( openssl x509 -fingerprint -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet1=$?
        if [ 0 -ne ${iRet1} ];then
            SHAkey="NA"
            continue
        fi
        if [ "X" == "X${SHAkey}" ];then
            SHAkey="NA"
            continue
        fi
        echo "name=${item};DeadLine=${DeadLine};Key=${SHAkey}"
    done

    # 针对viid视频语义这个特性，如果部署时候没有开启，后续就不会再开启咯
    viidSwitch=$( cat /opt/huawei/snas/etc/snas.ini |tr \\n ] |grep -Po '(?<=[[]'SERVICE'[]]).*' |tr ] \\n |grep -Po '(?<=^'viid'=).*' |awk 'NR==1{print}' )
    if [ X"${viidSwitch}" != X"1" ]; then
        LOG "[$FUNCNAME][$LINENO]viid is not in use.no need to check viid certificate."
        return
    fi

    for item in ${viidPemList}
    do
        if [ ! -f ${item} ];then
            # 直接不用管。退出即可
            continue
        fi
        DeadLine=$( openssl x509 -enddate -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet=$?
        if [ 0 -ne ${iRet} ];then
             DeadLine="NA"
             echo "[ERR]INFO:Get ${item} deadline failed"  >>$RESULTFILE 2>&1
             continue
        fi
        if [ "X" == "X${DeadLine}" ];then
            DeadLine="NA"
            continue
        fi
        SHAkey=$( openssl x509 -fingerprint -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet1=$?
        if [ 0 -ne ${iRet1} ];then
            SHAkey="NA"
            continue
        fi
        if [ "X" == "X${SHAkey}" ];then
            SHAkey="NA"
            continue
        fi
        echo "name=${item};DeadLine=${DeadLine};Key=${SHAkey}"
    done

    return
}

#所有类型节点都需要而且都存在的证书
function getALLPem()
{
    local iRet=""
    local iRet1=""

    for item in ${AllNodeNeedPemList}
    do
        if [ ! -f ${item} ];then
            echo "name=${item};DeadLine=NA;Key=NA"
            continue
        fi
        local DeadLine=$( openssl x509 -enddate -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet=$?
        if [ 0 -ne ${iRet} ];then
             DeadLine="NA"
             echo "[ERR]INFO:Get ${item} deadline failed"  >>$RESULTFILE 2>&1
             continue
        fi
        if [ "X" == "X${DeadLine}" ];then
            DeadLine="NA"
            continue
        fi
        local SHAkey=$( openssl x509 -fingerprint -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet1=$?
        if [ 0 -ne ${iRet1} ];then
            SHAkey="NA"
            continue
        fi
        if [ "X" == "X${SHAkey}" ];then
            SHAkey="NA"
            continue
        fi
        echo "name=${item};DeadLine=${DeadLine};Key=${SHAkey}"
    done

}
#所有类型节点都需要检查的证书
function getS3Pem()
{
    local iRet=""
    local iRet1=""

    for item in ${S3PemList}
    do
        if [ ! -f ${item} ];then
            echo "name=${item};DeadLine=NA;Key=NA"
            continue
        fi
        local DeadLine=$( openssl x509 -enddate -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet=$?
        if [ 0 -ne ${iRet} ];then
             DeadLine="NA"
             echo "get ${item} deadline failed"
             continue
        fi
        if [ "X" == "X${DeadLine}" ];then
            DeadLine="NA"
            continue
        fi
        local SHAkey=$( openssl x509 -fingerprint -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet1=$?
        if [ 0 -ne ${iRet1} ];then
            SHAkey="NA"
            continue
        fi
        if [ "X" == "X${SHAkey}" ];then
            SHAkey="NA"
            continue
        fi
        echo "name=${item};DeadLine=${DeadLine};Key=${SHAkey}"
    done

}

#只需要检查0号子域的证书
function getZeroPemCerti()
{

    local iRet=""
    local iRet1=""

    for item in ${DomainZeroPemList}
    do

        if [ ! -f ${item} ];then
            echo "name=${item};DeadLine=NA;Key=NA"
            continue
        fi
        local DeadLine=$( openssl x509 -enddate -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet=$?
        if [ 0 -ne ${iRet} ];then
             DeadLine="NA"
            continue
        fi
        if [ "X" == "X${DeadLine}" ];then
            DeadLine="NA"
            continue
        fi
        local SHAkey=$( openssl x509 -fingerprint -noout -in ${item} | awk -F"=" '{print $2}' )
        iRet1=$?
        if [ 0 -ne ${iRet1} ];then
             SHAkey="NA"
            continue
        fi
        if [ "X" == "X${SHAkey}" ];then
            SHAkey="NA"
            continue
        fi
        echo "name=${item};DeadLine=${DeadLine};Key=${SHAkey}"
    done

}

function getTimeZoneDiffSeconds()
{
    local timeSeconds=$1
    local curTimeZone="$(date +%z)"
    local curTimeZoneSign="${curTimeZone:0:1}"
    local curTimeZoneHour="${curTimeZone:1:2}"
    local curTimeZoneMin="${curTimeZone:3:2}"
    local diffSeconds=$(echo "${curTimeZoneHour} * 3600 + ${curTimeZoneMin} * 60" | bc)
    if [ "X${curTimeZoneSign}" == "X+" ];then
        timeSeconds=$(($timeSeconds - $diffSeconds))
    else
        timeSeconds=$(($timeSeconds + $diffSeconds))
    fi
    echo "${timeSeconds}"
}

#检查证书是否过期,证书是否替换
function CheckCertificate()
{
    local CertiInfo=$@
    local ExpirTime="15552000" #180*24*60*60  过期时间小于等于180天巡检不通过
    local willExpirtTime="31536000" #365*24*60*60 过期时间小于365天，大于180天，巡检建议优化
    local DeadLine=""
    local CertiTime=""
    local tmpDeadline=""
    local IsSoonOutTime="NO"

    local CerName=$( echo ${CertiInfo} | awk -F";" '{print $1}' | awk -F"=" '{print $2}' )
    local Deadline=$( echo ${CertiInfo} | awk -F";" '{print $2}' | awk -F"=" '{print $2}' )
    local SHAkey=$( echo ${CertiInfo} | awk -F";" '{print $3}' | awk -F"=" '{print $2}' )

    #check expiration time
    if [ "XNA" == "X${Deadline}" ];then
        DeadLine="NA"
        IsSoonOutTime="NA"
    else

        CertiTime=$( date -d "${Deadline}" +%s 2>/dev/null )
        if [ $? -ne 0 ];then
            #LOG "Get Seconds Fail! Time para is ${filedate}"
            local zt=$(echo "$Deadline" | awk '{for(i=1; i<=NF; i++) if($i~/^[A-Z]+$/) print $i}')
            if [[ "${zt}" != "" ]] && [[ "${zt}" != " " ]];then
                tmpDeadline=$(echo "$Deadline" | sed "s/${zt}/UTC/g")
                CertiTime="$( date -u -d "${tmpDeadline}" +%s 2>/dev/null )"
                CertiTime=$(getTimeZoneDiffSeconds ${CertiTime})
            fi
        fi
        if [[ "${CertiTime}" == "" ]];then
            echo "[ERR]INFO:Failed to calculate the validity period (${Deadline}) of certificate ${CerName}." >>$RESULTFILE 2>&1
            IsSoonOutTime="--"
            isPass=1
        else
            local passtime=`expr $CertiTime - $curtime`
            if [ $passtime -le ${ExpirTime} ];then   #180*24*60*60  过期时间小于等于180天巡检不通过
                echo "[ERR]INFO:The Certificate ${CerName} valid time(${passtime}s) is less than 180 days(15552000s)." >>$RESULTFILE 2>&1
                IsSoonOutTime="YES"
                isPass=1
            elif [ $passtime -le ${willExpirtTime} ];then   #365*24*60*60 过期时间小于365天，大于180天，巡检建议优化
                echo "[ERR]INFO:The Certificate ${CerName} valid time(${passtime}s) is less than 365 days(31536000)." >>$RESULTFILE 2>&1
                IsSoonOutTime="YES"
                isPass=4
            fi
        fi
    fi

    echo "CerName:${CerName}||IsSoonOutTime:${IsSoonOutTime}||ExpirationTime:${Deadline}||key:${SHAkey}" >>$RESULTFILE 2>&1
}

function CheckAllCertificate()
{
    local subDomain=$( GetDomain )
    local productversion=$( grep "ProductVersion" /opt/product/deploy/package/version | awk -F"=" '{print $2}')
    local IS_S3=$( CheckNodeServiceType )
    local curtime="$( date +%s )"

    #检查节点必然存在证书信息
    local AllCheckPem=$( getALLPem )
    set_ifs
    for Certi in ${AllCheckPem}
    do
        CheckCertificate ${Certi}
    done
    restore_ifs

    #检查节点可能存在证书信息
    local MayBeNonexistPemList=$( getMayBeNonexistPem )
    set_ifs
    for Certi in ${MayBeNonexistPemList}
    do
        CheckCertificate ${Certi}
    done
    restore_ifs

    #检查S3/UDS特有证书信息
    if [ "0" == "${IS_S3}" ];then
       local S3CheckPem=$( getS3Pem )
        set_ifs
        for Certi in ${S3CheckPem}
        do
            CheckCertificate ${Certi}
        done
        restore_ifs
    
        #检查keystore类证书信息
        local S3keyStoreCerti=$( /opt/product/snas/script/inspect_mml/KeyStoreGet "${S3keyStorelist}" )
        set_ifs
        for Certi in ${S3keyStoreCerti}
        do
            CheckCertificate ${Certi}
        done
        restore_ifs
    fi

    #检查0号子域生效证书信息
    if [ "X0" == "X${subDomain}" ];then
        local ZeroPem=$( getZeroPemCerti )
        set_ifs
        for Certi in ${ZeroPem}
        do
            CheckCertificate ${Certi}
        done
        restore_ifs
    
        local DominkeyStoreCerti=$( /opt/product/snas/script/inspect_mml/KeyStoreGet "${DominkeyStorelist}" )
        set_ifs
        for Certi in ${DominkeyStoreCerti}
        do
            CheckCertificate ${Certi}
        done
        restore_ifs
    fi
    
    #打印是否巡检通过
    echo "${CurInspectFun}_Pass $isPass" >>$RESULTFILE
    LOG "${CurInspectFun}_Pass $isPass"

}

CheckAllCertificate

