#!/bin/bash

# Copyright 2015 Jelastic, Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.



DESCRIPTION="Firewall module";
VERSION="1.1";
DEFAULT_ACTION="Usage";

inherit tests os envinfo log net config vzexec virtuozzo
include cartridge-common;

$PROGRAM 'iptables'
$PROGRAM 'ip6tables'
$PROGRAM 'find';
$PROGRAM 'xargs';
$PROGRAM 'netstat';
$PROGRAM 'rpcinfo'
$PROGRAM 'ip';
$PROGRAM 'sort';
$PROGRAM 'sed';
$PROGRAM 'grep';
$PROGRAM 'awk';
$PROGRAM 'iptables-restore';
$PROGRAM 'ip6tables-restore'
$PROGRAM 'vzctl'

SAVEFILE='/var/lib/jelastic/firewall'
CUSTOM_RULES_FILE='/etc/sysconfig/iptables-custom'
CUSTOM_6RULES_FILE='/etc/sysconfig/ip6tables-custom'
JELASTIC_RULES_DIR='/etc/sysconfig'
JELASTIC_4RULES_FILE=${JELASTIC_RULES_DIR}'/iptables4-jelastic'
JELASTIC_4NATRULES_FILE=${JELASTIC_RULES_DIR}'/iptables4-jelastic-nat'
JELASTIC_6RULES_FILE=${JELASTIC_RULES_DIR}'/iptables6-jelastic'
JELASTIC_6NATRULES_FILE=${JELASTIC_RULES_DIR}'/iptables6-jelastic-nat'

declare PublicIP;
declare FTPPort;
declare RSLV_ADDR;
declare CORE_ADDR;
declare APP_ADDR;
declare DB_ADDR;
declare -a OPENPORTS;
declare -a CLOSEDPORTS;

declare -r ERR_NO_METADATA=4080;
CTID=0

function _getbalancerRedirPorts() { return 0; }
function _getapache_phpRedirPorts { return 0; }
function _getnginx_phpRedirPorts { return 0; }
function _getmavenRedirPorts { return 0; }
function _getnginx_rubyRedirPorts { return 0; }

function _getcartridgePorts() {
    #restoreEnvironmentVariables;
    echo $($SED -re 's/"//g'  <<<  $($SED -re 's/Private_Port=//g' <<< $(cat $MANIFEST_EXPORTED | $GREP "Private_Port=" ))| sort -u) ${FTPPort};
    return 0;
}

function _getcartridgeRedirPorts () {
    echo "PREROUTING:0.0.0.0/0:0.0.0.0/0:80:8080:REDIRECT";
    return 0;
}

function _getglassfishRedirPorts () {
    echo "PREROUTING:0.0.0.0/0:0.0.0.0/0:80:28080:REDIRECT PREROUTING:0.0.0.0/0:0.0.0.0/0:443:8743:REDIRECT OUTPUT:0.0.0.0/0:127.0.0.0/8:80:28080:REDIRECT";
    return 0;
}

function _defaultComputeNodeRedirPorts () {
    return 0;
}

function _computeRedirPorts () {
    echo "PREROUTING:0.0.0.0/0:0.0.0.0/0:80:8080:REDIRECT PREROUTING:0.0.0.0/0:0.0.0.0/0:443:8743:REDIRECT OUTPUT:0.0.0.0/0:127.0.0.0/8:80:8080:REDIRECT";
    return 0;
}

function _getjettyRedirPorts () {
    echo "PREROUTING:0.0.0.0/0:0.0.0.0/0:80:8080:REDIRECT PREROUTING:0.0.0.0/0:0.0.0.0/0:443:8743:REDIRECT OUTPUT:0.0.0.0/0:127.0.0.0/8:80:8080:REDIRECT";
    return 0;
}

function _getapache_rubyRedirPorts() { return 0; }
function _getcouchdbRedirPorts() { return 0; }
function _getmysqlRedirPorts() { return 0; }
function _getmariadbRedirPorts() { return 0; }
function _getmongodbRedirPorts() { return 0; }
function _getpostgresRedirPorts() { return 0; }

