Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/lua/password.lua
34677 views
1
--
2
-- SPDX-License-Identifier: BSD-2-Clause
3
--
4
-- Copyright (c) 2015 Pedro Souza <[email protected]>
5
-- Copyright (c) 2018 Kyle Evans <[email protected]>
6
-- All rights reserved.
7
--
8
-- Redistribution and use in source and binary forms, with or without
9
-- modification, are permitted provided that the following conditions
10
-- are met:
11
-- 1. Redistributions of source code must retain the above copyright
12
-- notice, this list of conditions and the following disclaimer.
13
-- 2. Redistributions in binary form must reproduce the above copyright
14
-- notice, this list of conditions and the following disclaimer in the
15
-- documentation and/or other materials provided with the distribution.
16
--
17
-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
-- SUCH DAMAGE.
28
--
29
30
local core = require("core")
31
local screen = require("screen")
32
33
local password = {}
34
35
local INCORRECT_PASSWORD = "loader: incorrect password"
36
-- Asterisks as a password mask
37
local show_password_mask = false
38
local twiddle_chars = {"/", "-", "\\", "|"}
39
local screen_setup = false
40
41
local function setup_screen()
42
screen.clear()
43
screen.defcursor()
44
screen_setup = true
45
end
46
47
-- Module exports
48
function password.read(prompt_length)
49
local str = ""
50
local twiddle_pos = 1
51
52
local function draw_twiddle()
53
printc(twiddle_chars[twiddle_pos])
54
-- Reset cursor to just after the password prompt
55
screen.setcursor(prompt_length + 2, screen.default_y)
56
twiddle_pos = (twiddle_pos % #twiddle_chars) + 1
57
end
58
59
-- Space between the prompt and any on-screen feedback
60
printc(" ")
61
while true do
62
local ch = io.getchar()
63
if ch == core.KEY_ENTER then
64
break
65
end
66
if ch == core.KEY_BACKSPACE or ch == core.KEY_DELETE then
67
if #str > 0 then
68
if show_password_mask then
69
printc("\008 \008")
70
else
71
draw_twiddle()
72
end
73
str = str:sub(1, #str - 1)
74
end
75
else
76
if show_password_mask then
77
printc("*")
78
else
79
draw_twiddle()
80
end
81
str = str .. string.char(ch)
82
end
83
end
84
return str
85
end
86
87
function password.check()
88
-- pwd is optionally supplied if we want to check it
89
local function doPrompt(prompt, pwd)
90
local attempts = 1
91
92
local function clear_incorrect_text_prompt()
93
printc("\r" .. string.rep(" ", #INCORRECT_PASSWORD))
94
end
95
96
if not screen_setup then
97
setup_screen()
98
end
99
100
while true do
101
if attempts > 1 then
102
clear_incorrect_text_prompt()
103
end
104
screen.defcursor()
105
printc(prompt)
106
local read_pwd = password.read(#prompt)
107
if pwd == nil or pwd == read_pwd then
108
-- Clear the prompt + twiddle
109
printc(string.rep(" ", #prompt + 5))
110
return read_pwd
111
end
112
printc("\n" .. INCORRECT_PASSWORD)
113
attempts = attempts + 1
114
loader.delay(3*1000*1000)
115
end
116
end
117
local function compare(prompt, pwd)
118
if pwd == nil then
119
return
120
end
121
doPrompt(prompt, pwd)
122
end
123
124
local boot_pwd = loader.getenv("bootlock_password")
125
compare("Bootlock password:", boot_pwd)
126
127
local geli_prompt = loader.getenv("geom_eli_passphrase_prompt")
128
if geli_prompt ~= nil and geli_prompt:lower() == "yes" then
129
local passphrase = doPrompt("GELI Passphrase:")
130
loader.setenv("kern.geom.eli.passphrase", passphrase)
131
end
132
133
local pwd = loader.getenv("password")
134
if pwd ~= nil then
135
core.autoboot()
136
loader.setenv("autoboot_delay", "NO")
137
-- The autoboot sequence was interrupted, so we'll need to
138
-- prompt for a password. Put the screen back into a known
139
-- good state, otherwise we're drawing back a couple lines
140
-- in the middle of other text.
141
setup_screen()
142
end
143
compare("Loader password:", pwd)
144
end
145
146
return password
147
148