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