cmd/gitbayd/auditverify.go
53 lines · 1635 bytes
1package main
2
3import (
4 "fmt"
5
6 "github.com/spf13/cobra"
7
8 "gitbay.org/gitbay/internal/config"
9)
10
11// auditVerifyCmd recomputes the audit log's hash chain. A break names
12// the first row that does not match. Rows removed from the end of the
13// log, and rows written after that under the reused ids, leave no
14// break: the last id and hash printed here are what an operator
15// compares with the daemon's journal copy to see either.
16func auditVerifyCmd() *cobra.Command {
17 return &cobra.Command{
18 Use: "verify",
19 Short: "check the audit log's hash chain",
20 Args: cobra.NoArgs,
21 RunE: func(cmd *cobra.Command, args []string) error {
22 cfg, err := config.Load(configPath)
23 if err != nil {
24 return err
25 }
26 st, err := openStore(cfg)
27 if err != nil {
28 return err
29 }
30 defer st.Close()
31 res, err := st.VerifyAuditChain()
32 if err != nil {
33 return err
34 }
35 fmt.Printf("rows %d\nunchained %d\n", res.Rows, res.Unchained)
36 if res.BrokenAt != 0 {
37 return fmt.Errorf("chain broken at row %d: %s", res.BrokenAt, res.Reason)
38 }
39 // Every row unchained is what dropping and re-adding the hash
40 // columns leaves. It is also an upgrade from before migration
41 // 0064 with no row written since; the first new row clears it.
42 if res.Rows > 0 && res.Unchained == res.Rows {
43 return fmt.Errorf("no row carries a hash: the chain columns were cleared, or no audit row has been written since the upgrade")
44 }
45 if res.Last == 0 {
46 fmt.Println("no rows yet")
47 return nil
48 }
49 fmt.Printf("first %d\nlast %d\nlast hash %s\nchain intact\n", res.First, res.Last, res.LastHash)
50 return nil
51 },
52 }
53}