From e1508134c79bd440a2a0b649c6cba3291abf2349 Mon Sep 17 00:00:00 2001 From: Una Thompson Date: Tue, 3 Oct 2023 18:26:21 -0700 Subject: [PATCH 1/4] Prefer SHA-512 for Modrinth, add rehash command --- cmd/rehash.go | 86 ++++++++++++++++++++++++++++++++++++++++++++ modrinth/modrinth.go | 13 +++---- 2 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 cmd/rehash.go diff --git a/cmd/rehash.go b/cmd/rehash.go new file mode 100644 index 0000000..344b1a8 --- /dev/null +++ b/cmd/rehash.go @@ -0,0 +1,86 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/packwiz/packwiz/core" + "github.com/spf13/cobra" +) + +// rehashCmd represents the rehash command +var rehashCmd = &cobra.Command{ + Use: "rehash", + Short: "Migrate all hashes to a specific function", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + // Load pack + pack, err := core.LoadPack() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Load index + index, err := pack.LoadIndex() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Load mods + mods, err := index.LoadAllMods() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + session, err := core.CreateDownloadSession(mods, []string{args[0]}) + if err != nil { + fmt.Printf("Error retrieving external files: %v\n", err) + os.Exit(1) + } + for dl := range session.StartDownloads() { + if dl.Error != nil { + fmt.Printf("Error retrieving %s: %v\n", dl.Mod.Name, dl.Error); + } + dl.Mod.Download.HashFormat = args[0] + dl.Mod.Download.Hash = dl.Hashes[args[0]] + _, _, err := dl.Mod.Write() + if err != nil { + fmt.Printf("Error saving mod %s: %v\n", dl.Mod.Name, err) + os.Exit(1) + } + // TODO pass the hash to index instead of recomputing from scratch + } + + err = index.Refresh() + if err != nil { + fmt.Printf("Error refreshing index: %v\n", err) + os.Exit(1) + } + + err = index.Write() + if err != nil { + fmt.Printf("Error writing index: %v\n", err) + os.Exit(1) + } + + err = pack.UpdateIndexHash() + if err != nil { + fmt.Printf("Error updating index hash: %v\n", err) + os.Exit(1) + } + + err = pack.Write() + if err != nil { + fmt.Printf("Error writing pack: %v\n", err) + os.Exit(1) + } + }, +} + +func init() { + rootCmd.AddCommand(rehashCmd) +} diff --git a/modrinth/modrinth.go b/modrinth/modrinth.go index 2e920bd..74bdde4 100644 --- a/modrinth/modrinth.go +++ b/modrinth/modrinth.go @@ -361,12 +361,9 @@ func shouldDownloadOnSide(side string) bool { } func getBestHash(v *modrinthApi.File) (string, string) { - // Try preferred hashes first; SHA1 is first as it is required for Modrinth pack exporting - val, exists := v.Hashes["sha1"] - if exists { - return "sha1", val - } - val, exists = v.Hashes["sha512"] + // Try preferred hashes first; SHA1 is required for Modrinth pack exporting, but + // so is SHA512, so we can't win with the current one-hash format + val, exists := v.Hashes["sha512"] if exists { return "sha512", val } @@ -374,6 +371,10 @@ func getBestHash(v *modrinthApi.File) (string, string) { if exists { return "sha256", val } + val, exists = v.Hashes["sha1"] + if exists { + return "sha1", val + } val, exists = v.Hashes["murmur2"] // (not defined in Modrinth pack spec, use with caution) if exists { return "murmur2", val From c391e1cfdd1b70eb11d4a048f69a4da598aa3d31 Mon Sep 17 00:00:00 2001 From: comp500 Date: Wed, 28 Aug 2024 18:54:13 +0100 Subject: [PATCH 2/4] Run go fmt --- cmd/rehash.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/rehash.go b/cmd/rehash.go index 344b1a8..4843496 100644 --- a/cmd/rehash.go +++ b/cmd/rehash.go @@ -35,7 +35,7 @@ var rehashCmd = &cobra.Command{ fmt.Println(err) os.Exit(1) } - + session, err := core.CreateDownloadSession(mods, []string{args[0]}) if err != nil { fmt.Printf("Error retrieving external files: %v\n", err) @@ -43,7 +43,7 @@ var rehashCmd = &cobra.Command{ } for dl := range session.StartDownloads() { if dl.Error != nil { - fmt.Printf("Error retrieving %s: %v\n", dl.Mod.Name, dl.Error); + fmt.Printf("Error retrieving %s: %v\n", dl.Mod.Name, dl.Error) } dl.Mod.Download.HashFormat = args[0] dl.Mod.Download.Hash = dl.Hashes[args[0]] @@ -54,25 +54,25 @@ var rehashCmd = &cobra.Command{ } // TODO pass the hash to index instead of recomputing from scratch } - + err = index.Refresh() if err != nil { fmt.Printf("Error refreshing index: %v\n", err) os.Exit(1) } - + err = index.Write() if err != nil { fmt.Printf("Error writing index: %v\n", err) os.Exit(1) } - + err = pack.UpdateIndexHash() if err != nil { fmt.Printf("Error updating index hash: %v\n", err) os.Exit(1) } - + err = pack.Write() if err != nil { fmt.Printf("Error writing pack: %v\n", err) From 2d181f9f70cea998e6ea2e21a829b1145bd91caf Mon Sep 17 00:00:00 2001 From: comp500 Date: Wed, 28 Aug 2024 19:10:45 +0100 Subject: [PATCH 3/4] Restrict rehash hashes to secure hashes --- cmd/rehash.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/rehash.go b/cmd/rehash.go index 4843496..3128ecf 100644 --- a/cmd/rehash.go +++ b/cmd/rehash.go @@ -6,6 +6,7 @@ import ( "github.com/packwiz/packwiz/core" "github.com/spf13/cobra" + "golang.org/x/exp/slices" ) // rehashCmd represents the rehash command @@ -36,6 +37,11 @@ var rehashCmd = &cobra.Command{ os.Exit(1) } + if !slices.Contains([]string{"sha1", "sha512", "sha256"}, args[0]) { + fmt.Printf("Hash format '%s' is not supported\n", args[0]) + os.Exit(1) + } + session, err := core.CreateDownloadSession(mods, []string{args[0]}) if err != nil { fmt.Printf("Error retrieving external files: %v\n", err) From f1ea588c830fac0d8e2f30bdd0ec66cbc55337b5 Mon Sep 17 00:00:00 2001 From: comp500 Date: Wed, 28 Aug 2024 19:19:12 +0100 Subject: [PATCH 4/4] Don't write hash if retrieval failed --- cmd/rehash.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cmd/rehash.go b/cmd/rehash.go index 3128ecf..0019d70 100644 --- a/cmd/rehash.go +++ b/cmd/rehash.go @@ -50,13 +50,14 @@ var rehashCmd = &cobra.Command{ for dl := range session.StartDownloads() { if dl.Error != nil { fmt.Printf("Error retrieving %s: %v\n", dl.Mod.Name, dl.Error) - } - dl.Mod.Download.HashFormat = args[0] - dl.Mod.Download.Hash = dl.Hashes[args[0]] - _, _, err := dl.Mod.Write() - if err != nil { - fmt.Printf("Error saving mod %s: %v\n", dl.Mod.Name, err) - os.Exit(1) + } else { + dl.Mod.Download.HashFormat = args[0] + dl.Mod.Download.Hash = dl.Hashes[args[0]] + _, _, err := dl.Mod.Write() + if err != nil { + fmt.Printf("Error saving mod %s: %v\n", dl.Mod.Name, err) + os.Exit(1) + } } // TODO pass the hash to index instead of recomputing from scratch }