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 26ca987d46SWarner Loshmarker task-check-password.4th 27ca987d46SWarner Losh 28ca987d46SWarner Loshinclude /boot/screen.4th 29ca987d46SWarner Losh 30ca987d46SWarner Loshvocabulary password-processing 31ca987d46SWarner Loshonly forth also password-processing definitions 32ca987d46SWarner Losh 33ca987d46SWarner Losh13 constant enter_key \ The decimal ASCII value for Enter key 34ca987d46SWarner Losh8 constant bs_key \ The decimal ASCII value for Backspace key 35ca987d46SWarner Losh21 constant ctrl_u \ The decimal ASCII value for Ctrl-U sequence 36ca987d46SWarner Losh255 constant readmax \ Maximum number of characters for the password 37ca987d46SWarner Losh 38ca987d46SWarner Loshvariable read-tick \ Twiddle position (used by read) 39ca987d46SWarner Loshvariable read-start \ Starting X offset (column)(used by read) 40ca987d46SWarner Losh 41ca987d46SWarner Loshcreate readval readmax allot \ input obtained (up to readmax characters) 42ca987d46SWarner Loshvariable readlen \ input length 43ca987d46SWarner Losh 44ca987d46SWarner Losh\ This function blocks program flow (loops forever) until a key is pressed. 45ca987d46SWarner Losh\ The key that was pressed is added to the top of the stack in the form of its 46ca987d46SWarner Losh\ decimal ASCII representation. Note: the stack cannot be empty when this 47ca987d46SWarner Losh\ function starts or an underflow exception will occur. Simplest way to prevent 48ca987d46SWarner Losh\ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is 49ca987d46SWarner Losh\ called by the read function. You need not call it directly. NOTE: arrow keys 50ca987d46SWarner Losh\ show as 0 on the stack 51ca987d46SWarner Losh\ 52ca987d46SWarner Losh: sgetkey ( -- ) 53ca987d46SWarner Losh 54ca987d46SWarner Losh begin \ Loop forever 55ca987d46SWarner Losh key? if \ Was a key pressed? (see loader(8)) 56ca987d46SWarner Losh drop \ Remove stack-cruft 57ca987d46SWarner Losh key \ Get the key that was pressed 58ca987d46SWarner Losh 59ca987d46SWarner Losh \ Check key pressed (see loader(8)) and input limit 60ca987d46SWarner Losh dup 0<> if ( and ) readlen @ readmax < if 61ca987d46SWarner Losh \ Spin the twiddle and then exit this function 62ca987d46SWarner Losh read-tick @ dup 1+ 4 mod read-tick ! 63ca987d46SWarner Losh 2 spaces 64ca987d46SWarner Losh dup 0 = if ( 1 ) ." /" else 65ca987d46SWarner Losh dup 1 = if ( 2 ) ." -" else 66ca987d46SWarner Losh dup 2 = if ( 3 ) ." \" else 67ca987d46SWarner Losh dup 3 = if ( 4 ) ." |" else 68ca987d46SWarner Losh 1 spaces 69ca987d46SWarner Losh then then then then drop 70ca987d46SWarner Losh read-start @ 25 at-xy 71ca987d46SWarner Losh exit 72ca987d46SWarner Losh then then 73ca987d46SWarner Losh 74ca987d46SWarner Losh \ Always allow Backspace, Enter, and Ctrl-U 75ca987d46SWarner Losh dup bs_key = if exit then 76ca987d46SWarner Losh dup enter_key = if exit then 77ca987d46SWarner Losh dup ctrl_u = if exit then 78ca987d46SWarner Losh then 79ca987d46SWarner Losh 50 ms \ Sleep for 50 milliseconds (see loader(8)) 80ca987d46SWarner Losh again 81ca987d46SWarner Losh; 82ca987d46SWarner Losh 83ca987d46SWarner Losh: cfill ( c c-addr/u -- ) 84ca987d46SWarner Losh begin dup 0> while 85ca987d46SWarner Losh -rot 2dup c! 1+ rot 1- 86ca987d46SWarner Losh repeat 2drop drop 87ca987d46SWarner Losh; 88ca987d46SWarner Losh 89ca987d46SWarner Losh: read-reset ( -- ) 90ca987d46SWarner Losh 0 readlen ! 91ca987d46SWarner Losh 0 readval readmax cfill 92ca987d46SWarner Losh; 93ca987d46SWarner Losh 94ca987d46SWarner Losh: read ( c-addr/u -- ) \ Expects string prompt as stack input 95ca987d46SWarner Losh 96ca987d46SWarner Losh 0 25 at-xy \ Move the cursor to the bottom-left 97ca987d46SWarner Losh dup 1+ read-start ! \ Store X offset after the prompt 98ca987d46SWarner Losh 0 readlen ! \ Initialize the read length 99ca987d46SWarner Losh type \ Print the prompt 100ca987d46SWarner Losh 101ca987d46SWarner Losh begin \ Loop forever 102ca987d46SWarner Losh 103ca987d46SWarner Losh 0 sgetkey \ Block here, waiting for a key to be pressed 104ca987d46SWarner Losh 105ca987d46SWarner Losh \ We are not going to echo the password to the screen (for 106ca987d46SWarner Losh \ security reasons). If Enter is pressed, we process the 107ca987d46SWarner Losh \ password, otherwise augment the key to a string. 108ca987d46SWarner Losh 109ca987d46SWarner Losh dup enter_key = if 110ca987d46SWarner Losh drop \ Clean up stack cruft 111ca987d46SWarner Losh 3 spaces \ Erase the twiddle 112ca987d46SWarner Losh 10 emit \ Echo new line 113ca987d46SWarner Losh exit 114ca987d46SWarner Losh else dup ctrl_u = if 115ca987d46SWarner Losh 3 spaces read-start @ 25 at-xy \ Erase the twiddle 116ca987d46SWarner Losh 0 readlen ! \ Reset input to NULL 117ca987d46SWarner Losh else dup bs_key = if 118ca987d46SWarner Losh readlen @ 1 - dup readlen ! \ Decrement input length 119ca987d46SWarner Losh dup 0< if drop 0 dup readlen ! then \ Don't go negative 120ca987d46SWarner Losh 0= if 3 spaces read-start @ 25 at-xy then \ Twiddle 121ca987d46SWarner Losh else dup \ Store the character 122ca987d46SWarner Losh \ NB: sgetkey prevents overflow by way of blocking 123ca987d46SWarner Losh \ at readmax except for Backspace or Enter 124ca987d46SWarner Losh readlen @ 1+ dup readlen ! 1- readval + c! 125ca987d46SWarner Losh then then then 126ca987d46SWarner Losh 127ca987d46SWarner Losh drop \ last key pressed 128ca987d46SWarner Losh again \ Enter was not pressed; repeat 129ca987d46SWarner Losh; 130ca987d46SWarner Losh 131*ff9154beSDevin Teskeonly forth definitions also password-processing also support-functions 132ca987d46SWarner Losh 133ca987d46SWarner Losh: check-password ( -- ) 134ca987d46SWarner Losh 135ca987d46SWarner Losh \ Do not allow the user to proceed beyond this point if a boot-lock 136ca987d46SWarner Losh \ password has been set (preventing even boot from proceeding) 137ca987d46SWarner Losh s" bootlock_password" getenv dup -1 <> if 138ca987d46SWarner Losh dup readmax > if drop readmax then 139ca987d46SWarner Losh begin 140ca987d46SWarner Losh s" Boot Password: " read ( prompt -- ) 141ca987d46SWarner Losh 2dup readval readlen @ compare 0<> 142ca987d46SWarner Losh while 143ca987d46SWarner Losh 3000 ms ." loader: incorrect password" 10 emit 144ca987d46SWarner Losh repeat 145ca987d46SWarner Losh 2drop read-reset 146ca987d46SWarner Losh else drop then 147ca987d46SWarner Losh 148ca987d46SWarner Losh \ Prompt for GEOM ELI (geli(8)) passphrase if enabled 149ca987d46SWarner Losh s" geom_eli_passphrase_prompt" getenv dup -1 <> if 150ca987d46SWarner Losh s" YES" compare-insensitive 0= if 151ca987d46SWarner Losh s" GELI Passphrase: " read ( prompt -- ) 152ca987d46SWarner Losh readval readlen @ s" kern.geom.eli.passphrase" setenv 153ca987d46SWarner Losh read-reset 154ca987d46SWarner Losh then 155ca987d46SWarner Losh else drop then 156ca987d46SWarner Losh 157ca987d46SWarner Losh \ Exit if a password was not set 158ca987d46SWarner Losh s" password" getenv -1 = if exit else drop then 159ca987d46SWarner Losh 160ca987d46SWarner Losh \ We should prevent the user from visiting the menu or dropping to the 161ca987d46SWarner Losh \ interactive loader(8) prompt, but still allow the machine to boot... 162ca987d46SWarner Losh 163*ff9154beSDevin Teske any_conf_read? if load_kernel load_modules then 164ca987d46SWarner Losh 0 autoboot 165ca987d46SWarner Losh 166ca987d46SWarner Losh \ Only reached if autoboot fails for any reason (including if/when 167ca987d46SWarner Losh \ the user aborts/escapes the countdown sequence leading to boot). 168ca987d46SWarner Losh 169ca987d46SWarner Losh s" password" getenv dup readmax > if drop readmax then 170ca987d46SWarner Losh begin 171ca987d46SWarner Losh s" Password: " read ( prompt -- ) 172ca987d46SWarner Losh 2dup readval readlen @ compare 0= if \ Correct password? 173ca987d46SWarner Losh 2drop read-reset exit 174ca987d46SWarner Losh then 175ca987d46SWarner Losh 3000 ms ." loader: incorrect password" 10 emit 176ca987d46SWarner Losh again 177ca987d46SWarner Losh; 178ca987d46SWarner Losh 179ca987d46SWarner Loshonly forth definitions 180