1 \ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
4 \ Redistribution and use in source and binary forms, with or without
5 \ modification, are permitted provided that the following conditions
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.
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
26 marker task-check-password.4th
28 include /boot/screen.4th
30 vocabulary password-processing
31 only forth also password-processing definitions
33 13 constant enter_key \ The decimal ASCII value for Enter key
34 8 constant bs_key \ The decimal ASCII value for Backspace key
35 21 constant ctrl_u \ The decimal ASCII value for Ctrl-U sequence
36 255 constant readmax \ Maximum number of characters for the password
38 variable read-tick \ Twiddle position (used by read)
39 variable read-start \ Starting X offset (column)(used by read)
41 create readval readmax allot \ input obtained (up to readmax characters)
42 variable readlen \ input length
44 \ This function blocks program flow (loops forever) until a key is pressed.
45 \ The key that was pressed is added to the top of the stack in the form of its
46 \ decimal ASCII representation. Note: the stack cannot be empty when this
47 \ function starts or an underflow exception will occur. Simplest way to prevent
48 \ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is
49 \ called by the read function. You need not call it directly. NOTE: arrow keys
50 \ show as 0 on the stack
55 key? if \ Was a key pressed? (see loader(8))
56 drop \ Remove stack-cruft
57 key \ Get the key that was pressed
59 \ Check key pressed (see loader(8)) and input limit
60 dup 0<> if ( and ) readlen @ readmax < if
61 \ Spin the twiddle and then exit this function
62 read-tick @ dup 1+ 4 mod read-tick !
64 dup 0 = if ( 1 ) ." /" else
65 dup 1 = if ( 2 ) ." -" else
66 dup 2 = if ( 3 ) ." \" else
67 dup 3 = if ( 4 ) ." |" else
69 then then then then drop
74 \ Always allow Backspace, Enter, and Ctrl-U
75 dup bs_key = if exit then
76 dup enter_key = if exit then
77 dup ctrl_u = if exit then
79 50 ms \ Sleep for 50 milliseconds (see loader(8))
83 : cfill ( c c-addr/u -- )
85 -rot 2dup c! 1+ rot 1-
91 0 readval readmax cfill
94 : read ( c-addr/u -- ) \ Expects string prompt as stack input
96 0 25 at-xy \ Move the cursor to the bottom-left
97 dup 1+ read-start ! \ Store X offset after the prompt
98 0 readlen ! \ Initialize the read length
99 type \ Print the prompt
103 0 sgetkey \ Block here, waiting for a key to be pressed
105 \ We are not going to echo the password to the screen (for
106 \ security reasons). If Enter is pressed, we process the
107 \ password, otherwise augment the key to a string.
110 drop \ Clean up stack cruft
111 3 spaces \ Erase the twiddle
112 10 emit \ Echo new line
115 3 spaces read-start @ 25 at-xy \ Erase the twiddle
116 0 readlen ! \ Reset input to NULL
118 readlen @ 1 - dup readlen ! \ Decrement input length
119 dup 0< if drop 0 dup readlen ! then \ Don't go negative
120 0= if 3 spaces read-start @ 25 at-xy then \ Twiddle
121 else dup \ Store the character
122 \ NB: sgetkey prevents overflow by way of blocking
123 \ at readmax except for Backspace or Enter
124 readlen @ 1+ dup readlen ! 1- readval + c!
127 drop \ last key pressed
128 again \ Enter was not pressed; repeat
131 only forth definitions also password-processing also support-functions
133 : check-password ( -- )
135 \ Do not allow the user to proceed beyond this point if a boot-lock
136 \ password has been set (preventing even boot from proceeding)
137 s" bootlock_password" getenv dup -1 <> if
138 dup readmax > if drop readmax then
140 s" Boot Password: " read ( prompt -- )
141 2dup readval readlen @ compare 0<>
143 3000 ms ." loader: incorrect password" 10 emit
148 \ Prompt for GEOM ELI (geli(8)) passphrase if enabled
149 s" geom_eli_passphrase_prompt" getenv dup -1 <> if
150 s" YES" compare-insensitive 0= if
151 s" GELI Passphrase: " read ( prompt -- )
152 readval readlen @ s" kern.geom.eli.passphrase" setenv
157 \ Exit if a password was not set
158 s" password" getenv -1 = if exit else drop then
160 \ We should prevent the user from visiting the menu or dropping to the
161 \ interactive loader(8) prompt, but still allow the machine to boot...
163 any_conf_read? if load_kernel load_modules then
166 \ Only reached if autoboot fails for any reason (including if/when
167 \ the user aborts/escapes the countdown sequence leading to boot).
169 s" password" getenv dup readmax > if drop readmax then
171 s" Password: " read ( prompt -- )
172 2dup readval readlen @ compare 0= if \ Correct password?
173 2drop read-reset exit
175 3000 ms ." loader: incorrect password" 10 emit
179 only forth definitions