function _isPublicIPv4() {
    getAddr "venet0" "ipv4"
    [[ "${#ipv4_list[@]}" -ne 0 ]] && {
        for ip in ${ipv4_list[@]} ; do
            [[ "${ip}" == "127.0.0.1" ]] && continue;
            isLANIP "$ip" || return 0;
        done;
    }
    return 1;
}


function __getAllIPs() {
    echo $($IP a l | $SED -rne '/inet/{s/.*inet6.* //;s/\/.*//;s/peer.*//;s/in.*\s+(.*)/\1/; /(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/p}' | sort -u | $SED -re ':a;N;$!ba;s/\n/ /g;');
}

function getLANIPs() {
    local IPS=$(__getAllIPs);
    local res=();
    for ip in ${IPS[@]} ; do
        [[ "${ip}" == "127.0.0.1" ]] && continue;
        isLANIP "${ip}" && res=(${res} ${ip});
    done;
    echo "${res[@]}";
}

function isRange() {
    : ${1:?"Missing param: Port to test"};
    $GREP -qP "[-|:]" <<< $1;
    return $?;
}

function _setDefaultPolicy() {
    local policy=${1:-"DROP"}
    $IPTABLES -P INPUT ${policy}
    $IPTABLES -P FORWARD ${policy}
    $IPTABLES -P OUTPUT ACCEPT

    $IP6TABLES -P INPUT ${policy}
    $IP6TABLES -P FORWARD ${policy}
    $IP6TABLES -P OUTPUT ACCEPT
}

function checkRule() {
    chainName=$1
    rule=$2
    $IPTABLES -C $chainName $rule 1>/dev/null 2>&1
}

function processRule4File() {
    [ -f "$1" ] || return 0
    echo "CUSTOM RULES FILE $1 CONTENT"  >> $JEM_CALLS_LOG
    cat "$1" >> $JEM_CALLS_LOG
    $IPTABLES_RESTORE -n < "$1" 2>>$ACTIONS_LOG
    return $?
}

function processRule6File() {
    [ -f "$1" ] || return 0
    echo "CUSTOM RULES FILE $1 CONTENT "  >> $JEM_CALLS_LOG
    cat "$1" >> $JEM_CALLS_LOG
    $IP6TABLES_RESTORE -n < "$1" 2>>$ACTIONS_LOG
    return $?
}

function doUsage() {
    showUsageMessage
}

function onModLoadCallback() {
    log "Preload callback";
    local __closedports __openports

    #load ports lists from storage
    OPENPORTS=($(loadConfig "${SAVEFILE}" OPENPORTS))
    CLOSEDPORTS=($(loadConfig "${SAVEFILE}" CLOSEDPORTS))

    _isPublicIPv4 && PublicIP=$__TRUE || publicIP=$__FALSE;
    FTPPort=$($NETSTAT -tnlp | $SED -n -re '/ftp/{s/((\S+)\s+){3}(\S+)\s+((\S+)\s+)+/\3/;s/[^:]+:([0-9]+)/\1/;s/://g;p}');
    NFSPort=$($RPCINFO -p 2>/dev/null | $SED -n -re '/nfs/{s/\s+(\S+\s+)+([0-9]+)\s+nfs.*/\2/g;p}' | uniq | $SED -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' | $SED -e 's/ /,/g' )
    RPCPort=$($RPCINFO -p 2>/dev/null | $SED -n -re '/(portmapper|nlockmgr|mountd)/{s/\s+(\S+\s+)+([0-9]+)\s+.*/\2/g;p}' | uniq | $SED -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' | $SED -e 's/ /,/g' )

    ## TODO: remove "params" garbarge option
    local temp=`getopt -l ctid:,rules:,cp:,op:,rp: -- params "$@" 2>/dev/null` oldifs;
    [[ $? != 0 ]] && die -q "Terminating...";
    eval set -- "$temp";

    while true ; do
        case "$1" in
            --cp)
                # ports to close
                [[ ! -z "$2" && -z "$($SED -rne '/[0-9]+/p' <<< $2)" ]] && { shift 1; break; }
                oldifs=$IFS;
                IFS=',';
                __closedports=(${2});
                IFS=${oldifs};
                shift 2;
                ;;
            --op)
                # ports to open
                [[ ! -z "$2" && -z "$($SED -rne '/[0-9]+/p' <<< $2)" ]] && { shift 1; break; }
                oldifs=$IFS;
                IFS=',';
                __openports=(${2});
                IFS=${oldifs};
                shift 2;
                ;;
            --rp)
                # ports to remove from open ports list
                [[ ! -z "$2" && -z "$($SED -rne '/[0-9]+/p' <<< $2)" ]] && { shift 1; break; }
                oldifs=$IFS;
                IFS=',';
                __removeports=(${2});
                IFS=${oldifs};
                shift 2;

                for i in "${__removeports[@]}" ; do
                    # remove the port to remove from stored list of open ports
                    OPENPORTS=($(removeValueFromArray "${OPENPORTS[*]}" "${i}"));
                done

                ;;
            --ctid)
                shift
                CTID=$1
                vzexecSetCTID $CTID
                shift
                ;;
            --rules)
                shift;
                oldifs=$IFS;
                IFS=';';
                RULES=(${1// /});
                IFS=${oldifs};
                shift;
                ;;
            --)
                shift;
                break;
                ;;
        esac;
    done;
    return 0
}

