0b341f4fb2
Removed call from qubes_installation scripts for proxy files. will now be added by sub-template Renamed extra-whonix-files to files Modifies functions.sh to allow for very short proxy names and custom directories that will be dist independent
449 lines
11 KiB
Bash
Executable File
449 lines
11 KiB
Bash
Executable File
#
|
|
# Copyright (c) 2005 IBM Corporation
|
|
# Copyright (c) 2005 XenSource Ltd.
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of version 2.1 of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation.
|
|
#
|
|
# This library 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
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
|
|
dir=$(dirname "$0")
|
|
. "$dir/logging.sh"
|
|
. "$dir/locking.sh"
|
|
|
|
VTPMDB="/var/vtpm/vtpm.db"
|
|
|
|
#In the vtpm-impl file some commands should be defined:
|
|
# vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
|
|
if [ -r "$dir/vtpm-impl.alt" ]; then
|
|
. "$dir/vtpm-impl.alt"
|
|
elif [ -r "$dir/vtpm-impl" ]; then
|
|
. "$dir/vtpm-impl"
|
|
else
|
|
function vtpm_create () {
|
|
true
|
|
}
|
|
function vtpm_setup() {
|
|
true
|
|
}
|
|
function vtpm_start() {
|
|
true
|
|
}
|
|
function vtpm_suspend() {
|
|
true
|
|
}
|
|
function vtpm_resume() {
|
|
true
|
|
}
|
|
function vtpm_delete() {
|
|
true
|
|
}
|
|
function vtpm_migrate() {
|
|
echo "Error: vTPM migration accross machines not implemented."
|
|
}
|
|
function vtpm_migrate_local() {
|
|
echo "Error: local vTPM migration not supported"
|
|
}
|
|
function vtpm_migrate_recover() {
|
|
true
|
|
}
|
|
fi
|
|
|
|
|
|
#Find the instance number for the vtpm given the name of the domain
|
|
# Parameters
|
|
# - vmname : the name of the vm
|
|
# Return value
|
|
# Returns '0' if instance number could not be found, otherwise
|
|
# it returns the instance number in the variable 'instance'
|
|
function vtpmdb_find_instance () {
|
|
local vmname ret instance
|
|
vmname=$1
|
|
ret=0
|
|
|
|
instance=$(cat $VTPMDB | \
|
|
awk -vvmname=$vmname \
|
|
'{ \
|
|
if ( 1 != index($1,"#")) { \
|
|
if ( $1 == vmname ) { \
|
|
print $2; \
|
|
exit; \
|
|
} \
|
|
} \
|
|
}')
|
|
if [ "$instance" != "" ]; then
|
|
ret=$instance
|
|
fi
|
|
echo "$ret"
|
|
}
|
|
|
|
|
|
# Check whether a particular instance number is still available
|
|
# returns "0" if it is not available, "1" otherwise.
|
|
function vtpmdb_is_free_instancenum () {
|
|
local instance instances avail i
|
|
instance=$1
|
|
avail=1
|
|
#Allowed instance number range: 1-255
|
|
if [ $instance -eq 0 -o $instance -gt 255 ]; then
|
|
avail=0
|
|
else
|
|
instances=$(cat $VTPMDB | \
|
|
awk \
|
|
'{ \
|
|
if (1 != index($1,"#")) { \
|
|
printf("%s ",$2); \
|
|
} \
|
|
}')
|
|
for i in $instances; do
|
|
if [ $i -eq $instance ]; then
|
|
avail=0
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
echo "$avail"
|
|
}
|
|
|
|
|
|
# Get an available instance number given the database
|
|
# Returns an unused instance number
|
|
function vtpmdb_get_free_instancenum () {
|
|
local ctr instances don found
|
|
instances=$(cat $VTPMDB | \
|
|
awk \
|
|
'{ \
|
|
if (1 != index($1,"#")) { \
|
|
printf("%s ",$2); \
|
|
} \
|
|
}')
|
|
ctr=1
|
|
don=0
|
|
while [ $don -eq 0 ]; do
|
|
found=0
|
|
for i in $instances; do
|
|
if [ $i -eq $ctr ]; then
|
|
found=1;
|
|
break;
|
|
fi
|
|
done
|
|
|
|
if [ $found -eq 0 ]; then
|
|
don=1
|
|
break
|
|
fi
|
|
let ctr=ctr+1
|
|
done
|
|
echo "$ctr"
|
|
}
|
|
|
|
|
|
# Add a domain name and instance number to the DB file
|
|
function vtpmdb_add_instance () {
|
|
local res vmname inst
|
|
vmname=$1
|
|
inst=$2
|
|
|
|
if [ ! -f $VTPMDB ]; then
|
|
echo "#Database for VM to vTPM association" > $VTPMDB
|
|
echo "#1st column: domain name" >> $VTPMDB
|
|
echo "#2nd column: TPM instance number" >> $VTPMDB
|
|
fi
|
|
res=$(vtpmdb_validate_entry $vmname $inst)
|
|
if [ $res -eq 0 ]; then
|
|
echo "$vmname $inst" >> $VTPMDB
|
|
fi
|
|
}
|
|
|
|
|
|
#Validate whether an entry is the same as passed to this
|
|
#function
|
|
function vtpmdb_validate_entry () {
|
|
local res rc vmname inst
|
|
rc=0
|
|
vmname=$1
|
|
inst=$2
|
|
|
|
res=$(cat $VTPMDB | \
|
|
awk -vvmname=$vmname \
|
|
-vinst=$inst \
|
|
'{ \
|
|
if ( 1 == index($1,"#")) {\
|
|
} else \
|
|
if ( $1 == vmname && \
|
|
$2 == inst) { \
|
|
printf("1"); \
|
|
exit; \
|
|
} else \
|
|
if ( $1 == vmname || \
|
|
$2 == inst) { \
|
|
printf("2"); \
|
|
exit; \
|
|
} \
|
|
}')
|
|
|
|
if [ "$res" == "1" ]; then
|
|
rc=1
|
|
elif [ "$res" == "2" ]; then
|
|
rc=2
|
|
fi
|
|
echo "$rc"
|
|
}
|
|
|
|
|
|
#Remove an entry from the vTPM database given its domain name
|
|
#and instance number
|
|
function vtpmdb_remove_entry () {
|
|
local vmname instance VTPMDB_TMP
|
|
vmname=$1
|
|
instance=$2
|
|
VTPMDB_TMP="$VTPMDB".tmp
|
|
|
|
$(cat $VTPMDB | \
|
|
awk -vvmname=$vmname \
|
|
'{ \
|
|
if ( $1 != vmname ) { \
|
|
print $0; \
|
|
} \
|
|
'} > $VTPMDB_TMP)
|
|
if [ -e $VTPMDB_TMP ]; then
|
|
mv -f $VTPMDB_TMP $VTPMDB
|
|
vtpm_delete $instance
|
|
else
|
|
log err "Error creating temporary file '$VTPMDB_TMP'."
|
|
fi
|
|
}
|
|
|
|
|
|
# Find the reason for the creation of this device:
|
|
# Returns 'resume' or 'create'
|
|
function vtpm_get_create_reason () {
|
|
local resume
|
|
resume=$(xenstore_read $XENBUS_PATH/resume)
|
|
if [ "$resume" == "True" ]; then
|
|
echo "resume"
|
|
else
|
|
echo "create"
|
|
fi
|
|
}
|
|
|
|
|
|
#Create a vTPM instance
|
|
# If no entry in the TPM database is found, the instance is
|
|
# created and an entry added to the database.
|
|
function vtpm_create_instance () {
|
|
local res instance domname reason uuid
|
|
uuid=$(xenstore_read "$XENBUS_PATH"/uuid)
|
|
reason=$(vtpm_get_create_reason)
|
|
|
|
claim_lock vtpmdb
|
|
|
|
instance="0"
|
|
|
|
if [ "$uuid" != "" ]; then
|
|
instance=$(vtpmdb_find_instance $uuid)
|
|
fi
|
|
if [ "$instance" == "0" ]; then
|
|
domname=$(xenstore_read "$XENBUS_PATH"/domain)
|
|
instance=$(vtpmdb_find_instance $domname)
|
|
fi
|
|
|
|
if [ "$instance" == "0" -a "$reason" != "create" ]; then
|
|
release_lock vtpmdb
|
|
return
|
|
fi
|
|
|
|
if [ "$instance" == "0" ]; then
|
|
#Try to give the preferred instance to the domain
|
|
instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
|
|
if [ "$instance" != "" ]; then
|
|
res=$(vtpmdb_is_free_instancenum $instance)
|
|
if [ $res -eq 0 ]; then
|
|
instance=$(vtpmdb_get_free_instancenum)
|
|
fi
|
|
else
|
|
instance=$(vtpmdb_get_free_instancenum)
|
|
fi
|
|
|
|
vtpm_create $instance
|
|
|
|
if [ $vtpm_fatal_error -eq 0 ]; then
|
|
if [ "$uuid" != "" ]; then
|
|
vtpmdb_add_instance $uuid $instance
|
|
else
|
|
vtpmdb_add_instance $domname $instance
|
|
fi
|
|
fi
|
|
else
|
|
if [ "$reason" == "resume" ]; then
|
|
vtpm_resume $instance
|
|
else
|
|
vtpm_start $instance
|
|
fi
|
|
fi
|
|
|
|
release_lock vtpmdb
|
|
|
|
xenstore_write $XENBUS_PATH/instance $instance
|
|
}
|
|
|
|
|
|
#Remove an instance when a VM is terminating or suspending.
|
|
#Since it is assumed that the VM will appear again, the
|
|
#entry is kept in the VTPMDB file.
|
|
function vtpm_remove_instance () {
|
|
local instance reason domname uuid
|
|
#Stop script execution quietly if path does not exist (anymore)
|
|
xenstore-exists "$XENBUS_PATH"/domain
|
|
uuid=$(xenstore_read "$XENBUS_PATH"/uuid)
|
|
|
|
claim_lock vtpmdb
|
|
|
|
instance="0"
|
|
|
|
if [ "$uuid" != "" ]; then
|
|
instance=$(vtpmdb_find_instance $uuid)
|
|
fi
|
|
|
|
if [ "$instance" == "0" ]; then
|
|
domname=$(xenstore_read "$XENBUS_PATH"/domain)
|
|
instance=$(vtpmdb_find_instance $domname)
|
|
fi
|
|
|
|
if [ "$instance" != "0" ]; then
|
|
vtpm_suspend $instance
|
|
fi
|
|
|
|
release_lock vtpmdb
|
|
}
|
|
|
|
|
|
#Remove an entry in the VTPMDB file given the domain's name
|
|
#1st parameter: The name of the domain
|
|
function vtpm_delete_instance () {
|
|
local instance
|
|
|
|
claim_lock vtpmdb
|
|
|
|
instance=$(vtpmdb_find_instance $1)
|
|
if [ "$instance" != "0" ]; then
|
|
vtpmdb_remove_entry $1 $instance
|
|
fi
|
|
|
|
release_lock vtpmdb
|
|
}
|
|
|
|
# Determine whether the given address is local to this machine
|
|
# Return values:
|
|
# "-1" : the given machine name is invalid
|
|
# "0" : this is not an address of this machine
|
|
# "1" : this is an address local to this machine
|
|
function vtpm_isLocalAddress() {
|
|
local addr res
|
|
addr=$(ping $1 -c 1 | \
|
|
awk '{ print substr($3,2,length($3)-2); exit }')
|
|
if [ "$addr" == "" ]; then
|
|
echo "-1"
|
|
return
|
|
fi
|
|
res=$(ifconfig | grep "inet addr" | \
|
|
awk -vaddr=$addr \
|
|
'{ \
|
|
if ( addr == substr($2, 6)) {\
|
|
print "1"; \
|
|
} \
|
|
}' \
|
|
)
|
|
if [ "$res" == "" ]; then
|
|
echo "0"
|
|
return
|
|
fi
|
|
echo "1"
|
|
}
|
|
|
|
# Perform a migration step. This function differentiates between migration
|
|
# to the local host or to a remote machine.
|
|
# Parameters:
|
|
# 1st: destination host to migrate to
|
|
# 2nd: name of the domain to migrate
|
|
# 3rd: the migration step to perform
|
|
function vtpm_migration_step() {
|
|
local res=$(vtpm_isLocalAddress $1)
|
|
if [ "$res" == "0" ]; then
|
|
vtpm_migrate $1 $2 $3
|
|
else
|
|
vtpm_migrate_local
|
|
fi
|
|
}
|
|
|
|
# Recover from migration due to an error. This function differentiates
|
|
# between migration to the local host or to a remote machine.
|
|
# Parameters:
|
|
# 1st: destination host the migration was going to
|
|
# 2nd: name of the domain that was to be migrated
|
|
# 3rd: the last successful migration step that was done
|
|
function vtpm_recover() {
|
|
local res
|
|
res=$(vtpm_isLocalAddress $1)
|
|
if [ "$res" == "0" ]; then
|
|
vtpm_migrate_recover $1 $2 $3
|
|
fi
|
|
}
|
|
|
|
|
|
#Determine the domain id given a domain's name.
|
|
#1st parameter: name of the domain
|
|
#return value: domain id or -1 if domain id could not be determined
|
|
function vtpm_domid_from_name () {
|
|
local id name ids
|
|
ids=$(xenstore-list /local/domain)
|
|
for id in $ids; do
|
|
name=$(xenstore-read /local/domain/$id/name)
|
|
if [ "$name" == "$1" ]; then
|
|
echo "$id"
|
|
return
|
|
fi
|
|
done
|
|
echo "-1"
|
|
}
|
|
|
|
#Determine the virtual TPM's instance number using the domain ID.
|
|
#1st parm: domain ID
|
|
function vtpm_uuid_by_domid() {
|
|
echo $(xenstore-read /local/domain/0/backend/vtpm/$1/0/uuid)
|
|
}
|
|
|
|
|
|
# Determine the vTPM's UUID by the name of the VM
|
|
function vtpm_uuid_from_vmname() {
|
|
local domid=$(vtpm_domid_from_name $1)
|
|
if [ "$domid" != "-1" ]; then
|
|
echo $(vtpm_uuid_by_domid $domid)
|
|
return
|
|
fi
|
|
echo ""
|
|
}
|
|
|
|
#Add a virtual TPM instance number and its associated domain name
|
|
#to the VTPMDB file and activate usage of this virtual TPM instance
|
|
#by writing the instance number into the xenstore
|
|
#1st parm: name of virtual machine
|
|
#2nd parm: instance of associated virtual TPM
|
|
function vtpm_add_and_activate() {
|
|
local domid=$(vtpm_domid_from_name $1)
|
|
local vtpm_uuid=$(vtpm_uuid_from_vmname $1)
|
|
if [ "$vtpm_uuid" != "" -a "$domid" != "-1" ]; then
|
|
vtpmdb_add_instance $vtpm_uuid $2
|
|
xenstore-write backend/vtpm/$domid/0/instance $2
|
|
fi
|
|
}
|