#!/bin/sh
### BEGIN INIT INFO
# Provides:          bastion
# Required-Start:    $syslog $creoled
# Required-Stop:     $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Interactive:     true
# Short-Description: Start/stop le firewall de amon
### END INIT INFO
#
# description:  Lance le firewall
# config: /etc/init.d/bastion
# la commande start execute le script zephir-bastion.pl
# la commande stop passe le firewall en mode forteresse
#
#

RETVAL=0
[ "$TERM" = "dumb" ] && export TERM=eole
. /lib/lsb/init-functions
export TPUT=/usr/bin/tput
export EXPR=/usr/bin/expr
#test si TPUT est utilisable
if [ ! "$TERM" = "" ] && $TPUT hpa 60 >/dev/null 2>&1 && $TPUT setaf 1  >/dev/null 2>&1; then
    FANCYTTY=1
    COLS=`$TPUT cols`
    if [ "$COLS" ] && [ "$COLS" -gt 6 ]; then
        COL=`$EXPR $COLS - 7`
    else
    COLS=80
        COL=73
    fi
    export COL
else
    FANCYTTY=0
fi
LOCKBASTION='/var/lock/bastion'
CACHE='/etc/eole/iptables'
CACHEMOD='/etc/eole/bastion-modules'
CACHESET='/etc/eole/ipset'
TCPWRAPPER='/etc/eole/hosts.allow'
TCPWRAPPER_DEST='/etc/hosts.allow'

INITQOS='/etc/init.d/qoseole'
CONFQOS='/etc/qoseole.conf'
LOCKQOS='/var/lock/qoseole'
INITRVP='/etc/init.d/ipsec'
INITRVP_AMON='/etc/init.d/rvp'
install_rvp=$(CreoleGet install_rvp non)
if [ "$install_rvp" = "oui" ]
then
    if [ "$(CreoleGet sw_database_mode)" = "oui" ]
    then
    CONFRVP='/etc/ipsec.d/ipsec.db'
    else
    CONFRVP='/etc/ipsec.secrets'
    fi
else
    CONFRVP=''
fi
LOCKRVPDIR='/var/lock/subsys'
LOCKRVP=$LOCKRVPDIR'/ipsec'
INITAGR='/etc/init.d/agregation'
CONFAGR='/etc/agregation.conf'
LOCKAGR='/var/lock/agregation'

[ "$TERM" = "dumb" ] && export TERM="eole"

logit() {
    # log dans syslog
    /usr/bin/logger -t "bastion" -p local2.info "$1"
}
logit2(){
    # log dans syslog et sur la console
    FAILURE=$2
    logit "$1"
    log_begin_msg "$1"
    if [ "$FAILURE" = "failed" ]; then
        log_end_msg 1
    fi
}
test_iptables(){
    if [ ! -x /sbin/iptables ];then
        MSG="Erreur : /sbin/iptables non exécutable !"
        logit2 "$MSG" "failed"
        exit 1
    fi
    iptables -nL >/dev/null
    if [ $? -ne 0 ];then
        MSG="Erreur iptables, vérifiez le noyau Linux utilisé par le serveur"
        logit2 "$MSG" "failed"
        exit 1
    fi
}

firewall_start() {
    if [ -e $LOCKBASTION ]; then
        MSG="Erreur : le service bastion est déjà démarré"
        logit2 "$MSG" "failed"
        exit 1
    fi
    test_iptables
    if [ ! -x /usr/share/eole/firewall.start ]
    then
        logit2 "Pas de script permettant la prise en compte des règles de pare-feu" "failed"
        return 1
    fi
    echo -n " * Regénération des règles de pare-feu"
    . /usr/share/eole/firewall.start
    RETVAL=$?
    log_end_msg $RETVAL
    return $RETVAL
}
start() {
    if [ -e $LOCKBASTION ]; then
        MSG="Erreur : le service bastion est déjà démarré"
        logit2 "$MSG" "failed"
        exit 1
    fi
    if [ ! -e $CACHE ]; then
        MSG="Erreur : pas de règle de pare-feu en cache, lancer $0 restart"
        logit2 "$MSG" "failed"
        stop
        exit 1
    fi
    [ ! -d $LOCKRVPDIR ] && mkdir -p $LOCKRVPDIR
    MSG="Restauration des règles de pare-feu en cache"
    logit2 "$MSG"

    test_iptables
    [ -f $CACHEMOD ] && sh $CACHEMOD
    [ -f $CACHESET ] && /usr/sbin/ipset restore -exist < $CACHESET
    iptables-restore < $CACHE
    RETVAL=$?
    if [ "$(CreoleGet mode_conteneur_actif)" = "oui" ]
    then
        CreoleRun "/etc/init.d/bastion start" all no yes
    fi
    [ -f $TCPWRAPPER ] && /bin/cp -f $TCPWRAPPER $TCPWRAPPER_DEST
    #rules outside bastion scope
    /bin/run-parts /usr/share/eole/bastion/post_cache
    log_end_msg $RETVAL
    if [ $RETVAL -eq 0 ]; then
        touch $LOCKBASTION
        #lancement de la qos si activée
        if [ -e $CONFQOS ] && [ -x $INITQOS ]
        then
            logit "Mise en place des règles de QOS"
             $INITQOS start
        fi
        #lancement de l'agrégation si activée
        if [ -e $CONFAGR ] && [ -x $INITAGR ]
        then
            logit "Mise en place des règles d'agrégation"
            $INITAGR start
        fi
        #lancement du rvp si activé
        ## LE RVP DOIT ETRE LANCE EN DERNIER !!!
        if [ -e $CONFRVP ] && [ "$install_rvp" = "oui" ]
        then
            logit "Mise en place des règles RVP"
            if [ -e $INITRVP_AMON ]
            then
                $INITRVP_AMON start
            else
                $INITRVP start
            fi
        fi
    else
        exit 1
    fi
    return $RETVAL
}

