On Sun, Jul 26, 2009 at 6:20 PM, Vladimir 'phcoder'
Serbinenko<phco...@gmail.com> wrote:
>>> If I remember correctly, I had improved on the first patch to include
>>> most of the remarks. I'll have a look if I can find back the modified
>>> patch, and send it to the list for anyone to have it.
>>>
>>
>> What is with his patch? Shouldn't we just send him an assigment?
>> Adrian (the author of SGD) just mentioned on IRC that everyone tells him
>> grub2 won't be used widely by distros without password support.
> Yes. It's important. Quick look shows that this patch mainly deals
> with passwords and totally neglects authentication framework. While it
> already does password protection if later we want to extend support to
> new primitives or even just. Once we have the framework implementing
> particular authentication will be easy
>>
>> So it seems this is important to people.
>> I try to look into this but I have the feeling that I'm not really the
>> right person for this. Especially when we want something complete and
>> extensible etc.
>>
> I think you underestimate yourself. Especially if we agree on function
> propotypes you are completely able to implement. Discussing on IRC I
> formulated 3 criteria which our system must satisfy:
> (1) you can't access shell without authenticating as "superuser".
> (2) boot some entries without authenticating as one of users (list of
> allowed users may differ per menuentry)
> (3) new autentication schemes (e.g. ssh keys) should be implementable as 
> modules
>
> I propose following implementation guidelines:
> Syntax:
> set superusers=root,gnu
> password root "GRUB"
> md5_password operator $MD5$MD5$MD5
> fingeprint gnu /gnu.fp
> menuentry "single mode" --users root,operator {
>  ....
> }
>
> Wher user tries to authenticate GRUB2 will ask him login and then call
> a function from module
>
> Prototypes:
> grub_err_t grub_auth_register_authentication (const char *user,
> grub_err_t (*callback) (const char*, void *), void *arg);
> this will ask to call callback if login is USER.
> grub_err_t grub_auth_authenticate (const char *user);
> grub_err_t grub_auth_deauthenticate (const char *user);
> grub_err_t grub_auth_check_authentication (const char *userlist);
>
> grub_auth_check_authentication will output login prompt if no user
> from userlist is already authenticated
As agreed with Felix I implemented the framework. See attached patch
>> --
>> Felix Zielcke
>> Proud Debian Maintainer
>>
>>
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>
>
>
>
> --
> Regards
> Vladimir 'phcoder' Serbinenko
>
> Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
>



-- 
Regards
Vladimir 'phcoder' Serbinenko

Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
diff --git a/conf/common.rmk b/conf/common.rmk
index 032517f..f5843a7 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -503,7 +503,7 @@ probe_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For normal.mod.
 normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
-       normal/autofs.c normal/handler.c \
+       normal/auth.c normal/autofs.c normal/handler.c \
        normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
        normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
        normal/misc.c
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index 7ba5737..6be465b 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -127,7 +127,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c 
commands/cmp.c \
        kern/partition.c kern/reader.c kern/term.c                      \
        kern/rescue_reader.c kern/rescue_parser.c                       \
        lib/arg.c normal/cmdline.c normal/misc.c                        \
-       normal/handler.c normal/autofs.c                                \
+       normal/handler.c normal/auth.c normal/autofs.c                          
\
        normal/completion.c normal/datetime.c normal/main.c             \
        normal/menu_text.c                                              \
        normal/menu.c normal/menu_entry.c normal/menu_viewer.c          \
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index 9177b9d..47b4508 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -54,7 +54,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c 
commands/cmp.c   \
        kern/partition.c kern/reader.c kern/term.c                      \
        kern/rescue_reader.c kern/rescue_parser.c                       \
        lib/arg.c normal/cmdline.c normal/command.c normal/datetime.c   \
