#!/bin/bash
## Fichier /etc/openvpn/client.up

if [ "$(uname)" = "Darwin" ] ; then
  RESOLV_MASTER=/var/run/resolv.conf
  RESOLV_LINK=/etc/resolv.conf
  RESOLV_OWN=root:daemon
  RESOLV_PRM=664
else
  RESOLV_MASTER=/etc/resolv.conf
  RESOLV_LINK=
  RESOLV_OWN=root:root
  RESOLV_PRM=644
fi

function sanityCheck {
  if [ "$(uname)" = "Darwin" ] ; then
    CMD="netstat -rn"
  elif [ "$(uname)" = "Linux" ] ; then
    CMD="route -n"
  fi

  if [ -z "$CMD" ] ; then return; fi

  for ROUTEVAR in "${!route_network*}" ; do
    ROUTE=${!ROUTEVAR}
    if ( $CMD | grep -qe "$ROUTE" ) ; then
      echo "Routing table already contains a route to ${ROUTE} network; aborting."
      echo "Email it-staff@xxxxxxxxxxxxx for support."
      kill $PPID
      exit
    fi
  done
}

function replaceResolv {
  TEMPFILE=$1

  chown "$RESOLV_OWN" $TEMPFILE
  chmod "$RESOLV_PRM" $TEMPFILE
  mv $TEMPFILE "$RESOLV_MASTER"
  if [ -n "$RESOLV_LINK" ] ; then
    ln -sf "$RESOLV_MASTER" "$RESOLV_LINK"
  fi
}

function enableResolv {
  TEMPFILE=`mktemp /tmp/resolv.conf.XXXXXX`
  
  cat /etc/resolv.conf \
    | sed -re 's|^search (.*)|##ORIG## search \1|' \
    | egrep -ve '^(nameserver|search)'  >  $TEMPFILE
  
  for DHCPOPTVAR in ${!foreign_option*} ; do
    DHCPOPT="${!DHCPOPTVAR}"
    if echo $DHCPOPT | grep -qe '^dhcp-option[ \t]*DNS' ; then
      echo $DHCPOPT | sed -re 's/dhcp-option[ \t]*DNS[ \t]*([0-9.]+)$/nameserver \1/' >> $TEMPFILE
    elif echo $DHCPOPT | grep -qe '^dhcp-option[ \t]*DOMAIN' ; then
      echo $DHCPOPT | sed -re 's/dhcp-option[ \t]*DOMAIN[ \t]*(.*)$/search \1/' >> $TEMPFILE
    fi
  done
  
  cat /etc/resolv.conf | egrep -ve '^search' | sed -re 's|^nameserver (.*)$|##ORIG## nameserver \1\
nameserver \1|' >> $TEMPFILE
  
  replaceResolv $TEMPFILE
}

function disableResolv {
  TEMPFILE=`mktemp /tmp/resolv.conf.XXXXXX`

  # We test if resolf.conf contain ##ORIG
  VPN_RESOLV="0"
  grep -q -e '^##ORIG## ' /etc/resolv.conf && VPN_RESOLV="1"

  if [[ $VPN_RESOLV = "1" ]]; then

    cat /etc/resolv.conf \
      | egrep -ve '^(nameserver|search)' \
      | sed -e 's/^##ORIG## //' \
      > $TEMPFILE

    replaceResolv $TEMPFILE

  fi
}

function doRoute {
  OPERATION=$1
  NETWORK=$2
  NETMASK=$3
  GATEWAY=$4
  DEVICE=$5

  if [ "$(uname)" = "Darwin" ] ; then
    route $OPERATION -net $NETWORK $GATEWAY $NETMASK
  elif [ "$(uname)" = "Linux" ] ; then
    return 0 ## OpenVPN does routing on Linux correctly unassisted.
  else
    echo "Don't know how to add a route for OS \"$(uname)\"; aborting."
    echo "Email it-staff@xxxxxxxxxxxxx for support."
    exit 1
  fi
}

function doRoutes {
  OPERATION=$1

  NUM=1
  NETWORK_VARNAME="route_network_${NUM}"
  GATEWAY_VARNAME="route_gateway_${NUM}"
  NETMASK_VARNAME="route_netmask_${NUM}"
  while [ -n "${!NETWORK_VARNAME}" ] ; do
    if [ "$(uname)" = "Darwin" ] ; then
      route $OPERATION -net $NETWORK $GATEWAY $NETMASK
    elif [ "$(uname)" = "Linux" ] ; then
      return 0 ## OpenVPN does routing on Linux correctly unassisted.
    else
      echo "Don't know how to add a route for OS \"$(uname)\"; aborting."
      echo "Email it-staff@xxxxxxxxxxxxx for support."
      exit 1
    fi
    doRoute add ${!NETWORK_VARNAME} ${!NETMASK_VARNAME} ${!GATEWAY_VARNAME} ${dev}
    NUM=$(($NUM + 1))
    NETWORK_VARNAME="route_network_${NUM}"
    GATEWAY_VARNAME="route_gateway_${NUM}"
    NETMASK_VARNAME="route_netmask_${NUM}"
  done
}

case "$script_type" in
  up)
    sanityCheck
    ;;
  route-up)
    doRoutes add
    enableResolv
    ;;
  down)
    doRoutes delete
    disableResolv
    ;;
  *)
    echo "ERROR: Script type \"${script_type}\" unknown; aborting."
    echo "Email it-staff@xxxxxxxxxxxxx for support."
    exit 1
esac