stopother() {
    # arrêt des autres programmes gérés par bastion
    if [ -e $LOCKQOS ]
    then
        logit "Arrêt des règles de QOS"
        $INITQOS stop
    fi
    if [ -e $LOCKAGR ]
    then
        logit "Arrêt des règles d'agrégation"
        $INITAGR stop
    fi
    ## LE RVP DOIT ETRE ARRETE EN DERNIER (juste avant le flush iptables)
    if [ -e $LOCKRVP ]
    then
        logit "Arrêt des tunnels RVP"
        if [ -e $INITRVP_AMON ]
        then
            $INITRVP_AMON stop
        else
            $INITRVP stop
        fi
    fi
}

stop() {
    silent=$1
    logit "Stopping firewall: bastion"
    if [ ! -x /usr/sbin/ferme.firewall ]
    then
        logit2 "pas de script permettant la suppression des règles de pare-feu" "failed"
        return 1
    fi
    test_iptables
    /usr/sbin/ferme.firewall $silent
    RETVAL=$?
    log_end_msg $RETVAL
    stopother
    [ $RETVAL -eq 0 ] && rm -f $LOCKBASTION
    return $RETVAL
}

case "$1" in
  start)
    start
    ;;

  stop)
    stop
    ;;

  restart)
    stop yes
    if [ $? -ne 0 ]; then
        exit 1
    fi

    firewall_start

    RETVAL=$?
    MSG="Mise en cache des règles de pare-feu"
    if [ $RETVAL -eq 0 ]; then
        logit2 "$MSG"
        log_end_msg 0
        start
    else
        if [ -f $CACHE ]; then
            MSG="$MSG (utiliser '$0 reload' pour appliquer l'ancien cache)"
            logit2 "$MSG" "failed"
        fi
        stop
    fi
  ;;
  reload)
    # "restart" is really just "start" as this isn't a daemon,
    #  and "start" clears any pre-defined rules anyway.
    #  This is really only here to make those who expect it happy
    stop yes
    start
    ;;

  status)
    if [ -f /var/lib/eole/reports/bastion.log ]; then
        STATUS="0"
        . /var/lib/eole/reports/bastion.log
        if [ ! "$STATUS" = "0" ]; then
            logit2 "Bastion n'est pas démarré : $MSG" "failed"
            exit $STATUS
        fi
    fi
    if [ ! -f $LOCKBASTION ]; then
        MSG="fichier lock non présent"
        logit2 "Bastion n'est pas démarré : $MSG" "failed"
        exit 1
    fi
    ret=$(python -c "from pyeole.diagnose import compare_iptables; print compare_iptables()")
    if [ ! "$ret" = "0" ]; then
        [ "$ret" = "1" ] && MSG="règles iptables incorrectes"
        [ "$ret" = "2" ] && MSG="règles iptables non exportées"
        logit2 "Bastion n'est pas démarré : $MSG" "failed"
        exit $ret
    fi
    ret=$(python -c "from pyeole.diagnose import compare_ipset; print compare_ipset()")
    if [ "$ret" = "1" ]; then
        MSG="règles ipset incorrectes"
        logit2 "Bastion n'est pas démarré : $MSG" "failed"
        exit $ret
    fi
    tables=`cat /proc/net/ip_tables_names 2>/dev/null`
    for table in $tables; do
        echo "Table: $table"
        iptables -t $table --list -n
    done
    ;;

  *)
    echo "Usage: $0 {start|stop|restart|reload|status}"
    exit 1
esac

exit 0
