Projects
openEuler:Mainline
grub2
_service:tar_scm:grub2-set-password-prompts-to-...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:grub2-set-password-prompts-to-enter-the-current-pass.patch of Package grub2
From 23ade142e708ef9c225f0ccfd519e48132793888 Mon Sep 17 00:00:00 2001 From: liuxin <liuxin264@huawei.com> Date: Thu, 2 Sep 2021 17:30:39 +0800 Subject: [PATCH] grub2-set-password prompts to enter the current password and add the password complexity check --- util/grub-mkpasswd-pbkdf2.c | 105 ++++++++++++++++++++++++++++++--- util/grub-set-password.in | 114 ++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+), 7 deletions(-) diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index 29c68fb..b7c6e48 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -42,10 +42,14 @@ #include "progname.h" +#define GRUB_PARAM_ERROR 1 +#define GRUB_PARAM_SUCCESS 0 + static struct argp_option options[] = { {"iteration-count", 'c', N_("NUM"), 0, N_("Number of PBKDF2 iterations"), 0}, {"buflen", 'l', N_("NUM"), 0, N_("Length of generated hash"), 0}, {"salt", 's', N_("NUM"), 0, N_("Length of salt"), 0}, + {"salt arg", 'a', N_("VARCHAR"), 0, N_("preset salt var(hex code)"), 0}, { 0, 0, 0, 0, 0, 0 } }; @@ -54,8 +58,45 @@ struct arguments unsigned int count; unsigned int buflen; unsigned int saltlen; + char * salt; }; +static int illegal_char(char t) +{ + int illegal = GRUB_PARAM_ERROR; + char legal[] = "0123456789ABCDEF"; + for (int i = 0; i < grub_strlen(legal); ++i) { + if (t == legal[i]) { + illegal = GRUB_PARAM_SUCCESS; + break; + } + } + return illegal; +} + +static int check_salt_verify(const char * arg) +{ + grub_size_t len = grub_strlen(arg); + if (len <= 0 || len >= GRUB_SIZE_MAX) + { + fprintf(stderr, "salt length may be empty or too long!\n"); + return GRUB_PARAM_ERROR; + } + if (len % 2 != 0) + { + fprintf(stderr, "the salt value length is an even number!\n"); + return GRUB_PARAM_ERROR; + } + for (int i = 0; i < len; ++i) + { + if (illegal_char(arg[i])) + { + return GRUB_PARAM_ERROR; + } + } + return GRUB_PARAM_SUCCESS; +} + static error_t argp_parser (int key, char *arg, struct argp_state *state) { @@ -76,6 +117,16 @@ argp_parser (int key, char *arg, struct argp_state *state) case 's': arguments->saltlen = strtoul (arg, NULL, 0); break; + + case 'a': + if (check_salt_verify(arg)) + { + fprintf(stderr, "only hexadecimal numbers consisting of digits and uppercase letters are supported\n"); + return ARGP_ERR_UNKNOWN; + } + arguments->saltlen = grub_strlen(arg) / 2; + arguments->salt = arg; + break; default: return ARGP_ERR_UNKNOWN; } @@ -110,13 +161,44 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n) *hex = 0; } +static void +hextobyte(const char *hex, grub_uint8_t *bin, grub_size_t n) +{ + while(n) + { + grub_uint8_t tmp = 0x00; + if (((*hex) <= '9') && ((*hex) >= '0')) + { + tmp += (grub_uint8_t)((*hex) - '0') << 4 & 0xf0; + } + else + { + tmp += (grub_uint8_t)((*hex) - 'A' + 10) << 4 & 0xf0; + } + hex++; + if (((*hex) <= '9') && ((*hex) >= '0')) + { + tmp += (grub_uint8_t)((*hex) - '0') & 0x0f; + } + else + { + tmp += (grub_uint8_t)((*hex) - 'A' + 10) & 0x0f; + } + *bin = tmp; + bin++; + hex++; + n -= 2; + } +} + int main (int argc, char *argv[]) { struct arguments arguments = { .count = 10000, .buflen = 64, - .saltlen = 64 + .saltlen = 64, + .salt = NULL }; char *result, *ptr; gcry_err_code_t gcry_err; @@ -133,6 +215,12 @@ main (int argc, char *argv[]) exit(1); } + if (arguments.salt != NULL && grub_strlen(arguments.salt) != 2 * arguments.saltlen) + { + fprintf(stderr, "%s", _("If the -a parameter is set, don't set the -s parameter again\n")); + exit(1); + } + buf = xmalloc (arguments.buflen); salt = xmalloc (arguments.saltlen); @@ -161,13 +249,16 @@ main (int argc, char *argv[]) } memset (pass2, 0, sizeof (pass2)); - if (grub_get_random (salt, arguments.saltlen)) + if (arguments.salt != NULL) { - memset (pass1, 0, sizeof (pass1)); - free (buf); - free (salt); - grub_util_error ("%s", _("couldn't retrieve random data for salt")); - } + hextobyte(arguments.salt, salt, arguments.saltlen * 2); + } else if (grub_get_random (salt, arguments.saltlen)) + { + memset (pass1, 0, sizeof (pass1)); + free (buf); + free (salt); + grub_util_error ("%s", _("couldn't retrieve random data for salt")); + } gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) pass1, strlen (pass1), diff --git a/util/grub-set-password.in b/util/grub-set-password.in index c0b5ebb..3e14a5d 100644 --- a/util/grub-set-password.in +++ b/util/grub-set-password.in @@ -87,16 +87,130 @@ fixtty() { } trap fixtty EXIT + +getsaltpass() { + local P0 + local P1 + P0="$1" && shift + P1="$1" && shift + P2="$1" && shift + + ( echo ${P0} ; echo ${P1} ) | \ + LC_ALL=C ${grub_mkpasswd} -a ${P2} | \ + grep -v '[eE]nter password:' | \ + sed -e "s/PBKDF2 hash of your password is //" +} + +verifyusercfgoldpasswd() { + # get old password salt + expectsalt=`cat ${grubdir}/user.cfg | cut -d "." -f 5` + # get expect password + expectpass=`cat ${grubdir}/user.cfg` + prefix="GRUB2_PASSWORD=" + + stty -echo + echo -n "Enter Current password: " + read PASSWORD_CURRENT + echo + + needcheckpass="${prefix}$(getsaltpass "${PASSWORD_CURRENT}" "${PASSWORD_CURRENT}" "${expectsalt}")" + if [ "$expectpass" != "$needcheckpass" ]; then + echo "Authentication failed" + exit 1 + fi + + stty ${ttyopt} +} + +verifygrubcfgoldpasswd() { + # get old password line + expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root grub.pbkdf2.sha512" | cut -d " " -f 3` + # if not get password, try a quotation mark match + if [ -z "$expectpass" ];then + expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root \"grub.pbkdf2.sha512" | cut -d " " -f 3 | cut -d "\"" -f 2` + fi + if [ -z "$expectpass" ];then + expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root 'grub.pbkdf2.sha512" | cut -d " " -f 3 | cut -d "'" -f 2` + fi + if [ -n "$expectpass" ];then + # get old password salt + expectsalt=`echo ${expectpass} | cut -d "." -f 5` + stty -echo + echo -n "Enter Current password: " + read PASSWORD_CURRENT + echo + + needcheckpass="$(getsaltpass "${PASSWORD_CURRENT}" "${PASSWORD_CURRENT}" "${expectsalt}")" + if [ "$expectpass" != "$needcheckpass" ]; then + echo "Authentication failed" + exit 1 + fi + fi + +} + +if [ -e ${grubdir}/user.cfg ];then + verifyusercfgoldpasswd +else + verifygrubcfgoldpasswd +fi + +checkcomplexity() { + set +e + USERNAME=`cat ${grubdir}/grub.cfg | grep "set superusers=" | cut -d "\"" -f 2 |tail -1` + local P1="$1" && shift + if [ "$P1" = "$USERNAME" ];then + echo "The password contains the user name in some form" + exit 1 + fi + # password len >= 8 + strlen=`echo "$P1" | grep -E '^(.{8,}).*$'` + if [ -z "$strlen" ];then + echo "The password is shorter than 8 characters" + exit 1 + fi + # lowercase + strlow=`echo "$P1" | grep -E --color '^(.*[a-z]+).*$'` + # uppercase + strupp=`echo $P1 | grep -E --color '^(.*[A-Z]).*$'` + # special character + strts=`echo $P1 | grep -E --color '^(.*\W).*$'` + # num + strnum=`echo $P1 | grep -E --color '^(.*[0-9]).*$'` + complexity=0 + if [ -n "$strlow" ];then + complexity=`expr $complexity + 1` + fi + if [ -n "$strupp" ];then + complexity=`expr $complexity + 1` + fi + if [ -n "$strts" ];then + complexity=`expr $complexity + 1` + fi + if [ -n "$strnum" ];then + complexity=`expr $complexity + 1` + fi + if [ $complexity -lt 3 ];then + echo "The password contains less than 3 character classes" + exit 1 + fi + set -e +} + stty -echo # prompt & confirm new grub2 root user password echo -n "Enter password: " read PASSWORD echo +stty ${ttyopt} +checkcomplexity $PASSWORD +stty -echo echo -n "Confirm password: " read PASSWORD_CONFIRM echo stty ${ttyopt} +checkcomplexity $PASSWORD_CONFIRM getpass() { local P0 -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.