#!/bin/sh
# $Id: firewall,v 1.1.5.1 2000/07/16 12:00:01 root Exp root $
# $Date: 2000/07/16 12:00:01 $
#
# File: firewall
# Desc: setup your host as a firewall
#       with rules (scripts) specified in rules/*
#
# Author : Jens Friedrich
# 
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2, or (at your option)
#   any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
# (c) Copyright 1998 Jens Friedrich
#
# $Log: firewall,v $
# Revision 1.1.5.1  2000/07/16 12:00:01  root
# FCT
#
# Revision 1.1.4.2  2000/07/15 19:01:24  jens
# Rev.
#
# Revision 1.1.4.1  1999/08/01 21:44:54  jens
# .
#
# Revision 1.1  1999/08/01 21:44:54  jens
# Initial revision
#
# Revision 1.1.0.1  1998/11/02 09:36:30  jens
# .
#
# Revision 1.1  1998/11/02 09:35:49  jens
# Initial revision
#
# Revision 1.1  1998/11/02 09:33:28  jens
# Initial revision
#
# Revision 1.0.9.3  1998/06/14 10:50:29  jens
# fixed -s option
#
# Revision 1.0.9.2  1998/06/02 18:58:48  jens
# changed usage()
#
# Revision 1.0.9.1  1998/06/01 19:35:17  jens
# initial ci -r 1.0.9
#
# Revision 1.0  1998/06/01 19:32:53  jens
# initial ci -r 1.0
#
#

usage ()
{
    echo "Usage: $0 [-t] [-v] [-s] start|stop|status|list"
    echo "-t  run in test mode, only create the config files"
    echo "-v  run in verbose mode, print each ipfwadm line"
    echo "-s  run in setup mode, use files in setup directory"
    exit 1
}
        
