nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

Blame SOURCES/0048-Add-friendly-grub2-password-config-tool-985962.patch

5593c8
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
5593c8
From: Robert Marshall <rmarshall@redhat.com>
5593c8
Date: Thu, 25 Jun 2015 11:13:11 -0400
5593c8
Subject: [PATCH] Add friendly grub2 password config tool (#985962)
5593c8
5593c8
Provided a tool for users to reset the grub2 root user password
5593c8
without having to alter the grub.cfg. The hashed password now
5593c8
lives in a root-only-readable configuration file.
5593c8
5593c8
Resolves: rhbz#985962
5593c8
5593c8
Signed-off-by: Robert Marshall <rmarshall@redhat.com>
5593c8
[pjones: fix the efidir in grub-setpassword and rename tool]
5593c8
Signed-off-by: Peter Jones <pjones@redhat.com>
5593c8
[luto: fix grub-setpassword -o's output path]
5593c8
Andy Lutomirski <luto@kernel.org>
5593c8
---
5593c8
 configure.ac              |   1 +
5593c8
 Makefile.util.def         |  13 +++++
5593c8
 util/grub-mkconfig.in     |   2 +
5593c8
 util/grub-set-password.8  |  28 ++++++++++
5593c8
 util/grub-set-password.in | 128 ++++++++++++++++++++++++++++++++++++++++++++++
5593c8
 util/grub.d/01_users.in   |  11 ++++
5593c8
 6 files changed, 183 insertions(+)
5593c8
 create mode 100644 util/grub-set-password.8
5593c8
 create mode 100644 util/grub-set-password.in
5593c8
 create mode 100644 util/grub.d/01_users.in
5593c8
5593c8
diff --git a/configure.ac b/configure.ac
1c6ba0
index fdcb452581..30fd84d806 100644
5593c8
--- a/configure.ac
5593c8
+++ b/configure.ac
5593c8
@@ -72,6 +72,7 @@ grub_TRANSFORM([grub-mkrelpath])
5593c8
 grub_TRANSFORM([grub-mkrescue])
5593c8
 grub_TRANSFORM([grub-probe])
5593c8
 grub_TRANSFORM([grub-reboot])
5593c8
+grub_TRANSFORM([grub-set-password])
5593c8
 grub_TRANSFORM([grub-rpm-sort])
5593c8
 grub_TRANSFORM([grub-script-check])
5593c8
 grub_TRANSFORM([grub-set-default])
5593c8
diff --git a/Makefile.util.def b/Makefile.util.def
1c6ba0
index ba4cf4b29b..1a7dd433e3 100644
5593c8
--- a/Makefile.util.def
5593c8
+++ b/Makefile.util.def
5593c8
@@ -452,6 +452,12 @@ script = {
5593c8
   installdir = grubconf;
5593c8
 };
5593c8
 
5593c8
+script = {
5593c8
+  name = '01_users';
5593c8
+  common = util/grub.d/01_users.in;
5593c8
+  installdir = grubconf;
5593c8
+};
5593c8
+
5593c8
 script = {
5593c8
   name = '10_windows';
5593c8
   common = util/grub.d/10_windows.in;
5593c8
@@ -740,6 +746,13 @@ script = {
5593c8
   installdir = sbin;
5593c8
 };
5593c8
 
5593c8
+script = {
5593c8
+  name = grub-set-password;
5593c8
+  common = util/grub-set-password.in;
5593c8
+  mansection = 8;
5593c8
+  installdir = sbin;
5593c8
+};
5593c8
+
5593c8
 script = {
5593c8
   name = grub-mkconfig_lib;
5593c8
   common = util/grub-mkconfig_lib.in;
5593c8
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
1c6ba0
index 8ea2315ebc..ba14cf6261 100644
5593c8
--- a/util/grub-mkconfig.in
5593c8
+++ b/util/grub-mkconfig.in
5593c8
@@ -276,6 +276,8 @@ for i in "${grub_mkconfig_dir}"/* ; do
5593c8
     *~) ;;
5593c8
     # emacsen autosave files. FIXME: support other editors
5593c8
     */\#*\#) ;;
5593c8
+    # rpm config files of yore.
5593c8
+    *.rpmsave|*.rpmnew|*.rpmorig) ;;
5593c8
     *)
5593c8
       if grub_file_is_not_garbage "$i" && test -x "$i" ; then
5593c8
         echo
5593c8
diff --git a/util/grub-set-password.8 b/util/grub-set-password.8
5593c8
new file mode 100644
1c6ba0
index 0000000000..9646546e43
5593c8
--- /dev/null
5593c8
+++ b/util/grub-set-password.8
5593c8
@@ -0,0 +1,28 @@
5593c8
+.TH GRUB-SET-PASSWORD 3 "Thu Jun 25 2015"
5593c8
+.SH NAME
5593c8
+\fBgrub-set-password\fR \(em Generate the user.cfg file containing the hashed grub bootloader password.
5593c8
+
5593c8
+.SH SYNOPSIS
5593c8
+\fBgrub-set-password\fR [OPTION]
5593c8
+
5593c8
+.SH DESCRIPTION
5593c8
+\fBgrub-set-password\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.
5593c8
+
5593c8
+The file has the format:
5593c8
+GRUB2_PASSWORD=<\fIhashed password\fR>.
5593c8
+
5593c8
+.SH OPTIONS
5593c8
+.TP
5593c8
+-h, --help
5593c8
+Display program usage and exit.
5593c8
+.TP
5593c8
+-v, --version
5593c8
+Display the current version.
5593c8
+.TP
5593c8
+-o, --output=<\fIDIRECTORY\fR>
5593c8
+Choose the file path to which user.cfg will be written.
5593c8
+
5593c8
+.SH SEE ALSO
5593c8
+.BR "info grub"
5593c8
+
5593c8
+.BR "info grub2-mkpasswd-pbkdf2"
5593c8
diff --git a/util/grub-set-password.in b/util/grub-set-password.in
5593c8
new file mode 100644
1c6ba0
index 0000000000..5ebf50576d
5593c8
--- /dev/null
5593c8
+++ b/util/grub-set-password.in
5593c8
@@ -0,0 +1,128 @@
5593c8
+#!/bin/sh -e
5593c8
+
5593c8
+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/')
5593c8
+if [ -d /sys/firmware/efi/efivars/ ]; then
5593c8
+    grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'`
5593c8
+else
5593c8
+    grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
5593c8
+fi
5593c8
+
5593c8
+PACKAGE_VERSION="@PACKAGE_VERSION@"
5593c8
+PACKAGE_NAME="@PACKAGE_NAME@"
5593c8
+self=`basename $0`
5593c8
+bindir="@bindir@"
5593c8
+grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@"
5593c8
+
5593c8
+# Usage: usage
5593c8
+# Print the usage.
5593c8
+usage () {
5593c8
+    cat <
5593c8
+Usage: $0 [OPTION]
5593c8
+$0 prompts the user to set a password on the grub bootloader. The password
5593c8
+is written to a file named user.cfg which lives in the GRUB directory
5593c8
+located by default at ${grubdir}.
5593c8
+
5593c8
+  -h, --help                     print this message and exit
5593c8
+  -v, --version                  print the version information and exit
5593c8
+  -o, --output_path <DIRECTORY>  put user.cfg in a user-selected directory
5593c8
+
5593c8
+Report bugs at https://bugzilla.redhat.com.
5593c8
+EOF
5593c8
+}
5593c8
+
5593c8
+argument () {
5593c8
+    opt=$1
5593c8
+    shift
5593c8
+
5593c8
+    if test $# -eq 0; then
5593c8
+        gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2
5593c8
+        exit 1
5593c8
+    fi
5593c8
+    echo $1
5593c8
+}
5593c8
+
5593c8
+# Ensure that it's the root user running this script
5593c8
+if [ "${EUID}" -ne 0 ]; then
5593c8
+    echo "The grub bootloader password may only be set by root."
5593c8
+    usage
5593c8
+    exit 2
5593c8
+fi
5593c8
+
5593c8
+# Check the arguments.
5593c8
+while test $# -gt 0
5593c8
+do
5593c8
+    option=$1
5593c8
+    shift
5593c8
+
5593c8
+    case "$option" in
5593c8
+    -h | --help)
5593c8
+	usage
5593c8
+	exit 0 ;;
5593c8
+    -v | --version)
5593c8
+	echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
5593c8
+	exit 0 ;;
5593c8
+    -o | --output)
5593c8
+        OUTPUT_PATH=`argument $option "$@"`; shift ;;
5593c8
+    --output=*)
5593c8
+        OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;;
5593c8
+    -o=*)
5593c8
+        OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;;
5593c8
+    esac
5593c8
+done
5593c8
+
5593c8
+# set user input or default path for user.cfg file
5593c8
+if [ -z "${OUTPUT_PATH}" ]; then
5593c8
+    OUTPUT_PATH="${grubdir}"
5593c8
+fi
5593c8
+
5593c8
+if [ ! -d "${OUTPUT_PATH}" ]; then
5593c8
+    echo "${OUTPUT_PATH} does not exist."
5593c8
+    usage
5593c8
+    exit 2;
5593c8
+fi
5593c8
+
5593c8
+ttyopt=$(stty -g)
5593c8
+fixtty() {
5593c8
+      stty ${ttyopt}
5593c8
+}
5593c8
+
5593c8
+trap fixtty EXIT
5593c8
+stty -echo
5593c8
+
5593c8
+# prompt & confirm new grub2 root user password
5593c8
+echo -n "Enter password: "
5593c8
+read PASSWORD
5593c8
+echo
5593c8
+echo -n "Confirm password: "
5593c8
+read PASSWORD_CONFIRM
5593c8
+echo
5593c8
+stty ${ttyopt}
5593c8
+
5593c8
+getpass() {
5593c8
+    local P0
5593c8
+    local P1
5593c8
+    P0="$1" && shift
5593c8
+    P1="$1" && shift
5593c8
+
5593c8
+    ( echo ${P0} ; echo ${P1} ) | \
5593c8
+        LC_ALL=C ${grub_mkpasswd} | \
5593c8
+        grep -v '[eE]nter password:' | \
5593c8
+        sed -e "s/PBKDF2 hash of your password is //"
5593c8
+}
5593c8
+
5593c8
+MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")"
5593c8
+if [ -z "${MYPASS}" ]; then
5593c8
+      echo "${self}: error: empty password" 1>&2
5593c8
+      exit 1
5593c8
+fi
5593c8
+
5593c8
+# on the ESP, these will fail to set the permissions, but it's okay because
5593c8
+# the directory is protected.
5593c8
+install -m 0600 /dev/null "${OUTPUT_PATH}/user.cfg" 2>/dev/null || :
5593c8
+chmod 0600 "${OUTPUT_PATH}/user.cfg" 2>/dev/null || :
5593c8
+echo "GRUB2_PASSWORD=${MYPASS}" > "${OUTPUT_PATH}/user.cfg"
5593c8
+
5593c8
+if ! grep -q "^### BEGIN /etc/grub.d/01_users ###$" "${OUTPUT_PATH}/grub.cfg"; then
5593c8
+    echo "WARNING: The current configuration lacks password support!"
5593c8
+    echo "Update your configuration with @grub_mkconfig@ to support this feature."
5593c8
+fi
5593c8
diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in
5593c8
new file mode 100644
1c6ba0
index 0000000000..db2f44bfb7
5593c8
--- /dev/null
5593c8
+++ b/util/grub.d/01_users.in
5593c8
@@ -0,0 +1,11 @@
5593c8
+#!/bin/sh -e
5593c8
+cat << EOF
5593c8
+if [ -f \${prefix}/user.cfg ]; then
5593c8
+  source \${prefix}/user.cfg
5593c8
+  if [ -n "\${GRUB2_PASSWORD}" ]; then
5593c8
+    set superusers="root"
5593c8
+    export superusers
5593c8
+    password_pbkdf2 root \${GRUB2_PASSWORD}
5593c8
+  fi
5593c8
+fi
5593c8
+EOF