package main import ( "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "io" "os" "os/exec" "kisekinopureya.com.tr/updater/internal/archive" ) func sha256sum(path string) (string, error) { f, err := os.Open(path) if err != nil { return "", err } defer f.Close() h := sha256.New() if _, err := io.Copy(h, f); err != nil { return "", err } return hex.EncodeToString(h.Sum(nil)), nil } func main() { if len(os.Args) != 3 { fmt.Printf("Usage: %s \n", os.Args[0]) os.Exit(1) } archiveFile := os.Args[1] sig := os.Args[2] // Step 1: verify GPG signature cmd := exec.Command("/usr/bin/gpgv", "--keyring", "/etc/updates-public.gpg", sig, archiveFile) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { fmt.Fprintf(os.Stderr, "GPG verification failed: %v\n", err) os.Exit(1) } fmt.Println("GPG signature verified.") // Step 2: open archiveFile f, err := os.Open(archiveFile) if err != nil { panic(err) } defer f.Close() // Step 2: extract tar.xz using system tar cmdTar := exec.Command("tar", "-xJf", archiveFile) cmdTar.Stdout = os.Stdout cmdTar.Stderr = os.Stderr if err := cmdTar.Run(); err != nil { panic(err) } metaFile := "metadata.json" f, err = os.Open(metaFile) if err != nil { panic(err) } defer f.Close() var meta archive.Output if err := json.NewDecoder(f).Decode(&meta); err != nil { panic(err) } // Step 4: check sha256 ok := true for _, file := range meta.Files { sum, err := sha256sum(file.Name) if err != nil { fmt.Fprintf(os.Stderr, "Failed to hash %s: %v\n", file.Name, err) ok = false continue } if sum != file.Sha256 { fmt.Fprintf(os.Stderr, "Checksum mismatch for %s!\nExpected: %s\nGot: %s\n", file.Name, file.Sha256, sum) ok = false } else { fmt.Printf("%s checksum OK\n", file.Name) } } if !ok { os.Exit(1) } fmt.Println("All files verified successfully.") }