1ca987d46SWarner Losh\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org> 2ca987d46SWarner Losh\ All rights reserved. 3ca987d46SWarner Losh\ 4ca987d46SWarner Losh\ Redistribution and use in source and binary forms, with or without 5ca987d46SWarner Losh\ modification, are permitted provided that the following conditions 6ca987d46SWarner Losh\ are met: 7ca987d46SWarner Losh\ 1. Redistributions of source code must retain the above copyright 8ca987d46SWarner Losh\ notice, this list of conditions and the following disclaimer. 9ca987d46SWarner Losh\ 2. Redistributions in binary form must reproduce the above copyright 10ca987d46SWarner Losh\ notice, this list of conditions and the following disclaimer in the 11ca987d46SWarner Losh\ documentation and/or other materials provided with the distribution. 12ca987d46SWarner Losh\ 13ca987d46SWarner Losh\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14ca987d46SWarner Losh\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15ca987d46SWarner Losh\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16ca987d46SWarner Losh\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17ca987d46SWarner Losh\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18ca987d46SWarner Losh\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19ca987d46SWarner Losh\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20ca987d46SWarner Losh\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21ca987d46SWarner Losh\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22ca987d46SWarner Losh\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23ca987d46SWarner Losh\ SUCH DAMAGE. 24ca987d46SWarner Losh\ 25ca987d46SWarner Losh\ $FreeBSD$ 26ca987d46SWarner Losh 27ca987d46SWarner Loshmarker task-check-password.4th 28ca987d46SWarner Losh 29ca987d46SWarner Loshinclude /boot/screen.4th 30ca987d46SWarner Losh 31ca987d46SWarner Loshvocabulary password-processing 32ca987d46SWarner Loshonly forth also password-processing definitions 33ca987d46SWarner Losh 34ca987d46SWarner Losh13 constant enter_key \ The decimal ASCII value for Enter key 35ca987d46SWarner Losh8 constant bs_key \ The decimal ASCII value for Backspace key 36ca987d46SWarner Losh21 constant ctrl_u \ The decimal ASCII value for Ctrl-U sequence 37ca987d46SWarner Losh255 constant readmax \ Maximum number of characters for the password 38ca987d46SWarner Losh 39ca987d46SWarner Loshvariable read-tick \ Twiddle position (used by read) 40ca987d46SWarner Loshvariable read-start \ Starting X offset (column)(used by read) 41ca987d46SWarner Losh 42ca987d46SWarner Loshcreate readval readmax allot \ input obtained (up to readmax characters) 43ca987d46SWarner Loshvariable readlen \ input length 44ca987d46SWarner Losh 45ca987d46SWarner Losh\ This function blocks program flow (loops forever) until a key is pressed. 46ca987d46SWarner Losh\ The key that was pressed is added to the top of the stack in the form of its 47ca987d46SWarner Losh\ decimal ASCII representation. Note: the stack cannot be empty when this 48ca987d46SWarner Losh\ function starts or an underflow exception will occur. Simplest way to prevent 49ca987d46SWarner Losh\ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is 50ca987d46SWarner Losh\ called by the read function. You need not call it directly. NOTE: arrow keys 51ca987d46SWarner Losh\ show as 0 on the stack 52ca987d46SWarner Losh\ 53ca987d46SWarner Losh: sgetkey ( -- ) 54ca987d46SWarner Losh 55ca987d46SWarner Losh begin \ Loop forever 56ca987d46SWarner Losh key? if \ Was a key pressed? (see loader(8)) 57ca987d46SWarner Losh drop \ Remove stack-cruft 58ca987d46SWarner Losh key \ Get the key that was pressed 59ca987d46SWarner Losh 60ca987d46SWarner Losh \ Check key pressed (see loader(8)) and input limit 61ca987d46SWarner Losh dup 0<> if ( and ) readlen @ readmax < if 62ca987d46SWarner Losh \ Spin the twiddle and then exit this function 63ca987d46SWarner Losh read-tick @ dup 1+ 4 mod read-tick ! 64ca987d46SWarner Losh 2 spaces 65ca987d46SWarner Losh dup 0 = if ( 1 ) ." /" else 66ca987d46SWarner Losh dup 1 = if ( 2 ) ." -" else 67ca987d46SWarner Losh dup 2 = if ( 3 ) ." \" else 68ca987d46SWarner Losh dup 3 = if ( 4 ) ." |" else 69ca987d46SWarner Losh 1 spaces 70ca987d46SWarner Losh then then then then drop 71ca987d46SWarner Losh read-start @ 25 at-xy 72ca987d46SWarner Losh exit 73ca987d46SWarner Losh then then 74ca987d46SWarner Losh 75ca987d46SWarner Losh \ Always allow Backspace, Enter, and Ctrl-U 76ca987d46SWarner Losh dup bs_key = if exit then 77ca987d46SWarner Losh dup enter_key = if exit then 78ca987d46SWarner Losh dup ctrl_u = if exit then 79ca987d46SWarner Losh then 80ca987d46SWarner Losh 50 ms \ Sleep for 50 milliseconds (see loader(8)) 81ca987d46SWarner Losh again 82ca987d46SWarner Losh; 83ca987d46SWarner Losh 84ca987d46SWarner Losh: cfill ( c c-addr/u -- ) 85ca987d46SWarner Losh begin dup 0> while 86ca987d46SWarner Losh -rot 2dup c! 1+ rot 1- 87ca987d46SWarner Losh repeat 2drop drop 88ca987d46SWarner Losh; 89ca987d46SWarner Losh 90ca987d46SWarner Losh: read-reset ( -- ) 91ca987d46SWarner Losh 0 readlen ! 92ca987d46SWarner Losh 0 readval readmax cfill 93ca987d46SWarner Losh; 94ca987d46SWarner Losh 95ca987d46SWarner Losh: read ( c-addr/u -- ) \ Expects string prompt as stack input 96ca987d46SWarner Losh 97ca987d46SWarner Losh 0 25 at-xy \ Move the cursor to the bottom-left 98ca987d46SWarner Losh dup 1+ read-start ! \ Store X offset after the prompt 99ca987d46SWarner Losh 0 readlen ! \ Initialize the read length 100ca987d46SWarner Losh type \ Print the prompt 101ca987d46SWarner Losh 102ca987d46SWarner Losh begin \ Loop forever 103ca987d46SWarner Losh 104ca987d46SWarner Losh 0 sgetkey \ Block here, waiting for a key to be pressed 105ca987d46SWarner Losh 106ca987d46SWarner Losh \ We are not going to echo the password to the screen (for 107ca987d46SWarner Losh \ security reasons). If Enter is pressed, we process the 108ca987d46SWarner Losh \ password, otherwise augment the key to a string. 109ca987d46SWarner Losh 110ca987d46SWarner Losh dup enter_key = if 111ca987d46SWarner Losh drop \ Clean up stack cruft 112ca987d46SWarner Losh 3 spaces \ Erase the twiddle 113ca987d46SWarner Losh 10 emit \ Echo new line 114ca987d46SWarner Losh exit 115ca987d46SWarner Losh else dup ctrl_u = if 116ca987d46SWarner Losh 3 spaces read-start @ 25 at-xy \ Erase the twiddle 117ca987d46SWarner Losh 0 readlen ! \ Reset input to NULL 118ca987d46SWarner Losh else dup bs_key = if 119ca987d46SWarner Losh readlen @ 1 - dup readlen ! \ Decrement input length 120ca987d46SWarner Losh dup 0< if drop 0 dup readlen ! then \ Don't go negative 121ca987d46SWarner Losh 0= if 3 spaces read-start @ 25 at-xy then \ Twiddle 122ca987d46SWarner Losh else dup \ Store the character 123ca987d46SWarner Losh \ NB: sgetkey prevents overflow by way of blocking 124ca987d46SWarner Losh \ at readmax except for Backspace or Enter 125ca987d46SWarner Losh readlen @ 1+ dup readlen ! 1- readval + c! 126ca987d46SWarner Losh then then then 127ca987d46SWarner Losh 128ca987d46SWarner Losh drop \ last key pressed 129ca987d46SWarner Losh again \ Enter was not pressed; repeat 130ca987d46SWarner Losh; 131ca987d46SWarner Losh 132*ff9154beSDevin Teskeonly forth definitions also password-processing also support-functions 133ca987d46SWarner Losh 134ca987d46SWarner Losh: check-password ( -- ) 135ca987d46SWarner Losh 136ca987d46SWarner Losh \ Do not allow the user to proceed beyond this point if a boot-lock 137ca987d46SWarner Losh \ password has been set (preventing even boot from proceeding) 138ca987d46SWarner Losh s" bootlock_password" getenv dup -1 <> if 139ca987d46SWarner Losh dup readmax > if drop readmax then 140ca987d46SWarner Losh begin 141ca987d46SWarner Losh s" Boot Password: " read ( prompt -- ) 142ca987d46SWarner Losh 2dup readval readlen @ compare 0<> 143ca987d46SWarner Losh while 144ca987d46SWarner Losh 3000 ms ." loader: incorrect password" 10 emit 145ca987d46SWarner Losh repeat 146ca987d46SWarner Losh 2drop read-reset 147ca987d46SWarner Losh else drop then 148ca987d46SWarner Losh 149ca987d46SWarner Losh \ Prompt for GEOM ELI (geli(8)) passphrase if enabled 150ca987d46SWarner Losh s" geom_eli_passphrase_prompt" getenv dup -1 <> if 151ca987d46SWarner Losh s" YES" compare-insensitive 0= if 152ca987d46SWarner Losh s" GELI Passphrase: " read ( prompt -- ) 153ca987d46SWarner Losh readval readlen @ s" kern.geom.eli.passphrase" setenv 154ca987d46SWarner Losh read-reset 155ca987d46SWarner Losh then 156ca987d46SWarner Losh else drop then 157ca987d46SWarner Losh 158ca987d46SWarner Losh \ Exit if a password was not set 159ca987d46SWarner Losh s" password" getenv -1 = if exit else drop then 160ca987d46SWarner Losh 161ca987d46SWarner Losh \ We should prevent the user from visiting the menu or dropping to the 162ca987d46SWarner Losh \ interactive loader(8) prompt, but still allow the machine to boot... 163ca987d46SWarner Losh 164*ff9154beSDevin Teske any_conf_read? if load_kernel load_modules then 165ca987d46SWarner Losh 0 autoboot 166ca987d46SWarner Losh 167ca987d46SWarner Losh \ Only reached if autoboot fails for any reason (including if/when 168ca987d46SWarner Losh \ the user aborts/escapes the countdown sequence leading to boot). 169ca987d46SWarner Losh 170ca987d46SWarner Losh s" password" getenv dup readmax > if drop readmax then 171ca987d46SWarner Losh begin 172ca987d46SWarner Losh s" Password: " read ( prompt -- ) 173ca987d46SWarner Losh 2dup readval readlen @ compare 0= if \ Correct password? 174ca987d46SWarner Losh 2drop read-reset exit 175ca987d46SWarner Losh then 176ca987d46SWarner Losh 3000 ms ." loader: incorrect password" 10 emit 177ca987d46SWarner Losh again 178ca987d46SWarner Losh; 179ca987d46SWarner Losh 180ca987d46SWarner Loshonly forth definitions 181