#!/bin/sh
# @package      hubzero-mw2-front-virtualssh
# @file         xauth-incoming
# @author       Pascal Meunier <pmeunier@purdue.edu>
# @copyright    Copyright (c) 2016-2017 HUBzero Foundation, LLC.
# @license      http://opensource.org/licenses/MIT MIT
#
# Based on prior work by Richard L. Kennell
#
# Copyright (c) 2016-2017 HUBzero Foundation, LLC.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# HUBzero is a registered trademark of HUBzero Foundation, LLC.
#

# X11 and X forwarding support
# This program is called by the SSH daemon when the XAuthLocation option is specified:
# XAuthLocation /usr/bin/xauth-incoming
#
# XAuthLocation option in /etc/ssh/sshd_config is not configurable based on Match directives, so 
# this script must handle all users, doing regular SFTP, regular SSH, or virtual SSH
# most of the complexity is figuring out whether virtual SSH is being used or not.
#
# Goal: Modify calls to xauth to specify a custom path for the .Xauthority files of Virtual SSH users
#
# Normal logins use the user's home directory, as normal.
#
# For virtual SSH, we write the .Xauthority files in temporary directories 
# on the web server, so we don't mess up the user's home directories and to avoid 
# race conditions because ~/.Xauthority is also written to inside the containers. 
# We use a different directory for each user, and each user's display to a different session.
#
# Security analysis:  
# This script runs with the privileges of the login user (not elevated privileges, unless a privileged user logs on).
# This program uses predictable directory names in a shared directory, so a user that can login on the web server
# could possibly mess with the displays of other users.  
# Investigate trying to use a different path in the user's home instead.  XAUTHDIR must match with that in xauth-outgoing.
#
# The debug log file directory must therefore be writable by everyone.

DEBUG=0
if [ $DEBUG -eq 1 ]; then
  # warning:  don't leave DEBUG=1 in production
  echo "xauth incoming" >&2
  trap "echo xauth incoming exit; rm -f $tmpfile" 0 1 2 5 15

  #
  # Set up a log file.
  #
  tmpfile=`mktemp /tmp/xauth-in-XXXXXXXXXX.log`
  if [ $? -ne 0 ]; then
    echo can\'t create temporary file
    exit 1
  fi
  echo '<====' >> $tmpfile
  echo $(whoami): xauth $* >> $tmpfile
  env >> $tmpfile
fi

normal () {
	# treat this as a normal login and set up ~/.Xauthority.
	[ $DEBUG -eq 1 ] && echo "[Normal xauth]" >> $tmpfile
	for x in $(seq 1 3);	do
		[ $DEBUG -eq 1 ] && echo "Try #${x}" >> $tmpfile
		xauth -q $* && exit 0
	done
	[ $DEBUG -eq 1 ] && echo "Breaking .Xauthority lock" >> $tmpfile
	exec xauth -q -b $*
  exit 0
}

virtual () {
	#
	# avoid touching the user's .Xauthority file and drop it into a per-user temp directory.
	#
	[ $DEBUG -eq 1 ] && echo "[Virtualized xauth]" >> $tmpfile
	XAUTHDIR=/tmp/$(whoami)-$(echo ${DISPLAY} | tr '$' '_')
	mkdir -p -m 0700 ${XAUTHDIR}
	touch ${XAUTHDIR}/.Xauthority
	for x in $(seq 1 3)
	do
		[ $DEBUG -eq 1 ] && echo "Try #${x}" >> $tmpfile
		xauth -q -f ${XAUTHDIR}/.Xauthority $* && exit 0
	done
	[ $DEBUG -eq 1 ] && echo "Breaking .Xauthority lock" >> $tmpfile
	exec xauth -q -b -f ${XAUTHDIR}/.Xauthority $*
  exit 0
}

if [ `whoami` = 'root' ]; then
  normal
fi

# Privileged users must set X11_VSSH in their environment to be able to use X forwarding with Virtual SSH
# because a forced command wasn't used, SSH_ORIGINAL_COMMAND isn't set and we can't check for the "session" command
# users may need to set "SendEnv X11_VSSH" in their .ssh/config file (on their workstation/laptop)
if [ -n "$X11_VSSH" ]; then
  virtual
fi

# was this a forced command?  If so use virtual
echo "${SSH_ORIGINAL_COMMAND}" | egrep -q '^session( |$)' > /dev/null
if [ $? -eq 0 ]; then
  virtual
fi

# if not in privileged groups, use virtual
groups | egrep -q '(^| )(www-data|access-host|wheel|apache|staff|sudo)( |$)' > /dev/null
if [ $? -ne 0 ]; then
  virtual
fi
normal

