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
				
			
		
							
								
								
									
										118
									
								
								src/iso.c
									
										
									
									
									
								
							
							
						
						
									
										118
									
								
								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) { | ||||
| 				props->is_grub_cfg = TRUE; | ||||
| 			} else if (safe_stricmp(psz_basename, menu_cfg) == 0) { | ||||
| 			for (i = 0; i < ARRAYSIZE(grub_cfg); i++) { | ||||
| 				if (safe_stricmp(psz_basename, grub_cfg[i]) == 0) | ||||
| 					props->is_grub_cfg = TRUE; | ||||
| 			} | ||||
| 			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
 | ||||
|  | @ -248,7 +254,7 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const | |||
| 		if (safe_stricmp(psz_dirname, efi_dirname) == 0) { | ||||
| 			for (i=0; i<ARRAYSIZE(efi_bootname); i++) | ||||
| 				if (safe_stricmp(psz_basename, efi_bootname[i]) == 0) | ||||
| 					img_report.has_efi |= (2<<i);	// start at 2 since "bootmgr.efi" is bit 0
 | ||||
| 					img_report.has_efi |= (2 << i);	// start at 2 since "bootmgr.efi" is bit 0
 | ||||
| 		} | ||||
| 
 | ||||
| 		// Check for "install.###" in "###/sources/"
 | ||||
|  | @ -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)) { | ||||
| 			// 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) | ||||
| 				"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.
 | ||||
| 				uprintf("  Added 'persistent' kernel option"); | ||||
| 			// 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) | ||||
| 				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.
 | ||||
| 				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); | ||||
| 			} | ||||
| 			else if (replace_in_token_data(src, (props->is_conf) ? "options" : "append", | ||||
| 				iso_label, usb_label, TRUE) != NULL) | ||||
| 					modified = TRUE; | ||||
| 				} | ||||
| 			} 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue