Support BSD style for .md5/.sha1/.sh256/.sha512 checksum file.

Support VENTOY_CHECKSUM file for checksum file.
(#2112)
This commit is contained in:
longpanda 2023-01-01 00:31:08 +08:00
parent b4bb6efd3c
commit c6bd857cbe
4 changed files with 410 additions and 50 deletions

View File

@ -115,6 +115,92 @@ int ventoy_str_all_digit(const char *str)
return 1;
}
int ventoy_str_all_alnum(const char *str)
{
if (NULL == str || 0 == *str)
{
return 0;
}
while (*str)
{
if (!grub_isalnum(*str))
{
return 0;
}
}
return 1;
}
int ventoy_str_len_alnum(const char *str, int len)
{
int i;
int slen;
if (NULL == str || 0 == *str)
{
return 0;
}
slen = grub_strlen(str);
if (slen <= len)
{
return 0;
}
for (i = 0; i < len; i++)
{
if (!grub_isalnum(str[i]))
{
return 0;
}
}
if (str[len] == 0 || grub_isspace(str[len]))
{
return 1;
}
return 0;
}
char * ventoy_str_basename(char *path)
{
char *pos = NULL;
pos = grub_strrchr(path, '/');
if (pos)
{
pos++;
}
else
{
pos = path;
}
return pos;
}
int ventoy_str_chrcnt(const char *str, char c)
{
int n = 0;
if (str)
{
while (*str)
{
if (*str == c)
{
n++;
}
str++;
}
}
return n;
}
int ventoy_strcmp(const char *pattern, const char *str)
{
while (*pattern && *str)
@ -146,6 +232,14 @@ int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n)
return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str;
}
grub_err_t ventoy_env_int_set(const char *name, int value)
{
char buf[16];
grub_snprintf(buf, sizeof(buf), "%d", value);
return grub_env_set(name, buf);
}
void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid)
{
int i;

View File

@ -158,6 +158,8 @@ const char *g_menu_prefix[img_type_max] =
"iso", "wim", "efi", "img", "vhd", "vtoy"
};
static const char *g_lower_chksum_name[] = { "md5", "sha1", "sha256", "sha512" };
static int g_vtoy_secondary_need_recover = 0;
static int g_vtoy_load_prompt = 0;
@ -6292,6 +6294,274 @@ static grub_err_t ventoy_cmd_load_menu_lang(grub_extcmd_context_t ctxt, int argc
VENTOY_CMD_RETURN(0);
}
static grub_err_t ventoy_cmd_vtoychksum_exist(grub_extcmd_context_t ctxt, int argc, char **args)
{
int cnt;
char c;
char *pos = NULL;
(void)ctxt;
(void)argc;
cnt = ventoy_str_chrcnt(args[1], '/');
if (cnt > 1)
{
pos = grub_strrchr(args[1], '/');
c = *pos;
*pos = 0;
if (ventoy_check_file_exist("%s%s/VENTOY_CHECKSUM", args[0], args[1]))
{
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
*pos = c;
}
if (ventoy_check_file_exist("%s/VENTOY_CHECKSUM", args[0]))
{
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
return 1;
}
static int ventoy_chksum_pathcmp(int chktype, char *rlpath, char *rdpath)
{
char *pos1 = NULL;
char *pos2 = NULL;
if (chktype == 2)
{
pos1 = ventoy_str_basename(rlpath);
pos2 = ventoy_str_basename(rdpath);
return grub_strcmp(pos1, pos2);
}
else if (chktype == 3 || chktype == 4)
{
if (grub_strcmp(rlpath, rdpath) == 0 || grub_strcmp(rlpath + 1, rdpath) == 0)
{
return 0;
}
}
return 1;
}
static int ventoy_find_checksum
(
grub_file_t file,
const char *uname,
int retlen,
char *path,
int chktype,
char *chksum
)
{
int ulen;
char *pos = NULL;
char *pos1 = NULL;
char *pos2 = NULL;
char *buf = NULL;
char *currline = NULL;
char *nextline = NULL;
ulen = (int)grub_strlen(uname);
/* read file to buffer */
buf = grub_malloc(file->size + 4);
if (!buf)
{
return 1;
}
grub_file_read(file, buf, file->size);
buf[file->size] = 0;
/* parse each line */
for (currline = buf; currline; currline = nextline)
{
nextline = ventoy_get_line(currline);
VTOY_SKIP_SPACE(currline);
if (grub_strncasecmp(currline, uname, ulen) == 0)
{
pos = grub_strchr(currline, '=');
pos1 = grub_strchr(currline, '(');
pos2 = grub_strchr(currline, ')');
if (pos && pos1 && pos2)
{
*pos2 = 0;
if (ventoy_chksum_pathcmp(chktype, path, pos1 + 1) == 0)
{
VTOY_SKIP_SPACE_NEXT(pos, 1);
grub_memcpy(chksum, pos, retlen);
goto end;
}
}
}
else if (ventoy_str_len_alnum(currline, retlen))
{
VTOY_SKIP_SPACE_NEXT_EX(pos, currline, retlen);
if (ventoy_chksum_pathcmp(chktype, path, pos) == 0)
{
grub_memcpy(chksum, currline, retlen);
goto end;
}
}
}
end:
grub_free(buf);
return 0;
}
static int ventoy_check_chkfile(const char *isopart, char *path, const char *lchkname, grub_file_t *pfile)
{
int ret = 0;
int cnt = 0;
char c = 0;
char *pos = NULL;
grub_file_t file = NULL;
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s.%s", isopart, path, lchkname);
if (file)
{
VTOY_GOTO_END(1);
}
cnt = ventoy_str_chrcnt(path, '/');
if (cnt > 1)
{
pos = grub_strrchr(path, '/');
c = *pos;
*pos = 0;
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s/VENTOY_CHECKSUM", isopart, path);
if (file)
{
*pos = c;
VTOY_GOTO_END(2);
}
*pos = c;
}
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/VENTOY_CHECKSUM", isopart);
if (file)
{
ret = (cnt > 1) ? 3 : 4;
}
end:
if (pfile)
{
*pfile = file;
}
else
{
check_free(file, grub_file_close);
}
return ret;
}
static grub_err_t ventoy_cmd_cmp_checksum(grub_extcmd_context_t ctxt, int argc, char **args)
{
int index = 0;
int chktype = 0;
char *pos = NULL;
grub_file_t file = NULL;
const char *calc_value = NULL;
const char *isopart = NULL;
char fchksum[64];
char readchk[256] = {0};
char filebuf[512] = {0};
int retlen[] = { 32, 40, 64, 128 };
char uchkname[16];
(void)ctxt;
index = (int)grub_strtol(args[0], NULL, 10);
if (argc != 2 || index < 0 || index >= (int)ARRAY_SIZE(retlen))
{
return 1;
}
grub_strncpy(uchkname, g_lower_chksum_name[index], sizeof(uchkname));
ventoy_str_toupper(uchkname);
isopart = grub_env_get("vtoy_iso_part");
calc_value = grub_env_get("VT_LAST_CHECK_SUM");
chktype = ventoy_check_chkfile(isopart, args[1], g_lower_chksum_name[index], &file);
if (chktype <= 0)
{
grub_printf("\n\nNo checksum file found.\n");
goto end;
}
if (chktype == 1)
{
grub_snprintf(fchksum, sizeof(fchksum), ".%s", g_lower_chksum_name[index]);
grub_memset(filebuf, 0, sizeof(filebuf));
grub_file_read(file, filebuf, 511);
pos = grub_strchr(filebuf, '=');
if (pos)
{
VTOY_SKIP_SPACE_NEXT(pos, 1);
grub_memcpy(readchk, pos, retlen[index]);
}
else
{
grub_memcpy(readchk, filebuf, retlen[index]);
}
}
else if (chktype == 3 || chktype == 4)
{
grub_snprintf(fchksum, sizeof(fchksum), "global VENTOY_CHECKSUM");
ventoy_find_checksum(file, uchkname, retlen[index], args[1], chktype, readchk);
if (readchk[0] == 0)
{
grub_printf("\n\n%s value not found in %s.\n", uchkname, fchksum);
goto end;
}
}
else
{
grub_snprintf(fchksum, sizeof(fchksum), "local VENTOY_CHECKSUM");
ventoy_find_checksum(file, uchkname, retlen[index], args[1], chktype, readchk);
if (readchk[0] == 0)
{
grub_file_close(file);
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/VENTOY_CHECKSUM", isopart);
if (file)
{
grub_snprintf(fchksum, sizeof(fchksum), "global VENTOY_CHECKSUM");
ventoy_find_checksum(file, uchkname, retlen[index], args[1], 3, readchk);
if (readchk[0] == 0)
{
grub_printf("\n\n%s value not found in both local and global VENTOY_CHECKSUM.\n", uchkname);
goto end;
}
}
}
}
if (grub_strcasecmp(calc_value, readchk) == 0)
{
grub_printf("\n\nCheck %s value with %s file. [ SUCCESS ]\n", uchkname, fchksum);
}
else
{
grub_printf("\n\nCheck %s value with %s file. [ ERROR ]\n", uchkname, fchksum);
grub_printf("The %s value in %s file is:\n%s\n", uchkname, fchksum, readchk);
}
end:
grub_refresh();
check_free(file, grub_file_close);
VENTOY_CMD_RETURN(0);
}
static const char * ventoy_menu_lang_read_hook(struct grub_env_var *var, const char *val)
{
@ -6522,6 +6792,8 @@ static cmd_para ventoy_cmds[] =
{ "vt_load_menu_lang", ventoy_cmd_load_menu_lang, 0, NULL, "", "", NULL },
{ "vt_init_menu_lang", ventoy_cmd_init_menu_lang, 0, NULL, "", "", NULL },
{ "vt_cur_menu_lang", ventoy_cmd_cur_menu_lang, 0, NULL, "", "", NULL },
{ "vt_vtoychksum_exist", ventoy_cmd_vtoychksum_exist, 0, NULL, "", "", NULL },
{ "vt_cmp_checksum", ventoy_cmd_cmp_checksum, 0, NULL, "", "", NULL },
};

View File

@ -116,6 +116,15 @@
s++;\
}
#define VTOY_SKIP_SPACE_NEXT_EX(s, base, initial) \
s = base + initial;\
while (ventoy_isspace(*s)) \
{\
s++;\
}
#define VTOY_GOTO_END(v) ret = v; goto end
typedef enum VTOY_FILE_FLT
{
VTOY_FILE_FLT_ISO = 0, /* .iso */
@ -628,6 +637,11 @@ typedef struct chk_case_fs_dir
}chk_case_fs_dir;
int ventoy_str_all_digit(const char *str);
int ventoy_str_all_alnum(const char *str);
int ventoy_str_len_alnum(const char *str, int len);
char * ventoy_str_basename(char *path);
grub_err_t ventoy_env_int_set(const char *name, int value);
int ventoy_str_chrcnt(const char *str, char c);
int ventoy_strcmp(const char *pattern, const char *str);
int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n);
void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param);

