#!/bin/bash

logfile=/var/log/changeSshPort.log
port=$1
OLD_SSH_PORT=22
BACK_DIR=/var/log/SshPortBackDir
LASTSSHPORT_F=${BACK_DIR}/last_ssh_port_file

function LOG()
{
    echo -E "[$(date '+%F %T')]$@" >>${logfile}
}

function echo_green()
{
    echo -e "\033[32m$1\033[m"
}

function echo_red()
{
    echo -e "\033[31m$1\033[m"
}

function usage()
{
    echo "Usage:"
    echo "    sh $0 [0--65535]"
    echo "Example:"
    echo "    sh $0 12345"

    return
}

# portֻܼ⵽ǰʹеĶ˿ںţЩס̿ܵõĶ˿ڣѯeulerûа취ȥȷ
# ִ޸Ķ˿ںsshdǰǳפˡҳðssh󶨵Ķ˿ڣôsshdʧܣִл˿ڰͺ
# sshd°˿Ƿǳפָ󶨶˿ڣôָû취ģֻ˵һһһֱҲôɵ
function check_para_and_backup()
{
    local port="${1}"
    local digit_port=""

    digit_port=$( echo "${port}" | egrep -o "[0-9]*" )
    if [ "X${port}" == "X" -o "X${port}" != "X${digit_port}" ]
    then
        LOG [${FUNCNAME}][${LINENO}] "[ERR]:input port para format error,it is not all digit number."
        echo_red "[ERR]:input para port:(${port}) format error,it is not all digit number."
        usage
        exit 1
    fi

    if [ ${port} -gt 65535 ]
    then
        LOG [${FUNCNAME}][${LINENO}] "[ERR]:input port:($port) number is greater than 65535."
        echo_red "[ERR]:input port:($port) number is greater than 65535."
        usage
        exit 1
    fi

    # ssh°˿ǷǰʹеĶ˿ں
    netstat -tulnp | awk '{print $4}' | grep ":${port}$" >/dev/null
    if [ $? -eq 0 ]
    then
        LOG [${FUNCNAME}][${LINENO}] "[ERR]:The input port($port) is being used by another process."
        echo_red "[ERR]:The input port($port) is being used by another process."
        usage
        exit 1
    fi

    # Գ޸ģĿ¼
    if [ ! -d "${BACK_DIR}" ]
    then
        mkdir -p ${BACK_DIR}
    fi

    return
}

function modify_sshd_config()
{
    local port="${1}"

    if [ ! -f "${BACK_DIR}/sshd_config" ]
    then
        cp /etc/ssh/sshd_config "${BACK_DIR}/sshd_config"
    fi

    # пͻֶ޸/etc/sshd_configһ֮ģܳݣټ˵㣬ֲֹһPort xx,ּС¼ֱӱ˳ɡ
    # #Port 22
    # Port 45678
    cnt=$( grep "^[ ]*Port [0-9]*" /etc/ssh/sshd_config | wc -l )
    if [ ${cnt} -ge 2 ]
    then
        LOG [${FUNCNAME}][${LINENO}] "[ERR]:there ara ${cnt} Port lines in /etc/ssh/sshd_config."
        echo_red "[ERR]:there ara ${cnt} Port lines in /etc/ssh/sshd_config."
        exit 1
    elif [ ${cnt} -eq 1 ]
    then
        sed -i "s/^[ ]*Port [ \t0-9]*$/Port ${port}/g" /etc/ssh/sshd_config
    
    else
        grep -q "^[ #]*Port [0-9]*" /etc/ssh/sshd_config
        if [ $? -eq 0 ]
        then
            # sshd_configļж#PortֻһУ
            firtline=$( grep -n "^[ #]*Port [0-9]*" /etc/ssh/sshd_config | head -1 | awk -F: '{print $1}' )
            sed -i "${firtline}s/^[ #]*Port [0-9]* *$/Port ${port}/g" /etc/ssh/sshd_config
        else
            echo "Port ${port}" >>/etc/ssh/sshd_config
        fi
    fi

    grep -q "Port ${port}" /etc/ssh/sshd_config
    if [ $? -ne 0 ]
    then
        LOG [${FUNCNAME}][${LINENO}] "[ERR]:input port:($port) number is greater than 65535."
        cp "${BACK_DIR}/sshd_config" /etc/ssh/sshd_config
        echo_red "[ERR]:input port:($port) number is greater than 65535."
        exit 1
    fi

    service sshd restart 2>/dev/null
    sleep 3
    service sshd status 2>/dev/null | grep -q running
    if [ $? -ne 0 ]
    then
        LOG [${FUNCNAME}][${LINENO}] "[ERR]:failed to restart sshd service."
        LOG "-------------------------------------BEGIN-------------------------------"
        service sshd status >>${logfile} 2>&1
        LOG "-------------------------------------END-------------------------------"
        echo_red "[ERR]:failed to restart sshd service."
        exit 1
    fi

    return
}

