加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
grub2-set-password-prompts-to-enter-the-current-pass.patch 8.33 KB
一键复制 编辑 原始数据 按行查看 历史
zhangqiumiao 提交于 2022-03-07 17:05 . update to version 2.06
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 5805f3c..c9f39a5 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 d8005e5..9369b40 100644
--- a/util/grub-set-password.in
+++ b/util/grub-set-password.in
@@ -82,16 +82,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.19.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化