101 lines
1.9 KiB
Go
101 lines
1.9 KiB
Go
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 <archive.tar.xz> <archive.tar.xz.sig>\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.")
|
|
}
|