forked from TrueCloudLab/rclone
crypt: add --crypt-pass-bad-blocks to allow corrupted file output
This commit is contained in:
parent
d5afcf9e34
commit
d0810b602a
3 changed files with 36 additions and 1 deletions
|
@ -179,6 +179,7 @@ type Cipher struct {
|
||||||
buffers sync.Pool // encrypt/decrypt buffers
|
buffers sync.Pool // encrypt/decrypt buffers
|
||||||
cryptoRand io.Reader // read crypto random numbers from here
|
cryptoRand io.Reader // read crypto random numbers from here
|
||||||
dirNameEncrypt bool
|
dirNameEncrypt bool
|
||||||
|
passBadBlocks bool // if set passed bad blocks as zeroed blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCipher initialises the cipher. If salt is "" then it uses a built in salt val
|
// newCipher initialises the cipher. If salt is "" then it uses a built in salt val
|
||||||
|
@ -199,6 +200,11 @@ func newCipher(mode NameEncryptionMode, password, salt string, dirNameEncrypt bo
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call to set bad block pass through
|
||||||
|
func (c *Cipher) setPassBadBlocks(passBadBlocks bool) {
|
||||||
|
c.passBadBlocks = passBadBlocks
|
||||||
|
}
|
||||||
|
|
||||||
// Key creates all the internal keys from the password passed in using
|
// Key creates all the internal keys from the password passed in using
|
||||||
// scrypt.
|
// scrypt.
|
||||||
//
|
//
|
||||||
|
@ -864,8 +870,15 @@ func (fh *decrypter) fillBuffer() (err error) {
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
return err // return pending error as it is likely more accurate
|
return err // return pending error as it is likely more accurate
|
||||||
}
|
}
|
||||||
|
if !fh.c.passBadBlocks {
|
||||||
return ErrorEncryptedBadBlock
|
return ErrorEncryptedBadBlock
|
||||||
}
|
}
|
||||||
|
fs.Errorf(nil, "crypt: ignoring: %v", ErrorEncryptedBadBlock)
|
||||||
|
// Zero out the bad block and continue
|
||||||
|
for i := range fh.buf[:n] {
|
||||||
|
fh.buf[i] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
fh.bufIndex = 0
|
fh.bufIndex = 0
|
||||||
fh.bufSize = n - blockHeaderSize
|
fh.bufSize = n - blockHeaderSize
|
||||||
fh.nonce.increment()
|
fh.nonce.increment()
|
||||||
|
|
|
@ -1536,6 +1536,17 @@ func TestDecrypterRead(t *testing.T) {
|
||||||
}
|
}
|
||||||
file16copy[i] ^= 0xFF
|
file16copy[i] ^= 0xFF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that we can corrupt a byte and read zeroes if
|
||||||
|
// passBadBlocks is set
|
||||||
|
copy(file16copy, file16)
|
||||||
|
file16copy[len(file16copy)-1] ^= 0xFF
|
||||||
|
c.passBadBlocks = true
|
||||||
|
fh, err = c.newDecrypter(io.NopCloser(bytes.NewBuffer(file16copy)))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
buf, err := io.ReadAll(fh)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, make([]byte, 16), buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDecrypterClose(t *testing.T) {
|
func TestDecrypterClose(t *testing.T) {
|
||||||
|
|
|
@ -119,6 +119,15 @@ names, or for debugging purposes.`,
|
||||||
Help: "Encrypt file data.",
|
Help: "Encrypt file data.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
Name: "pass_bad_blocks",
|
||||||
|
Help: `If set this will pass bad blocks through as all 0.
|
||||||
|
|
||||||
|
This should not be set in normal operation, it should only be set if
|
||||||
|
trying to recover a crypted file with errors and it is desired to
|
||||||
|
recover as much of the file as possible.`,
|
||||||
|
Default: false,
|
||||||
|
Advanced: true,
|
||||||
}, {
|
}, {
|
||||||
Name: "filename_encoding",
|
Name: "filename_encoding",
|
||||||
Help: `How to encode the encrypted filename to text string.
|
Help: `How to encode the encrypted filename to text string.
|
||||||
|
@ -174,6 +183,7 @@ func newCipherForConfig(opt *Options) (*Cipher, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to make cipher: %w", err)
|
return nil, fmt.Errorf("failed to make cipher: %w", err)
|
||||||
}
|
}
|
||||||
|
cipher.setPassBadBlocks(opt.PassBadBlocks)
|
||||||
return cipher, nil
|
return cipher, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +272,7 @@ type Options struct {
|
||||||
Password2 string `config:"password2"`
|
Password2 string `config:"password2"`
|
||||||
ServerSideAcrossConfigs bool `config:"server_side_across_configs"`
|
ServerSideAcrossConfigs bool `config:"server_side_across_configs"`
|
||||||
ShowMapping bool `config:"show_mapping"`
|
ShowMapping bool `config:"show_mapping"`
|
||||||
|
PassBadBlocks bool `config:"pass_bad_blocks"`
|
||||||
FilenameEncoding string `config:"filename_encoding"`
|
FilenameEncoding string `config:"filename_encoding"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue