#!/usr/bin/sh # Helper script wich sets the root pasword from several sources # - Kernel boot command line (use --kernel option) # - Systemd ask password tool (use --systemd option) # - Interactively using a dialog (use --dialog option) # - ISO file metadata (use --iso option) # - Generates a random password unless already set (use --random option) 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" if dialog --keep-tite --backtitle "$BTITLE" --defaultno --yesno "Are you sure you want to cancel?" 5 40; then exit 1 fi } msg_box() { dialog --keep-tite --backtitle "$BTITLE" --msgbox "$1" 6 30 } ask_password() { if ! PWD1=$(dialog --keep-tite --title "$TITLE" --backtitle "$BTITLE" --stdout --insecure --passwordbox "Password:" 8 40); then confirm_exit ask_password fi if ! PWD2=$(dialog --keep-tite --title "$TITLE" --backtitle "$BTITLE" --stdout --insecure --passwordbox "Verify Password:" 8 40); then confirm_exit 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 exit 0 fi } # functions for entering the password using the "systemd-ask-password" tool ask_password_systemd() { if ! PWD1=$(systemd-ask-password --timeout=0 "Set login password: "); then exit 1 fi if ! PWD2=$(systemd-ask-password --timeout=0 "Verify password: "); then exit 1 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 exit 0 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" exit 0 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 echo "Reading password from $DEVICE..." # run tagmedia and extract the password value TAG=$(tagmedia "$DEVICE" | grep "^live_password = " | sed -e "s/^live_password = //") if [ -z "$TAG" ]; then echo "Password not found at $DEVICE" exit 0 fi if PWD=$(echo "$TAG" | base64 -d); then usermod -p "$PWD" root else echo "Base64 decoding of the password failed!" exit 1 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) if [ -n "$PASSWD" ]; then echo "$PASSWD" | passwd --stdin else # uh, the user cannot login now... =:-o echo "Failed to generate a password" exit 1 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 } if [ "$1" = "--kernel" ]; then # get the password from the kernel command line PWD=$(awk -F 'live.password=' '{sub(/ .*$/, "", $2); print $2}' < /proc/cmdline) if [ -n "$PWD" ]; then echo "$PWD" | passwd --stdin fi PWD=$(awk -F 'live.password_hash=' '{sub(/ .*$/, "", $2); print $2}' < /proc/cmdline) if [ -n "$PWD" ]; then usermod -p "$PWD" root fi elif [ "$1" = "--dialog" ]; then ask_password elif [ "$1" = "--systemd" ]; then ask_password_systemd elif [ "$1" = "--iso" ]; then password_from_iso elif [ "$1" = "--random" ]; then random_password fi