]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/boot/forth/check-password.4th
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / boot / forth / check-password.4th
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
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 16 constant readmax     \ Maximum number of characters for the password
34
35 variable readX          \ Current X offset (column)(used by read)
36 variable read-start     \ Starting X offset (column)(used by read)
37
38 create readval 16 allot \ input obtained (maximum 16 characters)
39 variable 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 ;