#!/bin/bash # Password setting/generation script. # Sets both root and u-boot password, # or optionally just U-boot. # What is actually written is the password # and salt. But the password is printed # for reference. # ubpasswd -h will print usage. # # Command changes the password based on the following # user list. The first user in this list that is found in # /etc/shadow is changed. root is only changed if mtadm # or admin is not found. # # -p option (pass password through stdin) is more secure # because another user on the system could use ps to acquire # the password. # ADMINLIST="mtadm admin" MTS=/sys/devices/platform/mts-io if (( $(id -u) != 0 )) ; then echo "Must have root privilege to procede." exit 1 fi if ! [[ -x /sbin/mts-hashpwd ]] ; then echo Need /sbin/mts-hashpwd to proceed. exit 1 fi usage() { echo "mts-ubpasswd [-c] [-d] [-n] [-i] [-m] [-u] [-r] [-f] [-p] [-s salt] [password]" echo " -c clear the U-Boot password" echo " -d debug" echo " -n dryrun for setting password" echo " -i use the uuid to generate the password" echo " -m means use the mac to generate the password." echo " -u means u-boot only (not UNIX password)" echo " -r returns true if U-Boot password" echo " is currently required" echo " -f returns true if U-Boot password" echo " feature is available." echo " -p read password from standard input" echo " -s salt is user supplied salt" echo " password is a user supplied password" echo "A salt not supplied is generated." echo "If a password is not supplied, it is generated" echo "If generating a password. The MAC address is" echo "preferred for generating the password, but the" echo "UUID will be used if the MAC is not present." exit 1 } ((ubonly=0)) ((usemac=0)) ((hassalt=0)) ((debug=0)) ((upwd=0)) ((dryrun=0)) ((stdp=0)) while getopts ":cdfimnprs:u" opt; do case $opt in c) u-boot setenv mtsp u-boot setenv mtss exit 0 ;; f) if ! /bin/fgrep "mts password protected" /dev/mtdblock2 >/dev/null 2>&1; then echo "U-Boot does not support password protection." exit 1 else echo "U-Boot supports password protection." exit 0 fi ;; i) ((useuuid=1)) if ! [[ -f "${MTS}/uuid" ]] ; then echo "${MTS}/uuid not found. Maybe mts-io driver is not loaded?" exit 1 fi uuid=$(cat "${MTS}/uuid") if ((${#uuid} == 0)) ; then echo "${MTS}/uuid must have a non-zero length value" usage fi ;; m) ((usemac=1)) if ! [[ -f "${MTS}/mac-eth" ]] ; then echo "${MTS}/mac-eth not found. Maybe mts-io driver is not loaded?" exit 1 fi mac=$(cat "${MTS}/mac-eth") if ((${#mac} == 0)) ; then echo "${MTS}/mac-eth must have a non-zero length value" usage fi ;; n) ((dryrun=1)) ;; p) ((stdp=1)) ;; u) ((ubonly=1)) ;; s) salt="$OPTARG" ((hassalt=1)) ;; r) if /usr/bin/u-boot printenv mtsp >/dev/null 2>&1 ; then echo "U-Boot password protection is on" exit 0 else echo "U-Boot password protection is off" exit 1 fi ;; d) ((debug=1)) ;; *) usage esac done ((debug)) && echo OPTIND is $OPTIND ((sc=OPTIND-1)) shift $sc if (($# == 1)) && ((stdp == 1)) ; then "Cannot use -p option with password on the command line" usage fi if (($# == 1)) ; then ((debug)) && echo "User set password is \"$1\"" ((upwd = 1)) pass="$1" elif ((stdp == 1)) ; then ((upwd = 1)) read -r pass fi ((debug)) && echo hassalt is $hassalt, salt is \"$salt\" ((debug)) && echo ubonly is $ubonly ((debug)) && echo debug is $debug len=8 saltlen=128 if ! /bin/fgrep "mts password protected" /dev/mtdblock2 >/dev/null 2>&1; then echo "U-Boot does not support password protection." exit 1 fi if ((hassalt == 0)) ; then salt="$(/bin/dd if=/dev/urandom count=1 bs=128 2>/dev/null | /bin/base64 | tr -d '\n' | cut -c1-${saltlen})" fi echo "salt: $salt" ((debug)) && echo upwd is $upwd ((debug)) && echo did length is ${#did} if ((useuuid == 0)) && ((usemac == 0)) ; then # Use MAC unless not present. # This is because old code did this, and because # UUID is not present in MTR and old Conduits. ((usemac=1)) mac=$(cat "${MTS}/mac-eth") if ((${#mac} == 0)) ; then ((usemac=0)) # Check for UUID ((useuuid=1)) uuid=$(cat "${MTS}/uuid") if ((${#uuid} == 0)) ; then echo "${MTS}/uuid or ${MTS}/mac-eth must have a non-zero length value" usage fi if ! [[ -f "${MTS}/uuid" ]] ; then echo "${MTS}/uuid not found. Maybe mts-io driver is not loaded?" exit 1 fi fi fi if ((upwd == 0)) ; then if ! [[ -f "${MTS}/device-id" ]] ; then echo "${MTS}/device-id not found. Maybe mts-io driver is not loaded?" exit 1 fi did=$(cat "${MTS}/device-id") if ((${#did} == 0)) ; then echo "${MTS}/device-id must have a non-zero length value" usage fi if ((usemac == 0)) ; then if ! [[ -f "${MTS}/uuid" ]] ; then echo "${MTS}/uuid not found. Maybe mts-io driver is not loaded?" exit 1 fi uuid=$(cat "${MTS}/uuid") if ((${#uuid} == 0)) ; then echo "${MTS}/uuid must have a non-zero length value" usage fi pwdsrc="-d ${did} -u ${uuid}" else pwdsrc="-d ${did} -m ${mac}" fi if ((debug)) ; then echo Try this: echo "/sbin/mts-hashpwd ${pwdsrc} ${salt}" fi result=$(/sbin/mts-hashpwd ${pwdsrc} ${salt}) else result=$(echo -n "$pass" | /sbin/mts-hashpwd -i ${salt}) fi if ! [[ $result =~ ^pass=([^$'\n']+)$'\n'password_hash=([^$'\n']+) ]] ; then echo "/sbin/mts-hashpwd failed: ${result}" exit 1 fi pass="${BASH_REMATCH[1]}" password_hash="${BASH_REMATCH[2]}" echo "uboot password hash: \"$password_hash\"" if ((ubonly == 0)) ; then rstring="^"${ADMINLIST// /:|^}":" list=" "$(egrep "${rstring}" /etc/shadow | sed 's/:.*//')" " for u in $ADMINLIST ; do ((debug)) && echo "list is: $list, u: is $u" if [[ $list =~ [[:space:]]${u}[[:space:]] ]] ; then USER="${u}" ((debug)) && echo Change password of $USER break fi done if ((${#USER} == 0)) ; then echo "No administrator user found" echo "Cannot change the administrator password" echo "Suggest using the \"-u\" option" exit 1 fi echo "setting ${USER} password to ${pass}" if ((dryrun == 0)) ; then echo -e "${pass}\n${pass}" | /usr/bin/passwd "${USER}" >/dev/null 2>&1 fi fi echo "u-boot password is ${pass}" if ((dryrun == 0)) ; then /usr/bin/u-boot setenv mtss "$salt" /usr/bin/u-boot setenv mtsp "$password_hash" fi