From e2481efcd9bf7db027a15d0934f9788979bd8af4 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 12 Apr 2017 20:40:43 +0100 Subject: [PATCH] [pki] application security improvements * Also clean up registry variables and add IsRegistryNode() call --- res/localization/rufus.loc | 2 ++ src/pki.c | 12 ++++++------ src/registry.h | 11 +++++++++++ src/rufus.c | 19 +++++++++++++++---- src/rufus.h | 1 + src/rufus.rc | 10 +++++----- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/res/localization/rufus.loc b/res/localization/rufus.loc index a0891943..8594c3dc 100644 --- a/res/localization/rufus.loc +++ b/res/localization/rufus.loc @@ -557,6 +557,8 @@ t MSG_291 "Version selection" t MSG_292 "Please select the version of Windows you want to install:" t MSG_293 "Unsupported Windows version" t MSG_294 "This version of Windows is no longer supported by Rufus." +t MSG_295 "Warning: Unofficial version" +t MSG_296 "This version of Rufus was NOT produced by its official developer(s).\n\nAre you sure you want to run it?" ################################################################################ ############################# TRANSLATOR END COPY ############################## diff --git a/src/pki.c b/src/pki.c index 13ee38f7..31bd0aad 100644 --- a/src/pki.c +++ b/src/pki.c @@ -36,7 +36,7 @@ #define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING) // Signatures names we accept (may be suffixed, but the signature should start with one of those) -const char* valid_cert_names[] = { "Akeo Consulting", "Akeo Systems", "Pete Batard" }; +const char* cert_name[3] = { "Akeo Consulting", "Akeo Systems", "Pete Batard" }; typedef struct { LPWSTR lpszProgramName; @@ -45,7 +45,7 @@ typedef struct { } SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO; // Mostly from https://support.microsoft.com/en-us/kb/323809 -static char* GetSignatureName(const char* path) +char* GetSignatureName(const char* path) { static char szSubjectName[128]; char* p = NULL; @@ -148,15 +148,15 @@ LONG ValidateSignature(HWND hDlg, const char* path) MessageBoxExU(hDlg, lmprintf(MSG_284), lmprintf(MSG_283), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid); return TRUST_E_NOSIGNATURE; } - for (i = 0; i < ARRAYSIZE(valid_cert_names); i++) { - len = strlen(valid_cert_names[i]); - if (strncmp(signature_name, valid_cert_names[i], len) == 0) { + for (i = 0; i < ARRAYSIZE(cert_name); i++) { + len = strlen(cert_name[i]); + if (strncmp(signature_name, cert_name[i], len) == 0) { // Test for whitespace after the part we match, for added safety if ((len >= strlen(signature_name)) || isspace(signature_name[len])) break; } } - if (i >= ARRAYSIZE(valid_cert_names)) { + if (i >= ARRAYSIZE(cert_name)) { uprintf("PKI: Signature '%s' is unexpected...", signature_name); if (MessageBoxExU(hDlg, lmprintf(MSG_285, signature_name), lmprintf(MSG_283), MB_YESNO | MB_ICONWARNING | MB_IS_RTL, selected_langid) != IDYES) diff --git a/src/registry.h b/src/registry.h index 01f686c7..f2eff34d 100644 --- a/src/registry.h +++ b/src/registry.h @@ -50,6 +50,17 @@ static __inline BOOL DeleteRegistryKey(HKEY key_root, const char* key_name) return ((s == ERROR_SUCCESS) || (s == ERROR_FILE_NOT_FOUND)); } +/* Find if a registry node exists */ +static __inline BOOL IsRegistryNode(HKEY key_root, const char* key_name) +{ + BOOL r; + HKEY hSoftware = NULL; + r = (RegOpenKeyExA(key_root, key_name, 0, KEY_READ, &hSoftware) == ERROR_SUCCESS); + if (hSoftware != NULL) + RegCloseKey(hSoftware); + return r; +} + /* Read a generic registry key value. If a short key_name is used, assume that it belongs to the application and create the app subkey if required */ static __inline BOOL _GetRegistryKey(HKEY key_root, const char* key_name, DWORD reg_type, LPBYTE dest, DWORD dest_size) diff --git a/src/rufus.c b/src/rufus.c index 5b116a41..2dadc2c0 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -61,6 +61,8 @@ PF_TYPE_DECL(WINAPI, ULONG, SHChangeNotifyRegister, (HWND, int, LONG, UINT, int, const char* cmdline_hogger = "rufus.com"; const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT", "ReFS" }; +const char* ep_reg = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"; +const char* vs_reg = "Software\\Microsoft\\VisualStudio"; // Number of steps for each FS for FCC_STRUCTURE_PROGRESS const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10 }; static const char* PartitionTypeLabel[2] = { "MBR", "GPT" }; @@ -77,6 +79,7 @@ extern BOOL enable_iso, enable_joliet, enable_rockridge, enable_ntfs_compression extern uint8_t* grub2_buf; extern long grub2_len; extern const char* old_c32_name[NB_OLD_C32]; +extern const char* cert_name[3]; static int selection_default; static UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU; static RECT relaunch_rc = { -65536, -65536, 0, 0}; @@ -2900,7 +2903,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine int wait_for_mutex = 0; FILE* fd; BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount = TRUE; - BOOL disable_hogger = FALSE, previous_enable_HDDs = FALSE; + BOOL disable_hogger = FALSE, previous_enable_HDDs = FALSE, vc = FALSE; BYTE *loc_data; DWORD loc_size, size; char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH] = "", ini_flags[] = "rb"; @@ -2955,7 +2958,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if ((strcmp(argv[i], "-g") == 0) || (strcmp(argv[i], "--gui") == 0)) disable_hogger = TRUE; } - + vc = IsRegistryNode(REGKEY_HKCU, vs_reg) || (safe_strcmp(GetSignatureName(argv[0]), cert_name[0]) == 0); // If our application name contains a 'p' (for "portable") create a 'rufus.ini' // NB: argv[0] is populated in the previous loop tmp = &argv[0][strlen(argv[0]) - 1]; @@ -3105,6 +3108,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } selected_langid = get_language_id(selected_locale); + if (!vc) { + get_loc_data_file(loc_file, selected_locale); + right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT); + if (MessageBoxExU(NULL, lmprintf(MSG_296), lmprintf(MSG_295), + MB_YESNO | MB_ICONWARNING | MB_IS_RTL | MB_SYSTEMMODAL, selected_langid) != IDYES) + goto out; + } + // This is needed as there appears to be a *FLAW* in Windows allowing the app to run unelevated with some // weirdly configured user accounts, even as we explicitly set 'requireAdministrator' in the manifest... if (!IsCurrentProcessElevated()) { @@ -3151,7 +3162,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine // We use local group policies rather than direct registry manipulation // 0x9e disables removable and fixed drive notifications - lgp_set = SetLGP(FALSE, &existing_key, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0x9e); + lgp_set = SetLGP(FALSE, &existing_key, ep_reg, "NoDriveTypeAutorun", 0x9e); if (nWindowsVersion > WINDOWS_XP) { // Re-enable AutoMount if needed @@ -3441,7 +3452,7 @@ out: safe_free(argv); } if (lgp_set) - SetLGP(TRUE, &existing_key, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0); + SetLGP(TRUE, &existing_key, ep_reg, "NoDriveTypeAutorun", 0); if ((nWindowsVersion > WINDOWS_XP) && (!automount) && (!SetAutoMount(FALSE))) uprintf("Failed to restore AutoMount to disabled"); // Unconditional delete with retry, just in case... diff --git a/src/rufus.h b/src/rufus.h index deee79fc..b4d57a22 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -472,6 +472,7 @@ extern BOOL IsBootableImage(const char* path); extern BOOL AppendVHDFooter(const char* vhd_path); extern BOOL SetWinToGoIndex(void); extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid); +extern char* GetSignatureName(const char* path); extern LONG ValidateSignature(HWND hDlg, const char* path); extern BOOL IsFontAvailable(const char* font_name); extern BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, diff --git a/src/rufus.rc b/src/rufus.rc index fbacd961..3399b70f 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 2.14.1087" +CAPTION "Rufus 2.14.1088" FONT 8, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -334,8 +334,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,14,1087,0 - PRODUCTVERSION 2,14,1087,0 + FILEVERSION 2,14,1088,0 + PRODUCTVERSION 2,14,1088,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -352,13 +352,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.14.1087" + VALUE "FileVersion", "2.14.1088" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "2.14.1087" + VALUE "ProductVersion", "2.14.1088" END END BLOCK "VarFileInfo"