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