if [ $# -eq 0 ]; then
  usage
fi

# where is the firewall-package located ?
[ -z "$FWDIR" ] && FWDIR=`echo "$0" | sed -e 's/[\/][A-Za-z0-9_\.-]*$//'`
if [ -z "$FWDIR" ]; then
  $FWDIR=`which "$0" | sed -e 's/[\/][A-Za-z0-9_\.-]*$//'` 
  if [ -z "$FWDIR" ]; then
    echo "Couldnt extract path from '$0', set variable \$FWDIR to the location where FCT is installed."
   exit 1
  fi
fi

# read the network configuration
. $FWDIR/etc/net.cfg

# some definitions and functions
. $FWDIR/etc/aliases.cfg

# the used functions for gatewaying
. $FWDIR/etc/gateway.sh

testing=false
verbose=false
setup=false

while [ $# -gt 0 ]; do

 case "$1" in

  -t) testing=true
      echo "TEST-MODE: See the logfile in $FWDIR/log/$ip_cmd.log"
      #echo ""
      ;;

  -h) usage
      ;;

  -v) verbose=true
      ;;

  -s) setup=true
      ;;

  start)
    if test -x $IPFWADM -o $testing=true; then

      #echo "--------------------------"
      echo "Starting FCT firewall:"
      #echo "--------------------------"

      ### clear all firewall rules ###
      . $FWDIR/reset > /dev/null

      ## clear directory 'log'
      [ -f $FWDIR/log/$ip_cmd.log ]  && rm $FWDIR/log/$ip_cmd.log
      [ -f $FWDIR/log/services.log ] && rm $FWDIR/log/services.log

      ### --- deny external connection until firewall is up --- ###
      echo "#--- deny external connections until firewall is up ! ---" | tee $FWDIR/log/$ip_cmd.log
      for outdev in $OUT_DEV0; do
          # activate this & the other below also, to have running traffic during setup, JH
          # $IPFW -I -a accept "" "" "" $INTERNAL "" "" $outdev
          # $IPFW -O -a accept "" "" "" $ANY      "" "" $outdev

          $IPFW -I -a deny "" "" "" $INTERNAL "" "" $outdev
          $IPFW -O -a deny "" "" "" $ANY      "" "" $outdev
      done

      ##### start accounting ####
      . $FWDIR/accounting start

      ##### start firewalling ####

      ## clear directory 'setup' !
      [ -f $FWDIR/setup/not_defined ] && rm $FWDIR/setup/not_defined
      [ "x$setup" = xfalse -a "x$testing" = "xfalse" ] && rm -f $FWDIR/setup/*.rules
      [ "x$setup" = xfalse -a "x$testing" = "xfalse" ] && rm -f $FWDIR/setup/Firewall/*.rules

      #####################
      ### Firewall Host ###
      #####################
      #echo ""                   | tee    $FWDIR/log/$ip_cmd.log  \
      #                                   $FWDIR/log/services.log
      echo "#Firewall Services:" | tee -a $FWDIR/log/$ip_cmd.log $FWDIR/log/services.log
      echo "#------------------" | tee -a $FWDIR/log/$ip_cmd.log

      echo "#--- Firewall.rules ---" >> $FWDIR/log/services.log
      if [ "x$setup" = "xfalse" ]; then
        . $FWDIR/rules/Firewall.rules
      else
        [ "x$testing" = xfalse ] && . $FWDIR/setup/Firewall.setup
      fi

      ###########################
      ### TRUSTED CONNECTIONS ###
      ###########################
      echo ""                      | tee -a $FWDIR/log/$ip_cmd.log
      echo "#Trusted Connections:" | tee -a $FWDIR/log/$ip_cmd.log $FWDIR/log/services.log
      echo "#--------------------" | tee -a $FWDIR/log/$ip_cmd.log

      echo "#--- Trusted.rules ---" >> $FWDIR/log/services.log
      if [ "x$setup" = "xfalse" ]; then
        . $FWDIR/rules/Trusted.rules
      else
        [ "x$testing" = xfalse ] && . $FWDIR/setup/Trusted.setup
      fi

      #########################
      ### INTERNET-SERVICES ###
      #########################

      # we use all lower-case <service>.rules files
      # for automatic setup, and all upper-case
      # for explicit calls.

      echo ""                   | tee -a $FWDIR/log/$ip_cmd.log
      echo "#Network Services:" | tee -a $FWDIR/log/$ip_cmd.log $FWDIR/log/services.log
      echo "#-----------------" | tee -a $FWDIR/log/$ip_cmd.log
      if [ "x$IN_DEV0" != x ]; then
        for service_file in $FWDIR/rules/[a-z]*.rules; do
          if [ -n "$service_file" ]; then
            service=`basename $service_file`

            # Uuuh, need this since Linux2.2 bash, this is really a bug, no feature
            [ `echo "$service" | egrep '^[a-z]'` ] || continue

            echo "#--- $service ---" | tee -a    $FWDIR/log/services.log
            echo ""                           >> $FWDIR/log/$ip_cmd.log
            echo "#Service: $service"         >> $FWDIR/log/$ip_cmd.log
            echo "#-------------------------" >> $FWDIR/log/$ip_cmd.log

            if [ "x$setup" = "xfalse" ]; then
              . $FWDIR/rules/$service
            else
              [ "x$testing" = xfalse ] && . $FWDIR/setup/Network.setup $service
            fi
          fi
        done
      else
        echo "### skipped: No internal Interface defined" | tee -a $FWDIR/log/$ip_cmd.log \
                                                                   $FWDIR/log/services.log
      fi

      ##########################
      #### Additional Stuff ####
      ##########################

      echo ""                      | tee -a $FWDIR/log/$ip_cmd.log
      echo "#Additional settings:" | tee -a $FWDIR/log/$ip_cmd.log $FWDIR/log/services.log
      echo "#--------------------" | tee -a $FWDIR/log/$ip_cmd.log

      for service_file in $FWDIR/rules/[A-Z]*.rules; do
        service=`basename $service_file`

        # Uuuh, need this since Linux2.2 bash, this is really a bug, no feature
        [ `echo "$service" | egrep '^[a-z]'` ] && continue

        if [ `echo "Firewall.rules Trusted.rules General.rules" | \
              fgrep "$service" | wc -l` -eq 0 ]; then
              
          echo "#--- $service ---"   | tee -a $FWDIR/log/services.log
          #echo "#Service: $service" | tee -a $FWDIR/log/$ip_cmd.log

          if [ "x$setup" = "xfalse" ]; then
              . $FWDIR/rules/$service
          else
              if [ -f $FWDIR/setup/$service ]; then
                  [ "x$testing" = xfalse ] && . $FWDIR/setup/Network.setup $service
              else
                  . $FWDIR/rules/$service
              fi
          fi
        fi
      done

      #################
      #### GENERAL ####
      #################

      echo ""         | tee -a $FWDIR/log/$ip_cmd.log
      echo "#--- General.rules ---" | tee -a $FWDIR/log/$ip_cmd.log $FWDIR/log/services.log
      if [ "x$setup" = "xfalse" ]; then
        . $FWDIR/rules/General.rules
      else
        [ "x$testing" = xfalse ] && . $FWDIR/setup/General.setup
      fi

      ### --- deny external connection until firewall is up --- ###
      echo "#--- allow defined external connections ---" | tee -a $FWDIR/log/$ip_cmd.log
      for outdev in $OUT_DEV0; do
          # activate this & the other above also, to have running traffic during setup, JH
          # $IPFW -I -d accept "" "" "" $INTERNAL "" "" $outdev
          # $IPFW -O -d accept "" "" "" $ANY      "" "" $outdev     

          $IPFW -I -d deny "" "" "" $INTERNAL "" "" $outdev
          $IPFW -O -d deny "" "" "" $ANY      "" "" $outdev
      done
    fi
    ;;
 
  stop)
    ### stop accouting ###
    . $FWDIR/accounting stop

    #### reset/clear firewall
    echo "Stopping IP firewalling."
    . $FWDIR/reset
    ;;

  status)
     ### show status (rules) of firewall
     case "$ip_cmd" in
        ipfwadm)
         $IPFWCMD -Ile | grep -v '  0  '
         echo
         $IPFWCMD -Fle | grep -v '  0  '
         echo
         $IPFWCMD -Ole | grep -v '  0  '
         echo
         ;;
        ipchains)
         $IPFWCMD -L input -n -v | grep -v '  0  '
         echo
         $IPFWCMD -L forward -n -v | grep -v '  0  '
         echo
         $IPFWCMD -L output -n -v | grep -v '  0  '
           ;;
        ipF)
         echo "Sorry not yet implemented"
           ;;
    esac
    ;;

  list)
     ### show status (rules) of firewall
     case "$ip_cmd" in
        ipfwadm)
         $IPFWCMD -Ile
         echo
         $IPFWCMD -Fle
         echo
         $IPFWCMD -Ole
         echo
         ;;
        ipchains)
         $IPFWCMD -L input -n -v
         echo
         $IPFWCMD -L forward -n -v
         echo
         $IPFWCMD -L output -n -v
           ;;
        ipF)
         echo "Sorry not yet implemented"
           ;;
    esac
    ;;

  *)
    usage
    ;;

 esac
 shift
done
