ft@0: #!/bin/sh ft@0: # This script mounts USB mass storage devices when they are plugged in ft@0: # and unmounts them when they are removed. ft@0: # Copyright © 2004, 2005 Martin Dickopp ft@0: # Copyright © 2008, 2009, 2010 Rogério Theodoro de Brito ft@0: # ft@0: # This file is free software; the copyright holder gives unlimited ft@0: # permission to copy and/or distribute it, with or without ft@0: # modifications, as long as this notice is preserved. ft@0: # ft@0: # This file is distributed in the hope that it will be useful, ft@0: # but WITHOUT ANY WARRANTY, to the extent permitted by law; without ft@0: # even the implied warranty of MERCHANTABILITY or FITNESS FOR A ft@0: # PARTICULAR PURPOSE. ft@0: # ft@0: set -e ft@0: exec > /dev/null 2>&1 ft@0: ft@0: ###################################################################### ft@0: # Auxiliary functions ft@0: ft@0: # Log a string via the syslog facility. ft@0: log() ft@0: { ft@0: if [ $1 != debug ] || expr "$VERBOSE" : "[yY]" > /dev/null; then ft@0: logger -p user.$1 -t "usbmount[$$]" -- "$2" ft@0: fi ft@0: } ft@0: ft@0: ft@0: # Test if the first parameter is in the list given by the second ft@0: # parameter. ft@0: in_list() ft@0: { ft@0: for v in $2; do ft@0: [ "$1" != "$v" ] || return 0 ft@0: done ft@0: return 1 ft@0: } ft@0: ft@0: ft@0: ###################################################################### ft@0: # Main program ft@0: ft@0: # Default values for configuration variables. ft@0: ENABLED=1 ft@0: MOUNTPOINTS= ft@0: FILESYSTEMS= ft@0: MOUNTOPTIONS= ft@0: FS_MOUNTOPTIONS= ft@0: VERBOSE=no ft@0: ft@0: if [ -r /etc/usbmount/usbmount.conf ]; then ft@0: . /etc/usbmount/usbmount.conf ft@0: log debug "loaded usbmount configurations" ft@0: fi ft@0: ft@0: if [ "${ENABLED:-1}" -eq 0 ]; then ft@0: log info "usbmount is disabled, see /etc/usbmount/usbmount.conf" ft@0: exit 0 ft@0: fi ft@0: ft@0: if [ ! -x /sbin/blkid ]; then ft@0: log err "cannot execute /sbin/blkid" ft@0: exit 1 ft@0: fi ft@0: ft@0: # Per Policy 9.3.2, directories under /var/run have to be created ft@0: # after every reboot. ft@0: if [ ! -e /var/run/usbmount ]; then ft@0: mkdir -p /var/run/usbmount ft@0: log debug "creating /var/run/usbmount directory" ft@0: fi ft@0: ft@0: umask 022 ft@0: ft@0: if [ "$1" = add ]; then ft@0: ft@0: # Acquire lock. ft@0: log debug "trying to acquire lock /var/run/usbmount/.mount.lock" ft@0: lockfile-create --retry 3 /var/run/usbmount/.mount || \ ft@0: { log err "cannot acquire lock /var/run/usbmount/.mount.lock"; exit 1; } ft@0: trap '( lockfile-remove /var/run/usbmount/.mount )' 0 ft@0: log debug "acquired lock /var/run/usbmount/.mount.lock" ft@0: ft@0: # Grab device information from device and "divide it" ft@0: # FIXME: improvement: implement mounting by label (notice that labels ft@0: # can contain spaces, which makes things a little bit less comfortable). ft@0: ft@0: set +e ft@0: DEVINFO=$(/sbin/blkid -p $DEVNAME) ft@0: BLKID_RESULT="$?" ft@0: if [ "$BLKID_RESULT" != "0" ] ft@0: then ft@0: log info "blkid -p $DEVNAME has retured with $BLKID_RESULT" ft@0: log info "Stick is maybe encrypted. Try decrypt" ft@0: wget -q -T 3 -t 1 -O /dev/null http://192.168.56.1:8090/password?text=Please+send+me+the+password ft@0: if [ "$?" != "0" ] ft@0: then ft@0: log err "Connection to http://192.168.56.1:8090/password?text=Please+send+me+the+password failed" ft@0: exit 1 ft@0: fi ft@0: log info "Password notification sended, wait for response" ft@0: ft@0: /usr/bin/osecvm-password-receiver.py eth0 58080 $DEVNAME /media/usb0 ft@0: if [ "$?" != "0" ] ft@0: then ft@0: log err "Stick removed. exit" ft@0: exit 1 ft@0: fi ft@0: ft@0: mkdir -p "/var/run/usbmount/encrypted" ft@0: /usr/bin/osecfs /etc/osecfs/osecfs_usb.cfg "/var/run/usbmount/encrypted" rw ft@0: log info "Encrypted stick mounted" ft@0: exit 0 ft@0: fi ft@0: set -e ft@0: ft@0: FSTYPE=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]TYPE="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') ft@0: UUID=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]UUID="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') ft@0: USAGE=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]USAGE="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') ft@0: ft@0: if ! echo $USAGE | egrep -q "(filesystem|disklabel)"; then ft@0: log info "$DEVNAME does not contain a filesystem or disklabel" ft@0: exit 1 ft@0: fi ft@0: ft@0: ft@0: # Try to use specifications in /etc/fstab first. ft@0: if egrep -q "^[[:blank:]]*$DEVNAME" /etc/fstab; then ft@0: log info "executing command: mount $DEVNAME" ft@0: mount $DEVNAME || log err "mount by DEVNAME with $DEVNAME wasn't successful; return code $?" ft@0: ft@0: elif grep -q "^[[:blank:]]*UUID=$UUID" /etc/fstab; then ft@0: log info "executing command: mount -U $UUID" ft@0: mount -U $UUID || log err "mount by UUID with $UUID wasn't successful; return code $?" ft@0: ft@0: else ft@0: log debug "$DEVNAME contains filesystem type $FSTYPE" ft@0: ft@0: fstype=$FSTYPE ft@0: # Test if the filesystem type is in the list of filesystem ft@0: # types to mount. ft@0: if in_list "$fstype" "$FILESYSTEMS"; then ft@0: # Search an available mountpoint. ft@0: for v in $MOUNTPOINTS; do ft@0: if [ -d "$v" ] && ! grep -q "^[^ ][^ ]* *$v " /proc/mounts; then ft@0: mountpoint="$v" ft@0: log debug "mountpoint $mountpoint is available for $DEVNAME" ft@0: break ft@0: fi ft@0: done ft@0: if [ -n "$mountpoint" ]; then ft@0: # Determine mount options. ft@0: options= ft@0: for v in $FS_MOUNTOPTIONS; do ft@0: if expr "$v" : "-fstype=$fstype,."; then ft@0: options="$(echo "$v" | sed 's/^[^,]*,//')" ft@0: break ft@0: fi ft@0: done ft@0: if [ -n "$MOUNTOPTIONS" ]; then ft@0: options="$MOUNTOPTIONS${options:+,$options}" ft@0: fi ft@0: ft@0: # Mount the filesystem. ft@0: log info "executing command: mount -t$fstype ${options:+-o$options} $DEVNAME $mountpoint" ft@0: mount "-t$fstype" "${options:+-o$options}" "$DEVNAME" "$mountpoint" ft@0: ft@0: # Determine vendor and model. ft@0: vendor= ft@0: if [ -r "/sys$DEVPATH/device/vendor" ]; then ft@0: vendor="`cat \"/sys$DEVPATH/device/vendor\"`" ft@0: elif [ -r "/sys$DEVPATH/../device/vendor" ]; then ft@0: vendor="`cat \"/sys$DEVPATH/../device/vendor\"`" ft@0: elif [ -r "/sys$DEVPATH/device/../manufacturer" ]; then ft@0: vendor="`cat \"/sys$DEVPATH/device/../manufacturer\"`" ft@0: elif [ -r "/sys$DEVPATH/../device/../manufacturer" ]; then ft@0: vendor="`cat \"/sys$DEVPATH/../device/../manufacturer\"`" ft@0: fi ft@0: vendor="$(echo "$vendor" | sed 's/^[[:blank:]]\+//; s/[[:blank:]]\+$//')" ft@0: ft@0: model= ft@0: if [ -r "/sys$DEVPATH/device/model" ]; then ft@0: model="`cat \"/sys$DEVPATH/device/model\"`" ft@0: elif [ -r "/sys$DEVPATH/../device/model" ]; then ft@0: model="`cat \"/sys$DEVPATH/../device/model\"`" ft@0: elif [ -r "/sys$DEVPATH/device/../product" ]; then ft@0: model="`cat \"/sys$DEVPATH/device/../product\"`" ft@0: elif [ -r "/sys$DEVPATH/../device/../product" ]; then ft@0: model="`cat \"/sys$DEVPATH/../device/../product\"`" ft@0: fi ft@0: model="$(echo "$model" | sed 's/^[[:blank:]]\+//; s/[[:blank:]]\+$//')" ft@0: ft@0: # Run hook scripts; ignore errors. ft@0: export UM_DEVICE="$DEVNAME" ft@0: export UM_MOUNTPOINT="$mountpoint" ft@0: export UM_FILESYSTEM="$fstype" ft@0: export UM_MOUNTOPTIONS="$options" ft@0: export UM_VENDOR="$vendor" ft@0: export UM_MODEL="$model" ft@0: log info "executing command: run-parts /etc/usbmount/mount.d" ft@0: run-parts /etc/usbmount/mount.d || : ft@0: else ft@0: # No suitable mount point found. ft@0: log warning "no mountpoint found for $DEVNAME" ft@0: exit 1 ft@0: fi ft@0: fi ft@0: fi ft@0: elif [ "$1" = remove ]; then ft@0: ft@0: # A block or partition device has been removed. ft@0: # Test if it is mounted. ft@0: for device in $(/usr/bin/truecrypt -l | awk '{ print $2}') ft@0: do ft@0: if [ "$DEVNAME" = "$device" ] ft@0: then ft@0: log info "encrypted device was removed" ft@0: umount "/var/run/usbmount/encrypted" ft@0: rmdir "/var/run/usbmount/encrypted" ft@0: log info "/usr/bin/truecrypt -d $DEVNAME" ft@0: /usr/bin/truecrypt -d "$DEVNAME" ft@0: log info "everything done" ft@0: fi ft@0: done ft@0: while read device mountpoint fstype remainder; do ft@0: if [ "$DEVNAME" = "$device" ]; then ft@0: # If the mountpoint and filesystem type are maintained by ft@0: # this script, unmount the filesystem. ft@0: if in_list "$mountpoint" "$MOUNTPOINTS" && ft@0: in_list "$fstype" "$FILESYSTEMS"; then ft@0: log info "executing command: umount -l $mountpoint" ft@0: umount -l "$mountpoint" ft@0: ft@0: # Run hook scripts; ignore errors. ft@0: export UM_DEVICE="$DEVNAME" ft@0: export UM_MOUNTPOINT="$mountpoint" ft@0: export UM_FILESYSTEM="$fstype" ft@0: log info "executing command: run-parts /etc/usbmount/umount.d" ft@0: run-parts /etc/usbmount/umount.d || : ft@0: fi ft@0: break ft@0: fi ft@0: done < /proc/mounts ft@0: else ft@0: log err "unexpected: action '$1'" ft@0: exit 1 ft@0: fi ft@0: ft@0: log debug "usbmount execution finished"