View File

@ -1,19 +1,17 @@
if [ -e "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.md5" ]; then
set default=0
unset vtchkdef
vt_vtoychksum_exist "${vtoy_iso_part}" "${VTOY_CHKSUM_FILE_PATH}"
set vtchksumfile=$?
if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.md5" -o $vtchksumfile -eq 0 ]; then
if [ -z "$vtchkdef" ]; then
set default=0
set vtchkdef=1
fi
menuentry "$VTLANG_CHKSUM_MD5_CALC_CHK" --class=checksum_md5 {
md5sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
vt_1st_line "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.md5" vtReadChecksum
if vt_str_casebegin "$vtReadChecksum" "$VT_LAST_CHECK_SUM"; then
echo -e "\n\nCheck MD5 value with .md5 file. [ OK ]"
else
echo -e "\n\nCheck MD5 value with .md5 file. [ FAIL ]"
echo "The MD5 value in .md5 file is:"
echo "$vtReadChecksum"
fi
md5sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
vt_cmp_checksum 0 "${VTOY_CHKSUM_FILE_PATH}"
echo -en "\n\n$VTLANG_ENTER_EXIT ..."
read vtInputKey
}
@ -26,20 +24,14 @@ else
}
fi
if [ -e "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha1" ]; then
set default=1
if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha1" -o $vtchksumfile -eq 0 ]; then
if [ -z "$vtchkdef" ]; then
set default=1
set vtchkdef=1
fi
menuentry "$VTLANG_CHKSUM_SHA1_CALC_CHK" --class=checksum_sha1 {
sha1sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
vt_1st_line "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha1" vtReadChecksum
if vt_str_casebegin "$vtReadChecksum" "$VT_LAST_CHECK_SUM"; then
echo -e "\n\nCheck SHA1 value with .sha1 file. [ OK ]"
else
echo -e "\n\nCheck SHA1 value with .sha1 file. [ FAIL ]"
echo "The SHA1 value in .sha1 file is:"
echo "$vtReadChecksum"
fi
vt_cmp_checksum 1 "${VTOY_CHKSUM_FILE_PATH}"
echo -en "\n\n$VTLANG_ENTER_EXIT ..."
read vtInputKey
@ -55,20 +47,14 @@ fi
if [ -e "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha256" ]; then
set default=2
if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha256" -o $vtchksumfile -eq 0 ]; then
if [ -z "$vtchkdef" ]; then
set default=2
set vtchkdef=1
fi
menuentry "$VTLANG_CHKSUM_SHA256_CALC_CHK" --class=checksum_sha256 {
sha256sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
vt_1st_line "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha256" vtReadChecksum
if vt_str_casebegin "$vtReadChecksum" "$VT_LAST_CHECK_SUM"; then
echo -e "\n\nCheck SHA256 value with .sha256 file. [ OK ]"
else
echo -e "\n\nCheck SHA256 value with .sha256 file. [ FAIL ]"
echo "The SHA256 value in .sha256 file is:"
echo "$vtReadChecksum"
fi
vt_cmp_checksum 2 "${VTOY_CHKSUM_FILE_PATH}"
echo -en "\n\n$VTLANG_ENTER_EXIT ..."
read vtInputKey
@ -84,20 +70,14 @@ fi
if [ -e "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha512" ]; then
set default=3
if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha512" -o $vtchksumfile -eq 0 ]; then
if [ -z "$vtchkdef" ]; then
set default=3
set vtchkdef=1
fi
menuentry "$VTLANG_CHKSUM_SHA512_CALC_CHK" --class=checksum_sha512{
sha512sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
vt_1st_line "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}.sha512" vtReadChecksum
if vt_str_casebegin "$vtReadChecksum" "$VT_LAST_CHECK_SUM"; then
echo -e "\n\nCheck SHA512 value with .sha512 file. [ OK ]"
else
echo -e "\n\nCheck SHA512 value with .sha512 file. [ FAIL ]"
echo "The SHA512 value in .sha512 file is:"
echo "$vtReadChecksum"
fi
vt_cmp_checksum 3 "${VTOY_CHKSUM_FILE_PATH}"
echo -en "\n\n$VTLANG_ENTER_EXIT ..."
read vtInputKey