#!/usr/bin/perl

# Copyright (C) 2007-2012 by X2Go project, http://wiki.x2go.org
#       Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de>

# X2Go is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# X2Go is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

use strict;
use File::Path::Expand;
use Sys::Syslog qw( :standard :macros );

openlog($0,'cons,pid','user');
setlogmask( LOG_UPTO(LOG_NOTICE) );

sub check_x2gothinclientd {
	my $x=`ps ax | grep x2gothinclient`;
	if ( $x=~m/thinclientd/ )
	{
		return 1;
	}
	return 0;
}

if ( check_x2gothinclientd() )
{

	open (F,">>/var/log/usb");

	my $dev=$ENV{'DEVNAME'};
	my $model=$ENV{'ID_MODEL'};
	my $vendor=$ENV{'ID_VENDOR'};
	my $action=$ENV{'ACTION'};
	my @ldev=split("/","$dev");
	my $ldev=@ldev[@ldev-1];
	my $mntdir;
	if ( -d expand_filename("~/mounts")) {
		$mntdir=expand_filename("~/mounts");
	} elsif ( -d "/var/run" ) {
		$mntdir="/var/run";
	} elsif ( -d "/run" ) {
		$mntdir="/run";
	} else {
		die "No directory found that we could use as \$mntdir..."
	}

	my $name="${vendor}_${model}";
	$name=~s/ //g;
	$name=~s/\\//g;
	$name=~s/\///g;
	print F "action: $action,  device: $dev, model: $model ($ldev), total: $name\n";
	mkdir("/media");
	mkdir("/media/$name");
	print F "$name\n";       

	if ( $action eq "add")
	{

		###
		### ACTION: mount device after it has been added to USB subsystem
		###

		syslog('notice', "device add action called");

		# prepare mount points
		mkdir("/media");
		mkdir("/media/$name");
		mkdir("/media/$name/$ldev");

		# mount the USB device
		if(system("mount $dev /media/$name/$ldev -o uid=x2gothinclient,sync,uni_xlate")==0)
		{
			syslog('notice', "USB device $name ($ldev) successfully mounted");
			# if mounted, inform x2goclient about it...
			system("touch $mntdir/$ldev.mounted");
			open (D,">",expand_filename("~x2gothinclient/export/$name.$ldev"));
			print D "export=/media/$name/$ldev\n";
			close (D);
		}
		else
		{
			# the mount failed, let's assume that the device is encrypted...
			my $enc=`ls -1 $mntdir | grep .encrypted`;
			if(  $enc eq "" )
			{
				# use cryptsetup to decrypt the device...
				system("/sbin/cryptsetup --key-file /etc/keys/keystick.key luksOpen $dev keystick");

				# mount the ,,decrypted'' USB device via devmapper...
				if(system("mount /dev/mapper/keystick  /media/$name/$ldev ")==0)
				{
					# inform x2goclient about this...
					system("touch $mntdir/$ldev.encrypted");
					system("chown -R x2gothinclient /media/$name/$ldev/dsa.key");
					open (D,">",expand_filename("~/x2gothinclient/logins/$name.$ldev"));
					print D "login=/media/$name/$ldev\n";
					close (D);
				}
				else
				{
					# on mount failures release the decrypted device again
					system("/sbin/cryptsetup luksClose keystick");
				}
			}
			else
			{
				print F "cryptodisk already present\n";
			}
		}
	}
	elsif ( $action eq "remove" )
	{

		###
		### ACTION: unmount device after it has been removed from the USB subsystem
		###

		syslog('notice', "device remove action called");

		# we rely on our own mount logistics here...
		if ( -e "$mntdir/$ldev.mounted" )
		{
			# inform x2goclient that the device has been removed
			system ("umount -ff /media/$name/$ldev");
			unlink ("$mntdir/$ldev.mounted");
			open ( D,">",expand_filename("~x2gothinclient/export/$name.$ldev.unexport"));
			print D "unexport=/media/$name/$ldev\n";
			close (D);
			syslog('notice', "USB device $name ($ldev) successfully unmounted");
		}
		elsif ( -e "$mntdir/$ldev.encrypted" )
		{
			# inform x2goclient that the device has been removed
			# release the encrypted device mapping
			unlink ("$mntdir/$ldev.encrypted");
			open ( D,">",expand_filename("~/x2gothinclient/logins/$name.$ldev.unexport"));
			print D "logout=/media/$name/$ldev\n";
			system("umount /media/$name/$ldev");
			system("/sbin/cryptsetup luksClose keystick");
			close (D);
		}
	}

	close (F);
}
