Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagebash
titleaddconnection.sh
linenumberstrue
#!/bin/bash

pass=replace_with_your_pass 

logfile=/home/vclguac/logs/addremoveconnections.log 

if [ "$#" -lt 3 ]; then
	echo "Usage:"
	echo ""
	echo "$0 <username> <IP> \"<image name>\""
	exit 1
fi

username=$1
IP=$2
image=$3
remoteIP=$4
conname="$username - $image - $IP"

now=`date`
echo "================================================================================" >> $logfile
echo "$now - adding connection entry" >> $logfile
echo "user:   $username" >> $logfile
echo "IP:     $IP" >> $logfile
echo "userIP: $remoteIP" >> $logfile
echo "image:  $image" >> $logfile
echo "name:   $conname" >> $logfile

# check that user has account
cnt=$(mysql -s -u vclguacsql -p$pass guacamole_db -e "SELECT COUNT(user_id) FROM guacamole_user WHERE full_name = '$username';" | tail -n 1)
if [[ "$cnt" -ne 1 ]]; then
       cat /home/vclguac/createusertemplate.sql | sed "s/THENEWUSER/$username/g" | mysql -u vclguacsql -p$pass guacamole_db | tee -a $logfile
fi

mysql -u vclguacsql -p$pass guacamole_db -e "INSERT INTO guacamole_connection (connection_name, protocol) VALUES ('$conname', 'rdp');" | tee -a $logfile

mysql -u vclguacsql -p$pass guacamole_db -e "INSERT INTO guacamole_connection_permission (entity_id, connection_id, permission) VALUES ((SELECT entity_id FROM guacamole_entity WHERE name = '$usern
ame$username' AND \`type\` = 'USER'), (SELECT connection_id FROM guacamole_connection WHERE connection_name = '$conname' AND protocol = 'rdp'), 'READ');" | tee -a $logfile

mysql -u vclguacsql -p$pass guacamole_db -e "INSERT INTO guacamole_connection_parameter (connection_id, parameter_name, parameter_value) VALUES ((SELECT connection_id FROM guacamole_connection WHE
REWHERE connection_name = '$conname' AND protocol = 'rdp'), 'disable-auth', 'true'), ((SELECT connection_id FROM guacamole_connection WHERE connection_name = '$conname' AND protocol = 'rdp'), 'hostname
', '$IP'), ((SELECT connection_id FROM guacamole_connection WHERE connection_name = '$conname' AND protocol = 'rdp'), 'ignore-cert', 'true'), ((SELECT connection_id FROM guacamole_connection WHERE
 connection_name = '$conname' AND protocol = 'rdp'), 'port', '3389'), ((SELECT connection_id FROM guacamole_connection WHERE connection_name = '$conname' AND protocol = 'rdp'), 'resize-method', 'd
isplaydisplay-update'), ((SELECT connection_id FROM guacamole_connection WHERE connection_name = '$conname' AND protocol = 'rdp'), 'security', 'any');" | tee -a $logfile

if [[ $remoteIP != "" ]]; then
       sudo /usr/local/bin/add_iptables_client.sh $remoteIP $username $IP | tee -a $logfile
fi

...

Code Block
languagesql
titlecreateusertemplate.sql
linenumberstrue
-- Generate salt 
SET @salt = UNHEX(SHA2(UUID(), 256)); 

-- Create base entity entry for user 
INSERT INTO guacamole_entity (name, type) 
VALUES ('THENEWUSER', 'USER'); 

-- Create user and hash password with salt 
INSERT INTO guacamole_user ( 
   entity_id, 
   password_salt, 
   password_hash, 
   password_date, 
   full_name 
) 
SELECT 
   entity_id, 
   @salt, 
   UNHEX(SHA2(CONCAT(LEFT(MD5(RAND()), 20), HEX(@salt)), 256)), 
   CURRENT_TIMESTAMP, 
   'THENEWUSER' 
FROM guacamole_entity 
WHERE 
   name = 'THENEWUSER' 
   AND type = 'USER'; 


INSERT INTO guacamole_user_permission (entity_id, affected_user_id, permission) 
VALUES 
((SELECT entity_id FROM guacamole_entity WHERE name = 'THENEWUSER' AND `type` = 'USER'), (SELECT user_id FROM guacamole_user WHERE full_name = 'THENEWUSER'), 'READ'), 
(1, (SELECT user_id FROM guacamole_user WHERE full_name = 'THENEWUSER'), 'READ'), 
(1, (SELECT user_id FROM guacamole_user WHERE full_name = 'THENEWUSER'), 'UPDATE'), 
(1, (SELECT user_id FROM guacamole_user WHERE full_name = 'THENEWUSER'), 'ADMINISTER'), 
(1, (SELECT user_id FROM guacamole_user WHERE full_name = 'THENEWUSER'), 'DELETE')

...

Code Block
languagebash
titledelconnection.sh
linenumberstrue
#!/bin/bash 

pass=replace_with_your_pass

logfile=/home/vclguac/logs/addremoveconnections.log 

if [ "$#" -lt 2 ]; then 
       echo "Usage:" 
       echo "" 
       echo "$0 <IP> \"<image name>\"" 
       exit 1 
fi 

IP=$1 
image=$2 
username=$3 
remoteIP=$4 
conname="$username - $image - $IP" 

now=`date` 
echo "================================================================================" >> $logfile 
echo "$now - deleting connection entry" >> $logfile 
echo "user:   $username" >> $logfile 
echo "IP:     $IP" >> $logfile 
echo "userIP: $remoteIP" >> $logfile 
echo "image:  $image" >> $logfile 
echo "name:   $conname" >> $logfile 

mysql -u vclguacsql -p$pass guacamole_db -e "DELETE FROM guacamole_connection WHERE connection_name = '$conname' AND protocol = 'rdp';" | tee -a $logfile 

if [[ $remoteIP != "" ]]; then 
       sudo /usr/local/bin/del_iptables_client.sh $remoteIP $username $IP 
fi

...

Code Block
languagebash
vclsystem ALL= NOPASSWD: /usr/local/bin/add_iptables_client.sh,/usr/local/bin/del_iptables_client.sh


Management Node

...

Patch

The DataStructure.pm file needs to be patched to add OS information to it. Create a patch file named guacamole_DataStructure.patch with the following content in it:


Code Block
languageperl
titleguacamole_DataStructure.patch
linenumberstrue
diff --git managementnode/lib/VCL/DataStructure.pm managementnode/lib/VCL/DataStructure.pm
index 8ffe9a2..238e164 100644
--- managementnode/lib/VCL/DataStructure.pm
+++ managementnode/lib/VCL/DataStructure.pm
@@ -2342,6 +2342,7 @@ sub get_reservation_info_json_string {
	$json_data->{reservation} 		= prune_hash_child_references($request_data_clone->{reservation}{$reservation_id});
	$json_data->{imagerevision}	= prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{imagerevision});
	$json_data->{image} 				= prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{image});
