2010-01-07 Vladimir Serbinenko <phcoder@gmail.com>
Merge crypto branch. * Makefile.in (pkglib_DATA): Add crypto.lst. (crypto.lst): New target. * commands/hashsum.c: New file. * commands/password.c (check_password): Use grub_crypto_memcmp. * commands/password_pbkdf2.c: New file. * commands/xnu_uuid.c: Remove MD5. Use GRUB_MD_MD5. * conf/any-emu.rmk (grub_emu_SOURCES): Add lib/crypto.c, normal/crypto.c and lib/libgcrypt-grub/cipher/md5.c. (grub_emu_CFLAGS): Add -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap. * conf/common.rmk (normal_mod_SOURCES): Add normal/crypto.c. (pkglib_MODULES): Add crypto.mod, hashsum.mod, pbkdf2.mod and password_pbkdf2.mod. (crypto_mod_SOURCES): New variable. (crypto_mod_CFLAGS): Likewise. (crypto_mod_LDFLAGS): Likewise. (hashsum_mod_SOURCES): New variable. (hashsum_mod_CFLAGS): Likewise. (hashsum_mod_LDFLAGS): Likewise. (pbkdf2_mod_SOURCES): New variable. (pbkdf2_mod_CFLAGS): Likewise. (pbkdf2_mod_LDFLAGS): Likewise. (password_pbkdf2_mod_SOURCES): New variable. (password_pbkdf2_mod_CFLAGS): Likewise. (password_pbkdf2_mod_LDFLAGS): Likewise. (bin_UTILITIES): Add grub-mkpasswd-pbkdf2. (grub_mkpasswd_pbkdf2_SOURCES): New variable. (grub_mkpasswd_pbkdf2_CFLAGS): Likewise. Include conf/gcry.rmk. * include/grub/auth.h: Rewritten. * include/grub/crypto.h: New file. * include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_LUKS_ID. * include/grub/normal.h (read_crypto_list): New prototype. * lib/crypto.c: New file. * lib/libgcrypt_wrap/cipher_wrap.h: Likewise. * lib/pbkdf2.c: Likewise. * normal/auth.c (grub_auth_strcmp): Removed. (grub_iswordseparator): Likewise. (grub_auth_strword): Likewise. (is_authenticated): Use grub_strword. (grub_auth_check_authentication): Use grub_strcmp, grub_password_get and grub_strword. Pass entered password to authentication callback. * normal/crypto.c: New file. * normal/main.c: Call read_crypto_list. * util/grub-mkpasswd-pbkdf2.c: New file. * util/import_gcry.py: Generate crypto.lst. Add hash blocklen.
This commit is contained in:
commit
607a3701db
21 changed files with 2086 additions and 414 deletions
|
@ -36,58 +36,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,
|
||||
|
@ -194,8 +142,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");
|
||||
|
@ -213,11 +161,12 @@ 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)
|
||||
{
|
||||
if (grub_auth_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
|
||||
if (grub_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
|
||||
cur = (struct grub_auth_user *) item;
|
||||
return 0;
|
||||
}
|
||||
|
@ -242,22 +191,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;
|
||||
|
|
153
normal/crypto.c
Normal file
153
normal/crypto.c
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* crypto.c - support crypto autoload */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/dl.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/crypto.h>
|
||||
#include <grub/normal.h>
|
||||
|
||||
struct load_spec
|
||||
{
|
||||
struct load_spec *next;
|
||||
char *name;
|
||||
char *modname;
|
||||
};
|
||||
|
||||
struct load_spec *crypto_specs = NULL;
|
||||
|
||||
static void
|
||||
grub_crypto_autoload (const char *name)
|
||||
{
|
||||
struct load_spec *cur;
|
||||
grub_dl_t mod;
|
||||
|
||||
for (cur = crypto_specs; cur; cur = cur->next)
|
||||
if (grub_strcasecmp (name, cur->name) == 0)
|
||||
{
|
||||
mod = grub_dl_load (cur->modname);
|
||||
if (mod)
|
||||
grub_dl_ref (mod);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
grub_crypto_spec_free (void)
|
||||
{
|
||||
struct load_spec *cur, *next;
|
||||
for (cur = crypto_specs; cur; cur = next)
|
||||
{
|
||||
next = cur->next;
|
||||
grub_free (cur->name);
|
||||
grub_free (cur->modname);
|
||||
grub_free (cur);
|
||||
}
|
||||
crypto_specs = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Read the file crypto.lst for auto-loading. */
|
||||
void
|
||||
read_crypto_list (void)
|
||||
{
|
||||
const char *prefix;
|
||||
char *filename;
|
||||
grub_file_t file;
|
||||
char *buf = NULL;
|
||||
|
||||
prefix = grub_env_get ("prefix");
|
||||
if (!prefix)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
filename = grub_malloc (grub_strlen (prefix) + sizeof ("/crypto.lst"));
|
||||
if (!filename)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
grub_sprintf (filename, "%s/crypto.lst", prefix);
|
||||
file = grub_file_open (filename);
|
||||
if (!file)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Override previous commands.lst. */
|
||||
grub_crypto_spec_free ();
|
||||
|
||||
for (;; grub_free (buf))
|
||||
{
|
||||
char *p, *name;
|
||||
struct load_spec *cur;
|
||||
|
||||
buf = grub_file_getline (file);
|
||||
|
||||
if (! buf)
|
||||
break;
|
||||
|
||||
name = buf;
|
||||
|
||||
p = grub_strchr (name, ':');
|
||||
if (! p)
|
||||
continue;
|
||||
|
||||
*p = '\0';
|
||||
while (*++p == ' ')
|
||||
;
|
||||
|
||||
cur = grub_malloc (sizeof (*cur));
|
||||
if (!cur)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
cur->name = grub_strdup (name);
|
||||
if (! name)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
grub_free (cur);
|
||||
continue;
|
||||
}
|
||||
|
||||
cur->modname = grub_strdup (p);
|
||||
if (! cur->modname)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
grub_free (cur);
|
||||
grub_free (cur->name);
|
||||
continue;
|
||||
}
|
||||
cur->next = crypto_specs;
|
||||
crypto_specs = cur;
|
||||
}
|
||||
|
||||
grub_file_close (file);
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
grub_crypto_autoload_hook = grub_crypto_autoload;
|
||||
}
|
|
@ -428,6 +428,7 @@ grub_normal_execute (const char *config, int nested, int batch)
|
|||
read_command_list ();
|
||||
read_fs_list ();
|
||||
read_handler_list ();
|
||||
read_crypto_list ();
|
||||
grub_command_execute ("parser.grub", 0, 0);
|
||||
|
||||
reader_nested = nested;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue