#!/bin/sh

# Copyright (c) 2005-2010 OpenVPN Technologies, Inc.
# Licensed under the GPL version 2

# First version by Jesse Adelman
# someone at boldandbusted dink com
# http://www.boldandbusted.com/

# PURPOSE: This script automatically sets the proper /etc/resolv.conf entries
# as pulled down from an OpenVPN server.

# INSTALL NOTES:
# Place this in /etc/openvpn/client.up
# Then, add the following to your /etc/openvpn/<clientconfig>.conf:
#   client
#   up /etc/openvpn/client.up
# Next, "chmod a+x /etc/openvpn/client.up"

# USAGE NOTES:
# Note that this script is best served with the companion "client.down"
# script.

# Tested under Debian lenny with OpenVPN 2.1_rc11
# It should work with any UNIX with a POSIX sh, /etc/resolv.conf or resolvconf

# This runs with the context of the OpenVPN UID/GID 
# at the time of execution. This generally means that
# the client "up" script will run fine, but the "down" script
# will require the use of the OpenVPN "down-root" plugin
# which is in the plugins/ directory of the OpenVPN source tree

# A horrid work around, from a security perspective,
# is to run OpenVPN as root. THIS IS NOT RECOMMENDED. You have
# been WARNED.
PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin

# init variables

i=1
domains=
fopt=
ndoms=0
nns=0
nl='
'

# $foreign_option_<n> is something like
# "dhcp-option DOMAIN example.com" (multiple allowed)
# or
# "dhcp-option DNS 10.10.10.10" (multiple allowed)

# each DNS option becomes a "nameserver" option in resolv.con
# if we get one DOMAIN, that becomes "domain" in resolv.conf
# if we get multiple DOMAINS, those become "search" lines in resolv.conf

while true; do
  eval fopt=\$foreign_option_${i}
  [ -z "${fopt}" ] && break

  case ${fopt} in
		dhcp-option\ DOMAIN\ *)
           ndoms=$((ndoms + 1))
           domains="${domains} ${fopt#dhcp-option DOMAIN }"
           ;;
		dhcp-option\ DNS\ *)
           nns=$((nns + 1))
           if [ $nns -le 3 ]; then
             dns="${dns}${dns:+$nl}nameserver ${fopt#dhcp-option DNS }"
           else
             printf "%s\n" "Too many nameservers - ignoring after third" >&2
           fi
           ;;
        *)
           printf "%s\n" "Unknown option \"${fopt}\" - ignored" >&2
           ;;
	esac
  i=$((i + 1))
done

ds=domain
if [ $ndoms -gt 1 ]; then
  ds=search
fi

# This is the complete file - "$domains" has a leading space already
out="# resolv.conf autogenerated by ${0} (${1})${nl}${dns}${nl}${ds}${domains}"

# use resolvconf if it's available
if type resolvconf >/dev/null 2>&1; then
  printf "%s\n" "${out}" | resolvconf -p -a "${1}"
else
  # Preserve the existing resolv.conf
  if [ -e /etc/resolv.conf ] ; then
    cp /etc/resolv.conf /etc/resolv.conf.ovpnsave
  fi
  printf "%s\n" "${out}" > /etc/resolv.conf
  chmod 644 /etc/resolv.conf
fi

exit 0
