Package: openvpn
Version: 2.3.2-7
Tags: patch

This patch is an update of the patch in bug 614036.  It is refreshed
for the changes to the init.d script merged in 2.3.2-6.  It is also
re-written to be more generic.

The script now reads external data files to build a list of files to
copy into the chroot.  It executes a root-privileged, non-chrooted
"down" script, again external.  There is no policy baked into this
script.  (Though there is special-cased support for "copying" /proc,
/run/openvpn, and /dev/null, if any of these are requested by an
external file list.)

 < Stephen


--- openvpn-2.3.2-7/debian/openvpn.init.d       2013-11-27 05:21:19.000000000 
-0800
+++ openvpn-2.3.2-patched/debian/openvpn.init.d 2013-12-04 22:14:57.805048898 
-0800
@@ -15,6 +15,32 @@
 #              in /etc/default/openvpn and /etc/openvpn/*.conf
 ### END INIT INFO
 
+# This script supports --chroot in the following ways:
+#
+# It can create and populate a chroot tree.
+# Files named in /etc/openvpn/chroot.files.d/*.files will be copied
+# into the configured chroot directory.  Files should be listed one per
+# line; lines that are blank or start with the "#" character are ignored.
+# Wild-card patterns are allowed, but they must match exactly one file;
+# this feature is intended to make versioned shared library matching
+# more robust.  This script copies no files by default, but it does
+# handle some files specially, if they are requested; see the code.
+#
+# It creates the --user for you.
+# If the user named by the --user option does not exist, this script
+# will create it.  This feature makes it easier to copy config files
+# onto a new machine and have openvpn just work the first time.
+#
+# It implements a "down" hook.
+# If an executable file /etc/openvpn/<vpn-name>.down exists,
+# it will be executed without arguments after the openvpn daemon is killed.
+# Unlike the "--down" script implemented by the daemon, this hook receives
+# no arguments nor environment variables; if it needs any, a "--down"
+# script called from the daemon must store them where this hook can
+# find them.  This "down" hook is run as root and not in a chroot;
+# this capability may be useful when using --chroot and/or --user with
+# the daemon.
+
 # Original version by Robert Leslie
 # <r...@mars.org>, edited by iwj and cs
 # Modified for openvpn by Alberto Gonzalez Iniesta <a...@inittab.org>
@@ -27,6 +53,7 @@
 DAEMON=/usr/sbin/openvpn
 DESC="virtual private network daemon"
 CONFIG_DIR=/etc/openvpn
+CHROOT_FILES=$CONFIG_DIR/chroot.files.d
 test -x $DAEMON || exit 0
 test -d $CONFIG_DIR || exit 0
 
@@ -38,6 +65,14 @@
   . /etc/default/openvpn
 fi
 
+# Outputs the value of a config variable.
+# $1 -- the name of the config variable to output
+config_line() {
+    sed -n "s/^[ \t]*$1[ \t]\+\(.*\)/\1/p" \
+        "$CONFIG_DIR/$NAME.conf"
+}
+
+# Start 1 VPN.  $NAME is the name of the VPN to start.
 start_vpn () {
     if grep -q '^[      ]*daemon' $CONFIG_DIR/$NAME.conf ; then
       # daemon already given in config file
@@ -58,7 +93,74 @@
       STATUSARG="--status /run/openvpn/$NAME.status $STATUSREFRESH"
     fi
 
-    mkdir -p /run/openvpn
+    USER_HOME=/var/lib/openvpn
+
+    CHROOT=$(config_line chroot)
+    if [ -n "$CHROOT" ]; then
+      # Sanity check for chroot directory name: 
+      # must include "openvpn" and not include ".."
+      if echo "$CHROOT" | grep -q -i openvpn &&
+        echo "$CHROOT" | grep -q -v '\.\.'
+      then
+        USER_HOME=$CHROOT
+        # Copy requested files into the chroot.
+        local files_to_copy_into_chroot="$(\
+            egrep -h -v '^#|^[[:blank:]]*$' "$CHROOT_FILES"/*.files)"
+        for file in $files_to_copy_into_chroot ; do
+          case $file in
+            *..*)
+              log_warning_msg " Pattern .. illegal in chroot file name: $file"
+              ;;
+            /*)
+              mkdir -p "$CHROOT/$(dirname "$file")"
+              case $file in
+                /dev/null)
+                  test -c "$CHROOT"/dev/null || mknod "$CHROOT"/dev/null c 1 3
+                  ;;
+                /proc*)
+                  mkdir -p "$CHROOT/$file"
+                  mount --bind "$file" "$CHROOT/$file"
+                  ;;
+                /run/?*)
+                  mkdir -p "$CHROOT/$file"
+                  # Arrange that this, like in the real /run, gets
+                  # cleared at boot.
+                  grep -q "$CHROOT/$file" /etc/mtab ||
+                      mount -t tmpfs -o noexec,nodev none "$CHROOT/$file"
+                  rm -rf "$file"
+                  # Link from the real rooted directory so future
+                  # invocations of this script will find it.
+                  ln -s "$CHROOT/$file" "$file"
+                  ;;
+                /*)
+                  if [ -f "$file" ]; then
+                    cp -pu "$file" "$CHROOT/$file"
+                  elif [ -d "$file" ]; then
+                    dest_dir=$CHROOT/$(dirname "$file")
+                    cp -pua "$file" "$dest_dir"
+                  fi
+                  ;;
+              esac
+              ;;
+            *)
+              log_warning_msg " Non-absolute chroot file name ignored: $file"
+              ;;
+          esac
+        done
+      else
+        log_failure_msg "$NAME (illegal chroot directory name)"
+      fi
+    else
+      mkdir -p /run/openvpn
+    fi
+
+    USERARG=$(config_line user)
+    if test -n "$USERARG" ; then
+      # user requested in config file, may need to create it
+      if test -z "$(getent passwd "$USERARG")" ; then
+        adduser --system --group --home "$USER_HOME" "$USERARG"
+      fi
+    fi
 
     # tun using the "subnet" topology confuses the routing code that wrongly
     # emits ICMP redirects for client to client communications
@@ -96,10 +198,26 @@
       sysctl -w 
net.ipv4.conf.default.send_redirects=$SAVED_DEFAULT_SEND_REDIRECTS > /dev/null
     fi
 }
+
+# Stop 1 VPN.  $NAME is the name of the VPN to stop,
+# and $PIDFILE is the file containing the pid of its daemon.
 stop_vpn () {
   start-stop-daemon --stop --quiet --oknodo \
       --pidfile $PIDFILE --exec $DAEMON --retry 5
   if [ "$?" -eq 0 ]; then
+    if [ -x "$CONFIG_DIR/$NAME.down" ]; then
+      # This is the only envvar we can set.
+      export config="$CONFIG_DIR/$NAME.conf"
+      "$CONFIG_DIR/$NAME.down"
+    fi
+    CHROOT=$(config_line chroot)
+    if [ -n "$CHROOT" ]; then
+      # unmount any chrooted /run and /proc bind-mounts
+      bind_mounts=$(mount | sed -n -e "s+.* \($CHROOT[^ ]*\).*+\1+p")
+      for mounted in $bind_mounts; do
+        umount "$mounted"
+      done
+    fi
     rm -f $PIDFILE
     [ "$OMIT_SENDSIGS" -ne 1 ] || rm -f /run/sendsigs.omit.d/openvpn.$NAME.pid
     rm -f /run/openvpn/$NAME.status 2> /dev/null


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to