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