+	$json_data->{OS}              = prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{image}{OS});
	$json_data->{computer} 			= prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{computer});
 	
	if (defined($request_data_clone->{reservation}{$reservation_id}{computer}{vmhost})) {
@@ -2349,10 +2350,15 @@ sub get_reservation_info_json_string {
		$json_data->{vmhost_computer}	= prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{computer}{vmhost}{computer});
	}
 	
-	# TODO: figure out how to handle user info, what structure, etc
	#$json_data->{users} 				= $request_data_clone->{reservation}{$reservation_id}{users};
-	#$json_data->{user} = $request_data_clone->{user};
-	#$json_data->{user}{username} = $json_data->{user}{unityid};
+	$json_data->{user}              = prune_hash_child_references($request_data_clone->{user});
+	$json_data->{user}{username}    = $json_data->{user}{unityid};
+	$json_data->{user}{affiliation} = $request_data_clone->{user}{affiliation}{name};
+
+	my @delete_keys = ('IMtypeid', 'sshpublickeys', 'showallgroups', 'validated', 'usepublickeys', 'RETRIEVAL_TIME', 'lastupdated', 'FEDERATED_LINUX_AUTHENTICATION', 'IMid', 'ROOTACCESS');
+	foreach my $key (@delete_keys) {
+		delete $json_data->{user}{$key};
+	}

	# IMPORTANT: delete vmprofile data and anything else that may contain passwords
	#delete $json_data->{computer}{vmhost}{vmprofile};

After creating the patch, cd to /usr/local/vcl and apply the patch with the following command (assuming the patch is in /tmp):

Code Block
languagebash
patch -p1 --ignore-whitespace < /tmp/guacamole_DataStructure.patch

You should see output similar to:

Code Block
patching file lib/VCL/DataStructure.pm
Hunk #1 succeeded at 2303 (offset -39 lines). 
Hunk #2 succeeded at 2311 (offset -39 lines).

