mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[iso] update MD5SUMS/md5sums.txt text file for distros that have them
* The upcoming Ubuntu 20.04 comes with MD5 validation turned on by default. * When creating persistent boot media, we may update some of the validated files to add persistence, update the search labels, etc. * Make sure that the files we modify get their MD5 updated where needed. * Also add 'loopback.cfg' to the list of config files we can add persistence to. * Part of #1499
This commit is contained in:
parent
045f590c3b
commit
1e6e38b180
4 changed files with 153 additions and 29 deletions
106
src/iso.c
106
src/iso.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Rufus: The Reliable USB Formatting Utility
|
||||
* ISO file extraction
|
||||
* Copyright © 2011-2019 Pete Batard <pete@akeo.ie>
|
||||
* Copyright © 2011-2020 Pete Batard <pete@akeo.ie>
|
||||
* Based on libcdio's iso & udf samples:
|
||||
* Copyright © 2003-2014 Rocky Bernstein <rocky@gnu.org>
|
||||
*
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include <errno.h>
|
||||
#include <direct.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <virtdisk.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@ -82,6 +83,7 @@ static const char* bootmgr_efi_name = "bootmgr.efi";
|
|||
static const char* grldr_name = "grldr";
|
||||
static const char* ldlinux_name = "ldlinux.sys";
|
||||
static const char* ldlinux_c32 = "ldlinux.c32";
|
||||
static const char* md5sum_name[] = { "MD5SUMS", "md5sum.txt" };
|
||||
static const char* casper_dirname = "/casper";
|
||||
static const char* efi_dirname = "/efi/boot";
|
||||
static const char* efi_bootname[] = { "bootia32.efi", "bootia64.efi", "bootx64.efi", "bootarm.efi", "bootaa64.efi", "bootebc.efi" };
|
||||
|
@ -90,7 +92,7 @@ static const char* wininst_name[] = { "install.wim", "install.esd", "install.swm
|
|||
// We only support GRUB/BIOS (x86) that uses a standard config dir (/boot/grub/i386-pc/)
|
||||
// If the disc was mastered properly, GRUB/EFI will take care of itself
|
||||
static const char* grub_dirname = "/boot/grub/i386-pc";
|
||||
static const char* grub_cfg = "grub.cfg";
|
||||
static const char* grub_cfg[] = { "grub.cfg", "loopback.cfg" };
|
||||
static const char* menu_cfg = "menu.cfg";
|
||||
// NB: Do not alter the order of the array below without validating hardcoded indexes in check_iso_props
|
||||
static const char* syslinux_cfg[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf", "txt.cfg" };
|
||||
|
@ -110,7 +112,7 @@ static const int64_t old_c32_threshold[NB_OLD_C32] = OLD_C32_THRESHOLD;
|
|||
static uint8_t joliet_level = 0;
|
||||
static uint64_t total_blocks, nb_blocks;
|
||||
static BOOL scan_only = FALSE;
|
||||
static StrArray config_path, isolinux_path;
|
||||
static StrArray config_path, isolinux_path, modified_path;
|
||||
|
||||
// Ensure filenames do not contain invalid FAT32 or NTFS characters
|
||||
static __inline char* sanitize_filename(char* filename, BOOL* is_identical)
|
||||
|
@ -183,9 +185,11 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const
|
|||
len = safe_strlen(psz_basename);
|
||||
if ((len >= 4) && safe_stricmp(&psz_basename[len - 4], ".cfg") == 0) {
|
||||
props->is_cfg = TRUE;
|
||||
if (safe_stricmp(psz_basename, grub_cfg) == 0) {
|
||||
for (i = 0; i < ARRAYSIZE(grub_cfg); i++) {
|
||||
if (safe_stricmp(psz_basename, grub_cfg[i]) == 0)
|
||||
props->is_grub_cfg = TRUE;
|
||||
} else if (safe_stricmp(psz_basename, menu_cfg) == 0) {
|
||||
}
|
||||
if (safe_stricmp(psz_basename, menu_cfg) == 0) {
|
||||
props->is_menu_cfg = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -218,6 +222,7 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const
|
|||
img_report.has_bootmgr = TRUE;
|
||||
}
|
||||
if (safe_stricmp(psz_basename, bootmgr_efi_name) == 0) {
|
||||
img_report.has_efi |= 1;
|
||||
img_report.has_bootmgr_efi = TRUE;
|
||||
}
|
||||
if (safe_stricmp(psz_basename, grldr_name) == 0) {
|
||||
|
@ -226,12 +231,13 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const
|
|||
if (safe_stricmp(psz_basename, kolibri_name) == 0) {
|
||||
img_report.has_kolibrios = TRUE;
|
||||
}
|
||||
if (safe_stricmp(psz_basename, bootmgr_efi_name) == 0) {
|
||||
img_report.has_efi |= 1;
|
||||
}
|
||||
if (safe_stricmp(psz_basename, manjaro_marker) == 0) {
|
||||
img_report.disable_iso = TRUE;
|
||||
}
|
||||
for (i = 0; i < ARRAYSIZE(md5sum_name); i++) {
|
||||
if (safe_stricmp(psz_basename, md5sum_name[i]) == 0)
|
||||
img_report.has_md5sum = (uint8_t)(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for ReactOS' setupldr.sys anywhere
|
||||
|
@ -296,6 +302,7 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const
|
|||
// Apply various workarounds to Linux config files
|
||||
static void fix_config(const char* psz_fullpath, const char* psz_path, const char* psz_basename, EXTRACT_PROPS* props)
|
||||
{
|
||||
BOOL modified = FALSE;
|
||||
size_t i, nul_pos;
|
||||
char *iso_label = NULL, *usb_label = NULL, *src, *dst;
|
||||
|
||||
|
@ -309,16 +316,19 @@ static void fix_config(const char* psz_fullpath, const char* psz_path, const cha
|
|||
// Add persistence to the kernel options
|
||||
if ((boot_type == BT_IMAGE) && HAS_PERSISTENCE(img_report) && persistence_size) {
|
||||
if ((props->is_grub_cfg) || (props->is_menu_cfg) || (props->is_syslinux_cfg)) {
|
||||
if (replace_in_token_data(src, props->is_grub_cfg ? "linux" : "append",
|
||||
"file=/cdrom/preseed", "persistent file=/cdrom/preseed", TRUE) != NULL) {
|
||||
// Ubuntu & derivatives are assumed to use 'file=/cdrom/preseed/...'
|
||||
// somewhere in their kernel options and use 'persistent' as keyword.
|
||||
if (replace_in_token_data(src, props->is_grub_cfg ? "linux" : "append",
|
||||
"file=/cdrom/preseed", "persistent file=/cdrom/preseed", TRUE) != NULL)
|
||||
uprintf(" Added 'persistent' kernel option");
|
||||
modified = TRUE;
|
||||
} else if (replace_in_token_data(src, props->is_grub_cfg ? "linux" : "append",
|
||||
"boot=live", "boot=live persistence", TRUE) != NULL) {
|
||||
// Debian & derivatives are assumed to use 'boot=live' in
|
||||
// their kernel options and use 'persistence' as keyword.
|
||||
else if (replace_in_token_data(src, props->is_grub_cfg ? "linux" : "append",
|
||||
"boot=live", "boot=live persistence", TRUE) != NULL)
|
||||
uprintf(" Added 'persistence' kernel option");
|
||||
modified = TRUE;
|
||||
}
|
||||
// Other distros can go to hell. Seriously, just check all partitions for
|
||||
// an ext volume with the right label and use persistence *THEN*. I mean,
|
||||
// why on earth do you need a bloody *NONSTANDARD* kernel option and/or a
|
||||
|
@ -336,12 +346,15 @@ static void fix_config(const char* psz_fullpath, const char* psz_path, const cha
|
|||
if (props->is_grub_cfg) {
|
||||
// Older versions of GRUB EFI used "linuxefi", newer just use "linux"
|
||||
if ((replace_in_token_data(src, "linux", iso_label, usb_label, TRUE) != NULL) ||
|
||||
(replace_in_token_data(src, "linuxefi", iso_label, usb_label, TRUE) != NULL))
|
||||
(replace_in_token_data(src, "linuxefi", iso_label, usb_label, TRUE) != NULL)) {
|
||||
uprintf(" Patched %s: '%s' ➔ '%s'\n", src, iso_label, usb_label);
|
||||
modified = TRUE;
|
||||
}
|
||||
else if (replace_in_token_data(src, (props->is_conf) ? "options" : "append",
|
||||
iso_label, usb_label, TRUE) != NULL)
|
||||
} else if (replace_in_token_data(src, (props->is_conf) ? "options" : "append",
|
||||
iso_label, usb_label, TRUE) != NULL) {
|
||||
uprintf(" Patched %s: '%s' ➔ '%s'\n", src, iso_label, usb_label);
|
||||
modified = TRUE;
|
||||
}
|
||||
}
|
||||
safe_free(iso_label);
|
||||
safe_free(usb_label);
|
||||
|
@ -364,13 +377,18 @@ static void fix_config(const char* psz_fullpath, const char* psz_path, const cha
|
|||
if ((iso_label != NULL) && (usb_label != NULL)) {
|
||||
safe_sprintf(iso_label, MAX_PATH, "cd9660:/dev/iso9660/%s", img_report.label);
|
||||
safe_sprintf(usb_label, MAX_PATH, "msdosfs:/dev/msdosfs/%s", img_report.usb_label);
|
||||
if (replace_in_token_data(src, "set", iso_label, usb_label, TRUE) != NULL)
|
||||
if (replace_in_token_data(src, "set", iso_label, usb_label, TRUE) != NULL) {
|
||||
uprintf(" Patched %s: '%s' ➔ '%s'\n", src, iso_label, usb_label);
|
||||
modified = TRUE;
|
||||
}
|
||||
}
|
||||
safe_free(iso_label);
|
||||
safe_free(usb_label);
|
||||
}
|
||||
|
||||
if (modified)
|
||||
StrArrayAdd(&modified_path, psz_fullpath, TRUE);
|
||||
|
||||
free(src);
|
||||
}
|
||||
|
||||
|
@ -551,6 +569,59 @@ out:
|
|||
return 1;
|
||||
}
|
||||
|
||||
// This upates the MD5SUMS/md5sum.txt file that some distros (Ubuntu, Mint...)
|
||||
// use to validate the media. Because we may alter some of the validated files
|
||||
// to add persistence and whatnot, we need to alter the MD5 list as a result.
|
||||
// The format of the file is expected to always be "<MD5SUM> <FILE_PATH>" on
|
||||
// individual lines.
|
||||
static void update_md5sum(void)
|
||||
{
|
||||
BOOL display_header = TRUE;
|
||||
intptr_t pos;
|
||||
uint32_t i, j, size, md5_size;
|
||||
uint8_t *buf = NULL, sum[16];
|
||||
char md5_path[64], *md5_data = NULL, *str_pos;
|
||||
|
||||
if (!img_report.has_md5sum)
|
||||
return;
|
||||
|
||||
assert(img_report.has_md5sum <= ARRAYSIZE(md5sum_name));
|
||||
if (img_report.has_md5sum > ARRAYSIZE(md5sum_name))
|
||||
return;
|
||||
|
||||
static_sprintf(md5_path, "%s\\%s", psz_extract_dir, md5sum_name[img_report.has_md5sum - 1]);
|
||||
md5_size = read_file(md5_path, (uint8_t**)&md5_data);
|
||||
if (md5_size == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < modified_path.Index; i++) {
|
||||
str_pos = strstr(md5_data, &modified_path.String[i][2]);
|
||||
if (str_pos == NULL)
|
||||
// File is not listed in md5 sums
|
||||
continue;
|
||||
if (display_header) {
|
||||
uprintf("Updating %s:", md5_path);
|
||||
display_header = FALSE;
|
||||
}
|
||||
uprintf("● %s", &modified_path.String[i][2]);
|
||||
pos = str_pos - md5_data;
|
||||
size = read_file(modified_path.String[i], &buf);
|
||||
if (size == 0)
|
||||
continue;
|
||||
HashBuffer(CHECKSUM_MD5, buf, size, sum);
|
||||
free(buf);
|
||||
while ((pos > 0) && (md5_data[pos - 1] != '\n'))
|
||||
pos--;
|
||||
for (j = 0; j < 16; j++) {
|
||||
md5_data[pos + 2 * j] = ((sum[j] >> 4) < 10) ? ('0' + (sum[j] >> 4)) : ('a' - 0xa + (sum[j] >> 4));
|
||||
md5_data[pos + 2 * j + 1] = ((sum[j] & 15) < 10) ? ('0' + (sum[j] & 15)) : ('a' - 0xa + (sum[j] & 15));
|
||||
}
|
||||
}
|
||||
|
||||
write_file(md5_path, md5_data, md5_size);
|
||||
free(md5_data);
|
||||
}
|
||||
|
||||
// Returns 0 on success, nonzero on error
|
||||
static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
|
||||
{
|
||||
|
@ -770,6 +841,7 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
|
|||
}
|
||||
nb_blocks = 0;
|
||||
iso_blocking_status = 0;
|
||||
StrArrayCreate(&modified_path, 8);
|
||||
}
|
||||
|
||||
// First try to open as UDF - fallback to ISO if it failed
|
||||
|
@ -1007,6 +1079,8 @@ out:
|
|||
}
|
||||
if (fd != NULL)
|
||||
fclose(fd);
|
||||
update_md5sum();
|
||||
StrArrayDestroy(&modified_path);
|
||||
} else if (HAS_BOOTMGR(img_report) && enable_ntfs_compression) {
|
||||
// bootmgr might need to be uncompressed: https://github.com/pbatard/rufus/issues/1381
|
||||
RunCommand("compact /u bootmgr* efi/boot/*.efi", dest_dir, TRUE);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Rufus: The Reliable USB Formatting Utility
|
||||
* Copyright © 2011-2019 Pete Batard <pete@akeo.ie>
|
||||
* Copyright © 2011-2020 Pete Batard <pete@akeo.ie>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -333,6 +333,7 @@ typedef struct {
|
|||
BOOLEAN disable_iso;
|
||||
uint16_t winpe;
|
||||
uint8_t has_efi;
|
||||
uint8_t has_md5sum;
|
||||
uint8_t wininst_index;
|
||||
uint8_t has_symlinks;
|
||||
BOOLEAN has_4GB_file;
|
||||
|
@ -533,6 +534,8 @@ extern void DownloadNewVersion(void);
|
|||
extern BOOL DownloadISO(void);
|
||||
extern BOOL IsDownloadable(const char* url);
|
||||
extern BOOL IsShown(HWND hDlg);
|
||||
extern uint32_t read_file(const char* path, uint8_t** buf);
|
||||
extern uint32_t write_file(const char* path, const uint8_t* buf, const uint32_t size);
|
||||
extern char* get_token_data_file_indexed(const char* token, const char* filename, int index);
|
||||
#define get_token_data_file(token, filename) get_token_data_file_indexed(token, filename, 1)
|
||||
extern char* set_token_data_file(const char* token, const char* data, const char* filename);
|
||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -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.10.1633"
|
||||
CAPTION "Rufus 3.10.1634"
|
||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||
|
@ -395,8 +395,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,10,1633,0
|
||||
PRODUCTVERSION 3,10,1633,0
|
||||
FILEVERSION 3,10,1634,0
|
||||
PRODUCTVERSION 3,10,1634,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -414,13 +414,13 @@ BEGIN
|
|||
VALUE "Comments", "https://rufus.ie"
|
||||
VALUE "CompanyName", "Akeo Consulting"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "3.10.1633"
|
||||
VALUE "FileVersion", "3.10.1634"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||
VALUE "OriginalFilename", "rufus-3.10.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "3.10.1633"
|
||||
VALUE "ProductVersion", "3.10.1634"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
49
src/stdio.c
49
src/stdio.c
|
@ -2,7 +2,7 @@
|
|||
* Rufus: The Reliable USB Formatting Utility
|
||||
* Standard User I/O Routines (logging, status, error, etc.)
|
||||
* Copyright © 2020 Mattiwatti <mattiwatti@gmail.com>
|
||||
* Copyright © 2011-2019 Pete Batard <pete@akeo.ie>
|
||||
* Copyright © 2011-2020 Pete Batard <pete@akeo.ie>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -93,6 +93,53 @@ void _uprintfs(const char* str)
|
|||
free(wstr);
|
||||
}
|
||||
|
||||
uint32_t read_file(const char* path, uint8_t** buf)
|
||||
{
|
||||
FILE* fd = fopenU(path, "rb");
|
||||
if (fd == NULL) {
|
||||
uprintf("Error: Can't open file '%s'", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(fd, 0L, SEEK_END);
|
||||
uint32_t size = (uint32_t)ftell(fd);
|
||||
fseek(fd, 0L, SEEK_SET);
|
||||
|
||||
*buf = malloc(size);
|
||||
if (*buf == NULL) {
|
||||
uprintf("Error: Can't allocate %d bytes buffer for file '%s'", size, path);
|
||||
size = 0;
|
||||
goto out;
|
||||
}
|
||||
if (fread(*buf, 1, size, fd) != size) {
|
||||
uprintf("Error: Can't read '%s'", path);
|
||||
size = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
fclose(fd);
|
||||
if (size == 0) {
|
||||
free(*buf);
|
||||
*buf = NULL;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t write_file(const char* path, const uint8_t* buf, const uint32_t size)
|
||||
{
|
||||
uint32_t written;
|
||||
FILE* fd = fopenU(path, "wb");
|
||||
if (fd == NULL) {
|
||||
uprintf("Error: Can't create '%s'", path);
|
||||
return 0;
|
||||
}
|
||||
written = (uint32_t)fwrite(buf, 1, size, fd);
|
||||
if (written != size)
|
||||
uprintf("Error: Can't write '%s'", path);
|
||||
fclose(fd);
|
||||
return written;
|
||||
}
|
||||
|
||||
// Prints a bitstring of a number of any size, with or without leading zeroes.
|
||||
// See also the printbits() and printbitslz() helper macros in rufus.h
|
||||
char *_printbits(size_t const size, void const * const ptr, int leading_zeroes)
|
||||
|
|
Loading…
Reference in a new issue