summaryrefslogtreecommitdiffstats
path: root/sys/boot/forth/check-password.4th
blob: 26d6b94b78a6dcb3ebec2b94b6912174bb950006 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
\ Copyright (c) 2006-2012 Devin Teske <dteske@FreeBSD.org>
\ All rights reserved.
\ 
\ Redistribution and use in source and binary forms, with or without
\ modification, are permitted provided that the following conditions
\ are met:
\ 1. Redistributions of source code must retain the above copyright
\    notice, this list of conditions and the following disclaimer.
\ 2. Redistributions in binary form must reproduce the above copyright
\    notice, this list of conditions and the following disclaimer in the
\    documentation and/or other materials provided with the distribution.
\ 
\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\ ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\ 
\ $FreeBSD$

marker task-check-password.4th

include /boot/screen.4th

13 constant enter_key   \ The decimal ASCII value for Enter key
8  constant bs_key      \ The decimal ASCII value for Backspace key
16 constant readmax     \ Maximum number of characters for the password

variable readX          \ Current X offset (column)(used by read)
variable read-start     \ Starting X offset (column)(used by read)

create readval 16 allot \ input obtained (maximum 16 characters)
variable readlen        \ input length

\ This function blocks program flow (loops forever) until a key is pressed.
\ The key that was pressed is added to the top of the stack in the form of its
\ decimal ASCII representation. Note: the stack cannot be empty when this
\ function starts or an underflow exception will occur. Simplest way to prevent
\ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is
\ called by the read function. You need not call it directly. NOTE: arrow keys
\ show as 0 on the stack
\ 
: sgetkey ( -- )

   begin \ Loop forever
      key? if \ Was a key pressed? (see loader(8))

         drop \ Remove stack-cruft
         key  \ Get the key that was pressed

         \ Check key pressed (see loader(8)) and input limit
         dup 0<> if ( and ) readlen @ readmax < if

            \ Echo an asterisk (unless Backspace/Enter)
            dup bs_key <> if ( and ) dup enter_key <> if
                  ." *" \ Echo an asterisk
            then then

            exit \ Exit from the function
         then then

         \ Always allow Backspace and Enter
         dup bs_key = if exit then
         dup enter_key = if exit then

      then
      50 ms \ Sleep for 50 milliseconds (see loader(8))
   again
;

: read ( String prompt -- )

	0 25 at-xy           \ Move the cursor to the bottom-left
	dup 1+ read-start !  \ Store X offset after the prompt
	read-start @ readX ! \ copy value to the current X offset
	0 readlen !          \ Initialize the read length
	type                 \ Print the prompt

	begin \ Loop forever

		0 sgetkey \ Block here, waiting for a key to be pressed

		\ We are not going to echo the password to the screen (for
		\ security reasons). If Enter is pressed, we process the
		\ password, otherwise augment the key to a string.

		\ If the key that was entered was not Enter, advance
		dup enter_key <> if
			readX @ 1+ readX !     \ Advance the column
			readlen @ 1+ readlen ! \ Increment input length
		then

		\ Handle backspacing
		dup bs_key = if
			readX @ 2 - readX !     \ Set new cursor position
			readlen @ 2 - readlen ! \ Decrement input length

			\ Don't move behind starting position
			readX @ read-start @ < if
				read-start @ readX !
			then
			readlen @ 0< if
				0 readlen !
			then

			\ Reposition cursor and erase character
			readX @ 25 at-xy 1 spaces readX @ 25 at-xy
		then

		dup enter_key = if
			drop    \ Clean up stack cruft
			10 emit \ Echo new line
			exit
		then

		\ If not Backspace or Enter, store the character
		dup bs_key <> if ( and ) dup enter_key <> if

			\ store the character in our buffer
			dup readval readlen @ 1- + c!

		then then

		drop \ drop the last key that was entered

	again \ Enter was not pressed; repeat
;

: check-password ( -- )

	\ Do not allow the user to proceed beyond this point if a boot-lock
	\ password has been set (preventing even boot from proceeding)
	s" bootlock_password" getenv dup -1 <> if
		begin
			s" Boot Password: " read ( prompt -- )
			2dup readval readlen @ compare 0<>
		while
			3000 ms ." loader: incorrect password" 10 emit
		repeat
		2drop ( c-addr/u )
	else
		drop ( -1 ) \ getenv cruft
	then

	\ Exit if a password was not set
	s" password" getenv -1 = if exit else drop then

	\ We should prevent the user from visiting the menu or dropping to the
	\ interactive loader(8) prompt, but still allow the machine to boot...

	0 autoboot

	\ Only reached if autoboot fails for any reason (including if/when
	\ the user aborts/escapes the countdown sequence leading to boot).

	s" password" getenv
	begin
		s" Password: " read ( prompt -- )
		2dup readval readlen @ compare 0= if
			2drop exit \ Correct password
		then
		3000 ms ." loader: incorrect password" 10 emit
	again
;
OpenPOWER on IntegriCloud