freebsd-nq/sys/boot/forth/check-password.4th
Devin Teske d35c4b1d44 Fix domain.
Approved by:	emaste
2012-07-14 01:45:35 +00:00

157 lines
4.9 KiB
Forth

\ Copyright (c) 2006-2011 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 ( -- )
\ Exit if a password was not set
s" password" getenv dup -1 = if
drop exit
then
begin \ Loop as long as it takes to get the right password
s" Password: " \ Output a prompt for a password
read \ Read the user's input until Enter
2dup readval readlen @ compare 0= if
2drop exit \ Correct password
then
\ Bad Password
3000 ms
." loader: incorrect password" 10 emit
again \ Not the right password; repeat
;