2018-02-12 10:32:00 -05:00
|
|
|
--
|
2023-05-10 11:40:58 -04:00
|
|
|
-- SPDX-License-Identifier: BSD-2-Clause
|
2018-02-22 21:51:35 -05:00
|
|
|
--
|
2018-02-12 10:32:00 -05:00
|
|
|
-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
|
2019-09-26 12:19:22 -04:00
|
|
|
-- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org>
|
2018-02-12 10:32:00 -05:00
|
|
|
-- 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.
|
|
|
|
|
--
|
|
|
|
|
|
2018-02-20 20:10:03 -05:00
|
|
|
local core = require("core")
|
|
|
|
|
local screen = require("screen")
|
2018-02-12 10:32:00 -05:00
|
|
|
|
2018-02-20 20:10:03 -05:00
|
|
|
local password = {}
|
2018-02-27 23:23:28 -05:00
|
|
|
|
2018-09-22 09:14:44 -04:00
|
|
|
local INCORRECT_PASSWORD = "loader: incorrect password"
|
2018-02-27 16:22:57 -05:00
|
|
|
-- Asterisks as a password mask
|
|
|
|
|
local show_password_mask = false
|
|
|
|
|
local twiddle_chars = {"/", "-", "\\", "|"}
|
2019-02-17 21:59:47 -05:00
|
|
|
local screen_setup = false
|
2018-02-19 12:54:22 -05:00
|
|
|
|
2019-03-25 22:33:27 -04:00
|
|
|
local function setup_screen()
|
|
|
|
|
screen.clear()
|
|
|
|
|
screen.defcursor()
|
|
|
|
|
screen_setup = true
|
|
|
|
|
end
|
|
|
|
|
|
2018-02-20 09:45:58 -05:00
|
|
|
-- Module exports
|
2018-02-27 23:23:28 -05:00
|
|
|
function password.read(prompt_length)
|
2018-02-20 20:10:03 -05:00
|
|
|
local str = ""
|
2018-02-27 16:30:24 -05:00
|
|
|
local twiddle_pos = 1
|
2018-02-12 10:32:00 -05:00
|
|
|
|
2018-02-27 16:22:57 -05:00
|
|
|
local function draw_twiddle()
|
2018-09-22 09:14:44 -04:00
|
|
|
printc(twiddle_chars[twiddle_pos])
|
2018-02-27 23:31:19 -05:00
|
|
|
-- Reset cursor to just after the password prompt
|
|
|
|
|
screen.setcursor(prompt_length + 2, screen.default_y)
|
2018-02-27 16:22:57 -05:00
|
|
|
twiddle_pos = (twiddle_pos % #twiddle_chars) + 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Space between the prompt and any on-screen feedback
|
2018-03-02 11:06:20 -05:00
|
|
|
printc(" ")
|
2018-02-21 15:17:08 -05:00
|
|
|
while true do
|
2018-02-21 23:15:02 -05:00
|
|
|
local ch = io.getchar()
|
2018-02-20 20:35:19 -05:00
|
|
|
if ch == core.KEY_ENTER then
|
2018-02-20 20:10:03 -05:00
|
|
|
break
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
2018-02-20 20:35:19 -05:00
|
|
|
if ch == core.KEY_BACKSPACE or ch == core.KEY_DELETE then
|
2018-03-01 21:39:41 -05:00
|
|
|
if #str > 0 then
|
2018-02-27 16:22:57 -05:00
|
|
|
if show_password_mask then
|
2018-03-02 11:06:20 -05:00
|
|
|
printc("\008 \008")
|
2018-02-27 16:22:57 -05:00
|
|
|
else
|
|
|
|
|
draw_twiddle()
|
|
|
|
|
end
|
2018-03-01 21:39:41 -05:00
|
|
|
str = str:sub(1, #str - 1)
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
|
|
|
|
else
|
2018-02-27 16:22:57 -05:00
|
|
|
if show_password_mask then
|
2018-03-02 11:06:20 -05:00
|
|
|
printc("*")
|
2018-02-27 16:22:57 -05:00
|
|
|
else
|
|
|
|
|
draw_twiddle()
|
|
|
|
|
end
|
2018-02-20 20:10:03 -05:00
|
|
|
str = str .. string.char(ch)
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
2018-02-21 15:17:08 -05:00
|
|
|
end
|
2018-02-20 20:10:03 -05:00
|
|
|
return str
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function password.check()
|
2018-02-17 00:26:28 -05:00
|
|
|
-- pwd is optionally supplied if we want to check it
|
2018-02-24 15:21:21 -05:00
|
|
|
local function doPrompt(prompt, pwd)
|
2018-02-27 23:23:28 -05:00
|
|
|
local attempts = 1
|
|
|
|
|
|
|
|
|
|
local function clear_incorrect_text_prompt()
|
2018-09-22 09:14:44 -04:00
|
|
|
printc("\r" .. string.rep(" ", #INCORRECT_PASSWORD))
|
2018-02-27 23:23:28 -05:00
|
|
|
end
|
|
|
|
|
|
2019-02-17 21:59:47 -05:00
|
|
|
if not screen_setup then
|
2019-03-25 22:33:27 -04:00
|
|
|
setup_screen()
|
2019-02-17 21:59:47 -05:00
|
|
|
end
|
|
|
|
|
|
2018-02-20 20:35:19 -05:00
|
|
|
while true do
|
2018-09-22 09:14:44 -04:00
|
|
|
if attempts > 1 then
|
|
|
|
|
clear_incorrect_text_prompt()
|
|
|
|
|
end
|
2018-02-27 23:23:28 -05:00
|
|
|
screen.defcursor()
|
2018-03-02 11:06:20 -05:00
|
|
|
printc(prompt)
|
2018-02-27 23:23:28 -05:00
|
|
|
local read_pwd = password.read(#prompt)
|
2018-02-20 20:35:19 -05:00
|
|
|
if pwd == nil or pwd == read_pwd then
|
2018-02-27 23:23:28 -05:00
|
|
|
-- Clear the prompt + twiddle
|
2018-03-02 11:06:20 -05:00
|
|
|
printc(string.rep(" ", #prompt + 5))
|
2018-02-20 20:10:03 -05:00
|
|
|
return read_pwd
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
2018-03-02 11:06:20 -05:00
|
|
|
printc("\n" .. INCORRECT_PASSWORD)
|
2018-02-27 23:23:28 -05:00
|
|
|
attempts = attempts + 1
|
2018-02-20 20:10:03 -05:00
|
|
|
loader.delay(3*1000*1000)
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
2018-02-17 00:26:28 -05:00
|
|
|
end
|
|
|
|
|
local function compare(prompt, pwd)
|
2018-02-20 20:35:19 -05:00
|
|
|
if pwd == nil then
|
2018-02-20 20:10:03 -05:00
|
|
|
return
|
2018-02-17 00:26:28 -05:00
|
|
|
end
|
2018-02-24 15:21:21 -05:00
|
|
|
doPrompt(prompt, pwd)
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
|
|
|
|
|
2018-02-20 20:10:03 -05:00
|
|
|
local boot_pwd = loader.getenv("bootlock_password")
|
2018-09-22 09:14:44 -04:00
|
|
|
compare("Bootlock password:", boot_pwd)
|
2018-02-12 10:32:00 -05:00
|
|
|
|
2018-02-20 20:10:03 -05:00
|
|
|
local geli_prompt = loader.getenv("geom_eli_passphrase_prompt")
|
2018-02-20 20:35:19 -05:00
|
|
|
if geli_prompt ~= nil and geli_prompt:lower() == "yes" then
|
2018-09-22 09:14:44 -04:00
|
|
|
local passphrase = doPrompt("GELI Passphrase:")
|
2018-02-20 20:10:03 -05:00
|
|
|
loader.setenv("kern.geom.eli.passphrase", passphrase)
|
2018-02-17 00:26:28 -05:00
|
|
|
end
|
|
|
|
|
|
2018-02-20 20:10:03 -05:00
|
|
|
local pwd = loader.getenv("password")
|
2018-02-20 20:35:19 -05:00
|
|
|
if pwd ~= nil then
|
2018-02-20 20:10:03 -05:00
|
|
|
core.autoboot()
|
2023-04-15 22:30:41 -04:00
|
|
|
loader.setenv("autoboot_delay", "NO")
|
2019-03-25 22:33:27 -04:00
|
|
|
-- The autoboot sequence was interrupted, so we'll need to
|
|
|
|
|
-- prompt for a password. Put the screen back into a known
|
|
|
|
|
-- good state, otherwise we're drawing back a couple lines
|
|
|
|
|
-- in the middle of other text.
|
|
|
|
|
setup_screen()
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
2018-09-22 09:14:44 -04:00
|
|
|
compare("Loader password:", pwd)
|
2018-02-12 10:32:00 -05:00
|
|
|
end
|
|
|
|
|
|
2018-02-20 20:10:03 -05:00
|
|
|
return password
|