-       normal/autofs.c                                                 \
+       normal/auth.c normal/autofs.c                                           
        \
        normal/completion.c normal/context.c normal/main.c              \
        normal/menu.c normal/menu_entry.c normal/menu_viewer.c          \
        normal/menu_text.c                                              \
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 0321979..9543a65 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -82,7 +82,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c 
commands/cmp.c   \
        kern/partition.c kern/reader.c kern/term.c                      \
        kern/rescue_reader.c kern/rescue_parser.c                       \
        lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c      \
-       normal/handler.c normal/autofs.c                                \
+       normal/handler.c normal/auth.c normal/autofs.c                          
\
        normal/completion.c normal/main.c normal/menu_text.c            \
        normal/menu.c normal/menu_entry.c normal/menu_viewer.c          \
        normal/color.c                                                  \
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 798aee2..6b827e3 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -136,7 +136,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c 
commands/cmp.c \
        kern/partition.c kern/reader.c kern/term.c                      \
        kern/rescue_reader.c kern/rescue_parser.c                       \
        lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c      \
-       normal/handler.c normal/autofs.c                                \
+       normal/handler.c normal/auth.c normal/autofs.c                          
\
        normal/completion.c normal/main.c normal/color.c                \
        normal/menu.c normal/menu_entry.c normal/menu_viewer.c          \
        normal/menu_text.c                                              \
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index af29d23..08c73b0 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -62,7 +62,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c 
commands/cmp.c   \
        kern/command.c kern/corecmd.c commands/extcmd.c                 \
        lib/arg.c normal/cmdline.c normal/datetime.c                    \
        normal/completion.c normal/misc.c                               \
-       normal/handler.c normal/autofs.c normal/main.c                  \
+       normal/handler.c normal/auth.c normal/autofs.c normal/main.c            
        \
        normal/menu.c                                                   \
        normal/menu_text.c                                              \
        normal/menu_entry.c normal/menu_viewer.c                        \
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
index aabccee..d61e97c 100644
--- a/conf/sparc64-ieee1275.rmk
+++ b/conf/sparc64-ieee1275.rmk
@@ -119,7 +119,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c 
commands/cmp.c         \
        kern/command.c kern/corecmd.c commands/extcmd.c                 \
        lib/arg.c normal/cmdline.c normal/datetime.c                    \
        normal/completion.c normal/misc.c                               \
-       normal/handler.c normal/autofs.c normal/main.c                  \
+       normal/handler.c normal/auth.c normal/autofs.c normal/main.c            
        \
        normal/menu.c                                                   \
        normal/menu_text.c                                              \
        normal/menu_entry.c normal/menu_viewer.c                        \
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
index 21da0e1..57254c0 100644
--- a/conf/x86_64-efi.rmk
+++ b/conf/x86_64-efi.rmk
@@ -50,7 +50,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c 
commands/cmp.c   \
        kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c     \
        kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \
        kern/partition.c kern/readerescue.c kern/term.c                 \
-       lib/arg.c normal/cmdline.c normal/misc.c normal/autofs.c        \
+       lib/arg.c normal/cmdline.c normal/misc.c normal/auth.c normal/autofs.c  
\
        normal/completion.c normal/datetime.c normal/context.c          \
        normal/main.c           \
        normal/menu.c normal/menu_entry.c normal/menu_viewer.c          \
diff --git a/include/grub/auth.h b/include/grub/auth.h
new file mode 100644
index 0000000..6a5d0b6
--- /dev/null
+++ b/include/grub/auth.h
@@ -0,0 +1,34 @@
+/*
+ *  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/>.
+ */
+#ifndef GRUB_AURH_HEADER
+#define GRUB_AUTH_HEADER       1
+
+#include <grub/err.h>
+
+typedef grub_err_t (*grub_auth_callback_t) (const char*, void *);
+
+grub_err_t grub_auth_register_authentication (const char *user,
+                                             grub_auth_callback_t callback,
+                                             void *arg);
+grub_err_t grub_auth_unregister_authentication (const char *user);
+
+grub_err_t grub_auth_authenticate (const char *user);
+grub_err_t grub_auth_deauthenticate (const char *user);
+grub_err_t grub_auth_check_authentication (const char *userlist);
+
+#endif /* ! GRUB_AUTH_HEADER */
diff --git a/include/grub/err.h b/include/grub/err.h
index 3435fb7..7a5ce1a 100644
--- a/include/grub/err.h
+++ b/include/grub/err.h
@@ -53,7 +53,8 @@ typedef enum
     GRUB_ERR_BAD_GZIP_DATA,
     GRUB_ERR_MENU,
     GRUB_ERR_TIMEOUT,
