IgnorantGuru / udevil

Mount without password
http://ignorantguru.github.com/udevil/
GNU General Public License v3.0
129 stars 30 forks source link

Implementing LUKS support with a wrapper script #79

Closed Chrysostomus closed 6 years ago

Chrysostomus commented 6 years ago

I apologize if this a wrong forum for this query. This is not a issue per se, but a question about udevils behavior.

I'm trying to extend udevil with a script in order to easily mount LUKS encrypted devices in spacefm. It is a simple password query with spacefm dialog, which takes device path as an argument:

#!/bin/sh
#needs to be run as root
#usage example: cryptomount /dev/sda4
device="$1"

if $(cryptsetup isLuks $device); then
    #Create device name
    if ! [ -z "$2"]; then
        devicename="$2"
    elif [ -e /dev/mapper/LUKS1 ]; then
        last_dev=$(echo /dev/mapper/LUKS* | sort | tail -n1)
        newnum=$((last_dev+1))  
        devicename="LUKS$newnum"
    else
        devicename="LUKS1"
    fi
    echo "cryptsetup luksOpen $device $devicename"
    #Open luks container
    eval "`spacefm -g --label "Password need to decrypt $device" --hbox --icon dialog-password-symbolic.symbolic --password --button cancel --button ok --title Cryptomount`"
    PASSWD="$dialog_password1"
    echo "$PASSWD" | cryptsetup luksOpen "$device" "$devicename"
    #mount the luks decice
    [ -e /media/"$devicename"] || mkdir /media/"$devicename"
    mount /dev/mapper/"$devicename" /media/"$devicename"
        exit 1
else
    exit 0
fi

I was thinking I could put it in validate_rootexec section of udevil.conf, but it does not seem to work there. Does validate_rootexec pass any arguments to the program it runs?

Also, is there a better way to do this? I would prefer to first decrypt the volume as root and then mount it with udevil.

IgnorantGuru commented 6 years ago

Does validate_rootexec pass any arguments to the program it runs?

From udevil.conf (validate_exec, which passes the same arguments as validate_rootexec):

# The program is passed the username, a printable description of what is
# happening, and the entire udevil command line as the first three arguments.

So to get the device path, you'll have to parse $3 yourself. $1 is only the username running udevil. I recommend running a test script which prints the values of $1, $2, and $3 so you can get that parse working as desired. This will also confirm that validate_rootexec is running when expected.

For example, you can use awk to split a string into space-separated parts. For example:

# This will print "bbb"
echo "aaa bbb ccc" | awk '{print $2}'

So to extract the third part of $3 passed by udevil (which may be the device path depending on the udevil command used):

devpath=`echo "$3" | awk '{print $3}'`

Note that in the above command, the first $3 refers to the third argument passed to your script by udevil (which contains the whole udevil command line quoted as a single string), and the second $3 in the awk command refers to the third column of the string passed to awk, usually the device path.

You can also simply hardcode the device path into your script if it doesn't change.

udevil doesn't have any awareness of LUKS containers, so that aspect will be up to you to handle. But it should be able to mount, maybe with some adjustments to udevil.conf required. Test it on the command line first, of course, before attempting to script it. Note that udevil performs its own checks prior to running validate_rootexec, so the LUKS container may have trouble passing those checks if it's not mountable at that point. Instead, you may want to run your script directly, have it unlock the container, and then have it run udevil to perform the mount, rather than udevil running your script via validate_rootexec.

One note: In your script, you might consider running spacefm with reduced priviledges (using su to run it as a normal user). There are pros and cons to this you can explore. Just note that when running spacefm as root, it runs GTK+ libraries as root, which can open exploits not suitable to a highly secure task.

For example, if you run this command as root, it will run spacefm as USERNAME (substitute normal user on your system) instead of as root:

su -c "spacefm -g --label test" <USERNAME>

Likewise, udevil does not usually need to be run as root, so your script will only need to do the unlock command as root. This makes your script safer (it can drop root priviledges for everything except the actual unlock command that requires root).

IgnorantGuru commented 6 years ago

Also, the most secure way to run your script from within SpaceFM is to create a custom command in the menus, then export and install the custom command as a plugin, so it is accessible via the Plugins menu. This will give the script and command root protection. Thus you would select the device you want to mount, and run the command from Plugins.

You can also add a SpaceFM device handler for LUKS, but that lacks root protection so is not recommended in this case.

Chrysostomus commented 6 years ago

Awesome, thank you very much for your detailed response and time! I should have read the configuration file more thoroughly. You gave me a lot to think about.