forked from TrueCloudLab/restic
backup: verify unpacked files before upload
This commit is contained in:
parent
c01a0c6da7
commit
30a84e9003
1 changed files with 26 additions and 1 deletions
|
@ -500,7 +500,8 @@ func (r *Repository) decompressUnpacked(p []byte) ([]byte, error) {
|
|||
|
||||
// SaveUnpacked encrypts data and stores it in the backend. Returned is the
|
||||
// storage hash.
|
||||
func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []byte) (id restic.ID, err error) {
|
||||
func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, buf []byte) (id restic.ID, err error) {
|
||||
p := buf
|
||||
if t != restic.ConfigFile {
|
||||
p, err = r.compressUnpacked(p)
|
||||
if err != nil {
|
||||
|
@ -515,6 +516,11 @@ func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []by
|
|||
|
||||
ciphertext = r.key.Seal(ciphertext, nonce, p, nil)
|
||||
|
||||
if err := r.verifyUnpacked(ciphertext, t, buf); err != nil {
|
||||
// FIXME call to action
|
||||
return restic.ID{}, fmt.Errorf("detected data corruption while saving file of type %v: %w", t, err)
|
||||
}
|
||||
|
||||
if t == restic.ConfigFile {
|
||||
id = restic.ID{}
|
||||
} else {
|
||||
|
@ -532,6 +538,25 @@ func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []by
|
|||
return id, nil
|
||||
}
|
||||
|
||||
func (r *Repository) verifyUnpacked(buf []byte, t restic.FileType, expected []byte) error {
|
||||
nonce, ciphertext := buf[:r.key.NonceSize()], buf[r.key.NonceSize():]
|
||||
plaintext, err := r.key.Open(nil, nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decryption failed: %w", err)
|
||||
}
|
||||
if t != restic.ConfigFile {
|
||||
plaintext, err = r.decompressUnpacked(plaintext)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decompression failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !bytes.Equal(plaintext, expected) {
|
||||
return errors.New("data mismatch")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Flush saves all remaining packs and the index
|
||||
func (r *Repository) Flush(ctx context.Context) error {
|
||||
if err := r.flushPacks(ctx); err != nil {
|
||||
|
|
Loading…
Reference in a new issue