function describeStart() {
    echo "start firewall and load rules";
}

function describeStartParameters() {
    echo "--op [port1,[port2,[port3-port4]] --cp [port1,[port2,[port3-port4]] --rp [port1,[port2]]";
}

function describeStartOptions() {
    echo "op: open port(s) list. A list of ports which have an 'ACCEPT' policy";
    echo "cp: closed port(s) list. A list of ports which have a 'DROP' policy";
    echo "rp: ports to remove from existing 'open' ports";
}

function doStart() {
    declare -a ports;
    log "Starting firewall";

    local cartridge_config="/opt/repo/jelastic/jelastic.conf";
    [ -f "$cartridge_config"  ] && Firewall_Enabled=$($GREP Firewall_Enabled "$cartridge_config" | $AWK -F "=" '{ print $2 }')
    [ ! -z "${Firewall_Enabled}" ] && FIREWALL_ENABLED=${Firewall_Enabled};  ### Override for cartridges
    [[ "${FIREWALL_ENABLED}" -eq "0" ]] || [ -z "${FIREWALL_ENABLED+xxx}" ] || [ -z "${FIREWALL_ENABLED}" -a "${FIREWALL_ENABLED+xxx}" = "xxx" ] && return 0;

    $IPTABLES -F;
    $IPTABLES -t nat -F;

    if [ -f /proc/net/if_inet6 ] ; then
        $IP6TABLES -F;
        $IP6TABLES -t nat -F 2>/dev/null;
    fi
    _setDefaultPolicy;

    #exports
    set -f
    NFSIPS=()
    [ -e '/etc/exports' ] && NFSIPS=($($SED -re 's/.+(\s|\t)+((\*)|([0-9]+\.){3}[0-9]+(\/[0-9]{0,2})?).*/\2/g' -e '/#/d' '/etc/exports' | sort | uniq | $SED -e '/^$/d' -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'))
    local __allnetwork=0

    # for internal services:
    intips=($(getLANIPs))
    for ip in ${intips[@]} ; do
        for nfsip in ${NFSIPS[@]} ; do
            if [[ "${#NFSPort}" -gt 0 ]] ; then
                if [ "$nfsip" == "*" ] ; then
                    $IPTABLES -A INPUT -p tcp -m multiport --dports $NFSPort -d $ip -j ACCEPT
                    $IPTABLES -A INPUT -p udp -m multiport --dports $NFSPort -d $ip -j ACCEPT
                    __allnetwork=1
                else
                    if [[ "$__allnetwork" -eq 0 ]] ; then
                        $IPTABLES -A INPUT -p tcp -m multiport --dports $NFSPort -d $ip -s $nfsip -j ACCEPT
                        $IPTABLES -A INPUT -p udp -m multiport --dports $NFSPort -d $ip -s $nfsip -j ACCEPT
                    fi
                fi
            fi
            if [[ "${#RPCPort}" -gt 0 ]] ; then
                if [ "$nfsip" == "*" ] ; then
                    $IPTABLES -A INPUT -p tcp -m multiport --dports $RPCPort -d $ip -j ACCEPT
                    $IPTABLES -A INPUT -p udp -m multiport --dports $RPCPort -d $ip -j ACCEPT
                    __allnetwork=1
                else
                    if [[ "$__allnetwork" -eq 0 ]] ; then
                        $IPTABLES -A INPUT -p tcp -m multiport --dports $RPCPort -d $ip -s $nfsip -j ACCEPT
                        $IPTABLES -A INPUT -p udp -m multiport --dports $RPCPort -d $ip -s $nfsip -j ACCEPT
                    fi
                fi
            fi
        done
    done;
    set +f

    $IPTABLES -A INPUT -i tap -j ACCEPT;

    redirPorts=($(isFunction _get$($SED -re 's/-/_/g' <<< ${COMPUTE_TYPE})RedirPorts && { _get$($SED -re 's/-/_/g' <<< ${COMPUTE_TYPE})RedirPorts; } || _defaultComputeNodeRedirPorts));

    # process input chain NAT
    for port in ${redirPorts[@]} ; do
        local ruleParams=($($SED 's/:/ /g' <<< ${port}));
        $IPTABLES -t nat -A ${ruleParams[0]} -s ${ruleParams[1]} -d ${ruleParams[2]} -m tcp -p tcp --dport ${ruleParams[3]} -j ${ruleParams[5]} --to-port ${ruleParams[4]};
    done;

    [ "x${COMPUTE_TYPE}" == "xcartridge" ] && {
        [ -f "${CARTRIDGE_HOME}/jelastic/scripts/firewall.sh" ] && source "${CARTRIDGE_HOME}/jelastic/scripts/firewall.sh" >>$JEM_CALLS_LOG 2>&1;
    }

    _rule4Files=($CUSTOM_RULES_FILE $JELASTIC_4RULES_FILE $JELASTIC_4NATRULES_FILE)
    _rule6Files=($CUSTOM_6RULES_FILE $JELASTIC_6RULES_FILE $JELASTIC_6NATRULES_FILE)

    _loadRes=0
    for j in $(seq 4 2 6) ; do
        eval "_ruleFiles=(\${_rule${j}Files[*]})"
        eval "_processRuleFile=processRule${j}File"
        for i in $(seq 0 $((${#_ruleFiles[*]}-1)) ) ; do
            $_processRuleFile ${_ruleFiles[$i]}
            _res=$?
            [[ "$_res" -ne 0 ]] && echo "Load contents of ${_ruleFiles[$i]} filed" >>$JEM_CALLS_LOG
            _loadRes=$((_loadRes+_res))
        done
    done

    if [ -f /proc/net/if_inet6 ] ; then
        $IP6TABLES -I INPUT -p icmpv6 -j ACCEPT
        $IP6TABLES -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
        $IP6TABLES -I INPUT -i lo -j ACCEPT
    fi

    $IPTABLES -I INPUT -p icmp -j ACCEPT
    $IPTABLES -I INPUT -i lo -j ACCEPT
    $IPTABLES -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

    #Add reject only if there was no problem while loading rules
    if [[ "$_loadRes" -gt 0 ]] ; then
        echo "Not saving rules due to errors above" >>$JEM_CALLS_LOG
        return 2
    fi

    checkRule "INPUT" "-j REJECT --reject-with icmp-host-prohibited" || $IPTABLES -A INPUT -j REJECT --reject-with icmp-host-prohibited

    log "saving rules"
    local issue_file="/etc/issue"
    local release_files="/etc/*-release"
    issue_string=$(set +f; cat $release_files $issue_file 2>/dev/null)
    OS=$(detectOS "$issue_string")
    OS_ver=$(getOSVersion "$issue_string")
    OS_ver=${OS_ver%%.*}

    # patch iptables-persistent plugins
    # VZ containers has no modprobe support
    if [ "x$OS" == "xubuntu" -o "x$OS" == "xdebian" ] ; then
        [ -x /etc/init.d/netfilter-persistent ] && /etc/init.d/netfilter-persistent save &>> $JEM_CALLS_LOG
    else
        /sbin/service iptables save 2>/dev/null | $GRAB_OUTPUT
        /sbin/service ip6tables save &> /dev/null
    fi
    echo "iptables rules saved" >>$JEM_CALLS_LOG
    return 0
}

function describeFWStart() {
    echo "Alias for Start";
}

function describeList() {
    echo "List firewall rules";
}

function doList() {
    echo "IPTABLES rules ($@)"
    echo "--------------------"
    $IPTABLES -L -t $@
    echo
    echo "IP6TABLES rules ($@)"
    echo "--------------------"
    $IP6TABLES -L -t $@
}

function doFWStart() {
    local resultMsg
    declare -i result
    if [[ $CTID -eq 0 ]] ; then
        log "FWSTART configuring firewall"
        resultMsg=$(doStart); result=$?
    else
        resultMsg=$(vzctl exec2 $CTID "jem firewall start"); result=$?
    fi
    [[ "$result" -eq "0" ]] && writeJSONResponseOut "result=>${result}" "message=>Firewall has been started" || writeJSONResponseErr "result=>${result}" "message=>${resultMsg}"
    return $result
}

function describeStop() {
    echo "clear all rules and stop firewall";
}

function doStop() {
    [[ "${FIREWALL_ENABLED}" -eq "0" ]] || [ -z "${FIREWALL_ENABLED+xxx}" ] || [ -z "${FIREWALL_ENABLED}" -a "${FIREWALL_ENABLED+xxx}" = "xxx" ] && return 0;
    $IPTABLES -X;
    $IPTABLES -X -t nat;
    $IPTABLES -F;
    $IPTABLES -F -t nat;
    _setDefaultPolicy "ACCEPT";
    return 0;
}

function describeFWStop() {
    echo "Alias for Stop";
}

function doFWStop() {
    local resultMsg;
    declare -i result;
    resultMsg=$(doStop); result=$?;
    [[ "${result}" ]] && writeJSONResponseOut "result=>${result}" "message=>Firewall has been stopped" || writeJSONResponseErr "result=>${result}" "message=>${resultMsg}";
}

function _isFWEnabled() {
    local status=$($SED -rne '/FIREWALL_ENABLED/{s/FIREWALL_ENABLED=([0-1]){1}/\1/;p}' ${META_FILE})
    local cartridge_config="/opt/repo/jelastic/jelastic.conf"
    if [ -f "$cartridge_config"  ] ; then
	status=$($GREP Firewall_Enabled "$cartridge_config" | $AWK -F "=" '{ print $2 }')
        [ -z "${status}" ] && status="1"
    fi
    [[ "${status}" -eq "1" ]] && return 0
    return 1
}

function doisEnabled() {
    _isFWEnabled
}

function describeFWStatus() {
    echo "displays firewall status";
}

function doFWStatus() {
    local param=${1};

    [[ -z ${param} ]] && {
        _isFWEnabled && writeJSONResponseOut "result=>0" "message=>Firewall enabled" || writeJSONResponseOut "result=>0" "message=>Firewall disabled";
        return 0;
    }

    message=$($IPTABLES -vnL INPUT | $SED -re '/INPUT/d;/target/d;s/\s*((\S+)\s+){8}(\S+)\s+(.*)/\4/g' | $SED -rne '/^\s*$/d;/:/{s/.*dpt(s)?:([0-9]+)(:)?([0-9]+)?.*/\2:\4/;p}' | $SED -re ':a;N;$!ba;s/\n/,/g;s/:,/,/g;s/:$//g');
    message="Open ports: ${message}";
    writeJSONResponseOut "result=>0" "message=>${message}";
    return 0;
}

function describeFWReconfigure() {
    echo "reconfigure firewall";
}

function describeFWReconfigureParameters() {
    describeStartParameters
}

function describeFWReconfigureOptions() {
    describeStartOptions
}


function doFWReconfigure() {
    _isFWEnabled && doStart;
}

function describeEnable() {
    echo "enable firewall";
}

function describeEnableParameters() {
   describeStartParameters
}

function describeEnableOptions() {
    describeStartOptions
}

function doEnable() {
    [ -d "${JELASTIC_RULES_DIR}" ] || mkdir -p "${JELASTIC_RULES_DIR}"
    [ ! -e "${META_FILE}" ] && touch ${META_FILE}
    [ ! -e "${CUSTOM_6RULES_FILE}" ] && touch ${CUSTOM_6RULES_FILE}
    [ -n "$DATA_OWNER" ] && chown "$DATA_OWNER" "${CUSTOM_6RULES_FILE}" &>>"$JEM_CALLS_LOG"
    if $GREP -q "FIREWALL_ENABLED" ${META_FILE} ; then
        $SED -i -re "s/FIREWALL_ENABLED=([0-9]+)/FIREWALL_ENABLED=1/g" ${META_FILE}
    else
        echo -e "\nFIREWALL_ENABLED=1" >> ${META_FILE}
        $SED -i -re '/^$/d' ${META_FILE}
    fi

    prefix=""
    [[ $CTID -gt 0 ]] && prefix="/vz/root/$CTID"
    local issue_file="$prefix/etc/issue"
    local release_files="$prefix/etc/*-release"
    issue_string=$(set +f; cat $release_files $issue_file 2>/dev/null)
    OS=$(detectOS "$issue_string")
    OS_ver=$(getOSVersion "$issue_string")
    OS_ver=${OS_ver%%.*}

    # patch iptables-persistent plugins
    # VZ containers has no modprobe support
    if [ "x$OS" == "xubuntu" -o "x$OS" == "xdebian" ] ; then
        [ -d "/usr/share/netfilter-persistent/plugins.d/" ] && {
            sed -i -re '/\/sbin\/modprobe/s/^/#/g' /usr/share/netfilter-persistent/plugins.d/* >>$ACTIONS_LOG 2>&1
            systemctl enable netfilter-persistent >>$ACTIONS_LOG 2>&1
        }
    else
        chkconfig --level 345 iptables on 2>&1 | $GRAB_OUTPUT
        chkconfig --level 345 ip6tables on 2>&1 | $GRAB_OUTPUT
    fi

    writeJSONResponseOut "result=>0" "message=>Firewall has been enabled"
    return 0
}

function describeFWEnable() {
    echo "Alias for Enable";
}

function doFWEnable() {
    declare -i result
    if [[ $CTID -eq 0 ]] ; then
        local resultMsg
        resultMsg=$(doEnable); result=$?
        [[ "${result}" ]] && writeJSONResponseOut "result=>${result}" "message=>Firewall has been enabled" || writeJSONResponseErr "result=>${result}" "message=>${resultMsg}"
        return $result
    fi

    resultMsg=$(vzctl exec2 $CTID "jem firewall Enable"); result=$?
    [[ "${result}" ]] || writeJSONResponseErr "result=>${result}" "message=>${resultMsg}"

    FWSetMsg=$(dofwset $@)
    eval $($SED -re 's/.*"result":"([0-9]+)".*"message":"([^"]+)".*/fwset_result="\1";fwset_msg="\2"/g' <<< $FWSetMsg)
    [[ "$fwset_result" -gt 0 ]] && writeJSONResponseErr "result=>$fwset_result" "message=>$fwset_msg"
    writeJSONResponseOut "result=>0" "message=>Firewall has been enabled"
    return 0
}

function describeDisable() {
    echo "disable firewall";
}

function doDisable() {
    [ ! -e "${META_FILE}" ] && touch ${META_FILE}
    if $GREP -q "FIREWALL_ENABLED" ${META_FILE} ; then
        $SED -i -re "s/FIREWALL_ENABLED=([0-9]+)/FIREWALL_ENABLED=0/g" ${META_FILE};
    fi
    echo "Firewall disabled";
    _setDefaultPolicy "ACCEPT";
    $IPTABLES -F ; service iptables save &> /dev/null;
    $IP6TABLES -F ; service ip6tables save &> /dev/null;
    writeJSONResponseOut "result=>0" "message=>Firewall has been disabled"
    return 0;
}

function describeDisable() {
    echo "Alias for Disable";
}

function doFWDisable() {
    local resultMsg
    declare -i result
    if [[ $CTID -eq 0 ]] ; then
        resultMsg=$(doDisable); result=$?
    else
        resultMsg=$(vzctl exec2 $CTID "jem firewall Disable"); result=$?
    fi

    [[ "${result}" ]] && writeJSONResponseOut "result=>${result}" "message=>Firewall has been disabled" || writeJSONResponseErr "result=>${result}" "message=>${resultMsg}"
}

function describePanic() {
    echo "clear all rules and set default policy to DROP";
}

function doPanic() {
    [[ "${FIREWALL_ENABLED}" -eq "0" ]] || [ -z "${FIREWALL_ENABLED+xxx}" ] || [ -z "${FIREWALL_ENABLED}" -a "${FIREWALL_ENABLED+xxx}" = "xxx" ] && return 0;
    $IPTABLES -X;
    $IPTABLES -X -t nat;
    $IPTABLES -F;
    $IPTABLES -F -t nat;
    _setDefaultPolicy "DROP";
    return 0;
}


function dofwset() {
    running=1
    if ! isContainerRunning ${CTID} ; then
        running=0
        vzctl mount ${CTID} >> $ACTIONS_LOG 2>&1
    fi
    [ -d "/vz/root/${CTID}${JELASTIC_RULES_DIR}" ] || mkdir -p "/vz/root/${CTID}${JELASTIC_RULES_DIR}"
    echo "*filter" > "/vz/root/${CTID}${JELASTIC_4RULES_FILE}"
    echo "*filter" > "/vz/root/${CTID}${JELASTIC_6RULES_FILE}"
    for ruleraw in ${RULES[@]} ; do
        rulevars=$(awk -F, '{print "proto="$1";ptype="$2";dport="$3";srchost="$4";dsthost="$5";chain="$6";raction="$7";tcptype="$8";cmd="$9";"}' <<< $ruleraw )
        eval $rulevars
        chain="${chain^^}"
        proto="${proto,,}"
        cmd="${cmd,^^}"
        if [ "x$cmd" != "x" ] ; then
            cmd="-$cmd"
        else
            cmd="-A"
        fi

        rulecmd="$cmd $chain"
        if [ "x$proto" != "x" ] ; then
            rulecmd="$rulecmd -p $proto"
        fi

        srchost=${srchost/ALL/0.0.0.0\/0}
        if [ "x$srchost" != "x" ] ; then
            if grep -q '!' <<< $srchost ; then
                srchost=${srchost//'!'/}
                rulecmd="$rulecmd ! -s $srchost"
            else
                rulecmd="$rulecmd -s $srchost"
            fi
        fi

        dsthost=${dsthost/ALL/0.0.0.0\/0}
        if [ "x$dsthost" != "x" ] ; then
            if grep -q '!' <<< $dsthost ; then
                dsthost=${dsthost//'!'/}
                rulecmd="$rulecmd ! -d $dsthost"
            else
                rulecmd="$rulecmd -d $dsthost"
            fi
        fi

        if [ "x$ptype" == "xrange" ] ; then
            if [ "x$dport" != "x" ] ; then
                rulecmd="$rulecmd -m multiport --dports $dport"
            fi
        else
            if [ "x$dport" != "x" ] ; then
                rulecmd="$rulecmd --dport $dport"
            fi
        fi

        rulecmd="$rulecmd -j $raction"

        if [ "x$proto" == "xall" ] ; then
            tcprule=$($SED -e 's/all/tcp/g' <<< $rulecmd )
            udprule=$($SED -e 's/all/udp/g' <<< $rulecmd )
            rulecmd="${tcprule}\n${udprule}"
        fi

        if [ "x$tcptype" == "xIPV4" ] ; then
            echo -e $rulecmd >> "/vz/root/${CTID}${JELASTIC_4RULES_FILE}"
        else
            echo -e $rulecmd >> "/vz/root/${CTID}${JELASTIC_6RULES_FILE}"
        fi

        echo "CTID $CTID RULE $rulecmd" >> ${JEM_CALLS_LOG} 2>&1
    done
    echo "COMMIT" >> "/vz/root/${CTID}${JELASTIC_4RULES_FILE}"
    echo "COMMIT" >> "/vz/root/${CTID}${JELASTIC_6RULES_FILE}"
    if [[ $running -eq 1 ]] ; then
        vzexecRun "jem firewall start"
    else
        vzctl umount ${CTID} >> $ACTIONS_LOG 2>&1
    fi
    log="$(vzexecGetLastStdOut) $(vzexecGetLastStdErr)"
    writeJSONResponseOut "result=>$(vzexecGetLastErrCode)" "message=>Firewall rules set" "log=>${log//\"/\\\"}"
    return 0
}
