Is there any chance to install Pamusb for external authentication by usb or SDcard on Ubuntu 16.04? It seems there's no longer pamusb for this LTS version!
Please advise or please recommend if any alternatives. Thank you very much!
Is there any chance to install Pamusb for external authentication by usb or SDcard on Ubuntu 16.04? It seems there's no longer pamusb for this LTS version!
Please advise or please recommend if any alternatives. Thank you very much!
This is not a PAM module. All it really does is automate typing the password and pressing enter. As such you should be REALLY CAREFUL when you plug in a USB stick. Your password will be typed into whatever application has focus, and then the enter key will be sent. This could be really bad if, say, the active window is a chat client. These scripts are made available as is, and before implementation you should probably add extra security measures. For example, one security measure I actually use that is not implemented here is to write the encrypted password to unused space before the first partition on my USB stick (with dd). Perhaps checking to see if we're on a login screen would be another security measure that should be implemented. Use this at your own risk! By using or tweaking any information/code provided below, you assume all responsibility for securing your own implementation.
I was faced with this same problem and created my own workaround hack. I'm using this on Ubuntu 16.04 with lightdm (which is the default). It will enter credentials ANYTIME a usb "key" is inserted, so BE CAREFUL when plugging in your USB stick when the screen is not locked!
When a USB stick is authorized to be used for authentication, various information from the USB stick is used as a password that is in turn used to encrypt your password. This encrypted password is then stored somewhere on the computer.
Next, a udev rule is written that watches for USB storage devices to be added to the system. When a USB storage device is added, the device path is written to a named pipe that is watched by a helper script.
Finally, the helper script that reads from the named pipe checks to see if the inserted USB has an associated, encrypted password entry. If it does, the encrypted password is decrypted and automatically typed wherever the focus is followed by the return key. It is important that the helper script be separate from the udev script because the scope in which the udev script runs prevents us from being able to use the xdotool as needed.
Insert the USB you want to use to log in. Copy the following script to an empty file and run* once: *Be aware that this script will create the path /etc/usbauth and it will install xdotool on your system.
#!/bin/bash
# This is the a script for authorizing USB devices as logon devices
# run as root
if [ "$(whoami)" != root ]; then
sudo $0 $@
exit
fi
# Install the xdotool if it's not already installed
(
[ "$(which xdotool)" == "" ] && apt install -y xdotool
) &
encryptedPasswordStorage="/etc/usbauth" # path where encrypted passwords are stored
# if path does not exist create it and make sure permissions are set correctly
[ ! -d "$encryptedPasswordStorage" ] && mkdir -p "$encryptedPasswordStorage"
chown root:root $encryptedPasswordStorage
chmod 700 $encryptedPasswordStorage
# Get a list of attached USB storage devices
usbDevices=$(ls -l /dev/disk/by-uuid/ | grep -oP "/sd[a-z][0-9]?" | sort | awk '{print "/dev" $1}' | while read part; do [ "$(udevadm info -q all -n $part | grep "E: ID_BUS" | cut -f2 -d=)" == "usb" ] && echo $part; done)
# Iterate over this list and display partitions
while read device
do
info="$(udevadm info -q all -n $device)"
vendor=$(echo "$info" | grep "E: ID_VENDOR_ID=" | cut -f2 -d=)
model=$(echo "$info" | grep "E: ID_MODEL_ID=" | cut -f2 -d=)
sn=$(echo "$info" | grep "E: ID_SERIAL_SHORT=" | cut -f2 -d=)
uuid=$(echo "$info" | grep "E: ID_FS_UUID=" | cut -f2 -d=)
label=$(echo "$info" | grep "E: ID_FS_LABEL=" | cut -f2 -d=)
key="$vendor$model$sn$uuid"
checksum=$(echo -n "$key" | sha256sum | cut -f1 -d' ')
keyList[$[++i]]="$key" # used as an encryption key for encrypting account password
labelList[$i]="$label"
checksumList[$i]="$checksum"
printf "%5s %-9s %-15s %s\n" "[$i]" $device "$label" $sn
done<<<"$usbDevices"
# Ask user which attached device should be used for authentication
echo ""
read -p "Enter the number of the device to authorize: " selection
read -sp "Enter your login password: " pwd
key=${keyList[$selection]}
encpwd=$(gpg2 --output - -a -c --passphrase "$key" --batch --cipher-algo AES256 --digest-algo SHA512<<< "$pwd")
# Save the encrypted password to the system
encPwdFile="$encryptedPasswordStorage/${labelList[$selection]}_${checksumList[$selection]}"
echo -e "$encpwd" > "$encPwdFile"
chmod 600 "$encPwdFile"
echo ""
* From here on out, create/edit all files as root or with sudo *
Next create the file /etc/usbauth/udev.sh with the following contents
#!/bin/bash
# This script watches for USB storage devices. As they are plugged in, this script
# sends the path of these devices to a named pipe that is watched by our helper
# script.
# This script is intended to be called by udev. Add the following rule
# file path: /etc/udev/rules.d/80-USB.rules
# file contents: ACTION=="add",KERNEL=="sd[a-z]*",RUN+="[path to this script]"
encryptedPasswordStorage="/etc/usbauth" # path where encrypted passwords are stored
namedPipe="/tmp/usb-auth" # named pipe used for notification of added USB storage devices
[ -e "$namedPipe" ] && echo "$DEVNAME" > "$namedPipe"
We need to create a udev rule as well. Create /etc/udev/rules.d/80-USB.rules with the following content.
ACTION=="add",KERNEL=="sd[a-z]*",RUN+="/etc/usbauth/udev.sh"
Now, create one last file, /etc/usbauth/lightdm.sh with the following content.
#!/bin/sh
# this is the helper script that reads devices that are added and automates typing
# the password if an authorized stick is plugged in.
(
encryptedPasswordStorage="/etc/usbauth" # path where encrypted passwords are stored
namedPipe="/tmp/usb-auth" # named pipe used for notification of added USB storage devices
rm "$namedPipe"; mkfifo "$namedPipe" # create the named pipe
while true;do # this infinite loop helps to ensure that we're always watching for the next device
while read device # when a device is read ...
do
# gather information about the device that was read
info="$(udevadm info -q all -n $device)"
vendor=$(echo "$info" | grep "E: ID_VENDOR_ID=" | cut -f2 -d=)
model=$(echo "$info" | grep "E: ID_MODEL_ID=" | cut -f2 -d=)
sn=$(echo "$info" | grep "E: ID_SERIAL_SHORT=" | cut -f2 -d=)
uuid=$(echo "$info" | grep "E: ID_FS_UUID=" | cut -f2 -d=)
key="$vendor$model$sn$uuid"
checksum=$(echo -n "$key" | sha256sum | cut -f1 -d' ')
# check to see if this device has an associted encrypted password file
encpwdFile="$(find $encryptedPasswordStorage -type f | grep "$checksum")"
echo "$key:checksum --> $encpwdFile" > /tmp/encfile
# if it does, decrypt the password, type it on the screen and press [Enter]
if [ -e "$encpwdFile" ]; then
pwd=$(gpg2 -a -d --passphrase "$key" --batch --output - < $encpwdFile)
echo "$pwd" > /tmp/pwd
xdotool type "$pwd"
sleep .5
xdotool key Return
fi
done < "$namedPipe"
done
) &
This script must be called when lightdm starts. To do that, edit /usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf. Under [Seat:*]
add
greeter-setup-script=/etc/usbauth/lightdm.sh
So for example, my /usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf file looks like
[Seat:*]
greeter-session=unity-greeter
greeter-setup-script=/etc/usbauth/lightdm.sh
I haven't created a script for managing USB devices that have been added, but you will find all of them listed in /etc/usbauth. Each encrypted password file in this folder begins with a partition label name followed by an underscore and the sha256 hash of the key used to encrypt the password. Simply deleting the encrypted password file is sufficient for removing the USB as an authentication device.
Be aware that if you reformat your USB storage device, the UUID will change and you won't be able to log in with that device again until you add it again as a key which can be done by simply re-running the first script provided in this post. I have incorporated UUID because plenty of the cheap storage devices coming out of China these days do not have the serial number configured. Also when you're using an SD card, its worth noting that the serial number you see is actually coming from the SD card reader on most systems these days. Hence if you're using SD cards, the serial number is going to be the same for every SD card you mount even if the serial numbers of the SD cards themselves are actually different.