From 17857eb8b55fa9864bfd71083d9291c74b0bab8e Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 26 Sep 2013 11:57:59 -0400 Subject: Port MokManager to Linux Foundation loader UI code This is the first stage of porting the MokManager UI to the UI code used by the Linux Foundation UEFI loader. --- lib/console.c | 402 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 lib/console.c (limited to 'lib/console.c') diff --git a/lib/console.c b/lib/console.c new file mode 100644 index 00000000..af01f035 --- /dev/null +++ b/lib/console.c @@ -0,0 +1,402 @@ +/* + * Copyright 2012 + * + * see COPYING file + */ +#include +#include + +#include +#include + +static int min(int a, int b) +{ + if (a < b) + return a; + return b; +} + +static int +count_lines(CHAR16 *str_arr[]) +{ + int i = 0; + + while (str_arr[i]) + i++; + return i; +} + +static void +SetMem16(CHAR16 *dst, UINT32 n, CHAR16 c) +{ + int i; + + for (i = 0; i < n/2; i++) { + dst[i] = c; + } +} + +EFI_INPUT_KEY +console_get_keystroke(void) +{ + EFI_INPUT_KEY key; + UINTN EventIndex; + + uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &EventIndex); + uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key); + + return key; +} + +void +console_print_box_at(CHAR16 *str_arr[], int highlight, int start_col, int start_row, int size_cols, int size_rows, int offset, int lines) +{ + int i; + SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut; + UINTN rows, cols; + CHAR16 *Line; + + if (lines == 0) + return; + + uefi_call_wrapper(co->QueryMode, 4, co, co->Mode->Mode, &cols, &rows); + + /* last row on screen is unusable without scrolling, so ignore it */ + rows--; + + if (size_rows < 0) + size_rows = rows + size_rows + 1; + if (size_cols < 0) + size_cols = cols + size_cols + 1; + + if (start_col < 0) + start_col = (cols + start_col + 2)/2; + if (start_row < 0) + start_row = (rows + start_row + 2)/2; + if (start_col < 0) + start_col = 0; + if (start_row < 0) + start_row = 0; + + if (start_col > cols || start_row > rows) { + Print(L"Starting Position (%d,%d) is off screen\n", + start_col, start_row); + return; + } + if (size_cols + start_col > cols) + size_cols = cols - start_col; + if (size_rows + start_row > rows) + size_rows = rows - start_row; + + if (lines > size_rows - 2) + lines = size_rows - 2; + + Line = AllocatePool((size_cols+1)*sizeof(CHAR16)); + if (!Line) { + Print(L"Failed Allocation\n"); + return; + } + + SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL); + + Line[0] = BOXDRAW_DOWN_RIGHT; + Line[size_cols - 1] = BOXDRAW_DOWN_LEFT; + Line[size_cols] = L'\0'; + uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, start_row); + uefi_call_wrapper(co->OutputString, 2, co, Line); + + int start; + if (offset == 0) + /* middle */ + start = (size_rows - lines)/2 + start_row + offset; + else if (offset < 0) + /* from bottom */ + start = start_row + size_rows - lines + offset - 1; + else + /* from top */ + start = start_row + offset; + + + for (i = start_row + 1; i < size_rows + start_row - 1; i++) { + int line = i - start; + + SetMem16 (Line, size_cols*2, L' '); + Line[0] = BOXDRAW_VERTICAL; + Line[size_cols - 1] = BOXDRAW_VERTICAL; + Line[size_cols] = L'\0'; + if (line >= 0 && line < lines) { + CHAR16 *s = str_arr[line]; + int len = StrLen(s); + int col = (size_cols - 2 - len)/2; + + if (col < 0) + col = 0; + + CopyMem(Line + col + 1, s, min(len, size_cols - 2)*2); + } + if (line >= 0 && line == highlight) + uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK); + uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, i); + uefi_call_wrapper(co->OutputString, 2, co, Line); + if (line >= 0 && line == highlight) + uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE); + + } + SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL); + Line[0] = BOXDRAW_UP_RIGHT; + Line[size_cols - 1] = BOXDRAW_UP_LEFT; + Line[size_cols] = L'\0'; + uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, i); + uefi_call_wrapper(co->OutputString, 2, co, Line); + + FreePool (Line); + +} + +void +console_print_box(CHAR16 *str_arr[], int highlight) +{ + SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode; + SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut; + CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode)); + uefi_call_wrapper(co->EnableCursor, 2, co, FALSE); + uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE); + + console_print_box_at(str_arr, highlight, 0, 0, -1, -1, 0, + count_lines(str_arr)); + + console_get_keystroke(); + + uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); + + uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); + uefi_call_wrapper(co->SetCursorPosition, 3, co, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow); + uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute); +} + +int +console_select(CHAR16 *title[], CHAR16* selectors[], int start) +{ + SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode; + SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut; + EFI_INPUT_KEY k; + int selector; + int selector_lines = count_lines(selectors); + int selector_max_cols = 0; + int i, offs_col, offs_row, size_cols, size_rows, lines; + int selector_offset; + UINTN cols, rows; + + uefi_call_wrapper(co->QueryMode, 4, co, co->Mode->Mode, &cols, &rows); + + for (i = 0; i < selector_lines; i++) { + int len = StrLen(selectors[i]); + + if (len > selector_max_cols) + selector_max_cols = len; + } + + if (start < 0) + start = 0; + if (start >= selector_lines) + start = selector_lines - 1; + + offs_col = - selector_max_cols - 4; + size_cols = selector_max_cols + 4; + + if (selector_lines > rows - 10) { + int title_lines = count_lines(title); + offs_row = title_lines + 1; + size_rows = rows - 3 - title_lines; + lines = size_rows - 2; + } else { + offs_row = - selector_lines - 4; + size_rows = selector_lines + 2; + lines = selector_lines; + } + + if (start > lines) { + selector = lines; + selector_offset = start - lines; + } else { + selector = start; + selector_offset = 0; + } + + CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode)); + uefi_call_wrapper(co->EnableCursor, 2, co, FALSE); + uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE); + + console_print_box_at(title, -1, 0, 0, -1, -1, 1, count_lines(title)); + + console_print_box_at(selectors, selector, offs_col, offs_row, + size_cols, size_rows, 0, lines); + + do { + k = console_get_keystroke(); + + if (k.ScanCode == SCAN_ESC) { + selector = -1; + break; + } + + if (k.ScanCode == SCAN_UP) { + if (selector > 0) + selector--; + else if (selector_offset > 0) + selector_offset--; + } else if (k.ScanCode == SCAN_DOWN) { + if (selector < lines - 1) + selector++; + else if (selector_offset < (selector_lines - lines)) + selector_offset++; + } + + console_print_box_at(&selectors[selector_offset], selector, + offs_col, offs_row, + size_cols, size_rows, 0, lines); + } while (!(k.ScanCode == SCAN_NULL + && k.UnicodeChar == CHAR_CARRIAGE_RETURN)); + + uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); + + uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); + uefi_call_wrapper(co->SetCursorPosition, 3, co, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow); + uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute); + + if (selector < 0) + /* ESC pressed */ + return selector; + return selector + selector_offset; +} + + +int +console_yes_no(CHAR16 *str_arr[]) +{ + return console_select(str_arr, (CHAR16 *[]){ L"No", L"Yes", NULL }, 0); +} + +void +console_alertbox(CHAR16 **title) +{ + console_select(title, (CHAR16 *[]){ L"OK", 0 }, 0); +} + +void +console_errorbox(CHAR16 *err) +{ + CHAR16 **err_arr = (CHAR16 *[]){ + L"ERROR", + L"", + 0, + 0, + }; + + err_arr[2] = err; + + console_alertbox(err_arr); +} + +void +console_notify(CHAR16 *string) +{ + CHAR16 **str_arr = (CHAR16 *[]){ + 0, + 0, + }; + + str_arr[0] = string; + + console_alertbox(str_arr); +} + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +/* Copy of gnu-efi-3.0 with the added secure boot strings */ +static struct { + EFI_STATUS Code; + WCHAR *Desc; +} error_table[] = { + { EFI_SUCCESS, L"Success"}, + { EFI_LOAD_ERROR, L"Load Error"}, + { EFI_INVALID_PARAMETER, L"Invalid Parameter"}, + { EFI_UNSUPPORTED, L"Unsupported"}, + { EFI_BAD_BUFFER_SIZE, L"Bad Buffer Size"}, + { EFI_BUFFER_TOO_SMALL, L"Buffer Too Small"}, + { EFI_NOT_READY, L"Not Ready"}, + { EFI_DEVICE_ERROR, L"Device Error"}, + { EFI_WRITE_PROTECTED, L"Write Protected"}, + { EFI_OUT_OF_RESOURCES, L"Out of Resources"}, + { EFI_VOLUME_CORRUPTED, L"Volume Corrupt"}, + { EFI_VOLUME_FULL, L"Volume Full"}, + { EFI_NO_MEDIA, L"No Media"}, + { EFI_MEDIA_CHANGED, L"Media changed"}, + { EFI_NOT_FOUND, L"Not Found"}, + { EFI_ACCESS_DENIED, L"Access Denied"}, + { EFI_NO_RESPONSE, L"No Response"}, + { EFI_NO_MAPPING, L"No mapping"}, + { EFI_TIMEOUT, L"Time out"}, + { EFI_NOT_STARTED, L"Not started"}, + { EFI_ALREADY_STARTED, L"Already started"}, + { EFI_ABORTED, L"Aborted"}, + { EFI_ICMP_ERROR, L"ICMP Error"}, + { EFI_TFTP_ERROR, L"TFTP Error"}, + { EFI_PROTOCOL_ERROR, L"Protocol Error"}, + { EFI_INCOMPATIBLE_VERSION, L"Incompatible Version"}, + { EFI_SECURITY_VIOLATION, L"Security Violation"}, + + // warnings + { EFI_WARN_UNKOWN_GLYPH, L"Warning Unknown Glyph"}, + { EFI_WARN_DELETE_FAILURE, L"Warning Delete Failure"}, + { EFI_WARN_WRITE_FAILURE, L"Warning Write Failure"}, + { EFI_WARN_BUFFER_TOO_SMALL, L"Warning Buffer Too Small"}, + { 0, NULL} +} ; + + +static CHAR16 * +err_string ( + IN EFI_STATUS Status + ) +{ + UINTN Index; + + for (Index = 0; error_table[Index].Desc; Index +=1) { + if (error_table[Index].Code == Status) { + return error_table[Index].Desc; + } + } + + return L""; +} + + +void +console_error(CHAR16 *err, EFI_STATUS status) +{ + CHAR16 **err_arr = (CHAR16 *[]){ + L"ERROR", + L"", + 0, + 0, + }; + CHAR16 str[512]; + + SPrint(str, sizeof(str), L"%s: (%d) %s", err, status, err_string(status)); + + err_arr[2] = str; + + console_alertbox(err_arr); +} + +void +console_reset(void) +{ + SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut; + + uefi_call_wrapper(co->Reset, 2, co, TRUE); + /* set mode 0 - required to be 80x25 */ + uefi_call_wrapper(co->SetMode, 2, co, 0); + uefi_call_wrapper(co->ClearScreen, 1, co); +} -- cgit v1.2.3 From 417077f8de33214b2942f5a6d8ff6af217b4f5dd Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 1 Oct 2013 14:03:16 -0400 Subject: Merge console_control.h and console.h Since these are topically the same thing, they can live together. Signed-off-by: Peter Jones --- Makefile | 4 ++-- MokManager.c | 1 - include/console.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ include/console_control.h | 46 ---------------------------------------------- lib/Makefile | 2 +- lib/console.c | 29 +++++++++++++++++++++++++++++ lib/console_control.c | 32 -------------------------------- shim.c | 1 - 8 files changed, 79 insertions(+), 83 deletions(-) delete mode 100644 include/console_control.h delete mode 100644 lib/console_control.c (limited to 'lib/console.c') diff --git a/Makefile b/Makefile index 40103eb3..581be0ac 100644 --- a/Makefile +++ b/Makefile @@ -38,9 +38,9 @@ VERSION = 0.4 TARGET = shim.efi MokManager.efi.signed fallback.efi.signed OBJS = shim.o netboot.o cert.o replacements.o KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key -SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h include/console_control.h +SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o -MOK_SOURCES = MokManager.c shim.h include/console_control.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h +MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h FALLBACK_OBJS = fallback.o FALLBACK_SRCS = fallback.c diff --git a/MokManager.c b/MokManager.c index 5d86e330..de0eb59a 100644 --- a/MokManager.c +++ b/MokManager.c @@ -2,7 +2,6 @@ #include #include #include -#include "console_control.h" #include "shim.h" #include "PeImage.h" #include "PasswordCrypt.h" diff --git a/include/console.h b/include/console.h index 7eb8a0be..d699d278 100644 --- a/include/console.h +++ b/include/console.h @@ -1,3 +1,6 @@ +#ifndef _SHIM_LIB_CONSOLE_H +#define _SHIM_LIB_CONSOLE_H 1 + EFI_INPUT_KEY console_get_keystroke(void); void @@ -19,3 +22,47 @@ console_notify(CHAR16 *string); void console_reset(void); #define NOSEL 0x7fffffff + +#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \ + { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} } + +typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL; + +typedef enum { + EfiConsoleControlScreenText, + EfiConsoleControlScreenGraphics, + EfiConsoleControlScreenMaxValue +} EFI_CONSOLE_CONTROL_SCREEN_MODE; + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode, + OUT BOOLEAN *GopUgaExists, OPTIONAL + OUT BOOLEAN *StdInLocked OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + IN CHAR16 *Password + ); + +struct _EFI_CONSOLE_CONTROL_PROTOCOL { + EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode; + EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode; + EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn; +}; + +extern VOID setup_console (int text); + +#endif /* _SHIM_LIB_CONSOLE_H */ diff --git a/include/console_control.h b/include/console_control.h deleted file mode 100644 index aec6f41d..00000000 --- a/include/console_control.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _SHIM_CONSOLE_CONTROL_H -#define _SHIM_CONSOLE_CONTROL_H 1 - -#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \ - { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} } - -typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL; - -typedef enum { - EfiConsoleControlScreenText, - EfiConsoleControlScreenGraphics, - EfiConsoleControlScreenMaxValue -} EFI_CONSOLE_CONTROL_SCREEN_MODE; - -typedef -EFI_STATUS -(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode, - OUT BOOLEAN *GopUgaExists, OPTIONAL - OUT BOOLEAN *StdInLocked OPTIONAL - ); - -typedef -EFI_STATUS -(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode - ); - -typedef -EFI_STATUS -(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - IN CHAR16 *Password - ); - -struct _EFI_CONSOLE_CONTROL_PROTOCOL { - EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode; - EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode; - EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn; -}; - -extern VOID setup_console (int text); - -#endif /* _SHIM_CONSOLE_CONTROL_H */ diff --git a/lib/Makefile b/lib/Makefile index f2b9091d..c1b9ab34 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,6 +1,6 @@ TARGET = lib.a -LIBFILES = simple_file.o guid.o console.o execute.o configtable.o shell.o variables.o security_policy.o console_control.o +LIBFILES = simple_file.o guid.o console.o execute.o configtable.o shell.o variables.o security_policy.o ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,) diff --git a/lib/console.c b/lib/console.c index af01f035..72d64271 100644 --- a/lib/console.c +++ b/lib/console.c @@ -1,5 +1,6 @@ /* * Copyright 2012 + * Copyright 2013 Red Hat Inc. * * see COPYING file */ @@ -400,3 +401,31 @@ console_reset(void) uefi_call_wrapper(co->SetMode, 2, co, 0); uefi_call_wrapper(co->ClearScreen, 1, co); } + +VOID setup_console (int text) +{ + EFI_STATUS status; + EFI_GUID console_control_guid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; + EFI_CONSOLE_CONTROL_PROTOCOL *concon; + static EFI_CONSOLE_CONTROL_SCREEN_MODE mode = + EfiConsoleControlScreenGraphics; + EFI_CONSOLE_CONTROL_SCREEN_MODE new_mode; + + status = LibLocateProtocol(&console_control_guid, (VOID **)&concon); + if (status != EFI_SUCCESS) + return; + + if (text) { + new_mode = EfiConsoleControlScreenText; + + status = uefi_call_wrapper(concon->GetMode, 4, concon, &mode, + 0, 0); + /* If that didn't work, assume it's graphics */ + if (status != EFI_SUCCESS) + mode = EfiConsoleControlScreenGraphics; + } else { + new_mode = mode; + } + + uefi_call_wrapper(concon->SetMode, 2, concon, new_mode); +} diff --git a/lib/console_control.c b/lib/console_control.c deleted file mode 100644 index 604a60f5..00000000 --- a/lib/console_control.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -#include "console_control.h" - -VOID setup_console (int text) -{ - EFI_STATUS status; - EFI_GUID console_control_guid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; - EFI_CONSOLE_CONTROL_PROTOCOL *concon; - static EFI_CONSOLE_CONTROL_SCREEN_MODE mode = - EfiConsoleControlScreenGraphics; - EFI_CONSOLE_CONTROL_SCREEN_MODE new_mode; - - status = LibLocateProtocol(&console_control_guid, (VOID **)&concon); - if (status != EFI_SUCCESS) - return; - - if (text) { - new_mode = EfiConsoleControlScreenText; - - status = uefi_call_wrapper(concon->GetMode, 4, concon, &mode, - 0, 0); - /* If that didn't work, assume it's graphics */ - if (status != EFI_SUCCESS) - mode = EfiConsoleControlScreenGraphics; - } else { - new_mode = mode; - } - - uefi_call_wrapper(concon->SetMode, 2, concon, new_mode); -} diff --git a/shim.c b/shim.c index a72e0910..3c55a5a4 100644 --- a/shim.c +++ b/shim.c @@ -43,7 +43,6 @@ #include "replacements.h" #include "ucs2.h" -#include "console_control.h" #include "guid.h" #include "variables.h" #include "efiauthenticated.h" -- cgit v1.2.3 From 0fb089ee14e92bd1f6909deaf4d32a926053edcd Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 3 Oct 2013 11:11:09 -0400 Subject: Add ident-like blobs to shim.efi for version checking. I feel dirty. --- .gitignore | 1 + Makefile | 14 +++++++++++--- include/console.h | 2 ++ lib/console.c | 14 ++++++++++++++ shim.c | 4 ++++ version.c.in | 8 ++++++++ version.h | 8 ++++++++ 7 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 version.c.in create mode 100644 version.h (limited to 'lib/console.c') diff --git a/.gitignore b/.gitignore index 85da8e77..586bc246 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ shim_cert.h *.srl *.srl.old *.tar.* +version.c diff --git a/Makefile b/Makefile index 53c4e000..4a8b5531 100644 --- a/Makefile +++ b/Makefile @@ -40,9 +40,9 @@ LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH VERSION = 0.4 TARGET = shim.efi MokManager.efi.signed fallback.efi.signed -OBJS = shim.o netboot.o cert.o replacements.o +OBJS = shim.o netboot.o cert.o replacements.o version.o KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer -SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h +SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h version.c version.h MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h FALLBACK_OBJS = fallback.o @@ -61,6 +61,12 @@ shim_cert.h: shim.cer hexdump -v -e '1/1 "0x%02x, "' $< >> $@ echo "};" >> $@ +version.c : version.c.in + sed -e "s,@@VERSION@@,$(VERSION)," \ + -e "s,@@UNAME@@,$(shell uname -a)," \ + -e "s,@@COMMIT@@,$(shell if [ -d .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \ + < version.c.in > version.c + certdb/secmod.db: shim.crt -mkdir certdb certutil -A -n 'my CA' -d certdb/ -t CT,CT,CT -i ca.crt @@ -115,7 +121,7 @@ clean: $(MAKE) -C Cryptlib/OpenSSL clean $(MAKE) -C lib clean rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb - rm -f *.debug *.so *.efi *.tar.* + rm -f *.debug *.so *.efi *.tar.* version.c GITTAG = $(VERSION) @@ -125,6 +131,7 @@ test-archive: @git archive --format=tar $(shell git branch | awk '/^*/ { print $$2 }') | ( cd /tmp/shim-$(VERSION)-tmp/ ; tar x ) @git diff | ( cd /tmp/shim-$(VERSION)-tmp/ ; patch -s -p1 -b -z .gitdiff ) @mv /tmp/shim-$(VERSION)-tmp/ /tmp/shim-$(VERSION)/ + @git log -1 --pretty=format:%H > /tmp/shim-$(VERSION)/commit @dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/shim-$(VERSION).tar.bz2 shim-$(VERSION) @rm -rf /tmp/shim-$(VERSION) @echo "The archive is in shim-$(VERSION).tar.bz2" @@ -135,6 +142,7 @@ archive: @mkdir -p /tmp/shim-$(VERSION)-tmp @git archive --format=tar $(GITTAG) | ( cd /tmp/shim-$(VERSION)-tmp/ ; tar x ) @mv /tmp/shim-$(VERSION)-tmp/ /tmp/shim-$(VERSION)/ + @git log -1 --pretty=format:%H > /tmp/shim-$(VERSION)/commit @dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/shim-$(VERSION).tar.bz2 shim-$(VERSION) @rm -rf /tmp/shim-$(VERSION) @echo "The archive is in shim-$(VERSION).tar.bz2" diff --git a/include/console.h b/include/console.h index d699d278..fbeb7e68 100644 --- a/include/console.h +++ b/include/console.h @@ -20,6 +20,8 @@ console_alertbox(CHAR16 **title); void console_notify(CHAR16 *string); void +console_notify_ascii(CHAR8 *string); +void console_reset(void); #define NOSEL 0x7fffffff diff --git a/lib/console.c b/lib/console.c index 72d64271..44b08f25 100644 --- a/lib/console.c +++ b/lib/console.c @@ -312,6 +312,20 @@ console_notify(CHAR16 *string) console_alertbox(str_arr); } +void +console_notify_ascii(CHAR8 *string) +{ + CHAR16 *str = AllocateZeroPool((strlena(string) + 1) * 2); + int i, j; + + if (!str) + return; + + for (i = 0, j = 1; string[i] != '\0'; i++, j+=2) + str[j] = string[i]; + console_notify(str); +} + #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) /* Copy of gnu-efi-3.0 with the added secure boot strings */ diff --git a/shim.c b/shim.c index 690cb091..873fd2ed 100644 --- a/shim.c +++ b/shim.c @@ -48,6 +48,7 @@ #include "efiauthenticated.h" #include "security_policy.h" #include "console.h" +#include "version.h" #define FALLBACK L"\\fallback.efi" #define MOK_MANAGER L"\\MokManager.efi" @@ -1668,6 +1669,9 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab) if (!EFI_ERROR(efi_status)) verbose = verbose_check; + if (verbose) + console_notify_ascii(shim_version); + /* Set the second stage loader */ set_second_stage (image_handle); diff --git a/version.c.in b/version.c.in new file mode 100644 index 00000000..9e71970d --- /dev/null +++ b/version.c.in @@ -0,0 +1,8 @@ + +#include "version.h" + +CHAR8 shim_version[] = + "UEFI SHIM\n" + "$Version: @@VERSION@@ $\n" + "$BuildMachine: @@UNAME@@ $\n" + "$Commit: @@COMMIT@@ $\n"; diff --git a/version.h b/version.h new file mode 100644 index 00000000..7fb3d81b --- /dev/null +++ b/version.h @@ -0,0 +1,8 @@ +#ifndef _SHIM_VERSION_H +#define _SHIM_VERSION_H 1 + +#include + +extern CHAR8 shim_version[]; + +#endif /* SHIM_VERSION_H */ -- cgit v1.2.3 From 4ab978a3697c88827f4099fe5774031caf5baf44 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 4 Oct 2013 11:51:09 -0400 Subject: Try to actually make debug printing look reasonable. Signed-off-by: Peter Jones --- include/console.h | 22 ++++++++++++++++++++-- lib/console.c | 33 +++++++++++++++++++-------------- shim.c | 32 ++++++++------------------------ 3 files changed, 47 insertions(+), 40 deletions(-) (limited to 'lib/console.c') diff --git a/include/console.h b/include/console.h index fbeb7e68..e6c2818f 100644 --- a/include/console.h +++ b/include/console.h @@ -20,8 +20,6 @@ console_alertbox(CHAR16 **title); void console_notify(CHAR16 *string); void -console_notify_ascii(CHAR8 *string); -void console_reset(void); #define NOSEL 0x7fffffff @@ -66,5 +64,25 @@ struct _EFI_CONSOLE_CONTROL_PROTOCOL { }; extern VOID setup_console (int text); +extern VOID setup_verbosity(VOID); +extern UINT8 verbose; +#define dprint(fmt, ...) ({ \ + UINTN __dprint_ret = 0; \ + if (verbose) \ + __dprint_ret = Print((fmt), ##__VA_ARGS__); \ + __dprint_ret; \ + }) +#define dprinta(fmt, ...) ({ \ + UINTN __dprinta_ret = 0; \ + if (verbose) { \ + UINTN __dprinta_i; \ + CHAR16 *__dprinta_str = AllocateZeroPool((strlena(fmt) + 1) * 2); \ + for (__dprinta_i = 0; fmt[__dprinta_i] != '\0'; __dprinta_i++) \ + __dprinta_str[__dprinta_i] = fmt[__dprinta_i]; \ + __dprinta_ret = Print((__dprinta_str), ##__VA_ARGS__); \ + FreePool(__dprinta_str); \ + } \ + __dprinta_ret; \ + }) #endif /* _SHIM_LIB_CONSOLE_H */ diff --git a/lib/console.c b/lib/console.c index 44b08f25..1f8f59ca 100644 --- a/lib/console.c +++ b/lib/console.c @@ -8,6 +8,7 @@ #include #include +#include #include static int min(int a, int b) @@ -312,20 +313,6 @@ console_notify(CHAR16 *string) console_alertbox(str_arr); } -void -console_notify_ascii(CHAR8 *string) -{ - CHAR16 *str = AllocateZeroPool((strlena(string) + 1) * 2); - int i, j; - - if (!str) - return; - - for (i = 0, j = 1; string[i] != '\0'; i++, j+=2) - str[j] = string[i]; - console_notify(str); -} - #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) /* Copy of gnu-efi-3.0 with the added secure boot strings */ @@ -416,6 +403,24 @@ console_reset(void) uefi_call_wrapper(co->ClearScreen, 1, co); } +UINT8 verbose; + +VOID +setup_verbosity(VOID) +{ + EFI_STATUS status; + EFI_GUID global_var = EFI_GLOBAL_VARIABLE; + UINT8 verbose_check; + UINTN verbose_check_size; + + verbose_check_size = 1; + status = get_variable(L"SHIM_VERBOSE", (void *)&verbose_check, + &verbose_check_size, global_var); + verbose = 0; + if (!EFI_ERROR(status)) + verbose = verbose_check; +} + VOID setup_console (int text) { EFI_STATUS status; diff --git a/shim.c b/shim.c index 51dfc26d..502a91dd 100644 --- a/shim.c +++ b/shim.c @@ -59,7 +59,6 @@ static EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TAB static CHAR16 *second_stage; static void *load_options; static UINT32 load_options_size; -static UINT8 verbose; EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }; @@ -731,12 +730,8 @@ static EFI_STATUS verify_buffer (char *data, int datasize, * databases */ status = check_whitelist(cert, sha256hash, sha1hash); - - if (status == EFI_SUCCESS) { - if (verbose) - console_notify(L"Binary is whitelisted\n"); + if (status == EFI_SUCCESS) return status; - } /* * Check against the shim build key @@ -746,8 +741,6 @@ static EFI_STATUS verify_buffer (char *data, int datasize, shim_cert, sizeof(shim_cert), sha256hash, SHA256_DIGEST_SIZE)) { status = EFI_SUCCESS; - if (verbose) - console_notify(L"Binary is verified by the vendor certificate\n"); return status; } @@ -760,12 +753,9 @@ static EFI_STATUS verify_buffer (char *data, int datasize, vendor_cert, vendor_cert_size, sha256hash, SHA256_DIGEST_SIZE)) { status = EFI_SUCCESS; - if (verbose) - console_notify(L"Binary is verified by the vendor certificate\n"); return status; } - Print(L"Invalid signature\n"); status = EFI_ACCESS_DENIED; return status; @@ -896,9 +886,12 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize, if (secure_mode ()) { efi_status = verify_buffer(data, datasize, &context); - if (efi_status != EFI_SUCCESS) { - Print(L"Verification failed\n"); + if (EFI_ERROR(efi_status)) { + console_error(L"Verification failed", efi_status); return efi_status; + } else { + if (verbose) + console_notify(L"Verification succeeded"); } } @@ -1681,9 +1674,6 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab) static SHIM_LOCK shim_lock_interface; EFI_HANDLE handle = NULL; EFI_STATUS efi_status; - UINT8 verbose_check; - UINTN verbose_check_size; - EFI_GUID global_var = EFI_GLOBAL_VARIABLE; verification_method = VERIFIED_BY_NOTHING; @@ -1708,15 +1698,9 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab) InitializeLib(image_handle, systab); setup_console(1); + setup_verbosity(); - verbose_check_size = 1; - efi_status = get_variable(L"SHIM_VERBOSE", (void *)&verbose_check, - &verbose_check_size, global_var); - if (!EFI_ERROR(efi_status)) - verbose = verbose_check; - - if (verbose) - console_notify_ascii(shim_version); + dprinta(shim_version); /* Set the second stage loader */ set_second_stage (image_handle); -- cgit v1.2.3 From 29d9c7c32799b3f9d95c8c971af827a049931801 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 4 Oct 2013 13:54:35 -0400 Subject: Put SHIM_VERBOSE under shim's guid, not global. Signed-off-by: Peter Jones --- lib/console.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/console.c') diff --git a/lib/console.c b/lib/console.c index 1f8f59ca..2fc8db3a 100644 --- a/lib/console.c +++ b/lib/console.c @@ -11,6 +11,8 @@ #include #include +static EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }; + static int min(int a, int b) { if (a < b) @@ -409,13 +411,13 @@ VOID setup_verbosity(VOID) { EFI_STATUS status; - EFI_GUID global_var = EFI_GLOBAL_VARIABLE; + EFI_GUID guid = SHIM_LOCK_GUID; UINT8 verbose_check; UINTN verbose_check_size; verbose_check_size = 1; status = get_variable(L"SHIM_VERBOSE", (void *)&verbose_check, - &verbose_check_size, global_var); + &verbose_check_size, guid); verbose = 0; if (!EFI_ERROR(status)) verbose = verbose_check; -- cgit v1.2.3 From dcc523811b7763036682ba42cc83cbf88f42a8f2 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Wed, 25 Jun 2014 10:02:18 -0400 Subject: MokManager: handle the error status from ReadKeyStroke On some machines, even though the key event was signaled, ReadKeyStroke still got EFI_NOT_READY. This commit handles the error status to avoid console_get_keystroke from returning unexpected keys. Signed-off-by: Gary Ching-Pang Lin Conflicts: MokManager.c --- MokManager.c | 17 +++++++++++++---- include/console.h | 4 ++-- lib/console.c | 26 ++++++++++++++++++-------- 3 files changed, 33 insertions(+), 14 deletions(-) (limited to 'lib/console.c') diff --git a/MokManager.c b/MokManager.c index 0ab308f7..50cb9d7f 100644 --- a/MokManager.c +++ b/MokManager.c @@ -488,13 +488,19 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title) return EFI_SUCCESS; } -static UINT8 get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show) +static EFI_STATUS get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show) { EFI_INPUT_KEY key; + EFI_STATUS status; unsigned int count = 0; do { - key = console_get_keystroke(); + status = console_get_keystroke(&key); + if (EFI_ERROR (status)) { + console_error(L"Failed to read the keystroke", status); + *length = 0; + return status; + } if ((count >= line_max && key.UnicodeChar != CHAR_BACKSPACE) || @@ -525,7 +531,7 @@ static UINT8 get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show *length = count; - return 1; + return EFI_SUCCESS; } static EFI_STATUS compute_pw_hash (void *Data, UINTN DataSize, UINT8 *password, @@ -989,6 +995,7 @@ static INTN mok_deletion_prompt (void *MokDel, UINTN MokDelSize) static CHAR16 get_password_charater (CHAR16 *prompt) { SIMPLE_TEXT_OUTPUT_MODE SavedMode; + EFI_STATUS status; CHAR16 *message[2]; CHAR16 character; UINTN length; @@ -1003,7 +1010,9 @@ static CHAR16 get_password_charater (CHAR16 *prompt) message[1] = NULL; length = StrLen(message[0]); console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1); - get_line(&pw_length, &character, 1, 0); + status = get_line(&pw_length, &character, 1, 0); + if (EFI_ERROR(status)) + character = 0; console_restore_mode(&SavedMode); diff --git a/include/console.h b/include/console.h index e6c2818f..9c793ea5 100644 --- a/include/console.h +++ b/include/console.h @@ -1,8 +1,8 @@ #ifndef _SHIM_LIB_CONSOLE_H #define _SHIM_LIB_CONSOLE_H 1 -EFI_INPUT_KEY -console_get_keystroke(void); +EFI_STATUS +console_get_keystroke(EFI_INPUT_KEY *key); void console_print_box_at(CHAR16 *str_arr[], int highlight, int start_col, int start_row, int size_cols, int size_rows, int offset, int lines); void diff --git a/lib/console.c b/lib/console.c index 2fc8db3a..41ed83a3 100644 --- a/lib/console.c +++ b/lib/console.c @@ -40,16 +40,18 @@ SetMem16(CHAR16 *dst, UINT32 n, CHAR16 c) } } -EFI_INPUT_KEY -console_get_keystroke(void) +EFI_STATUS +console_get_keystroke(EFI_INPUT_KEY *key) { - EFI_INPUT_KEY key; UINTN EventIndex; + EFI_STATUS status; - uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &EventIndex); - uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key); + do { + uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &EventIndex); + status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, key); + } while (status == EFI_NOT_READY); - return key; + return status; } void @@ -162,6 +164,8 @@ console_print_box(CHAR16 *str_arr[], int highlight) { SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode; SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut; + EFI_INPUT_KEY key; + CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode)); uefi_call_wrapper(co->EnableCursor, 2, co, FALSE); uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE); @@ -169,7 +173,7 @@ console_print_box(CHAR16 *str_arr[], int highlight) console_print_box_at(str_arr, highlight, 0, 0, -1, -1, 0, count_lines(str_arr)); - console_get_keystroke(); + console_get_keystroke(&key); uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); @@ -184,6 +188,7 @@ console_select(CHAR16 *title[], CHAR16* selectors[], int start) SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode; SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut; EFI_INPUT_KEY k; + EFI_STATUS status; int selector; int selector_lines = count_lines(selectors); int selector_max_cols = 0; @@ -237,7 +242,12 @@ console_select(CHAR16 *title[], CHAR16* selectors[], int start) size_cols, size_rows, 0, lines); do { - k = console_get_keystroke(); + status = console_get_keystroke(&k); + if (EFI_ERROR (status)) { + Print(L"Failed to read the keystroke: %r", status); + selector = -1; + break; + } if (k.ScanCode == SCAN_ESC) { selector = -1; -- cgit v1.2.3 From d8d7464f2cdd86ae01293086119463bf4a6b4a9c Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Wed, 25 Jun 2014 10:15:31 -0400 Subject: Remove the duplicate calls in lib/console.c Signed-off-by: Gary Ching-Pang Lin --- lib/console.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/console.c') diff --git a/lib/console.c b/lib/console.c index 41ed83a3..83ee679e 100644 --- a/lib/console.c +++ b/lib/console.c @@ -175,8 +175,6 @@ console_print_box(CHAR16 *str_arr[], int highlight) console_get_keystroke(&key); - uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); - uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); uefi_call_wrapper(co->SetCursorPosition, 3, co, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow); uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute); @@ -272,8 +270,6 @@ console_select(CHAR16 *title[], CHAR16* selectors[], int start) } while (!(k.ScanCode == SCAN_NULL && k.UnicodeChar == CHAR_CARRIAGE_RETURN)); - uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); - uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible); uefi_call_wrapper(co->SetCursorPosition, 3, co, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow); uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute); -- cgit v1.2.3