Restart vcld after applying the patch.

Management Node Scripts

There are three hook scripts that need to be added to the management node so that connections are added/removed There are three hook scripts that need to be added to the management node so that connections are added/removed on the Guacamole server as reservations are created and deleted. All of the scripts are located under /usr/local/vcl/tools/ManagementNode/Scripts. Ensure to set the IP address for your Guacamole server in place of 10.10.10.10 for $guacServerIP.

...

Code Block
languageperl
titlepost_reservation/guacamole_post_reservation.pl
linenumberstrue
#!/usr/bin/perl 
use strict; 
use warnings FATAL => 'all'; 

use JSON; 

my $guacServerIP=10.10.10.10;

my $datafile = $ARGV[0]; 

if(! (open(DATA, '<', "$datafile"))) { 
  exit 1; 
} 

my $jsondata = do { local $/; <DATA> }; 
close(DATA); 

my $data = decode_json($jsondata); 

my $image = $data->{image}{prettyname}; 
$image =~ s/[\[\]\(\)\!\@\#\$\%\^\&\*\+\=\<\>]//g; 

if($data->{OS}{type} eq 'windows') { 
   `ssh -q -i /etc/vcl/vcl.key vclguac\@
$guacServerIP@$guacServerIP ./delconnection.sh $data->{computer}{IPaddress} \\'$image\\' $data->{user}{unityid} $data->{reservation}{remoteIP}`; 
   `ssh -q $data->{computer}{privateIPaddress} c:/windows/sysnative/netsh.exe advfirewall firewall delete rule name=\\\\\\"VCL: allow TCP/3389 from Guacamole server\\\\\\"`; 
   `echo "\$(date) deleted firewall rule on $data->{computer}{IPaddress} for Guacamole server" >> /var/log/guacamole.log`; 
} 

...

Code Block
languageperl
titlepost_reserve/guacamole_post_reserve.pl
linenumberstrue
#!/usr/bin/perl 
use strict; 
use warnings FATAL => 'all'; 

use JSON; 

my $guacServerIP=10.10.10.10;

my $datafile = $ARGV[0]; 

if(! (open(DATA, '<', "$datafile"))) { 
  exit 1; 
} 

my $jsondata = do { local $/; <DATA> }; 
close(DATA); 

my $data = decode_json($jsondata); 

my $image = $data->{image}{prettyname}; 
$image =~ s/[\[\]\(\)\!\@\#\$\%\^\&\*\+\=\<\>]//g; 

if($data->{OS}{type} eq 'windows') { 
   `ssh -q -i /etc/vcl/vcl.key vclguac\@$guacServerIP ./addconnection.sh $data->{user}{unityid} $data->{computer}{IPaddress} \\'$image\\' $data->{reservation}{remoteIP}`; 
   `ssh -q $data->{computer}{privateIPaddress} c:/windows/sysnative/netsh.exe advfirewall firewall add rule name=\\\\\\"VCL: allow TCP/3389 from Guacamole server\\\\\\" dir=in action=allow protocol=tcp localport=3389 remoteip=
$guacServerIP`; 
   `echo "\$(date) added firewall rule on $data->{computer}{IPaddress} for Guacamole server" >> /var/log/guacamole.log`; 
   `ssh -q $data->{computer}{privateIPaddress} \"echo vcld_tainted=user may have logged in >> currentimage.txt\"` 
} 

...

Code Block
languagesql
INSERT INTO connectmethod (name, description, connecttext, servicename, startupscript) VALUES 
('guacamole', 'Guacamole Web Connection', 'Use your web browser to connect to the following URL. If you only have one reservation, you will be connected to it after logging in to Guacamole. If you have multiple reservations, select the desired reservation after logging in to the Guacamole server. Use the following username and password when logging in to your reservation after logging in to the Guacamole server. <br>\r\n<ul>\r\n<li><b>URL</b>: <a href=\"https://10.10.10.10/\">https://10.10.10.10/</a></li>\r\n<li><b>User ID</b>: #userid#</li>\r\n<li><b>Password</b>: #password#</li>\r\n</ul>\r\n', '', NULL);
INSERT INTO connectmethodmap (connectmethodid, OStypeid, OSid, imagerevisionid, disabled, autoprovisioned) VALUES 
((SELECT id FROM connectmethod WHERE name = 'guacamole'), (SELECT id FROM OStype WHERE name = 'windows'), NULL, NULL, 0, 1);

...