# иƣ;sed -iʧˣּС¼ֶֻBACK_DIRĿ¼аԭʼļȡ¸
function modify_firmwall()
{
    local port="${1}"
    local default_ssh_port=22
    local lastsshport=""

    if [ -f "${LASTSSHPORT_F}" -a -s "${LASTSSHPORT_F}" ]
    then
        lastsshport=$( cat ${LASTSSHPORT_F} | grep -o "[0-9]*" )
        if [ "X${lastsshport}" == "X" ]
        then
            LOG [${FUNCNAME}][${LINENO}] "[ERR]:the content:($(cat ${LASTSSHPORT_F})) in ${LASTSSHPORT_F} is error."
            lastsshport=${default_ssh_port}
        fi
    else
        lastsshport=${default_ssh_port}
    fi

    OLD_SSH_PORT=${lastsshport}
    if [ ! -f "${BACK_DIR}/deploy_set_firewall.py" ]
    then
        cp /opt/huawei/snas/script/deploy_set_firewall.py "${BACK_DIR}/deploy_set_firewall.py"
        cp /etc/tiny-firewall/* ${BACK_DIR}/
    fi

    cp /opt/huawei/snas/script/deploy_set_firewall.py /opt/huawei/snas/script/deploy_set_firewall.py.bak
    sed -i "s/ ${lastsshport} / $port /g" /opt/huawei/snas/script/deploy_set_firewall.py
    ret1=$?
    sed -i "s/\"${lastsshport} 8088/\"$port 8088/g" /opt/huawei/snas/script/deploy_set_firewall.py
    ret2=$?
    sed -i "s/,${lastsshport},/,$port,/g" /opt/huawei/snas/script/deploy_set_firewall.py
    ret3=$?
    sed -i "s/\"${lastsshport},8088/\"$port,8088/g" /opt/huawei/snas/script/deploy_set_firewall.py
    ret4=$?
    sed -i "s/9443,${lastsshport}\"/9443,$port\"/g" /opt/huawei/snas/script/deploy_set_firewall.py
    ret5=$?
    sed -i "s/dport=${lastsshport} /dport=$port /g" /opt/huawei/snas/script/deploy_set_firewall.py
    ret6=$?
    LOG [${FUNCNAME}][${LINENO}] "[INFO]:modify deploy_set_firewall.py result is:${ret1} ${ret2} ${ret3} ${ret4} ${ret5} ${ret6}."

    # ޸֮󣬼¼portں޸ġ˵ͻ޸ĳ4434434ٵִ4434ȷ޸
    echo "${port}" >${LASTSSHPORT_F}

    python /opt/huawei/snas/script/deploy_set_firewall.py >/dev/null 2>&1
    ret=$?
    if [ ${ret} -ne 0 ]
    then
        LOG [${FUNCNAME}][${LINENO}] "[ERR]:failed to excute python /opt/huawei/snas/script/deploy_set_firewall.py,ret:${ret}."
        echo_red "[ERR]:failed to excute python /opt/huawei/snas/script/deploy_set_firewall.py,ret:${ret}."
        exit 1
    fi

    return
}

function modify_ssh_scp_exp()
{
    local port="${1}"

    if [ ! -f "${BACK_DIR}/snas_ssh.exp" ]
    then
        cp /usr/local/bin/snas_ssh.exp "${BACK_DIR}/snas_ssh.exp"
    fi

    if [ ! -f "${BACK_DIR}/snas_scp.exp" ]
    then
        cp /usr/local/bin/snas_scp.exp "${BACK_DIR}/snas_scp.exp"
    fi

    grep -q "spawn ssh -p [0-9]*" /usr/local/bin/snas_ssh.exp
    if [ $? -eq 0 ]
    then
        sed -i "s/spawn ssh -p [0-9]*/spawn ssh -p $port/g" /usr/local/bin/snas_ssh.exp
    else
        sed -i "s/spawn ssh/spawn ssh -p $port/g" /usr/local/bin/snas_ssh.exp
    fi

    grep -q "spawn scp -P [0-9]*" /usr/local/bin/snas_scp.exp
    if [ $? -eq 0 ]
    then
        sed -i "s/spawn scp -P [0-9]*/spawn scp -P $port/g" /usr/local/bin/snas_scp.exp
    else
        sed -i "s/spawn scp/spawn scp -P $port/g" /usr/local/bin/snas_scp.exp
    fi

    return
}

port=$1

# ޸ĵssh˿Ƿ
check_para_and_backup $port

# ޸sshd½˿ļ/etc/ssh/sshd_configͬʱsshd
modify_sshd_config ${port}

# ޸/opt/huawei/snas/script/deploy_set_firewallɷǽļ
modify_firmwall ${port}

# ޸snas_ssh.expsnas_scp.expűе½˿
modify_ssh_scp_exp "${port}"

echo_green "Success to modify ssh login port from ${OLD_SSH_PORT} to ${port}."
LOG [${FUNCNAME}][${LINENO}] "Success to modify ssh login port from ${OLD_SSH_PORT} to ${port}."
