]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/boot/forth/check-password.4th
Increase max input for password/bootlock_password from 16 to 255.
[FreeBSD/FreeBSD.git] / sys / boot / forth / check-password.4th
1 \ Copyright (c) 2006-2015 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
27 marker task-check-password.4th
28
29 include /boot/screen.4th
30
31 13  constant enter_key       \ The decimal ASCII value for Enter key
32 8   constant bs_key          \ The decimal ASCII value for Backspace key
33 21  constant ctrl_u          \ The decimal ASCII value for Ctrl-U sequence
34 255 constant readmax         \ Maximum number of characters for the password
35
36 variable read-tick           \ Twiddle position (used by read)
37 variable read-start          \ Starting X offset (column)(used by read)
38
39 create readval readmax allot \ input obtained (up to readmax characters)
40 variable readlen             \ input length
41
42 \ This function blocks program flow (loops forever) until a key is pressed.
43 \ The key that was pressed is added to the top of the stack in the form of its
44 \ decimal ASCII representation. Note: the stack cannot be empty when this
45 \ function starts or an underflow exception will occur. Simplest way to prevent
46 \ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is
47 \ called by the read function. You need not call it directly. NOTE: arrow keys
48 \ show as 0 on the stack
49
50 : sgetkey ( -- )
51
52         begin \ Loop forever
53                 key? if \ Was a key pressed? (see loader(8))
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                                 \ Spin the twiddle and then exit this function
60                                 read-tick @ dup 1+ 4 mod read-tick !
61                                 2 spaces
62                                 dup 0 = if ( 1 ) ." /" else
63                                 dup 1 = if ( 2 ) ." -" else
64                                 dup 2 = if ( 3 ) ." \" else
65                                 dup 3 = if ( 4 ) ." |" else
66                                         1 spaces
67                                 then then then then drop
68                                 read-start @ 25 at-xy
69                                 exit
70                         then then
71
72                         \ Always allow Backspace, Enter, and Ctrl-U
73                         dup bs_key = if exit then
74                         dup enter_key = if exit then
75                         dup ctrl_u = if exit then
76                 then
77                 50 ms \ Sleep for 50 milliseconds (see loader(8))
78         again
79 ;
80
81 : read ( c-addr/u -- ) \ Expects string prompt as stack input
82
83         0 25 at-xy           \ Move the cursor to the bottom-left
84         dup 1+ read-start !  \ Store X offset after the prompt
85         0 readlen !          \ Initialize the read length
86         type                 \ Print the prompt
87
88         begin \ Loop forever
89
90                 0 sgetkey \ Block here, waiting for a key to be pressed
91
92                 \ We are not going to echo the password to the screen (for
93                 \ security reasons). If Enter is pressed, we process the
94                 \ password, otherwise augment the key to a string.
95
96                 dup enter_key = if
97                         drop     \ Clean up stack cruft
98                         3 spaces \ Erase the twiddle
99                         10 emit  \ Echo new line
100                         exit
101                 else dup ctrl_u = if
102                         3 spaces read-start @ 25 at-xy \ Erase the twiddle
103                         0 readlen ! \ Reset input to NULL
104                 else dup bs_key = if
105                         readlen @ 1 - dup readlen ! \ Decrement input length
106                         dup 0< if drop 0 dup readlen ! then \ Don't go negative
107                         0= if 3 spaces read-start @ 25 at-xy then \ Twiddle
108                 else dup \ Store the character
109                         \ NB: sgetkey prevents overflow by way of blocking
110                         \     at readmax except for Backspace or Enter
111                         readlen @ 1+ dup readlen ! 1- readval + c!
112                 then then then
113
114                 drop \ last key pressed
115         again \ Enter was not pressed; repeat
116 ;
117
118 : check-password ( -- )
119
120         \ Do not allow the user to proceed beyond this point if a boot-lock
121         \ password has been set (preventing even boot from proceeding)
122         s" bootlock_password" getenv dup -1 <> if
123                 dup readmax > if drop readmax then
124                 begin
125                         s" Boot Password: " read ( prompt -- )
126                         2dup readval readlen @ compare 0<>
127                 while
128                         3000 ms ." loader: incorrect password" 10 emit
129                 repeat
130                 2drop ( c-addr/u )
131         else
132                 drop ( -1 ) \ getenv cruft
133         then
134
135         \ Exit if a password was not set
136         s" password" getenv -1 = if exit else drop then
137
138         \ We should prevent the user from visiting the menu or dropping to the
139         \ interactive loader(8) prompt, but still allow the machine to boot...
140
141         0 autoboot
142
143         \ Only reached if autoboot fails for any reason (including if/when
144         \ the user aborts/escapes the countdown sequence leading to boot).
145
146         s" password" getenv dup readmax > if drop readmax then
147         begin
148                 s" Password: " read ( prompt -- )
149                 2dup readval readlen @ compare 0= if
150                         2drop exit \ Correct password
151                 then
152                 3000 ms ." loader: incorrect password" 10 emit
153         again
154 ;