#!/bin/sh

# <copyright file="iptables.sh" company="Encodo Systems AG">
# Copyright (c) 2010 Encodo Systems AG. All rights reserved.
# </copyright>
# 
# <author>ENCODO</author>
# <modified>2010/04/21 12:00:00</modified>

function inlist
{
  less `dirname $0`/$1 | egrep "^${CLIENTCERT}$" > /dev/null
  if [ $? -eq 0 ]; then
    return 0
  else
    return 1
  fi
}

function get_next_matching_firewall_rule
{
  ip_address=$1
  channel=$2

  RULE="`iptables -L $channel -n –line-numbers | grep $ip_address | head -n 1`"
}

function drop_rule_from_iptables
{
  rule="$1"
  channel="$2"
  echo "  Drop rule [$rule] for channel [$channel]"
  line_number=`echo "$rule" | awk '{print $1}'`
  iptables -D $channel $line_number
}

function add_port_to_iptables
{
  source_ip=$1
  destination_ip=$2
  protocol=$3
  port=$4

  iptables -A INPUT -i tun0 -s $source_ip -d $destination_ip -p $protocol –dport $port -j ACCEPT
  iptables -A INPUT -i tun0 -s $source_ip -d $destination_ip -p $protocol –dport $port -j ACCEPT
}

function add_destination_to_iptables
{
  source_ip=$1
  destination_ip=$2
  iptables -A INPUT -i tun0 -s $source_ip -d $destination_ip -j ACCEPT
  iptables -A FORWARD -i tun0 -s $source_ip -d $destination_ip -j ACCEPT
}

function open_firewall_for_strangers
{
  echo "  Add route for DNS"
  add_port_to_iptables $CLIENTIP 192.168.1.1 "UDP" 53

  echo "  Add route for Windows shares"
  add_port_to_iptables $CLIENTIP 192.168.1.5 "TCP" 139
  add_port_to_iptables $CLIENTIP 192.168.1.5 "TCP" 445

  return 0
}

function open_firewall_for_employees
{
  echo "  Add routes for all ip addresses"
  iptables -A INPUT -i tun0 -s $CLIENTIP -j ACCEPT
  iptables -A FORWARD -i tun0 -s $CLIENTIP -j ACCEPT
  return 0
}

function open_firewall
{
  echo "Opening firewall for $CLIENTCERT @ [$CLIENTIP]"
# TODO Add filtering for other lists, if desired
# inlist "MYGROUP.list"
#if [ $? -eq 0 ]; then
#  echo "  Certificate found in MYGROUP list"
#  open_firewall_for_MYGROUP
#  return 0
#else
  inlist "strangers.list"
  if [ $? -eq 0 ]; then
    echo "  Certificate found in strangers list"
    open_firewall_for_strangers
    return 0
  else
    inlist "employees.list"
    if [ $? -eq 0 ]; then
      echo "  Certificate found in employee list"
      open_firewall_for_employees
      return 0
    else
      echo "  Certificate not found in any list"
      return 1
    fi
  fi
}

function close_firewall_channel
{
  channel=$1

  get_next_matching_firewall_rule $CLIENTIP $channel

  while [ -n "$RULE" ]
  do
    drop_rule_from_iptables "$RULE" $channel
    get_next_matching_firewall_rule $CLIENTIP $channel
  done

}

function close_firewall
{
  echo "CloseFirewall for [$CLIENTIP]"

  close_firewall_channel "INPUT"
  close_firewall_channel "FORWARD"
  close_firewall_channel "OUTPUT"
}

# Main

OPERATION=$1
CLIENTIP=$2
CLIENTCERT=$3

case "$1" in
  add)
    close_firewall
    open_firewall
    ;;

  update)
    close_firewall
    open_firewall
    ;;

  delete)
    close_firewall
    ;;
  *)
    echo "Unknown operation"
    exit 1
esac

exit $?