forcedecode: tighten checks
...and fix a few golint issues and print a scary warning message on mount. Also, force the fs to ro,noexec.
This commit is contained in:
parent
f1945c4daa
commit
3409ade272
@ -67,11 +67,16 @@ failing with an IO error. Warning messages are still printed to syslog if corrup
|
||||
files are encountered.
|
||||
It can be useful to recover files from disks with bad sectors or other corrupted
|
||||
media. It shall not be used if the origin of corruption is unknown, specially
|
||||
if you want to run executable files. For corrupted media, note that you probably want
|
||||
to use dd_rescue(1) instead.
|
||||
This option has no effect in reverse mode. It requires gocryptfs to be compiled with openssl
|
||||
if you want to run executable files.
|
||||
|
||||
For corrupted media, note that you probably want to use dd_rescue(1)
|
||||
instead, which will recover all but the corrupted 4kB block.
|
||||
|
||||
This option makes no sense in reverse mode. It requires gocryptfs to be compiled with openssl
|
||||
support and implies -openssl true. Because of this, it is not compatible with -aessiv,
|
||||
that uses built-in Go crpyto.
|
||||
that uses built-in Go crypto.
|
||||
|
||||
Setting this option forces the filesystem to read-only and noexec.
|
||||
|
||||
#### -fsname string
|
||||
Override the filesystem name (first column in df -T). Can also be
|
||||
|
12
cli_args.go
12
cli_args.go
@ -171,11 +171,17 @@ func parseCliOpts() (args argContainer) {
|
||||
tlog.Fatal.Printf("The reverse mode and the -forcedecode option are not compatible")
|
||||
os.Exit(ErrExitUsage)
|
||||
}
|
||||
v, e := strconv.ParseBool(opensslAuto)
|
||||
if e == nil && v == false {
|
||||
tlog.Warn.Printf("-openssl set to true, as it is required by -forcedecode flag")
|
||||
// Has the user explicitely disabled openssl using "-openssl=false/0"?
|
||||
if !args.openssl && opensslAuto != "auto" {
|
||||
tlog.Fatal.Printf("-forcedecode requires openssl, but is disabled via command-line option")
|
||||
os.Exit(ErrExitUsage)
|
||||
}
|
||||
args.openssl = true
|
||||
|
||||
// Try to make it harder for the user to shoot himself in the foot.
|
||||
args.ro = true
|
||||
args.allow_other = false
|
||||
args.ko = "noexec"
|
||||
}
|
||||
// '-passfile FILE' is a shortcut for -extpass='/bin/cat -- FILE'
|
||||
if args.passfile != "" {
|
||||
|
@ -86,7 +86,9 @@ func (be *ContentEnc) DecryptBlocks(ciphertext []byte, firstBlockNo uint64, file
|
||||
var pBlock []byte
|
||||
pBlock, err = be.DecryptBlock(cBlock, firstBlockNo, fileID)
|
||||
if err != nil {
|
||||
if be.forceDecode == false || (be.forceDecode == true && stupidgcm.AuthError != err) {
|
||||
if be.forceDecode && err == stupidgcm.ErrAuth {
|
||||
tlog.Warn.Printf("DecryptBlocks: authentication failure in block #%d, overriden by forcedecode", firstBlockNo)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -139,11 +141,10 @@ func (be *ContentEnc) DecryptBlock(ciphertext []byte, blockNo uint64, fileID []b
|
||||
if err != nil {
|
||||
tlog.Warn.Printf("DecryptBlock: %s, len=%d", err.Error(), len(ciphertextOrig))
|
||||
tlog.Debug.Println(hex.Dump(ciphertextOrig))
|
||||
if be.forceDecode == true {
|
||||
if be.forceDecode && err == stupidgcm.ErrAuth {
|
||||
return plaintext, err
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plaintext, nil
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
|
||||
"github.com/rfjakob/gocryptfs/internal/contentenc"
|
||||
"github.com/rfjakob/gocryptfs/internal/serialize_reads"
|
||||
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
|
||||
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
|
||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||
)
|
||||
@ -200,9 +201,14 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
|
||||
// Decrypt it
|
||||
plaintext, err := f.contentEnc.DecryptBlocks(ciphertext, firstBlockNo, fileID)
|
||||
if err != nil {
|
||||
curruptBlockNo := firstBlockNo + f.contentEnc.PlainOffToBlockNo(uint64(len(plaintext)))
|
||||
tlog.Warn.Printf("ino%d: doRead: corrupt block #%d: %v", f.devIno.ino, curruptBlockNo, err)
|
||||
if (f.fs.args.ForceDecode == false) {
|
||||
if f.fs.args.ForceDecode && err == stupidgcm.ErrAuth {
|
||||
// We do not have the information which block was corrupt here anymore,
|
||||
// but DecryptBlocks() has already logged it anyway.
|
||||
tlog.Warn.Printf("ino%d: doRead off=%d len=%d: returning corrupt data due to forcedecode",
|
||||
f.devIno.ino, off, length)
|
||||
} else {
|
||||
curruptBlockNo := firstBlockNo + f.contentEnc.PlainOffToBlockNo(uint64(len(plaintext)))
|
||||
tlog.Warn.Printf("ino%d: doRead: corrupt block #%d: %v", f.devIno.ino, curruptBlockNo, err)
|
||||
return nil, fuse.EIO
|
||||
}
|
||||
}
|
||||
|
8
internal/stupidgcm/autherr.go
Normal file
8
internal/stupidgcm/autherr.go
Normal file
@ -0,0 +1,8 @@
|
||||
package stupidgcm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ErrAuth is returned when the message authentication fails
|
||||
var ErrAuth = fmt.Errorf("stupidgcm: message authentication failed")
|
@ -10,7 +10,6 @@ import "C"
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
"log"
|
||||
"unsafe"
|
||||
)
|
||||
@ -30,9 +29,6 @@ type stupidGCM struct {
|
||||
forceDecode bool
|
||||
}
|
||||
|
||||
//authentication error
|
||||
var AuthError error = fmt.Errorf("stupidgcm: message authentication failed")
|
||||
|
||||
var _ cipher.AEAD = &stupidGCM{}
|
||||
|
||||
// New returns a new cipher.AEAD implementation..
|
||||
@ -193,10 +189,9 @@ func (g stupidGCM) Open(dst, iv, in, authData []byte) ([]byte, error) {
|
||||
// The error code must always be checked by the calling function, because the decrypted buffer
|
||||
// may contain corrupted data that we are returning in case the user forced reads
|
||||
if g.forceDecode == true {
|
||||
return append(dst, buf...), AuthError
|
||||
} else {
|
||||
return nil, AuthError
|
||||
return append(dst, buf...), ErrAuth
|
||||
}
|
||||
return nil, ErrAuth
|
||||
}
|
||||
|
||||
return append(dst, buf...), nil
|
||||
|
@ -14,9 +14,6 @@ const (
|
||||
BuiltWithoutOpenssl = true
|
||||
)
|
||||
|
||||
//authentication error - needed to compile as same varaible is exported when openssl is enable via stupidgcm.go
|
||||
var AuthError error = fmt.Errorf("stupidgcm: message authentication failed with openssl disabled!")
|
||||
|
||||
func errExit() {
|
||||
fmt.Fprintln(os.Stderr, "gocryptfs has been compiled without openssl support but you are still trying to use openssl")
|
||||
os.Exit(2)
|
||||
|
4
mount.go
4
mount.go
@ -249,6 +249,10 @@ func initFuseFrontend(key []byte, args *argContainer, confFile *configfile.ConfF
|
||||
// Make the kernel check the file permissions for us
|
||||
mOpts.Options = append(mOpts.Options, "default_permissions")
|
||||
}
|
||||
if args.forcedecode {
|
||||
tlog.Info.Printf(tlog.ColorYellow + "THE OPTION \"-forcedecode\" IS ACTIVE. GOCRYPTFS WILL RETURN CORRUPT DATA!" +
|
||||
tlog.ColorReset)
|
||||
}
|
||||
if args.nonempty {
|
||||
mOpts.Options = append(mOpts.Options, "nonempty")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user