bde43ee183
Prior to r222417, setting `password' in loader.conf(5) did not prevent boot but instead only prevented changes to boot options by prompting for password if autoboot failed or the user interrupted the countdown sequence. After r222417 the same machine with `password' set in loader.conf(5) would no longer boot without _always_ entering the password. This patch restores the old (8.x and older) functionality for password in loader.conf(5) while adding a new bootlock_password feature to replace the edge-case should anybody desire the regressed functionality (HINT: great for PXE servers and/or private distributions). loader.conf(5) was updated to be more clear with-respect to password setting (previous text was misleading). Documentation (loader.conf(5) and check-password.4th(8)) has been updated to include notes on the new bootlock_password setting. Special thanks to Alex Verbod for bringing this to my attention and helping to refine the loader.conf(5) text. PR: conf/170110 Submitted by: Vitaly Zakharov <ded3axap@gmail.com> Reviewed by: Alexander Verbod <alexander.verbod@gmail.com>
171 lines
5.5 KiB
Forth
171 lines
5.5 KiB
Forth
\ Copyright (c) 2006-2012 Devin Teske <dteske@FreeBSD.org>
|
|
\ All rights reserved.
|
|
\
|
|
\ Redistribution and use in source and binary forms, with or without
|
|
\ modification, are permitted provided that the following conditions
|
|
\ are met:
|
|
\ 1. Redistributions of source code must retain the above copyright
|
|
\ notice, this list of conditions and the following disclaimer.
|
|
\ 2. Redistributions in binary form must reproduce the above copyright
|
|
\ notice, this list of conditions and the following disclaimer in the
|
|
\ documentation and/or other materials provided with the distribution.
|
|
\
|
|
\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
\ SUCH DAMAGE.
|
|
\
|
|
\ $FreeBSD$
|
|
|
|
marker task-check-password.4th
|
|
|
|
include /boot/screen.4th
|
|
|
|
13 constant enter_key \ The decimal ASCII value for Enter key
|
|
8 constant bs_key \ The decimal ASCII value for Backspace key
|
|
16 constant readmax \ Maximum number of characters for the password
|
|
|
|
variable readX \ Current X offset (column)(used by read)
|
|
variable read-start \ Starting X offset (column)(used by read)
|
|
|
|
create readval 16 allot \ input obtained (maximum 16 characters)
|
|
variable readlen \ input length
|
|
|
|
\ This function blocks program flow (loops forever) until a key is pressed.
|
|
\ The key that was pressed is added to the top of the stack in the form of its
|
|
\ decimal ASCII representation. Note: the stack cannot be empty when this
|
|
\ function starts or an underflow exception will occur. Simplest way to prevent
|
|
\ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is
|
|
\ called by the read function. You need not call it directly. NOTE: arrow keys
|
|
\ show as 0 on the stack
|
|
\
|
|
: sgetkey ( -- )
|
|
|
|
begin \ Loop forever
|
|
key? if \ Was a key pressed? (see loader(8))
|
|
|
|
drop \ Remove stack-cruft
|
|
key \ Get the key that was pressed
|
|
|
|
\ Check key pressed (see loader(8)) and input limit
|
|
dup 0<> if ( and ) readlen @ readmax < if
|
|
|
|
\ Echo an asterisk (unless Backspace/Enter)
|
|
dup bs_key <> if ( and ) dup enter_key <> if
|
|
." *" \ Echo an asterisk
|
|
then then
|
|
|
|
exit \ Exit from the function
|
|
then then
|
|
|
|
\ Always allow Backspace and Enter
|
|
dup bs_key = if exit then
|
|
dup enter_key = if exit then
|
|
|
|
then
|
|
50 ms \ Sleep for 50 milliseconds (see loader(8))
|
|
again
|
|
;
|
|
|
|
: read ( String prompt -- )
|
|
|
|
0 25 at-xy \ Move the cursor to the bottom-left
|
|
dup 1+ read-start ! \ Store X offset after the prompt
|
|
read-start @ readX ! \ copy value to the current X offset
|
|
0 readlen ! \ Initialize the read length
|
|
type \ Print the prompt
|
|
|
|
begin \ Loop forever
|
|
|
|
0 sgetkey \ Block here, waiting for a key to be pressed
|
|
|
|
\ We are not going to echo the password to the screen (for
|
|
\ security reasons). If Enter is pressed, we process the
|
|
\ password, otherwise augment the key to a string.
|
|
|
|
\ If the key that was entered was not Enter, advance
|
|
dup enter_key <> if
|
|
readX @ 1+ readX ! \ Advance the column
|
|
readlen @ 1+ readlen ! \ Increment input length
|
|
then
|
|
|
|
\ Handle backspacing
|
|
dup bs_key = if
|
|
readX @ 2 - readX ! \ Set new cursor position
|
|
readlen @ 2 - readlen ! \ Decrement input length
|
|
|
|
\ Don't move behind starting position
|
|
readX @ read-start @ < if
|
|
read-start @ readX !
|
|
then
|
|
readlen @ 0< if
|
|
0 readlen !
|
|
then
|
|
|
|
\ Reposition cursor and erase character
|
|
readX @ 25 at-xy 1 spaces readX @ 25 at-xy
|
|
then
|
|
|
|
dup enter_key = if
|
|
drop \ Clean up stack cruft
|
|
10 emit \ Echo new line
|
|
exit
|
|
then
|
|
|
|
\ If not Backspace or Enter, store the character
|
|
dup bs_key <> if ( and ) dup enter_key <> if
|
|
|
|
\ store the character in our buffer
|
|
dup readval readlen @ 1- + c!
|
|
|
|
then then
|
|
|
|
drop \ drop the last key that was entered
|
|
|
|
again \ Enter was not pressed; repeat
|
|
;
|
|
|
|
: check-password ( -- )
|
|
|
|
\ Do not allow the user to proceed beyond this point if a boot-lock
|
|
\ password has been set (preventing even boot from proceeding)
|
|
s" bootlock_password" getenv dup -1 <> if
|
|
begin
|
|
s" Boot Password: " read ( prompt -- )
|
|
2dup readval readlen @ compare 0<>
|
|
while
|
|
3000 ms ." loader: incorrect password" 10 emit
|
|
repeat
|
|
2drop ( c-addr/u )
|
|
else
|
|
drop ( -1 ) \ getenv cruft
|
|
then
|
|
|
|
\ Exit if a password was not set
|
|
s" password" getenv -1 = if exit else drop then
|
|
|
|
\ We should prevent the user from visiting the menu or dropping to the
|
|
\ interactive loader(8) prompt, but still allow the machine to boot...
|
|
|
|
0 autoboot
|
|
|
|
\ Only reached if autoboot fails for any reason (including if/when
|
|
\ the user aborts/escapes the countdown sequence leading to boot).
|
|
|
|
s" password" getenv
|
|
begin
|
|
s" Password: " read ( prompt -- )
|
|
2dup readval readlen @ compare 0= if
|
|
2drop exit \ Correct password
|
|
then
|
|
3000 ms ." loader: incorrect password" 10 emit
|
|
again
|
|
;
|