mirror of
https://github.com/octoleo/restic.git
synced 2024-11-21 20:35:12 +00:00
backup: verify unpacked files before upload
This commit is contained in:
parent
2f30c940b2
commit
cb85fb46dd
@ -500,7 +500,8 @@ func (r *Repository) decompressUnpacked(p []byte) ([]byte, error) {
|
|||||||
|
|
||||||
// SaveUnpacked encrypts data and stores it in the backend. Returned is the
|
// SaveUnpacked encrypts data and stores it in the backend. Returned is the
|
||||||
// storage hash.
|
// 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 {
|
if t != restic.ConfigFile {
|
||||||
p, err = r.compressUnpacked(p)
|
p, err = r.compressUnpacked(p)
|
||||||
if err != nil {
|
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)
|
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 {
|
if t == restic.ConfigFile {
|
||||||
id = restic.ID{}
|
id = restic.ID{}
|
||||||
} else {
|
} else {
|
||||||
@ -532,6 +538,25 @@ func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []by
|
|||||||
return id, nil
|
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
|
// Flush saves all remaining packs and the index
|
||||||
func (r *Repository) Flush(ctx context.Context) error {
|
func (r *Repository) Flush(ctx context.Context) error {
|
||||||
if err := r.flushPacks(ctx); err != nil {
|
if err := r.flushPacks(ctx); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user