#include <grub/video.h>
#include <grub/acpi.h>
#include <grub/charset.h>
+#include <grub/crypto.h>
#include <grub/ventoy.h>
#include "ventoy_def.h"
int g_tree_view_menu_style = 0;
static grub_file_t g_old_file;
static int g_ventoy_last_entry_back;
+static grub_uint32_t g_ventoy_plat_data;
char g_iso_path[256];
char g_img_swap_tmp_buf[1024];
for (i = 0; i < (int)ARRAY_SIZE(files); i++)
{
- grub_snprintf(buf, sizeof(buf) - 1, "[ -e %s/%s ]", args[0], files[i]);
+ grub_snprintf(buf, sizeof(buf) - 1, "[ -e \"%s/%s\" ]", args[0], files[i]);
if (0 == grub_script_execute_sourcecode(buf))
{
debug("file %s exist, ventoy_compatible YES\n", buf);
return 0;
}
+static int ventoy_arch_mode_init(void)
+{
+ #ifdef GRUB_MACHINE_EFI
+ if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0)
+ {
+ g_ventoy_plat_data = VTOY_PLAT_I386_UEFI;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "ia32");
+ }
+ else if (grub_strcmp(GRUB_TARGET_CPU, "arm64") == 0)
+ {
+ g_ventoy_plat_data = VTOY_PLAT_ARM64_UEFI;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64");
+ }
+ else
+ {
+ g_ventoy_plat_data = VTOY_PLAT_X86_64_UEFI;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "uefi");
+ }
+#else
+ g_ventoy_plat_data = VTOY_PLAT_X86_LEGACY;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "legacy");
+#endif
+
+ return 0;
+}
+
int ventoy_fill_data(grub_uint32_t buflen, char *buffer)
{
int len = GRUB_UINT_MAX;
grub_memcpy(guidstr, &guid, sizeof(guid));
- #if defined (GRUB_MACHINE_EFI)
- puint2[0] = grub_swap_bytes32(0x55454649);
- #else
- puint2[0] = grub_swap_bytes32(0x42494f53);
- #endif
+ puint2[0] = grub_swap_bytes32(g_ventoy_plat_data);
/* Easter egg :) It will be appreciated if you reserve it, but NOT mandatory. */
#pragma GCC diagnostic push
return len;
}
+int ventoy_check_password(const vtoy_password *pwd, int retry)
+{
+ int offset;
+ char input[256];
+ grub_uint8_t md5[16];
+
+ while (retry--)
+ {
+ grub_memset(input, 0, sizeof(input));
+
+ grub_printf("Enter password: ");
+ grub_refresh();
+
+ if (pwd->type == VTOY_PASSWORD_TXT)
+ {
+ grub_password_get(input, 128);
+ if (grub_strcmp(pwd->text, input) == 0)
+ {
+ return 0;
+ }
+ }
+ else if (pwd->type == VTOY_PASSWORD_MD5)
+ {
+ grub_password_get(input, 128);
+ grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input));
+ if (grub_memcmp(pwd->md5, md5, 16) == 0)
+ {
+ return 0;
+ }
+ }
+ else if (pwd->type == VTOY_PASSWORD_SALT_MD5)
+ {
+ offset = (int)grub_snprintf(input, 128, "%s", pwd->salt);
+ grub_password_get(input + offset, 128);
+
+ grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input));
+ if (grub_memcmp(pwd->md5, md5, 16) == 0)
+ {
+ return 0;
+ }
+ }
+
+ grub_printf("Invalid password!\n\n");
+ grub_refresh();
+ }
+
+ return 1;
+}
+
static img_info * ventoy_get_min_iso(img_iterator_node *node)
{
img_info *minimg = NULL;
char *pos = NULL;
char buf[256] = {0};
- grub_snprintf(buf, sizeof(buf), "%s", "[ -f ");
- pos = buf + 5;
+ grub_snprintf(buf, sizeof(buf), "%s", "[ -f \"");
+ pos = buf + 6;
va_start (ap, fmt);
len = grub_vsnprintf(pos, 255, fmt, ap);
va_end (ap);
- grub_strncpy(pos + len, " ]", 2);
+ grub_strncpy(pos + len, "\" ]", 3);
debug("script exec %s\n", buf);
char *pos = NULL;
char buf[256] = {0};
- grub_snprintf(buf, sizeof(buf), "%s", "[ -d ");
- pos = buf + 5;
+ grub_snprintf(buf, sizeof(buf), "%s", "[ -d \"");
+ pos = buf + 6;
va_start (ap, fmt);
len = grub_vsnprintf(pos, 255, fmt, ap);
va_end (ap);
- grub_strncpy(pos + len, " ]", 2);
+ grub_strncpy(pos + len, "\" ]", 3);
debug("script exec %s\n", buf);
cmd_para *cur = NULL;
ventoy_env_init();
-
-#ifdef GRUB_MACHINE_EFI
- if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0)
- {
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "ia32");
- }
- else if (grub_strcmp(GRUB_TARGET_CPU, "arm64") == 0)
- {
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64");
- }
- else
- {
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "uefi");
- }
-#else
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "legacy");
-#endif
+
+ ventoy_arch_mode_init();
for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++)
{
#define VTOY_WARNING "!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
+#define VTOY_PLAT_I386_UEFI 0x49413332
+#define VTOY_PLAT_ARM64_UEFI 0x41413634
+#define VTOY_PLAT_X86_64_UEFI 0x55454649
+#define VTOY_PLAT_X86_LEGACY 0x42494f53
+
#define VTOY_PWD_CORRUPTED(err) \
{\
grub_printf("\n\n Password corrupted, will reboot after 5 seconds.\n\n"); \
struct image_list *next;
}image_list;
+#define VTOY_PASSWORD_NONE 0
+#define VTOY_PASSWORD_TXT 1
+#define VTOY_PASSWORD_MD5 2
+#define VTOY_PASSWORD_SALT_MD5 3
+
typedef struct vtoy_password
+{
+ int type;
+ char text[128];
+ char salt[64];
+ grub_uint8_t md5[16];
+}vtoy_password;
+
+typedef struct menu_password
{
int pathlen;
char isopath[256];
- grub_uint8_t sha256[32];
- struct vtoy_password *next;
-}vtoy_password;
+ vtoy_password password;
+
+ struct menu_password *next;
+}menu_password;
extern int g_ventoy_menu_esc;
extern int g_ventoy_suppress_esc;
grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args);
-int ventoy_check_password(const grub_uint8_t *pwdsha256, int retry);
+int ventoy_check_password(const vtoy_password *pwd, int retry);
#endif /* __VENTOY_DEF_H__ */
char g_arch_mode_suffix[64];
static char g_iso_disk_name[128];
-static grub_uint8_t g_boot_pwd = 0;
-static grub_uint8_t g_boot_sha256[32];
+static vtoy_password g_boot_pwd;
static install_template *g_install_template_head = NULL;
static dud *g_dud_head = NULL;
-static vtoy_password *g_pwd_head = NULL;
+static menu_password *g_pwd_head = NULL;
static persistence_config *g_persistence_head = NULL;
static menu_alias *g_menu_alias_head = NULL;
static menu_class *g_menu_class_head = NULL;
return 0;
}
+static int ventoy_plugin_parse_pwdstr(char *pwdstr, vtoy_password *pwd)
+{
+ int i;
+ int len;
+ char ch;
+ char *pos;
+ char bytes[3];
+ vtoy_password tmpPwd;
+
+ len = (int)grub_strlen(pwdstr);
+ if (len > 64)
+ {
+ if (NULL == pwd) grub_printf("Password too long %d\n", len);
+ return 1;
+ }
+
+ grub_memset(&tmpPwd, 0, sizeof(tmpPwd));
+
+ if (grub_strncmp(pwdstr, "txt#", 4) == 0)
+ {
+ tmpPwd.type = VTOY_PASSWORD_TXT;
+ grub_snprintf(tmpPwd.text, sizeof(tmpPwd.text), "%s", pwdstr + 4);
+ }
+ else if (grub_strncmp(pwdstr, "md5#", 4) == 0)
+ {
+ if ((len - 4) == 32)
+ {
+ for (i = 0; i < 16; i++)
+ {
+ bytes[0] = pwdstr[4 + i * 2];
+ bytes[1] = pwdstr[4 + i * 2 + 1];
+ bytes[2] = 0;
+
+ if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1]))
+ {
+ tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16);
+ }
+ else
+ {
+ if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i);
+ return 1;
+ }
+ }
+ tmpPwd.type = VTOY_PASSWORD_MD5;
+ }
+ else if ((len - 4) > 32)
+ {
+ pos = grub_strchr(pwdstr + 4, '#');
+ if (!pos)
+ {
+ if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr);
+ return 1;
+ }
+
+ if (len - 1 - (int)(long)(pos - pwdstr) != 32)
+ {
+ if (NULL == pwd) grub_printf("Invalid md5 salt password format %s\n", pwdstr);
+ return 1;
+ }
+
+ ch = *pos;
+ *pos = 0;
+ grub_snprintf(tmpPwd.salt, sizeof(tmpPwd.salt), "%s", pwdstr + 4);
+ *pos = ch;
+
+ pos++;
+ for (i = 0; i < 16; i++)
+ {
+ bytes[0] = pos[i * 2];
+ bytes[1] = pos[i * 2 + 1];
+ bytes[2] = 0;
+
+ if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1]))
+ {
+ tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16);
+ }
+ else
+ {
+ if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i);
+ return 1;
+ }
+ }
+
+ tmpPwd.type = VTOY_PASSWORD_SALT_MD5;
+ }
+ else
+ {
+ if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr);
+ return 1;
+ }
+ }
+ else
+ {
+ if (NULL == pwd) grub_printf("Invalid password format %s\n", pwdstr);
+ return 1;
+ }
+
+ if (pwd)
+ {
+ grub_memcpy(pwd, &tmpPwd, sizeof(tmpPwd));
+ }
+
+ return 0;
+}
+
static int ventoy_plugin_pwd_entry(VTOY_JSON *json, const char *isodisk)
{
- int i = 0;
- int len = 0;
const char *iso = NULL;
const char *pwd = NULL;
VTOY_JSON *pNode = NULL;
VTOY_JSON *pCNode = NULL;
- vtoy_password *node = NULL;
- vtoy_password *tail = NULL;
- vtoy_password *next = NULL;
- char bytes[3];
+ menu_password *node = NULL;
+ menu_password *tail = NULL;
+ menu_password *next = NULL;
(void)isodisk;
{
if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0)
{
- len = (int)grub_strlen(pNode->unData.pcStrVal);
- if (len == 64)
- {
- g_boot_pwd = 1;
- for (i = 0; i < 32; i++)
- {
- bytes[0] = pNode->unData.pcStrVal[i * 2];
- bytes[1] = pNode->unData.pcStrVal[i * 2 + 1];
- bytes[2] = 0;
- g_boot_sha256[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16);
- }
- }
+ ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, &g_boot_pwd);
}
else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0)
{
pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd");
if (iso && pwd && iso[0] == '/')
{
- node = grub_zalloc(sizeof(vtoy_password));
+ node = grub_zalloc(sizeof(menu_password));
if (node)
{
node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
- len = (int)grub_strlen(pwd);
- if (len != 64)
+
+ if (ventoy_plugin_parse_pwdstr((char *)pwd, &(node->password)))
{
grub_free(node);
continue;
}
-
- for (i = 0; i < 32; i++)
- {
- bytes[0] = pwd[i * 2];
- bytes[1] = pwd[i * 2 + 1];
- bytes[2] = 0;
- node->sha256[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16);
- }
if (g_pwd_head)
{
static int ventoy_plugin_pwd_check(VTOY_JSON *json, const char *isodisk)
{
- int len = 0;
const char *iso = NULL;
const char *pwd = NULL;
VTOY_JSON *pNode = NULL;
{
if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0)
{
- len = (int)grub_strlen(pNode->unData.pcStrVal);
- if (len != 64)
+ if (0 == ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, NULL))
{
- grub_printf("Invalid bootpwd len :%d\n", len);
+ grub_printf("bootpwd:<%s>\n", pNode->unData.pcStrVal);
}
else
{
- grub_printf("bootpwd:<%s>\n", pNode->unData.pcStrVal);
+ grub_printf("Invalid bootpwd.\n");
}
}
else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0)
{
+ grub_printf("\n");
for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext)
{
if (pCNode->enDataType != JSON_TYPE_OBJECT)
{
pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd");
- len = (int)grub_strlen(pwd);
- if (len != 64)
+ if (0 == ventoy_plugin_parse_pwdstr((char *)pwd, NULL))
{
- grub_printf("Invalid sha256 len <%d>\n", len);
+ grub_printf("file:<%s> [OK]\n", iso);
+ grub_printf("pwd:<%s>\n\n", pwd);
}
else
{
- grub_printf("file:<%s> [OK]\n", iso);
- grub_printf("pwd:<%s>\n\n", pwd);
+ grub_printf("Invalid password for <%s>\n", iso);
}
}
+ else
+ {
+ grub_printf("<%s%s> not found\n", isodisk, iso);
+ }
}
else
{
- grub_printf("No file found\n");
+ grub_printf("No file item found in json.\n");
}
}
}
{
grub_printf("iso:<%s> [OK]\n", isof);
- grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck %s%s", isodisk, isof);
+ grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck \"%s%s\"", isodisk, isof);
grub_script_execute_sourcecode(cmd);
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vtisocheck)/%s", orgf);
grub_free(buf);
- if (g_boot_pwd)
- {
- grub_printf("\n\n\n\n");
- if (ventoy_check_password(g_boot_sha256, 3))
+ if (g_boot_pwd.type)
+ {
+ grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
+ if (ventoy_check_password(&g_boot_pwd, 3))
{
grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
grub_refresh();
return 0;
}
-static const grub_uint8_t * ventoy_plugin_get_password(const char *isopath)
+static const vtoy_password * ventoy_plugin_get_password(const char *isopath)
{
int len;
- vtoy_password *node = NULL;
+ menu_password *node = NULL;
if ((!g_pwd_head) || (!isopath))
{
{
if (node->pathlen == len && grub_strncmp(isopath, node->isopath, len) == 0)
{
- return node->sha256;
+ return &(node->password);
}
}
return NULL;
}
-int ventoy_check_password(const grub_uint8_t *pwdsha256, int retry)
-{
- char input[128];
- grub_uint8_t sha256[32];
-
- while (retry--)
- {
- grub_memset(input, 0, sizeof(input));
-
- grub_printf("Enter password: ");
- grub_refresh();
- grub_password_get(input, sizeof(input));
-
- grub_crypto_hash(GRUB_MD_SHA256, sha256, input, grub_strlen(input));
-
- if (grub_memcmp(pwdsha256, sha256, 32) == 0)
- {
- return 0;
- }
- else
- {
- grub_printf("Invalid password!\n\n");
- grub_refresh();
- }
- }
-
- return 1;
-}
-
grub_err_t ventoy_cmd_check_password(grub_extcmd_context_t ctxt, int argc, char **args)
{
int ret;
- const grub_uint8_t *sha256 = NULL;
+ const vtoy_password *pwd = NULL;
(void)ctxt;
(void)argc;
- sha256 = ventoy_plugin_get_password(args[0]);
- if (sha256)
+ pwd = ventoy_plugin_get_password(args[0]);
+ if (pwd)
{
- if (0 == ventoy_check_password(sha256, 1))
+ if (0 == ventoy_check_password(pwd, 1))
{
ret = 1;
}
grub_file_t file;
char cmdbuf[128];
- grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback wimiso %s", filepath);
+ grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback wimiso \"%s\"", filepath);
grub_script_execute_sourcecode(cmdbuf);
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(wimiso)/boot/boot.wim");
div:
crypto:
part_bsd: part_msdos
-ventoy: ext2 fshelp font crypto exfat udf extcmd normal video gcry_sha256 gcry_sha1 iso9660
+ventoy: ext2 fshelp font crypto gcry_md5 exfat udf extcmd normal video gcry_sha1 iso9660
gcry_sha512: crypto
password: crypto normal
fshelp:
fi
if [ -n "${vtdebug_flag}" ]; then
- echo ISO is $vtoy_os
+ echo ISO is "$vtoy_os"
fi
}
function vt_check_compatible_pe {
#Check for PE without external tools
- if [ -f $1/HBCD_PE.ini ]; then
+ if [ -f "$1/HBCD_PE.ini" ]; then
set ventoy_compatible=YES
fi
}
ventoy_img_easyos
elif [ -e (vtimghd,1)/volumio.initrd ]; then
ventoy_img_volumio
- elif vt_str_begin $vtImgHd1Label "LAKKA"; then
+ elif vt_str_begin "$vtImgHd1Label" "LAKKA"; then
ventoy_img_openelec lakka
- elif vt_str_begin $vtImgHd1Label "LIBREELEC"; then
+ elif vt_str_begin "$vtImgHd1Label" "LIBREELEC"; then
ventoy_img_openelec LibreELEC
- elif vt_str_begin $vtImgHd1Label "paldo-live"; then
+ elif vt_str_begin "$vtImgHd1Label" "paldo-live"; then
ventoy_img_paldo
- elif vt_str_begin $vtImgHostname "freedombox"; then
+ elif vt_str_begin "$vtImgHostname" "freedombox"; then
ventoy_img_freedombox
- elif vt_str_begin $vtImgHd1Label "BATOCERA"; then
+ elif vt_str_begin "$vtImgHd1Label" "BATOCERA"; then
ventoy_img_batocera
elif [ "$vtImgHd2Label" = "RECALBOX" ]; then
ventoy_img_recalbox
if [ "$grub_platform" = "pc" ]; then
set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net"
-else
- set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI www.ventoy.net"
+else
if [ "$grub_cpu" = "i386" ]; then
set VTOY_EFI_ARCH=ia32
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION IA32 www.ventoy.net"
elif [ "$grub_cpu" = "arm64" ]; then
set VTOY_EFI_ARCH=aa64
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION AA64 www.ventoy.net"
else
set VTOY_EFI_ARCH=x64
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI www.ventoy.net"
fi
fi
if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then
clear
vt_load_plugin $vtoy_iso_part
+ clear
fi
if [ -n "$VTOY_MENU_TIMEOUT" ]; then
crypto:
part_bsd: part_msdos
cs5536:
-ventoy: ext2 fshelp font crypto exfat udf extcmd normal video gcry_sha256 gcry_sha1 iso9660
+ventoy: ext2 fshelp font crypto gcry_md5 exfat udf extcmd normal video gcry_sha1 iso9660
gcry_sha512: crypto
password: crypto normal
fshelp:
part_bsd: part_msdos
cs5536: pci
biosdisk:
-ventoy: ext2 fshelp font crypto exfat udf extcmd normal video gcry_sha256 gcry_sha1 iso9660 acpi
+ventoy: ext2 fshelp font crypto gcry_md5 exfat udf extcmd normal video gcry_sha1 iso9660 acpi
lsapm:
gcry_sha512: crypto
password: crypto normal
crypto:
part_bsd: part_msdos
cs5536:
-ventoy: ext2 fshelp font crypto exfat udf extcmd normal video gcry_sha256 gcry_sha1 iso9660
+ventoy: ext2 fshelp font crypto gcry_md5 exfat udf extcmd normal video gcry_sha1 iso9660
gcry_sha512: crypto
password: crypto normal
fshelp:
dd status=none conv=fsync if=${DISK} skip=2040 bs=512 count=8 of=./rsvdata.bin
if [ "$PART1_TYPE" = "EE" ]; then
- vtdebug "This is GPT partition style ..."
+ vtdebug "This is GPT partition style ..."
+ echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92
xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
else
* UEFI Secure Boot supported (1.0.07+)
* Persistence supported (1.0.11+)
* Windows/Linux auto installation supported (1.0.09+)
+* FAT32/exFAT/NTFS/UDF/XFS/Ext2(3)(4) supported for main partition
* ISO files larger than 4GB supported
* Native boot menu style for Legacy & UEFI
* Most type of OS supported, 580+ iso files tested
* Linux vDisk boot supported
* Not only boot but also complete installation process
-* Menu can be switched between List mode and TreeView mode dynamically
+* Menu dynamically switchable between List/TreeView mode
* "Ventoy Compatible" concept
* Plugin Framework
* Injection files to runtime enviroment