#!/bin/sh
#
# xsandbox username
#
# Start a nested XServer on display :1 and
# start processes in that Server as
# another user. Aim is to avoid grabbing
# of XEvents by untrusted programs which
# can be restricted to the nested display
#
# Requires sudo

function die {
	echo $1
	exit 1
}

user=$1
devrandom=/dev/arandom	# Replace with your favourite PRNG if necessary

if [ -z $user ]; then
	die "Please give a username"
fi

umask 0022

# Make two xauthority files, one for the user starting
# the script, the other as $user who will run inside the
# display.
xauth_you=`mktemp "/tmp/xauth.you.XXX"` || die "could not mktemp"
xauth_other=`sudo -u $user mktemp "/tmp/xauth.$user.XXX"` || \
	die "could not mktemp as $user"
x1=`dd if=$devrandom bs=32 count=1 2&gt;/dev/null | sha1`
x2=`dd if=$devrandom bs=32 count=1 2&gt;/dev/null | sha1`
cookie=`echo $x1$x2|cut -c-64`

# Clean up when finished
trap 'rm -f $xauth_you; sudo -u $user rm -f $xauth_other' EXIT INT

# Create auth cookie for display :1.0
xauth -i -f $xauth_you add :1.0 . $cookie || \
	die "could not create $xauth_you"

# Transfer authority to $user
xauth -i -f $xauth_you nextract - :1.0 | \
sudo -u $user xauth -f $xauth_other nmerge -  || \
die "Could not transfer authorization to $user"

# Start Xnest
Xnest :1 -auth $xauth_you -sss 2&gt;1 1&gt; /dev/null & xnest_pid=$!

# Start xterm as $user inside the Xnest
sudo -u $user sh -lc "export XAUTHORITY=$xauth_other; \
	/usr/X11R6/bin/xterm -display :1.0"

# Kill the Xnest when finished
kill $xnest_pid
