From ce7c6fd0a9cbd3ff047365a34ef61163d123e763 Mon Sep 17 00:00:00 2001 From: okuji Date: Sat, 22 Apr 2000 23:29:23 +0000 Subject: [PATCH] add new features into the password system. --- ChangeLog | 33 +++++++++++++++++++++++++++++++++ NEWS | 6 ++++++ docs/user-ref.texi | 2 +- stage2/builtins.c | 42 ++++++++++++++++++++++++++++++++++++++---- stage2/common.c | 1 + stage2/shared.h | 2 ++ stage2/stage2.c | 27 ++++++++++++++++++++++----- 7 files changed, 103 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 48b64028f..aa8ac8c33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2000-04-23 OKUJI Yoshinori + + More security-related features. + + * stage2/builtins.c (auth): New global variable. + (configfile_func): Clear AUTH before jumping to cmain. + (lock_func): New function. + (builtin_lock): New variable. + (password_func): Make sure that LEN + 2 is less than or equal to + PASSWORD_BUFLEN, because now the password must be terminated + with double NULs, in order to permit an empty configuration file + name. + Copy LEN bytes from ARG to PASSWORD, instead of LEN + 1 bytes. + Clear the rest of the buffer PASSWORD. + (builtin_table): Added a pointer to BUILTIN_LOCK. + * stage2/common.c (err_list): Added an entry for ERR_PRIVILEGED. + * stage2/stage2.c (run_menu): If AUTH is true, show the messages + for a non-password configuration, even if PASSWORD is not NULL. + Likewise, if AUTH is true, allow the user to use privileged + instructions (such as `c'). + If a correct password is entered, check if *PPTR is NUL or not. + If it is NUL, set AUTH to 1 and go to the label restart, + otherwise, copy PPTR to NEW_FILE, clear AUTH, and return. + * stage2/shared.h (grub_error_t): Added a new constant + ERR_PRIVILEGED. + (auth): Declared. + +2000-04-23 OKUJI Yoshinori + + * docs/user-ref.texi (Command-line-specific commands): Don't use + the command @var for the argument "file" to the command + "configfile" on the definition. + 2000-04-22 OKUJI Yoshinori Update the network support to Etherboot 4.5.8. diff --git a/NEWS b/NEWS index abed5ae9f..339de099d 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,12 @@ New in 0.5.95 - XXXX-XX-XX: `--disable-lba-support-bitmap-check' any longer. Use the option above. * The network support is updated to Etherboot-4.5.8. So now we have 3Com59x and DEPCA drivers. +* Now you can omit the configuration file argument to the command + "password". If you omit it, then GRUB will just unlock privileged + instructions (such as `c') when you enter a correct password. +* The new command "lock" can be used to prevent end-users from executing + arbitrary menu entries. This command will emit an error until the user + enters a correct password. New in 0.5.94 - 2000-03-06: * Stage 1 supports both the LBA mode and the CHS mode. diff --git a/docs/user-ref.texi b/docs/user-ref.texi index bb3a6628a..d40ee04e7 100644 --- a/docs/user-ref.texi +++ b/docs/user-ref.texi @@ -810,7 +810,7 @@ Differ at the offset 777: 0xbe [foo], 0xef [bar] If they are complete identical, nothing will be printed. @end deffn -@deffn Command configfile @var{file} +@deffn Command configfile file Load @var{file} as the configuration file. @end deffn diff --git a/stage2/builtins.c b/stage2/builtins.c index 2400e6b11..785072b35 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -45,6 +45,8 @@ int fallback_entry = -1; static char *mb_cmdline; /* The password. */ char *password; +/* The flag for indicating that the user is authoritative. */ +int auth = 0; /* Color settings. */ int normal_color; int highlight_color; @@ -643,6 +645,9 @@ configfile_func (char *arg, int flags) use_config_file = 1; #endif + /* Make sure that the user will not be authoritative. */ + auth = 0; + /* Restart cmain. */ grub_longjmp (restart_env, 0); @@ -1944,6 +1949,29 @@ static struct builtin builtin_kernel = " \"multiboot\"." }; + +/* lock */ +static int +lock_func (char *arg, int flags) +{ + if (! auth && password) + { + errnum = ERR_PRIVILEGED; + return 1; + } + + return 0; +} + +static struct builtin builtin_lock = +{ + "lock", + lock_func, + BUILTIN_CMDLINE, + "lock", + "Break a command execution unless the user is authenticated." +}; + /* makeactive */ static int @@ -2114,14 +2142,17 @@ password_func (char *arg, int flags) { int len = grub_strlen (arg); - if (len > PASSWORD_BUFLEN) + /* PASSWORD NUL NUL ... */ + if (len + 2 > PASSWORD_BUFLEN) { errnum = ERR_WONT_FIT; return 1; } + /* Copy the password and clear the rest of the buffer. */ password = (char *) PASSWORD_BUF; - grub_memmove (password, arg, len + 1); + grub_memmove (password, arg, len); + grub_memset (password + len, 0, PASSWORD_BUFLEN - len); return 0; } @@ -2131,10 +2162,12 @@ static struct builtin builtin_password = password_func, BUILTIN_MENU, #if 0 - "password PASSWD FILE", + "password PASSWD [FILE]", "Disable all interactive editing control (menu entry editor and" " command line). If the password PASSWD is entered, it loads the" - " FILE as a new config file and restarts the GRUB Stage 2." + " FILE as a new config file and restarts the GRUB Stage 2. If you" + " omit the argument FILE, then GRUB just unlocks privileged" + " instructions." #endif }; @@ -3029,6 +3062,7 @@ struct builtin *builtin_table[] = &builtin_install, &builtin_ioprobe, &builtin_kernel, + &builtin_lock, &builtin_makeactive, &builtin_map, &builtin_module, diff --git a/stage2/common.c b/stage2/common.c index 081c32fcc..a1a9b5be8 100644 --- a/stage2/common.c +++ b/stage2/common.c @@ -76,6 +76,7 @@ char *err_list[] = [ERR_WRITE] = "Disk write error", [ERR_BAD_ARGUMENT] = "Invaild argument specified", [ERR_UNALIGNED] = "File is not sector aligned", + [ERR_PRIVILEGED] = "Must be authenticated", }; diff --git a/stage2/shared.h b/stage2/shared.h index 9efa324c5..81958abea 100644 --- a/stage2/shared.h +++ b/stage2/shared.h @@ -417,6 +417,7 @@ typedef enum ERR_WRITE, ERR_BAD_ARGUMENT, ERR_UNALIGNED, + ERR_PRIVILEGED, MAX_ERR_NUM } grub_error_t; @@ -461,6 +462,7 @@ extern void assign_device_name (int drive, const char *device); extern int fallback_entry; extern int default_entry; extern char *password; +extern int auth; extern char commands[]; #endif diff --git a/stage2/stage2.c b/stage2/stage2.c index 452a6a70e..50ab8a1e3 100644 --- a/stage2/stage2.c +++ b/stage2/stage2.c @@ -202,7 +202,7 @@ restart: DISP_UP, DISP_DOWN); #endif - if (password) + if (! auth && password) { printf (" Press enter to boot the selected OS or \'p\' to enter a password to unlock the next set of features."); @@ -364,7 +364,7 @@ restart: break; } - if (password) + if (! auth && password) { if (c == 'p') { @@ -389,9 +389,26 @@ restart: char *new_file = config_file; while (isspace (*pptr)) pptr++; - while ((*(new_file++) = *(pptr++)) != 0) - ; - return; + + /* If *PPTR is NUL, then allow the user to use + privileged instructions, otherwise, load + another configuration file. */ + if (*pptr != 0) + { + while ((*(new_file++) = *(pptr++)) != 0) + ; + + /* Make sure that the user will not have + authority in the next configuration. */ + auth = 0; + return; + } + else + { + /* Now the user is superhuman. */ + auth = 1; + goto restart; + } } else {