xref: /freebsd/stand/forth/check-password.4th (revision 26a58599a09a6181e0f5abe624021865a0c23186)
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