From c1613d899c70d7e138fac7c55a82af71cdda5a78 Mon Sep 17 00:00:00 2001 From: Robert Marshall Date: Thu, 25 Jun 2015 11:13:11 -0400 Subject: [PATCH 65/88] Add friendly grub2 password config tool (#985962) Provided a tool for users to reset the grub2 root user password without having to alter the grub.cfg. The hashed password now lives in a root-only-readable configuration file. Resolves: rhbz#985962 --- .gitignore | 1 + Makefile.util.def | 13 +++++ configure.ac | 1 + util/grub-mkconfig.in | 2 + util/grub-setpassword.8 | 28 +++++++++++ util/grub-setpassword.in | 123 +++++++++++++++++++++++++++++++++++++++++++++++ util/grub.d/01_users.in | 11 +++++ 7 files changed, 179 insertions(+) create mode 100644 util/grub-setpassword.8 create mode 100644 util/grub-setpassword.in create mode 100644 util/grub.d/01_users.in diff --git a/.gitignore b/.gitignore index 7697877..53a391e 100644 --- a/.gitignore +++ b/.gitignore @@ -127,6 +127,7 @@ grub-render-label grub-rpm-sort grub-script-check grub-set-default +grub-setpassword grub-shell grub-shell-tester grub-sparc64-setup diff --git a/Makefile.util.def b/Makefile.util.def index d846b81..226c46b 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -440,6 +440,12 @@ script = { }; script = { + name = '01_users'; + common = util/grub.d/01_users.in; + installdir = grubconf; +}; + +script = { name = '10_windows'; common = util/grub.d/10_windows.in; installdir = grubconf; @@ -722,6 +728,13 @@ script = { }; script = { + name = grub-setpassword; + common = util/grub-setpassword.in; + mansection = 8; + installdir = sbin; +}; + +script = { name = grub-mkconfig_lib; common = util/grub-mkconfig_lib.in; installdir = noinst; diff --git a/configure.ac b/configure.ac index ad2cff3..627c146 100644 --- a/configure.ac +++ b/configure.ac @@ -65,6 +65,7 @@ grub_TRANSFORM([grub-mkrelpath]) grub_TRANSFORM([grub-mkrescue]) grub_TRANSFORM([grub-probe]) grub_TRANSFORM([grub-reboot]) +grub_TRANSFORM([grub-setpassword]) grub_TRANSFORM([grub-rpm-sort]) grub_TRANSFORM([grub-script-check]) grub_TRANSFORM([grub-set-default]) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 9d595ac..fb87247 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -263,6 +263,8 @@ for i in "${grub_mkconfig_dir}"/* ; do *~) ;; # emacsen autosave files. FIXME: support other editors */\#*\#) ;; + # rpm config files of yore. + *.rpmsave|*.rpmnew|*.rpmorig) ;; *) if grub_file_is_not_garbage "$i" && test -x "$i" ; then echo diff --git a/util/grub-setpassword.8 b/util/grub-setpassword.8 new file mode 100644 index 0000000..5973abe --- /dev/null +++ b/util/grub-setpassword.8 @@ -0,0 +1,28 @@ +.TH GRUB-SETPASSWORD 3 "Thu Jun 25 2015" +.SH NAME +\fBgrub-setpassword\fR \(em Generate the user.cfg file containing the hashed grub bootloader password. + +.SH SYNOPSIS +\fBgrub-setpassword\fR [OPTION] + +.SH DESCRIPTION +\fBgrub-setpassword\fR outputs the user.cfg file which contains the hashed GRUB bootloader password. This utility only supports configurations where there is a single root user. + +The file has the format: +GRUB_2PASSWORD=<\fIhashed password\fR>. + +.SH OPTIONS +.TP +-h, --help +Display program usage and exit. +.TP +-v, --version +Display the current version. +.TP +-o, --output[=\fIDIRECTORY PATH\fR] +Choose the file path to which user.cfg will be written. + +.SH SEE ALSO +.BR "info grub" + +.BR "info grub2-mkpasswd-pbkdf2" diff --git a/util/grub-setpassword.in b/util/grub-setpassword.in new file mode 100644 index 0000000..dd76f00 --- /dev/null +++ b/util/grub-setpassword.in @@ -0,0 +1,123 @@ +#!/bin/sh -e + +if [ -d /sys/firmware/efi/efivars/ ]; then + grubdir=`echo "/@bootdirname@/efi/EFI/redhat/" | sed 's,//*,/,g'` +else + grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` +fi + +PACKAGE_VERSION="@PACKAGE_VERSION@" +PACKAGE_NAME="@PACKAGE_NAME@" +self=`basename $0` +bindir="@bindir@" +grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@" + +# Usage: usage +# Print the usage. +usage () { + cat <&2 + exit 1 + fi + echo $1 +} + +# Ensure that it's the root user running this script +if [ "${EUID}" -ne 0 ]; then + echo "The grub bootloader password may only be set by root." + usage + exit 2 +fi + +# Check the arguments. +while test $# -gt 0 +do + option=$1 + shift + + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" + exit 0 ;; + -o | --output) + OUTPUT_PATH=`argument $option "$@"`; shift ;; + --output=*) + OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;; + -o=*) + OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;; + esac +done + +# set user input or default path for user.cfg file +if [ -z "${OUTPUT_PATH}" ]; then + OUTPUT_PATH="${grubdir}" +fi + +if [ ! -d "${OUTPUT_PATH}" ]; then + echo "${OUTPUT_PATH} does not exist." + usage + exit 2; +fi + +ttyopt=$(stty -g) +fixtty() { + stty ${ttyopt} +} + +trap fixtty EXIT +stty -echo + +# prompt & confirm new grub2 root user password +echo -n "Enter password: " +read PASSWORD +echo +echo -n "Confirm password: " +read PASSWORD_CONFIRM +echo +stty ${ttyopt} + +getpass() { + local P0 + local P1 + P0="$1" && shift + P1="$1" && shift + + ( echo ${P0} ; echo ${P1} ) | \ + ${grub_mkpasswd} | \ + grep -v '[eE]nter password:' | \ + sed -e "s/PBKDF2 hash of your password is //" +} + +MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")" +if [ -z "${MYPASS}" ]; then + echo "${self}: error: empty password" 1>&2 + exit 1 +fi + +# on the ESP, these will fail to set the permissions, but it's okay because +# the directory is protected. +install -m 0600 /dev/null "${grubdir}/user.cfg" 2>/dev/null || : +chmod 0600 "${grubdir}/user.cfg" 2>/dev/null || : +echo "GRUB2_PASSWORD=${MYPASS}" > "${grubdir}/user.cfg" diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in new file mode 100644 index 0000000..facd409 --- /dev/null +++ b/util/grub.d/01_users.in @@ -0,0 +1,11 @@ +#!/bin/sh -e +cat << EOF +if [ -f \${prefix}/user.cfg ]; then + source \${prefix}/user.cfg + if [ -n \${GRUB2_PASSWORD} ]; then + set superusers="root" + export superusers + password_pbkdf2 root \${GRUB2_PASSWORD} + fi +fi +EOF -- 2.5.5