From 4922daee362adf600fd19f91aa11cc603d8d17e1 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 21 Mar 2019 20:57:16 +0100 Subject: Implement better timeout mechanism for password input. Implement new actions "shutdown" and "reboot". Set default timeout value to 3 minutes and default timeout action to "shutdown" --- DcsBoot/DcsBoot.c | 14 +++++++++ DcsCfg/DcsCfgCrypt.c | 7 +++++ DcsInt/DcsInt.c | 53 +++++++++++++++++++++++++++++------ Include/Library/CommonLib.h | 8 ++++++ Include/Library/PasswordLib.h | 3 +- Library/PasswordLib/ConsolePassword.c | 6 ++-- Library/VeraCryptLib/DcsVeraCrypt.c | 11 +++++--- Library/VeraCryptLib/DcsVeraCrypt.h | 1 + 8 files changed, 86 insertions(+), 17 deletions(-) diff --git a/DcsBoot/DcsBoot.c b/DcsBoot/DcsBoot.c index e013dea..d4f4d56 100644 --- a/DcsBoot/DcsBoot.c +++ b/DcsBoot/DcsBoot.c @@ -169,6 +169,20 @@ DcsBootMain( res = EfiExec(NULL, L"\\EFI\\VeraCrypt\\DcsInt.dcs"); if (EFI_ERROR(res)) { // ERR_PRINT(L"\nDcsInt.efi %r\n",res); + if (res == EFI_DCS_SHUTDOWN_REQUESTED) + { + res = EFI_SUCCESS; + gST->RuntimeServices->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); + } + else if (res == EFI_DCS_REBOOT_REQUESTED) + { + res = EFI_SUCCESS; + gST->RuntimeServices->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + } + else if (res == EFI_DCS_HALT_REQUESTED) + { + EfiCpuHalt(); + } return res; } diff --git a/DcsCfg/DcsCfgCrypt.c b/DcsCfg/DcsCfgCrypt.c index 7bfb17f..2d5497b 100644 --- a/DcsCfg/DcsCfgCrypt.c +++ b/DcsCfg/DcsCfgCrypt.c @@ -169,11 +169,18 @@ ChangePassword( if (gAuthPwdCode == AskPwdRetCancel) { return EFI_NOT_READY; } + if (gAuthPwdCode == AskPwdRetTimeout) { + return EFI_TIMEOUT; + } VCAskPwd(AskPwdConfirm, &confirmPassword); if (gAuthPwdCode == AskPwdRetCancel) { MEM_BURN(&newPassword, sizeof(newPassword)); return EFI_NOT_READY; } + if (gAuthPwdCode == AskPwdRetTimeout) { + MEM_BURN(&newPassword, sizeof(newPassword)); + return EFI_TIMEOUT; + } if (newPassword.Length == confirmPassword.Length) { if (CompareMem(newPassword.Text, confirmPassword.Text, confirmPassword.Length) == 0) { gAuthPassword = newPassword; diff --git a/DcsInt/DcsInt.c b/DcsInt/DcsInt.c index 0cc4c4e..8b6c803 100644 --- a/DcsInt/DcsInt.c +++ b/DcsInt/DcsInt.c @@ -565,11 +565,18 @@ SecRegionChangePwd() { if (gAuthPwdCode == AskPwdRetCancel) { return EFI_NOT_READY; } + if (gAuthPwdCode == AskPwdRetTimeout) { + return EFI_TIMEOUT; + } VCAskPwd(AskPwdConfirm, &confirmPassword); if (gAuthPwdCode == AskPwdRetCancel) { MEM_BURN(&newPassword, sizeof(newPassword)); return EFI_NOT_READY; } + if (gAuthPwdCode == AskPwdRetTimeout) { + MEM_BURN(&newPassword, sizeof(newPassword)); + return EFI_TIMEOUT; + } if (newPassword.Length == confirmPassword.Length) { if (CompareMem(newPassword.Text, confirmPassword.Text, confirmPassword.Length) == 0) { break; @@ -677,6 +684,9 @@ SecRegionTryDecrypt() if (gAuthPwdCode == AskPwdRetCancel) { return EFI_NOT_READY; } + if (gAuthPwdCode == AskPwdRetTimeout) { + return EFI_TIMEOUT; + } OUT_PRINT(L"%a", gAuthStartMsg); do { // EFI tables? @@ -793,6 +803,7 @@ SecRegionTryDecrypt() enum OnExitTypes{ OnExitAuthFaild = 1, OnExitAuthNotFound, + OnExitAuthTimeout, OnExitSuccess }; @@ -820,7 +831,7 @@ AsciiStrNStr( ++posp; ++pos2; } - if (*pos2 == 0) return NULL; + if (*pos2 == 0 && *posp) return NULL; if (*posp == 0) return pos1; ++pos1; } @@ -866,7 +877,14 @@ OnExit( CHAR8* delayStr = NULL; EFI_GUID *guid = NULL; CHAR16 *fileStr = NULL; + + if (EFI_ERROR(retValue)) + { + CleanSensitiveData(); + } + if (action == NULL) return retValue; + if (OnExitGetParam(action, "guid", &guidStr, NULL)) { EFI_GUID tmp; if (DcsAsciiStrToGuid(&tmp, guidStr)) { @@ -905,29 +923,43 @@ OnExit( } if (AsciiStrNStr(action, "halt") == action) { - EfiCpuHalt(); + retValue = EFI_DCS_HALT_REQUESTED; } - if (AsciiStrNStr(action, "exec") == action) { + else if (AsciiStrNStr(action, "shutdown") == action) { + retValue = EFI_DCS_SHUTDOWN_REQUESTED; + } + + else if (AsciiStrNStr(action, "reboot") == action) { + retValue = EFI_DCS_REBOOT_REQUESTED; + } + + else if (AsciiStrNStr(action, "exec") == action) { if (guid != NULL) { EFI_STATUS res; EFI_HANDLE h; res = EfiFindPartByGUID(guid, &h); if (EFI_ERROR(res)) { ERR_PRINT(L"\nCan't find start partition\n"); - EfiCpuHalt(); + CleanSensitiveData(); + retValue = EFI_DCS_HALT_REQUESTED; + goto exit; } // Try to exec if (fileStr != NULL) { res = EfiExec(h, fileStr); if (EFI_ERROR(res)) { ERR_PRINT(L"\nStart %s - %r\n", fileStr, res); - EfiCpuHalt(); + CleanSensitiveData(); + retValue = EFI_DCS_HALT_REQUESTED; + goto exit; } } else { ERR_PRINT(L"\nNo EFI execution path specified. Halting!\n"); - EfiCpuHalt(); + CleanSensitiveData(); + retValue = EFI_DCS_HALT_REQUESTED; + goto exit; } } @@ -937,7 +969,7 @@ OnExit( goto exit; } - if (AsciiStrNStr(action, "postexec") == action) { + else if (AsciiStrNStr(action, "postexec") == action) { if (guid != NULL) { EfiSetVar(L"DcsExecPartGuid", NULL, &guid, sizeof(EFI_GUID), EFI_VARIABLE_BOOTSERVICE_ACCESS); } @@ -947,7 +979,7 @@ OnExit( goto exit; } - if (AsciiStrStr(action, "exit") == action) { + else if (AsciiStrStr(action, "exit") == action) { goto exit; } @@ -1151,7 +1183,10 @@ UefiMain( gST->ConIn->Reset(gST->ConIn, FALSE); if (EFI_ERROR(res)) { - return OnExit(gOnExitFailed, OnExitAuthFaild, res); + if (res == EFI_TIMEOUT) + return OnExit(gOnExitTimeout, OnExitAuthTimeout, res); + else + return OnExit(gOnExitFailed, OnExitAuthFaild, res); } res = PrepareBootParams(BootDriveSignature, SecRegionCryptInfo); diff --git a/Include/Library/CommonLib.h b/Include/Library/CommonLib.h index 17b0c72..479c5c1 100644 --- a/Include/Library/CommonLib.h +++ b/Include/Library/CommonLib.h @@ -24,6 +24,14 @@ https://opensource.org/licenses/LGPL-3.0 #include #include +////////////////////////////////////////////////////////////////////////// +// Custom error codes +////////////////////////////////////////////////////////////////////////// + +#define EFI_DCS_SHUTDOWN_REQUESTED ENCODE_ERROR(0xDC50001) +#define EFI_DCS_REBOOT_REQUESTED ENCODE_ERROR(0xDC50002) +#define EFI_DCS_HALT_REQUESTED ENCODE_ERROR(0xDC50003) + ////////////////////////////////////////////////////////////////////////// // Check error ////////////////////////////////////////////////////////////////////////// diff --git a/Include/Library/PasswordLib.h b/Include/Library/PasswordLib.h index 25ee1aa..cc77957 100644 --- a/Include/Library/PasswordLib.h +++ b/Include/Library/PasswordLib.h @@ -43,7 +43,8 @@ enum AskPwdType { enum AskPwdRetCode { AskPwdRetCancel = 0, AskPwdRetLogin = 1, - AskPwdRetChange + AskPwdRetChange = 2, + AskPwdRetTimeout }; VOID diff --git a/Library/PasswordLib/ConsolePassword.c b/Library/PasswordLib/ConsolePassword.c index 43e03e6..0b2d3c6 100644 --- a/Library/PasswordLib/ConsolePassword.c +++ b/Library/PasswordLib/ConsolePassword.c @@ -36,12 +36,12 @@ AskConsolePwdInt( UINTN EventIndex = 0; InputEvents[0] = gST->ConIn->WaitForKey; gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]); - gBS->SetTimer(InputEvents[1], TimerPeriodic, 10000000 * gPasswordTimeout); + gBS->SetTimer(InputEvents[1], TimerRelative, 10000000 * gPasswordTimeout); gBS->WaitForEvent(2, InputEvents, &EventIndex); - gPasswordTimeout = 0; + gBS->SetTimer(InputEvents[1], TimerCancel, 0); gBS->CloseEvent(InputEvents[1]); if (EventIndex == 1) { - *retCode = AskPwdRetCancel; + *retCode = AskPwdRetTimeout; return ; } } diff --git a/Library/VeraCryptLib/DcsVeraCrypt.c b/Library/VeraCryptLib/DcsVeraCrypt.c index 1249718..10bb7d7 100644 --- a/Library/VeraCryptLib/DcsVeraCrypt.c +++ b/Library/VeraCryptLib/DcsVeraCrypt.c @@ -81,6 +81,7 @@ UINT8 gForcePasswordProgress = 1; CHAR8* gOnExitFailed = NULL; CHAR8* gOnExitSuccess = NULL; CHAR8* gOnExitNotFound = NULL; +CHAR8* gOnExitTimeout = NULL; ////////////////////////////////////////////////////////////////////////// // Authorize @@ -147,7 +148,7 @@ VCAuthLoadConfig() gPasswordProgress = (UINT8)ConfigReadInt("AuthorizeProgress", 1); // print "*" gPasswordVisible = (UINT8)ConfigReadInt("AuthorizeVisible", 0); // show chars gPasswordShowMark = ConfigReadInt("AuthorizeMarkTouch", 1); // show touch points - gPasswordTimeout = (UINT8)ConfigReadInt("PasswordTimeout", 0); // If no password for => + gPasswordTimeout = (UINT8)ConfigReadInt("PasswordTimeout", 180); // If no password for => gDcsBootForce = ConfigReadInt("DcsBootForce", 1); // Ask password even if no USB marked found. @@ -181,6 +182,8 @@ VCAuthLoadConfig() ConfigReadString("ActionNotFound", "Exit", gOnExitNotFound, MAX_MSG); VCCONFIG_ALLOC(gOnExitFailed, MAX_MSG); ConfigReadString("ActionFailed", "Exit", gOnExitFailed, MAX_MSG); + VCCONFIG_ALLOC(gOnExitTimeout, MAX_MSG); + ConfigReadString("ActionTimeout", "Shutdown", gOnExitTimeout, MAX_MSG); strTemp = MEM_ALLOC(MAX_MSG); ConfigReadString("PartitionGuidOS", "", strTemp, MAX_MSG); @@ -321,7 +324,7 @@ VCAskPwd( ERR_PRINT(L"%r\n", res); } } while (gCfgMenuContinue); - if (gAuthPwdCode == AskPwdRetCancel) { + if ((gAuthPwdCode == AskPwdRetCancel) || (gAuthPwdCode == AskPwdRetTimeout)) { return; } } @@ -355,7 +358,7 @@ VCAskPwd( AskConsolePwdInt(&vcPwd->Length, vcPwd->Text, &gAuthPwdCode, sizeof(vcPwd->Text), gPasswordVisible); } - if (gAuthPwdCode == AskPwdRetCancel) { + if ((gAuthPwdCode == AskPwdRetCancel) || (gAuthPwdCode == AskPwdRetTimeout)) { return; } } @@ -396,7 +399,7 @@ VCAuthAsk() { VCAskPwd(AskPwdLogin, &gAuthPassword); - if (gAuthPwdCode == AskPwdRetCancel) { + if ((gAuthPwdCode == AskPwdRetCancel) || (gAuthPwdCode == AskPwdRetTimeout)) { return; } diff --git a/Library/VeraCryptLib/DcsVeraCrypt.h b/Library/VeraCryptLib/DcsVeraCrypt.h index f7a3c8f..152a335 100644 --- a/Library/VeraCryptLib/DcsVeraCrypt.h +++ b/Library/VeraCryptLib/DcsVeraCrypt.h @@ -74,6 +74,7 @@ extern UINT8 gForcePasswordProgress; extern CHAR8* gOnExitFailed; extern CHAR8* gOnExitSuccess; extern CHAR8* gOnExitNotFound; +extern CHAR8* gOnExitTimeout; void VCAuthAsk(); -- cgit v1.2.3