111 lines
2.5 KiB
Go
111 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/safing/jess/filesig"
|
|
)
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(checksum)
|
|
checksum.AddCommand(checksumAdd)
|
|
checksum.AddCommand(checksumVerify)
|
|
}
|
|
|
|
var (
|
|
checksum = &cobra.Command{
|
|
Use: "checksum",
|
|
Short: "add or verify embedded checksums",
|
|
}
|
|
|
|
checksumAddUsage = "usage: checksum add <file>"
|
|
checksumAdd = &cobra.Command{
|
|
Use: "add <file>",
|
|
Short: "add an embedded checksum to a file",
|
|
Long: "add an embedded checksum to a file (support file types: txt, json, yaml)",
|
|
RunE: handleChecksumAdd,
|
|
}
|
|
|
|
checksumVerifyUsage = "usage: checksum verify <file>"
|
|
checksumVerify = &cobra.Command{
|
|
Use: "verify <file>",
|
|
Short: "verify the embedded checksum of a file",
|
|
Long: "verify the embedded checksum of a file (support file types: txt, json, yaml)",
|
|
RunE: handleChecksumVerify,
|
|
}
|
|
)
|
|
|
|
func handleChecksumAdd(cmd *cobra.Command, args []string) error {
|
|
// Check args.
|
|
if len(args) != 1 {
|
|
return errors.New(checksumAddUsage)
|
|
}
|
|
filename := args[0]
|
|
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read file: %w", err)
|
|
}
|
|
|
|
switch filepath.Ext(filename) {
|
|
case ".json":
|
|
data, err = filesig.AddJSONChecksum(data)
|
|
case ".yml", ".yaml":
|
|
data, err = filesig.AddYAMLChecksum(data, filesig.TextPlacementAfterComment)
|
|
case ".txt":
|
|
data, err = filesig.AddTextFileChecksum(data, "#", filesig.TextPlacementAfterComment)
|
|
default:
|
|
return errors.New("unsupported file format")
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Write back to disk.
|
|
fileInfo, err := os.Stat(filename)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to stat file: %w", err)
|
|
}
|
|
err = os.WriteFile(filename, data, fileInfo.Mode().Perm())
|
|
if err != nil {
|
|
return fmt.Errorf("failed to write back file with checksum: %w", err)
|
|
}
|
|
|
|
fmt.Println("checksum added")
|
|
return nil
|
|
}
|
|
|
|
func handleChecksumVerify(cmd *cobra.Command, args []string) error {
|
|
// Check args.
|
|
if len(args) != 1 {
|
|
return errors.New(checksumVerifyUsage)
|
|
}
|
|
filename := args[0]
|
|
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read file: %w", err)
|
|
}
|
|
|
|
switch filepath.Ext(filename) {
|
|
case ".json":
|
|
err = filesig.VerifyJSONChecksum(data)
|
|
case ".yml", ".yaml":
|
|
err = filesig.VerifyYAMLChecksum(data)
|
|
case ".txt":
|
|
err = filesig.VerifyTextFileChecksum(data, "#")
|
|
default:
|
|
return errors.New("unsupported file format")
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println("checksum verified")
|
|
return nil
|
|
}
|