diff --git a/src/iso.c b/src/iso.c index b667555b..8019fbb0 100644 --- a/src/iso.c +++ b/src/iso.c @@ -887,7 +887,6 @@ void GetGrubVersion(char* buf, size_t buf_size) const char* grub_version_str[] = { "GRUB version %s", "GRUB version %s" }; const char* grub_debug_is_enabled_str = "grub_debug_is_enabled"; const size_t max_string_size = 32; // The strings above *MUST* be no longer than this value - char *p, unauthorized[] = {'<', '>', ':', '|', '*', '?', '\\', '/'}; size_t i, j; BOOL has_grub_debug_is_enabled = FALSE; @@ -902,13 +901,9 @@ void GetGrubVersion(char* buf, size_t buf_size) has_grub_debug_is_enabled = TRUE; } } - // Sanitize the string - for (p = &img_report.grub2_version[0]; *p; p++) { - for (i = 0; i < sizeof(unauthorized); i++) { - if (*p == unauthorized[i]) - *p = '_'; - } - } + + uprintf(" Reported Grub version: %s", img_report.grub2_version); + // "KASPERSKYYYYYY!!!..." (https://github.com/pbatard/rufus/issues/467) // But seriously, these guys should know better than "security" through obscurity... if (img_report.grub2_version[0] == '0') @@ -931,16 +926,33 @@ void GetGrubVersion(char* buf, size_t buf_size) // if [ -e /boot/grub2/i386-pc/normal.mod ]; then set prefix = ... // you still must embed 'configfile.mod' and 'normal.mod' in 'core.img' in order // to do that, which ends up tripling the file size... - // Also, as mentioned above, Fedora have started applying *BREAKING* patches - // willy-nilly, without bothering to alter the GRUB version string. - // Soooo, since the universe is conspiring against us and since we already have - // a facility for it, we'll use it to dowload the relevant 'core.img' by - // appending a missing version suffix as needed... + // Also, as mentioned above, Fedora, Ubuntu and others have started applying + // *BREAKING* patches willy-nilly, without bothering to alter the GRUB version + // string. And it gets worse with 2.06 since there are patches we can't detect + // that will produce "452: out of range pointer" whether they are applied OR NOT + // (meaning that if you use a patched GRUB 2.06 with unpatched GRUB 2.06 modules + // you will get the error, and if you use unpatched with patched modules, you + // will also get the error). + // Soooo, since the universe, and project maintainers who do not REALISE that + // NOT RELEASING IN A TIMELY MANNER *DOES* HAVE VERY NEGATIVE CONSEQUENCES FOR + // END USERS, are conspiring against us, and since we already have a facility + // for it, we'll use it to dowload the relevant 'core.img' by appending a missing + // version suffix as needed. Especially, if GRUB only identifies itself as '2.06' + // we'll append a sanitized version of the ISO label to try to differentiate + // between GRUB 2.06 incompatible versions... if (img_report.grub2_version[0] != 0) { - if (has_grub_debug_is_enabled) - strcat(img_report.grub2_version, "-fedora"); + // Make sure we append '-nonstandard' and '-gdie' before the sanitized label. + BOOL append_label = (safe_strcmp(img_report.grub2_version, "2.06") == 0); + // Must be in the same order as we have on the server if (img_report.has_grub2 > 1) - strcat(img_report.grub2_version, "-nonstandard"); + safe_strcat(img_report.grub2_version, sizeof(img_report.grub2_version), "-nonstandard"); + if (has_grub_debug_is_enabled) + safe_strcat(img_report.grub2_version, sizeof(img_report.grub2_version), "-gdie"); + if (append_label) { + safe_strcat(img_report.grub2_version, sizeof(img_report.grub2_version), "-"); + safe_strcat(img_report.grub2_version, sizeof(img_report.grub2_version), img_report.label); + } + sanitize_label(img_report.grub2_version); } } @@ -1188,9 +1200,7 @@ out: free(buf); DeleteFileU(path); } - if (img_report.grub2_version[0] != 0) { - uprintf(" Detected Grub version: %s", img_report.grub2_version); - } else { + if (img_report.grub2_version[0] == 0) { uprintf(" Could not detect Grub version"); img_report.has_grub2 = 0; } diff --git a/src/parser.c b/src/parser.c index f9d15c21..fb312102 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1480,3 +1480,67 @@ void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str free(oid); return data; } + +/* + * Sanitize an ISO volume label or GRUB version, so that we can use it for bootloader lookup. + * Note that this call modifies the string passed as parameter. + */ +int sanitize_label(char* label) +{ + // Notice: Do not add "-beta" to this list as we have existing GRUB lookups for + // "grub-2.02-beta2" and stuff... + static const char* remove[] = { "-i386", "-i686", "-amd64", "-x86-64", ".x86-64", + "-x64", "-armhf", "-arm64", "-aarch64", "-32-bit", "-64-bit", "-32bit", "-64bit", + "-intel", "-cd", "-dvd", "-standard", "-live", "-install", "-server", "-net", + "-desktop", "-lts", "-studio", "-baseos", "-kde", "-xfce", "-lxde", "-gnome", + "-mate", "-unstable", "-debug", "-release", "-final", "-stream", "-cinnamon", + "-cinn", "-leap", "-tumbleweed", "-budgie", "-ws", "-iot", "-ostree", ".iso" + }; + size_t i, len; + char *s; + + len = strlen(label); + for (i = 0; i < len; i++) { + char c = label[i]; + // Convert to lowercase + if (c >= 'A' && c <= 'Z') + c += 0x20; + // Convert non alphanum (except '.') to dash + if ((c < '0' && c != '.') || (c > '9' && c < 'a') || (c > 'z')) + c = '-'; + label[i] = c; + } + + // Remove all leading '-' + for (i = 0; i < len && label[i] == '-'; i++); + if (i != 0) + memcpy(label, &label[i], len - i); + len = strlen(label); + if (len <= 1) + return -1; + + // Remove all trailing '-' + for (i = len - 1; i > 0 && label[i] == '-'; i--) + label[i] = 0; + len = strlen(label); + if (len <= 1) + return -1; + + // Remove all duplicate '-' (non-optimized!) + for (i = 0; len >= 2 && i < len - 2; i++) { + if (label[i] == '-' && label[i + 1] == '-') { + memcpy(&label[i + 1], &label[i + 2], len - i - 1); + len--; + i--; + } + } + + // Remove specific substrings + for (i = 0; i < ARRAYSIZE(remove); i++) { + s = strstr(label, remove[i]); + if (s != NULL) + strcpy(s, &s[strlen(remove[i])]); + } + + return 0; +} diff --git a/src/rufus.c b/src/rufus.c index 336cd1c9..8e900dc1 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -1118,7 +1118,7 @@ static void DisplayISOProps(void) PRINT_ISO_PROP(HAS_KOLIBRIOS(img_report), " Uses: KolibriOS"); PRINT_ISO_PROP(HAS_REACTOS(img_report), " Uses: ReactOS"); PRINT_ISO_PROP(img_report.has_grub4dos, " Uses: Grub4DOS"); - PRINT_ISO_PROP(img_report.has_grub2, " Uses: GRUB2"); + PRINT_ISO_PROP(img_report.has_grub2, " Uses: GRUB2 (%s)", img_report.grub2_version); if (img_report.has_efi == 0x80) uprintf(" Uses: EFI (through '%s')", img_report.efi_img_path); else @@ -1430,7 +1430,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param) const char* ldlinux = "ldlinux"; const char* syslinux = "syslinux"; const char* ldlinux_ext[3] = { "sys", "bss", "c32" }; - char tmp[MAX_PATH], tmp2[MAX_PATH]; + char tmp[MAX_PATH], tmp2[MAX_PATH], c; syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0; safe_free(grub2_buf); @@ -1658,23 +1658,17 @@ static DWORD WINAPI BootCheckThread(LPVOID param) static_sprintf(tmp, "%s-%s", grub, img_report.grub2_version); IGNORE_RETVAL(_mkdir(tmp)); IGNORE_RETVAL(_chdir(tmp)); - static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, img_report.grub2_version, core_img); - grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE); - if ((grub2_len == 0) && (DownloadStatus == 404)) { - // Manjaro (always them!) are using "2.03.5" as identifier, so we must detect first dot... - BOOL first_dot = TRUE; - // Couldn't locate the file on the server => try to download without the version extra - uprintf("Extended version was not found, trying main version..."); - static_strcpy(tmp2, img_report.grub2_version); - // Isolate the #.### part - for (i = 0; ((tmp2[i] >= '0') && (tmp2[i] <= '9')) || ((tmp2[i] == '.') && first_dot); i++) { - if (tmp2[i] == '.') - first_dot = FALSE; - } - tmp2[i] = 0; - static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, tmp2, core_img); - grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE); + // The following loops through the grub2 version (which may have the ISO label appended) + // and breaks it according to '.' or '-' until it finds a match on the server. + // + for (i = (int)strlen(img_report.grub2_version), grub2_len = 0; i > 0 && grub2_len <= 0; i--) { + c = img_report.grub2_version[i]; + if (c != 0 && c != '.' && c != '-') + continue; + img_report.grub2_version[i] = 0; static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, img_report.grub2_version, core_img); + grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE); + img_report.grub2_version[i] = c; } if (grub2_len <= 0) { PrintInfo(0, MSG_195, "Grub2"); @@ -3829,7 +3823,25 @@ extern int TestChecksum(void); // Ctrl-T => Alternate Test mode that doesn't require a full rebuild if ((ctrl_without_focus || ((GetKeyState(VK_CONTROL) & 0x8000) && (msg.message == WM_KEYDOWN))) && (msg.wParam == 'T')) { - TestChecksum(); + char tmp[256], c; + char label[256] = "2.06-blah-bli-ubutnu.23.2.1-blo"; + size_t i; + for (i = strlen(label); i > 0; i--) { + c = label[i]; + if (c != 0 && c != '.' && c != '-') + continue; + label[i] = 0; + static_sprintf(tmp, "%s/%s-%s/core.img", FILES_URL, "grub", label); + uprintf(tmp); + label[i] = c; + } +// TestChecksum(); + //FILE* fd = fopen("D:\\ISOs\\vol.txt", "r"); + //while (fgets(label, 256, fd) != NULL) { + // sanitize_label(label); + // uprintf(label); + //} + //fclose(fd); continue; } #endif diff --git a/src/rufus.h b/src/rufus.h index a65e8ffe..05209daf 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -403,7 +403,7 @@ typedef struct { uint16_t sl_version; // Syslinux/Isolinux version char sl_version_str[12]; char sl_version_ext[32]; - char grub2_version[64]; + char grub2_version[192]; } RUFUS_IMG_REPORT; /* Isolate the Syslinux version numbers */ @@ -676,6 +676,7 @@ extern char* replace_in_token_data(const char* filename, const char* token, cons extern char* replace_char(const char* src, const char c, const char* rep); extern void parse_update(char* buf, size_t len); extern void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str, uint8_t asn1_type, size_t* data_len); +extern int sanitize_label(char* label); extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid); extern char* GetSignatureName(const char* path, const char* country_code, BOOL bSilent); extern uint64_t GetSignatureTimeStamp(const char* path); diff --git a/src/rufus.rc b/src/rufus.rc index 62087f41..699cbe40 100644 --- a/src/rufus.rc +++ b/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 4.0.2038" +CAPTION "Rufus 4.0.2039" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -392,8 +392,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,0,2038,0 - PRODUCTVERSION 4,0,2038,0 + FILEVERSION 4,0,2039,0 + PRODUCTVERSION 4,0,2039,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -411,13 +411,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.0.2038" + VALUE "FileVersion", "4.0.2039" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.0.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.0.2038" + VALUE "ProductVersion", "4.0.2039" END END BLOCK "VarFileInfo"