From 228734ab023191ff8df42e83c615d7ab610a3aea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 15 Nov 2009 23:36:42 +0100 Subject: [PATCH] MAX_PASSLEN based authentication --- commands/password.c | 13 ++++++++--- include/grub/auth.h | 7 +----- normal/auth.c | 56 ++------------------------------------------- 3 files changed, 13 insertions(+), 63 deletions(-) diff --git a/commands/password.c b/commands/password.c index 0e048797e..247e0bffd 100644 --- a/commands/password.c +++ b/commands/password.c @@ -26,18 +26,20 @@ static grub_dl_t my_mod; +#define MAX_PASSLEN 1024 + static grub_err_t check_password (const char *user, void *password) { - char entered[1024]; + char entered[MAX_PASSLEN]; grub_memset (entered, 0, sizeof (entered)); if (!GRUB_GET_PASSWORD (entered, sizeof (entered) - 1)) return GRUB_ACCESS_DENIED; - if (grub_auth_strcmp (entered, password) != 0) + if (grub_crypto_memcmp (entered, password, MAX_PASSLEN) != 0) return GRUB_ACCESS_DENIED; grub_auth_authenticate (user); @@ -51,13 +53,18 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), { grub_err_t err; char *pass; + int copylen; if (argc != 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected."); - pass = grub_strdup (args[1]); + pass = grub_zalloc (MAX_PASSLEN); if (!pass) return grub_errno; + copylen = grub_strlen (argv[1]); + if (copylen >= MAX_PASSLEN) + copylen = MAX_PASSLEN - 1; + grub_memcpy (pass, argv[1], copylen); err = grub_auth_register_authentication (args[0], check_password, pass); if (err) diff --git a/include/grub/auth.h b/include/grub/auth.h index da930eeda..e72d984ae 100644 --- a/include/grub/auth.h +++ b/include/grub/auth.h @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ -#ifndef GRUB_AURH_HEADER +#ifndef GRUB_AUTH_HEADER #define GRUB_AUTH_HEADER 1 #include @@ -26,11 +26,6 @@ string, len, \ '*', 0, 0) -/* Like strcmp but untimeable. Accepts NULL as second argument. */ -int grub_auth_strcmp (const char *user_input, const char *template); -/* Like strcmp but untimeable and ignores commas in needle. */ -int grub_auth_strword (const char *haystack, const char *needle); - typedef grub_err_t (*grub_auth_callback_t) (const char*, void *); grub_err_t grub_auth_register_authentication (const char *user, diff --git a/normal/auth.c b/normal/auth.c index c71262584..7d5a07d26 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -35,58 +35,6 @@ struct grub_auth_user struct grub_auth_user *users = NULL; -int -grub_auth_strcmp (const char *s1, const char *s2) -{ - int ret; - grub_uint64_t end; - - end = grub_get_time_ms () + 100; - ret = grub_strcmp (s1, s2); - - /* This prevents an attacker from deriving information about the - password from the time it took to execute this function. */ - while (grub_get_time_ms () < end); - - return ret; -} - -static int -grub_iswordseparator (int c) -{ - return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&'); -} - -int -grub_auth_strword (const char *haystack, const char *needle) -{ - const char *n_pos = needle; - int found = 0; - - while (grub_iswordseparator (*haystack)) - haystack++; - - while (*haystack) - { - int ok = 1; - /* Crawl both the needle and the haystack word we're on. */ - while(*haystack && !grub_iswordseparator (*haystack)) - { - if (*haystack == *n_pos && ok) - n_pos++; - else - ok = 0; - - haystack++; - } - - if (ok) - found = 1; - } - - return found; -} - grub_err_t grub_auth_register_authentication (const char *user, grub_auth_callback_t callback, @@ -193,8 +141,8 @@ is_authenticated (const char *userlist) return 0; name = ((struct grub_auth_user *) item)->name; - return (userlist && grub_auth_strword (userlist, name)) - || grub_auth_strword (superusers, name); + return (userlist && grub_strword (userlist, name)) + || grub_strword (superusers, name); } superusers = grub_env_get ("superusers");