mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-04-24 20:06:21 +02:00
79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
// Copyright 2026 Syntrex Lab. All rights reserved.
|
|
// Use of this source code is governed by an Apache-2.0 license
|
|
// that can be found in the LICENSE file.
|
|
|
|
package lifecycle
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
)
|
|
|
|
// ShredDatabase irreversibly destroys a database file by overwriting
|
|
// its header with random bytes, making it unreadable without backup.
|
|
//
|
|
// For SQLite: overwrites first 100 bytes (header with magic bytes "SQLite format 3\000").
|
|
// For BoltDB: overwrites first 4096 bytes (two 4KB meta pages).
|
|
//
|
|
// WARNING: This operation is IRREVERSIBLE. Data is only recoverable from peer backup.
|
|
func ShredDatabase(dbPath string, headerSize int) error {
|
|
f, err := os.OpenFile(dbPath, os.O_WRONLY, 0)
|
|
if err != nil {
|
|
return fmt.Errorf("shred: open %s: %w", dbPath, err)
|
|
}
|
|
defer f.Close()
|
|
|
|
// Overwrite header with random bytes.
|
|
noise := make([]byte, headerSize)
|
|
if _, err := rand.Read(noise); err != nil {
|
|
return fmt.Errorf("shred: random: %w", err)
|
|
}
|
|
|
|
if _, err := f.WriteAt(noise, 0); err != nil {
|
|
return fmt.Errorf("shred: write %s: %w", dbPath, err)
|
|
}
|
|
|
|
// Force flush to disk.
|
|
if err := f.Sync(); err != nil {
|
|
return fmt.Errorf("shred: sync %s: %w", dbPath, err)
|
|
}
|
|
|
|
log.Printf("SHRED: %s header (%d bytes) destroyed", dbPath, headerSize)
|
|
return nil
|
|
}
|
|
|
|
// ShredSQLite shreds a SQLite database (100-byte header).
|
|
func ShredSQLite(dbPath string) error {
|
|
return ShredDatabase(dbPath, 100)
|
|
}
|
|
|
|
// ShredBoltDB shreds a BoltDB database (4096-byte meta pages).
|
|
func ShredBoltDB(dbPath string) error {
|
|
return ShredDatabase(dbPath, 4096)
|
|
}
|
|
|
|
// ShredAll shreds all known database files in the .rlm directory.
|
|
func ShredAll(rlmDir string) []error {
|
|
var errs []error
|
|
|
|
sqlitePath := rlmDir + "/memory/memory_bridge_v2.db"
|
|
if _, err := os.Stat(sqlitePath); err == nil {
|
|
if err := ShredSQLite(sqlitePath); err != nil {
|
|
errs = append(errs, err)
|
|
}
|
|
}
|
|
|
|
boltPath := rlmDir + "/cache.db"
|
|
if _, err := os.Stat(boltPath); err == nil {
|
|
if err := ShredBoltDB(boltPath); err != nil {
|
|
errs = append(errs, err)
|
|
}
|
|
}
|
|
|
|
if len(errs) == 0 {
|
|
log.Printf("SHRED: All databases destroyed in %s", rlmDir)
|
|
}
|
|
return errs
|
|
}
|