175 lines
5.3 KiB
Bash
Executable file
175 lines
5.3 KiB
Bash
Executable file
#!/usr/bin/sh
|
|
|
|
# Helper script which sets the root password from several sources
|
|
# - ISO file metadata
|
|
# - Kernel boot command line
|
|
# - Systemd ask password tool
|
|
# - Interactively using a dialog
|
|
# - Generates a random password as a fallback
|
|
|
|
MYDIR=$(realpath "$(dirname "$0")")
|
|
export DIALOGRC="$MYDIR/../share/live/misc/dialog.conf"
|
|
|
|
# dialog titles
|
|
BTITLE="Live System Configuration (Press Ctrl+L to refresh the screen)"
|
|
TITLE="Set Login Password"
|
|
|
|
# functions for entering the password in an interactive dialog
|
|
confirm_exit() {
|
|
# --keep-tite is not a misspelling of "title"
|
|
dialog --keep-tite --backtitle "$BTITLE" --defaultno --yesno "Are you sure you want to cancel?" 5 40
|
|
}
|
|
|
|
msg_box() {
|
|
dialog --keep-tite --backtitle "$BTITLE" --msgbox "$1" 6 30
|
|
}
|
|
|
|
ask_password() {
|
|
# check if user wants dialog password
|
|
if ! grep -q "\blive.password_dialog=1\b" /run/agama/cmdline.d/agama.conf; then
|
|
return
|
|
fi
|
|
|
|
if ! PWD1=$(dialog --keep-tite --title "$TITLE" --backtitle "$BTITLE" --stdout --insecure --passwordbox "Password:" 8 40); then
|
|
if confirm_exit; then
|
|
return
|
|
fi
|
|
|
|
ask_password
|
|
fi
|
|
|
|
if ! PWD2=$(dialog --keep-tite --title "$TITLE" --backtitle "$BTITLE" --stdout --insecure --passwordbox "Verify Password:" 8 40); then
|
|
if confirm_exit; then
|
|
return
|
|
fi
|
|
ask_password
|
|
fi
|
|
|
|
if [ "$PWD1" != "$PWD2" ]; then
|
|
msg_box "Passwords do not match.\nPlease try again."
|
|
ask_password
|
|
elif [ -z "$PWD1" ]; then
|
|
msg_box "Password cannot be empty.\nPlease try again."
|
|
ask_password
|
|
else
|
|
echo "$PWD1" | passwd --stdin
|
|
fi
|
|
|
|
# clear the terminal
|
|
clear
|
|
# unfortunately it also changes the cursor position, move it back to the last line
|
|
tput cup $(tput lines) 0
|
|
}
|
|
|
|
# functions for entering the password using the "systemd-ask-password" tool
|
|
ask_password_systemd() {
|
|
# check if user wants systemd password
|
|
if ! grep -q "\blive.password_systemd=1\b" /run/agama/cmdline.d/agama.conf; then
|
|
return
|
|
fi
|
|
if ! PWD1=$(systemd-ask-password --timeout=0 "Set login password: "); then
|
|
return
|
|
fi
|
|
|
|
if ! PWD2=$(systemd-ask-password --timeout=0 "Verify password: "); then
|
|
return
|
|
fi
|
|
|
|
if [ "$PWD1" != "$PWD2" ]; then
|
|
echo "Passwords do not match, please try again."
|
|
ask_password_systemd
|
|
elif [ -z "$PWD1" ]; then
|
|
echo "Password cannot be empty, please try again. To skip the password configuration press Ctrl+C."
|
|
ask_password_systemd
|
|
else
|
|
echo "$PWD1" | passwd --stdin
|
|
fi
|
|
}
|
|
|
|
# check if the root password is present in the ISO file metadata
|
|
password_from_iso() {
|
|
# get the partition where the live ISO is mounted, the real name is set by the
|
|
# config.sh script which gets the live partition label name from KIWI
|
|
PARTITION=$(blkid -L "@@LIVE_MEDIUM_LABEL@@")
|
|
|
|
if [ -z "$PARTITION" ]; then
|
|
echo "Live ISO partition not found, skipping password configuration"
|
|
return
|
|
fi
|
|
|
|
# get the parent device name for the partition (/dev/sda2 -> /dev/sda),
|
|
# for some devices just removing the trailing number does not work
|
|
DEVICE=$(lsblk --noheadings --output PKNAME "$PARTITION")
|
|
|
|
# if there is no parent device use the device itself (e.g. /dev/sr0)
|
|
if [ -z "$DEVICE" ]; then
|
|
DEVICE="$PARTITION"
|
|
else
|
|
# add the /dev/ prefix
|
|
DEVICE="/dev/$DEVICE"
|
|
fi
|
|
|
|
# run tagmedia and extract the password value
|
|
TAG=$(tagmedia "$DEVICE" | grep "^live_password = " | sed -e "s/^live_password = //")
|
|
|
|
if [ -z "$TAG" ]; then
|
|
return
|
|
fi
|
|
|
|
if PWD=$(echo "$TAG" | base64 -d); then
|
|
usermod -p "$PWD" root
|
|
else
|
|
echo "Base64 decoding of the password failed!"
|
|
fi
|
|
}
|
|
|
|
# generate a random password unless a password is already set
|
|
random_password() {
|
|
if grep -q '^root:!\*:' /etc/shadow; then
|
|
echo "Root password not set, generating a random password..."
|
|
# generate a random password, omit symbols and confusing characters to avoid
|
|
# mistakes, the password will be very likely re-typed in a different device
|
|
# so make the password easy to type (it cannot be copy pasted)
|
|
#
|
|
# TODO: check this with the security team
|
|
PASSWD=$( (base64 -w 0 < /dev/random | tr -d "+/0OolI1" | head -c 8) 2> /dev/null)
|
|
|
|
if [ -n "$PASSWD" ]; then
|
|
echo "$PASSWD" | passwd --stdin
|
|
else
|
|
# uh, the user cannot login now... =:-o
|
|
echo "Failed to generate a password"
|
|
return
|
|
fi
|
|
|
|
# display the generated password in the console
|
|
mkdir -p /run/issue.d
|
|
echo "Password for root user: \e{lightcyan}$PASSWD\e{reset}" > /run/issue.d/99-live-password.issue
|
|
# the /etc/issue or /run/issue file must exist to show the issues in console
|
|
# hint: run "agetty --show-issue" to see what will be displayed
|
|
touch /run/issue
|
|
fi
|
|
}
|
|
|
|
password_from_iso
|
|
|
|
# get the password from the kernel command line. It can contain newlines
|
|
PWD=$(grep 'live.password=' < /run/agama/cmdline.d/agama.conf | awk -F 'live.password=' '{sub(/ .*$/, "", $2); print $2}')
|
|
if [ -n "$PWD" ]; then
|
|
echo "$PWD" | passwd --stdin
|
|
fi
|
|
|
|
# get the password hash from the kernel command line. It can contain newlines
|
|
PWD=$(grep 'live.password_hash=' < /run/agama/cmdline.d/agama.conf | awk -F 'live.password_hash=' '{sub(/ .*$/, "", $2); print $2}')
|
|
if [ -n "$PWD" ]; then
|
|
usermod -p "$PWD" root
|
|
fi
|
|
|
|
# set the password interactively (using dialog)
|
|
ask_password
|
|
|
|
# set the password interactively (using systemd)
|
|
ask_password_systemd
|
|
|
|
# fallback to random password if not set
|
|
random_password
|