-    GRUB_ERR_IO
+    GRUB_ERR_IO,
+    GRUB_ERR_ACCESS_DENIED
   }
 grub_err_t;
 
diff --git a/include/grub/menu.h b/include/grub/menu.h
index 3bd25e8..70aa7fd 100644
--- a/include/grub/menu.h
+++ b/include/grub/menu.h
@@ -32,6 +32,9 @@ struct grub_menu_entry
   /* The title name.  */
   const char *title;
 
+  /* Allowed users. NULL means 'everybody'.  */
+  const char *users;
+
   /* The classes associated with the menu entry:
      used to choose an icon or other style attributes.
      This is a dummy head node for the linked list, so for an entry E,
diff --git a/include/grub/normal.h b/include/grub/normal.h
index 7d8122a..feebc85 100644
--- a/include/grub/normal.h
+++ b/include/grub/normal.h
@@ -56,7 +56,7 @@ void grub_cmdline_run (int nested);
 
 /* Defined in `cmdline.c'.  */
 int grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
-                     int echo_char, int readline);
+                     int echo_char, int readline, int history);
 grub_err_t grub_set_history (int newsize);
 
 /* Defined in `completion.c'.  */
diff --git a/normal/auth.c b/normal/auth.c
new file mode 100644
index 0000000..8633006
--- /dev/null
+++ b/normal/auth.c
@@ -0,0 +1,184 @@
+/*
+ *  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/auth.h>
+#include <grub/list.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+
+struct grub_auth_user
+{
+  struct grub_auth_user *next;
+  char *name;
+  grub_auth_callback_t callback;
+  void *arg;
+  int authenticated;
+};
+
+struct grub_auth_user *users = 0;
+
+grub_err_t 
+grub_auth_register_authentication (const char *user,
+                                  grub_auth_callback_t callback,
+                                  void *arg)
+{
+  struct grub_auth_user *cur;
+
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    cur = grub_zalloc (sizeof (*cur));
+  if (!cur)
+    return grub_errno;
+  cur->callback = callback;
+  cur->arg = arg;
+  if (! cur->name)
+    {
+      cur->name = grub_strdup (user);
+      if (!cur->name)
+       {
+         grub_free (cur);
+         return grub_errno;
+       }
+      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t 
+grub_auth_unregister_authentication (const char *user)
+{
+  struct grub_auth_user *cur;
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
+  if (!cur->authenticated)
+    {
+      grub_free (cur->name);
+      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+      grub_free (cur);
+    }
+  else
+    {
+      cur->callback = 0;
+      cur->arg = 0;
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t 
+grub_auth_authenticate (const char *user)
+{
+  struct grub_auth_user *cur;
+
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    cur = grub_zalloc (sizeof (*cur));
+  if (!cur)
+    return grub_errno;
+
+  cur->authenticated = 1;
+
+  if (! cur->name)
+    {
+      cur->name = grub_strdup (user);
+      if (!cur->name)
+       {
+         grub_free (cur);
+         return grub_errno;
+       }
+      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t 
+grub_auth_deauthenticate (const char *user)
+{
+  struct grub_auth_user *cur;
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
+  if (!cur->callback)
+    {
+      grub_free (cur->name);
+      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+      grub_free (cur);
+    }
+  else
+    cur->authenticated = 0;
+  return GRUB_ERR_NONE;
+}
+
+static int
+is_authenticated (const char *userlist)
+{
+  const char *superusers;
+
+  auto int hook (grub_list_t item);
+  int hook (grub_list_t item)
+  {
+    return (userlist && grub_strword (userlist,
+                                     ((struct grub_auth_user *) item)->name))
+      || grub_strword (superusers, ((struct grub_auth_user *) item)->name);
+  }
+
+  superusers = grub_env_get ("superusers");
+  
+  if (!superusers)
+    return GRUB_ERR_NONE;
+
+  return grub_list_iterate (GRUB_AS_LIST (users), hook);
+}
+
+grub_err_t 
+grub_auth_check_authentication (const char *userlist)
+{
+  char login[1024] = {0};
+  struct grub_auth_user *cur = 0;
+  grub_err_t err;
+
+  auto int hook (grub_list_t item);
+  int hook (grub_list_t item)
+  {
+    if (grub_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
+      {
+       cur = (struct grub_auth_user *) item;
+       return 1;
+      }
+    return 0;
+  }
+
+  if (is_authenticated (userlist))
+    return GRUB_ERR_NONE;
+
+  if (!grub_cmdline_get ("Enter username: ", login, sizeof (login) - 1, 0, 0, 
0))
+    return grub_error (GRUB_ERR_ACCESS_DENIED, "login aborted");
+
+  if (!grub_list_iterate (GRUB_AS_LIST (users), hook) || ! cur->callback)
+    {
+      /* XXX Show a fake password prompt*/
+      return grub_error (GRUB_ERR_ACCESS_DENIED, "password incorrect");      
+    }
+  err = cur->callback (login, cur->arg);
+  if (is_authenticated (userlist))
+    return GRUB_ERR_NONE;
+  return grub_error (GRUB_ERR_ACCESS_DENIED, "access denied");
+}
diff --git a/normal/cmdline.c b/normal/cmdline.c
index 9a07d7d..56f8921 100644
--- a/normal/cmdline.c
+++ b/normal/cmdline.c
@@ -181,7 +181,7 @@ print_completion (const char *item, grub_completion_type_t 
type, int count)
 /* FIXME: The dumb interface is not supported yet.  */
 int
 grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
