Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
138 lines (111 sloc) 4.09 KB
#!/bin/sh
################################################################################
# Thunderbolt(TM) tbtacl tool
# This code is distributed under the following BSD-style license:
#
# Copyright(c) 2017 Intel Corporation.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Intel Corporation nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
################################################################################
log="logger -t tbtacl $$:"
$log args: "$*"
acltree=/var/lib/thunderbolt/acl
write_helper=@UDEV_BIN_DIR@/tbtacl-write
action=$1
device=/sys$2
debug() {
$log "$*"
}
die() {
debug "$*"
exit 1
}
# The main function to authorize a specific device. The parameter it expects is
# the full sysfs path to the device. Then, if the device is found in ACL, it
# authorizes it.
authorize() {
# TOCTOU protection: chdir so if an attacker replaces the device between
# the read of unique_id and the write of authorized, the write will fail
cd "$1" || { debug "can't access $1" ; return 1 ; }
$log authorizing "$1"
uuid=$( cat unique_id )
[ -n "$uuid" ] || { debug -p err no UUID; return 1 ; } # Exit if UUID read failed
[ -e "$acltree/$uuid" ] || { debug not in ACL ; return 1 ; } # Exit if UUID isn't in ACL
if [ "$sl" -eq 2 ]; then
# Exit if device doesn't support SL2 or key is empty
[ -e key ] || { debug "device doesn't support SL2"; return 1 ; }
[ -e "$acltree/$uuid/key" ] || { debug no key found ; return 1 ; }
cat "$acltree/$uuid/key" > key
$log key found
fi
$write_helper "$sl" authorized
err=$?
if which errno; then
errstr=$( errno $err | cut -d' ' -f1 )
fi
$log "authorization result: $err $errstr"
case "$err" in
126|129) # ENOKEY or EKEYREJECTED
rm -f "$acltree/$uuid/key"
debug invalid key removed, reapprove
udevadm trigger -c change "$1" # Not needed if GUI watchs $acltree/$uuid/key
;;
esac
}
# Find the domain and extract the current SL
domain=$device
while [ -n "$domain" ] && [ "$domain" != '/' ]; do
basename "$domain" | grep -Fq "domain" && break
domain=$( dirname "$domain" )
done
sl=$( cat "$domain/security" )
case "$sl" in
user) sl=1
;;
secure) sl=2
;;
*) die SL is $sl, leaving...
;;
esac
case "$action" in
# New device attached, go to authorize it
add) authorize "$device"
;;
# The device got authorized, let's try to authorize again the devices
# behind it
change) list="$device/*/authorized" # this glob is expanded later
# Stop if no substitution was done (no relevant childs found)
echo $list | grep -Fvq '*' || die no childs found
for i in $list ; do
i=$( dirname "$i" )
[ -e "$i/uevent" ] || continue
if grep -Fxq 'DEVTYPE=thunderbolt_device' "$i/uevent"; then
authorize "$i"
fi
done
;;
*) die "unhandled action: $action"
;;
esac