diff --git a/commands/password.c b/commands/password.c
index 99b993839..7bb2f0ae5 100644
--- a/commands/password.c
+++ b/commands/password.c
@@ -27,20 +27,11 @@
static grub_dl_t my_mod;
-#define MAX_PASSLEN 1024
-
static grub_err_t
-check_password (const char *user,
+check_password (const char *user, const char *entered,
void *password)
{
- char entered[MAX_PASSLEN];
-
- grub_memset (entered, 0, sizeof (entered));
-
- if (!GRUB_GET_PASSWORD (entered, sizeof (entered) - 1))
- return GRUB_ACCESS_DENIED;
-
- if (grub_crypto_memcmp (entered, password, MAX_PASSLEN) != 0)
+ if (grub_crypto_memcmp (entered, password, GRUB_AUTH_MAX_PASSLEN) != 0)
return GRUB_ACCESS_DENIED;
grub_auth_authenticate (user);
@@ -59,12 +50,12 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
if (argc != 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");
- pass = grub_zalloc (MAX_PASSLEN);
+ pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN);
if (!pass)
return grub_errno;
copylen = grub_strlen (args[1]);
- if (copylen >= MAX_PASSLEN)
- copylen = MAX_PASSLEN - 1;
+ if (copylen >= GRUB_AUTH_MAX_PASSLEN)
+ copylen = GRUB_AUTH_MAX_PASSLEN - 1;
grub_memcpy (pass, args[1], copylen);
err = grub_auth_register_authentication (args[0], check_password, pass);
diff --git a/commands/password_pbkdf2.c b/commands/password_pbkdf2.c
index 38481f362..51c8ea794 100644
--- a/commands/password_pbkdf2.c
+++ b/commands/password_pbkdf2.c
@@ -16,6 +16,7 @@
* along with GRUB. If not, see .
*/
+#include
#include
#include
#include
@@ -36,23 +37,17 @@ struct pbkdf2_password
};
static grub_err_t
-check_password (const char *user, void *pin)
+check_password (const char *user, const char *entered, void *pin)
{
- char entered[1024];
grub_uint8_t *buf;
struct pbkdf2_password *pass = pin;
gcry_err_code_t err;
- grub_memset (entered, 0, sizeof (entered));
-
- if (!GRUB_GET_PASSWORD (entered, sizeof (entered) - 1))
- return GRUB_ACCESS_DENIED;
-
buf = grub_malloc (pass->buflen);
if (!buf)
return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY);
- err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) &entered,
+ err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) entered,
grub_strlen (entered),
pass->salt, pass->saltlen, pass->c,
buf, pass->buflen);
diff --git a/conf/common.rmk b/conf/common.rmk
index 0c6fb0cae..ad0e4942c 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -651,6 +651,6 @@ password_pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS)
bin_UTILITIES += grub-mkpasswd-pbkdf2
grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c
-grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap
+grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1
include $(srcdir)/conf/gcry.mk
diff --git a/include/grub/auth.h b/include/grub/auth.h
index e72d984ae..747334451 100644
--- a/include/grub/auth.h
+++ b/include/grub/auth.h
@@ -19,14 +19,11 @@
#define GRUB_AUTH_HEADER 1
#include
+#include
-/* Macros for indistinguishibility. */
-#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.")
-#define GRUB_GET_PASSWORD(string, len) grub_cmdline_get ("Enter password: ", \
- string, len, \
- '*', 0, 0)
+#define GRUB_AUTH_MAX_PASSLEN 1024
-typedef grub_err_t (*grub_auth_callback_t) (const char*, void *);
+typedef grub_err_t (*grub_auth_callback_t) (const char *, const char *, void *);
grub_err_t grub_auth_register_authentication (const char *user,
grub_auth_callback_t callback,
diff --git a/include/grub/crypto.h b/include/grub/crypto.h
index eb1898fe4..3129131cb 100644
--- a/include/grub/crypto.h
+++ b/include/grub/crypto.h
@@ -26,8 +26,6 @@
#include
#include
#include
-/* For GRUB_ACCESS_DENIED. */
-#include
typedef enum
{
@@ -264,6 +262,12 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
grub_uint8_t *DK, grub_size_t dkLen);
int
-grub_crypto_memcmp (void *a, void *b, grub_size_t n);
+grub_crypto_memcmp (const void *a, const void *b, grub_size_t n);
+
+int
+grub_password_get (char buf[], unsigned buf_size);
+
+/* For indistinguishibility. */
+#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.")
#endif
diff --git a/lib/crypto.c b/lib/crypto.c
index 4b36dde6f..06104bd4d 100644
--- a/lib/crypto.c
+++ b/lib/crypto.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
struct grub_crypto_hmac_handle
{
@@ -372,10 +373,10 @@ grub_crypto_gcry_error (gcry_err_code_t in)
}
int
-grub_crypto_memcmp (void *a, void *b, grub_size_t n)
+grub_crypto_memcmp (const void *a, const void *b, grub_size_t n)
{
register grub_size_t counter = 0;
- grub_uint8_t *pa, *pb;
+ const grub_uint8_t *pa, *pb;
for (pa = a, pb = b; n; pa++, pb++, n--)
{
@@ -385,3 +386,44 @@ grub_crypto_memcmp (void *a, void *b, grub_size_t n)
return !!counter;
}
+
+#ifndef GRUB_MKPASSWD
+int
+grub_password_get (char buf[], unsigned buf_size)
+{
+ unsigned cur_len = 0;
+ int key;
+
+ while (1)
+ {
+ key = GRUB_TERM_ASCII_CHAR (grub_getkey ());
+ if (key == '\n' || key == '\r')
+ break;
+
+ if (key == '\e')
+ {
+ cur_len = 0;
+ break;
+ }
+
+ if (key == '\b')
+ {
+ cur_len--;
+ continue;
+ }
+
+ if (!grub_isprint (key))
+ continue;
+
+ if (cur_len + 2 < buf_size)
+ buf[cur_len++] = key;
+ }
+
+ grub_memset (buf + cur_len, 0, buf_size - cur_len);
+
+ grub_putchar ('\n');
+ grub_refresh ();
+
+ return (key != '\e');
+}
+#endif
diff --git a/normal/auth.c b/normal/auth.c
index 0a8b5bc82..d679fcc35 100644
--- a/normal/auth.c
+++ b/normal/auth.c
@@ -160,6 +160,7 @@ grub_auth_check_authentication (const char *userlist)
struct grub_auth_user *cur = NULL;
grub_err_t err;
static unsigned long punishment_delay = 1;
+ char entered[GRUB_AUTH_MAX_PASSLEN];
auto int hook (grub_list_t item);
int hook (grub_list_t item)
@@ -189,22 +190,17 @@ grub_auth_check_authentication (const char *userlist)
0, 0, 0))
goto access_denied;
+ grub_printf ("Enter password: ");
+
+ if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
+ goto access_denied;
+
grub_list_iterate (GRUB_AS_LIST (users), hook);
if (!cur || ! cur->callback)
- {
- grub_list_iterate (GRUB_AS_LIST (users), hook_any);
+ goto access_denied;
- /* No users present at all. */
- if (!cur)
- goto access_denied;
-
- /* Display any of available authentication schemes. */
- err = cur->callback (login, 0);
-
- goto access_denied;
- }
- err = cur->callback (login, cur->arg);
+ err = cur->callback (login, entered, cur->arg);
if (is_authenticated (userlist))
{
punishment_delay = 1;