-                 int echo_char, int readline)
+                 int echo_char, int readline, int history)
 {
   unsigned xpos, ypos, ystart;
   grub_size_t lpos, llen;
@@ -280,7 +280,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], 
unsigned max_len,
 
   cl_insert (cmdline);
 
-  if (hist_used == 0)
+  if (history && hist_used == 0)
     grub_history_add (buf);
 
   while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
@@ -468,11 +468,14 @@ grub_cmdline_get (const char *prompt, char cmdline[], 
unsigned max_len,
     while (buf[lpos] == ' ')
       lpos++;
 
-  histpos = 0;
-  if (grub_strlen (buf) > 0)
+  if (history)
     {
-      grub_history_replace (histpos, buf);
-      grub_history_add ("");
+      histpos = 0;
+      if (grub_strlen (buf) > 0)
+       {
+         grub_history_replace (histpos, buf);
+         grub_history_add ("");
+       }
     }
 
   grub_memcpy (cmdline, buf + lpos, llen - lpos + 1);
diff --git a/normal/main.c b/normal/main.c
index 66d8418..b2029ce 100644
--- a/normal/main.c
+++ b/normal/main.c
@@ -28,6 +28,7 @@
 #include <grub/parser.h>
 #include <grub/reader.h>
 #include <grub/menu_viewer.h>
+#include <grub/auth.h>
 
 #define GRUB_DEFAULT_HISTORY_SIZE      50
 
@@ -164,6 +165,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
   int i;
   struct grub_menu_entry_class *classes_head;  /* Dummy head node for list.  */
   struct grub_menu_entry_class *classes_tail;
+  char *users = 0;
 
   /* Allocate dummy head node for class list.  */
   classes_head = grub_zalloc (sizeof (struct grub_menu_entry_class));
@@ -218,6 +220,18 @@ grub_normal_add_menu_entry (int argc, const char **args,
              classes_tail = new_class;
              continue;
            }
+         else if (grub_strcmp(arg, "users") == 0)
+           {
+             i++;
+             users = grub_strdup (args[i]);
+             if (! users)
+               {
+                 failed = 1;
+                 break;
+               }
+
+             continue;
+           }
          else
            {
              /* Handle invalid argument.  */
@@ -275,6 +289,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
 
   (*last)->title = menutitle;
   (*last)->classes = classes_head;
+  (*last)->users = users;
   (*last)->sourcecode = menusourcecode;
 
   menu->size++;
@@ -465,7 +480,19 @@ quit:
 void
 grub_cmdline_run (int nested)
 {
-  grub_reader_t reader = grub_reader_get_current ();
+  grub_reader_t reader;
+  grub_err_t err = GRUB_ERR_NONE;
+
+  err = grub_auth_check_authentication (0);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  reader = grub_reader_get_current ();
 
   reader_nested = nested;
   if (reader->init)
@@ -501,7 +528,7 @@ grub_normal_read_line (char **line, int cont)
   while (1)
     {
       cmdline[0] = 0;
-      if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1))
+      if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1, 1))
        break;
 
       if ((reader_nested) || (cont))
