[fido] download an LZMA compressed version of the script

* Since we have compression available through Bled we might as well use it
* Also validate that the download URL comes from https://github.com/pbatard/Fido
* Also prevent the check for update from running while we are downloading ISOs
This commit is contained in:
Pete Batard 2019-03-23 13:59:20 +00:00
parent 7ad3b31be9
commit 4271e42b50
No known key found for this signature in database
GPG Key ID: 38E0CF5E69EDD671
7 changed files with 112 additions and 20 deletions

View File

@ -25,6 +25,9 @@ progress_t bled_progress = NULL;
unsigned long* bled_cancel_request;
static bool bled_initialized = 0;
jmp_buf bb_error_jmp;
char* bb_virtual_buf = NULL;
size_t bb_virtual_len = 0, bb_virtual_pos = 0;
int bb_virtual_fd = -1;
static long long int unpack_none(transformer_state_t *xstate)
{
@ -49,8 +52,10 @@ int64_t bled_uncompress(const char* src, const char* dst, int type)
transformer_state_t xstate;
int64_t ret;
if (!bled_initialized)
if (!bled_initialized) {
bb_error_msg("The library has not been initialized");
return -1;
}
bb_total_rb = 0;
init_transformer_state(&xstate);
@ -95,8 +100,10 @@ int64_t bled_uncompress_with_handles(HANDLE hSrc, HANDLE hDst, int type)
{
transformer_state_t xstate;
if (!bled_initialized)
if (!bled_initialized) {
bb_error_msg("The library has not been initialized");
return -1;
}
bb_total_rb = 0;
init_transformer_state(&xstate);
@ -132,8 +139,15 @@ int64_t bled_uncompress_to_buffer(const char* src, char* buf, size_t size, int t
transformer_state_t xstate;
int64_t ret;
if (!bled_initialized)
if (!bled_initialized) {
bb_error_msg("The library has not been initialized");
return -1;
}
if ((src == NULL) || (buf == NULL)) {
bb_error_msg("Invalid parameter");
return -1;
}
bb_total_rb = 0;
init_transformer_state(&xstate);
@ -141,7 +155,11 @@ int64_t bled_uncompress_to_buffer(const char* src, char* buf, size_t size, int t
xstate.dst_fd = -1;
xstate.check_signature = 1;
xstate.src_fd = _openU(src, _O_RDONLY | _O_BINARY, 0);
if (src[0] == 0) {
xstate.src_fd = bb_virtual_fd;
} else {
xstate.src_fd = _openU(src, _O_RDONLY | _O_BINARY, 0);
}
if (xstate.src_fd < 0) {
bb_error_msg("Could not open '%s' (errno: %d)", src, errno);
goto err;
@ -159,7 +177,8 @@ int64_t bled_uncompress_to_buffer(const char* src, char* buf, size_t size, int t
if (setjmp(bb_error_jmp))
goto err;
ret = unpacker[type](&xstate);
_close(xstate.src_fd);
if (src[0] != 0)
_close(xstate.src_fd);
return ret;
err:
@ -168,6 +187,39 @@ err:
return -1;
}
int64_t bled_uncompress_from_buffer_to_buffer(const char* src, const size_t src_len, char* dst, size_t dst_len, int type)
{
int64_t ret;
if (!bled_initialized) {
bb_error_msg("The library has not been initialized");
return -1;
}
if ((src == NULL) || (dst == NULL)) {
bb_error_msg("Invalid parameter");
return -1;
}
if (bb_virtual_buf != NULL) {
bb_error_msg("Can not decompress more than one buffer at once");
return -1;
}
bb_virtual_buf = (char*)src;
bb_virtual_len = src_len;
bb_virtual_pos = 0;
bb_virtual_fd = 0;
ret = bled_uncompress_to_buffer("", dst, dst_len, type);
bb_virtual_buf = NULL;
bb_virtual_len = 0;
bb_virtual_fd = -1;
return ret;
}
/* Initialize the library.
* When the parameters are not NULL you can:
* - specify the printf-like function you want to use to output message

View File

@ -39,6 +39,9 @@ int64_t bled_uncompress_with_handles(HANDLE hSrc, HANDLE hDst, int type);
/* Uncompress file 'src', compressed using 'type', to buffer 'buf' of size 'size' */
int64_t bled_uncompress_to_buffer(const char* src, char* buf, size_t size, int type);
/* Uncompress buffer 'src' of length 'src_len' to buffer 'dst' of size 'dst_len' */
int64_t bled_uncompress_from_buffer_to_buffer(const char* src, const size_t src_len, char* dst, size_t dst_len, int type);
/* Initialize the library.
* When the parameters are not NULL you can:
* - specify the printf-like function you want to use to output message

View File

@ -98,6 +98,9 @@ typedef unsigned int uid_t;
extern smallint bb_got_signal;
extern uint32_t *global_crc32_table;
extern jmp_buf bb_error_jmp;
extern char* bb_virtual_buf;
extern size_t bb_virtual_len, bb_virtual_pos;
extern int bb_virtual_fd;
uint32_t* crc32_filltable(uint32_t *crc_table, int endian);
uint32_t crc32_le(uint32_t crc, unsigned char const *p, size_t len, uint32_t *crc32table_le);
@ -174,7 +177,15 @@ static inline int full_read(int fd, void *buf, size_t count) {
return -1;
}
rb = _read(fd, buf, (int)count);
if (fd == bb_virtual_fd) {
if (bb_virtual_pos + count > bb_virtual_len)
count = bb_virtual_len - bb_virtual_pos;
memcpy(buf, &bb_virtual_buf[bb_virtual_pos], count);
bb_virtual_pos += count;
rb = (int)count;
} else {
rb = _read(fd, buf, (int)count);
}
if (rb > 0) {
bb_total_rb += rb;
if (bled_progress != NULL)

View File

@ -36,6 +36,7 @@
#include "resource.h"
#include "msapi_utf8.h"
#include "localization.h"
#include "bled/bled.h"
#include "settings.h"
@ -878,11 +879,14 @@ static DWORD WINAPI DownloadISOThread(LPVOID param)
char locale_str[1024], cmdline[sizeof(locale_str) + 512], pipe[MAX_GUID_STRING_LENGTH + 16] = "\\\\.\\pipe\\";
char powershell_path[MAX_PATH], icon_path[MAX_PATH] = "", script_path[MAX_PATH] = "";
char *url = NULL, sig_url[128];
BYTE *sig = NULL;
uint64_t uncompressed_size;
int64_t size = -1;
BYTE *compressed = NULL, *sig = NULL;
HANDLE hFile, hPipe;
DWORD dwExitCode = 99, dwSize, dwAvail, dwPipeSize = 4096;
DWORD dwExitCode = 99, dwCompressedSize, dwSize, dwAvail, dwPipeSize = 4096;
GUID guid;
dialog_showing++;
IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
// Use a GUID as random unique string, else ill-intentioned security "researchers"
@ -903,22 +907,38 @@ static DWORD WINAPI DownloadISOThread(LPVOID param)
#else
// If we don't have the script, download it
if (fido_script == NULL) {
fido_len = (DWORD)DownloadToFileOrBuffer(fido_url, NULL, &fido_script, hMainDialog, FALSE);
if (fido_len == 0)
dwCompressedSize = (DWORD)DownloadToFileOrBuffer(fido_url, NULL, &compressed, hMainDialog, FALSE);
if (dwCompressedSize == 0)
goto out;
static_sprintf(sig_url, "%s.sig", fido_url);
dwSize = (DWORD)DownloadToFileOrBuffer(sig_url, NULL, &sig, NULL, FALSE);
if ((dwSize != RSA_SIGNATURE_SIZE) || (!ValidateOpensslSignature(fido_script, fido_len, sig, dwSize))) {
if ((dwSize != RSA_SIGNATURE_SIZE) || (!ValidateOpensslSignature(compressed, dwCompressedSize, sig, dwSize))) {
uprintf("FATAL: Signature is invalid ✗");
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_BAD_SIGNATURE);
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_ERROR, 0);
SetTaskbarProgressState(TASKBAR_ERROR);
safe_free(fido_script);
safe_free(compressed);
free(sig);
goto out;
}
free(sig);
uprintf("Signature is valid ✓");
uncompressed_size = *((uint64_t*)&compressed[5]);
if ((uncompressed_size < 1 * MB) && (bled_init(_uprintf, NULL, &FormatStatus) >= 0)) {
fido_script = malloc((size_t)uncompressed_size);
size = bled_uncompress_from_buffer_to_buffer(compressed, dwCompressedSize, fido_script, (size_t)uncompressed_size, BLED_COMPRESSION_LZMA);
bled_exit();
}
safe_free(compressed);
if (size != uncompressed_size) {
uprintf("FATAL: Could not uncompressed download script");
safe_free(fido_script);
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_DATA;
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_ERROR, 0);
SetTaskbarProgressState(TASKBAR_ERROR);
goto out;
}
fido_len = (DWORD)size;
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0);
SetTaskbarProgressState(TASKBAR_NORMAL);
SetTaskbarProgressValue(0, MAX_PROGRESS);
@ -1012,6 +1032,7 @@ out:
#endif
free(url);
SendMessage(hMainDialog, UM_ENABLE_CONTROLS, 0, 0);
dialog_showing--;
ExitThread(dwExitCode);
}

View File

@ -104,7 +104,7 @@
#endif
#define DOWNLOAD_URL RUFUS_URL "/downloads"
#define FILES_URL RUFUS_URL "/files"
#define FIDO_VERSION "v1"
#define FIDO_VERSION "z1"
#define SECURE_BOOT_MORE_INFO_URL "https://github.com/pbatard/rufus/wiki/FAQ#Why_do_I_need_to_disable_Secure_Boot_to_use_UEFINTFS"
#define WPPRECORDER_MORE_INFO_URL "https://github.com/pbatard/rufus/wiki/FAQ#BSODs_with_Windows_To_Go_drives_created_from_Windows_10_1809_ISOs"
#define SEVENZIP_URL "https://www.7-zip.org"

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 3.5.1487"
CAPTION "Rufus 3.5.1488"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -394,8 +394,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,5,1487,0
PRODUCTVERSION 3,5,1487,0
FILEVERSION 3,5,1488,0
PRODUCTVERSION 3,5,1488,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -413,13 +413,13 @@ BEGIN
VALUE "Comments", "https://akeo.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.5.1487"
VALUE "FileVersion", "3.5.1488"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus-3.5.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.5.1487"
VALUE "ProductVersion", "3.5.1488"
END
END
BLOCK "VarFileInfo"

View File

@ -1558,8 +1558,13 @@ BOOL SetUpdateCheck(void)
if ((loc_len != 0) && (loc_len < 4 * KB)) {
loc_len++; // DownloadToFileOrBuffer allocated an extra NUL character if needed
fido_url = get_token_data_buffer(FIDO_VERSION, 1, loc, (size_t)loc_len);
uprintf("Fido URL is %s", fido_url);
enable_fido = IsDownloadable(fido_url);
if (safe_strncmp(fido_url, "https://github.com/pbatard/Fido", 31) != 0) {
ubprintf("WARNING: Download script URL %s is invalid ✗", fido_url);
safe_free(fido_url);
} else {
uprintf("Fido URL is %s", fido_url);
enable_fido = IsDownloadable(fido_url);
}
}
safe_free(loc);
}