diff --git a/normal/menu.c b/normal/menu.c
index 59ad83f..b9b7763 100644
--- a/normal/menu.c
+++ b/normal/menu.c
@@ -26,6 +26,7 @@
 #include <grub/menu_viewer.h>
 #include <grub/command.h>
 #include <grub/parser.h>
+#include <grub/auth.h>
 
 /* Get a menu entry by its index in the entry list.  */
 grub_menu_entry_t
@@ -124,6 +125,18 @@ get_and_remove_first_entry_number (const char *name)
 void
 grub_menu_execute_entry(grub_menu_entry_t entry)
 {
+  grub_err_t err = GRUB_ERR_NONE;
+
+  if (entry->users)
+    err = grub_auth_check_authentication (entry->users);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
   grub_parser_execute ((char *) entry->sourcecode);
 
   if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
diff --git a/normal/menu_entry.c b/normal/menu_entry.c
index f7662ff..9505df0 100644
--- a/normal/menu_entry.c
+++ b/normal/menu_entry.c
@@ -23,6 +23,7 @@
 #include <grub/loader.h>
 #include <grub/command.h>
 #include <grub/parser.h>
+#include <grub/auth.h>
 
 enum update_mode
   {
@@ -1026,6 +1027,16 @@ grub_menu_entry_run (grub_menu_entry_t entry)
 {
   struct screen *screen;
   int prev_c;
+  grub_err_t err = GRUB_ERR_NONE;
+
+  err = grub_auth_check_authentication (0);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
 
   screen = make_screen (entry);
   if (! screen)
diff --git a/normal/menu_viewer.c b/normal/menu_viewer.c
index 37d317b..ef715c9 100644
--- a/normal/menu_viewer.c
+++ b/normal/menu_viewer.c
@@ -21,6 +21,7 @@
 #include <grub/env.h>
 #include <grub/menu_viewer.h>
 #include <grub/menu.h>
+#include <grub/auth.h>
 
 /* The list of menu viewers.  */
 static grub_menu_viewer_t menu_viewer_list;
@@ -55,9 +56,24 @@ grub_err_t
 grub_menu_viewer_show_menu (grub_menu_t menu, int nested)
 {
   grub_menu_viewer_t cur = get_current_menu_viewer ();
+  grub_err_t err1, err2;
   if (!cur)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "No menu viewer available.");
 
-  return cur->show_menu (menu, nested);
+  while (1)
+    {
+      err1 = cur->show_menu (menu, nested);
+      grub_print_error ();
+
+      err2 = grub_auth_check_authentication (0);
+      if (err2)
+       {
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         continue;
+       }
+    }
+ 
+  return err1;
 }
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to