Convert logging to standard Go log.Logger
This is in preparation of logging to syslog.
This commit is contained in:
parent
b9dd9e9a1c
commit
17f0eb1339
@ -75,17 +75,17 @@ func LoadConfFile(filename string, password string) ([]byte, *ConfFile, error) {
|
|||||||
// Unmarshal
|
// Unmarshal
|
||||||
err = json.Unmarshal(js, &cf)
|
err = json.Unmarshal(js, &cf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warn.Printf("Failed to unmarshal config file\n")
|
Warn.Printf("Failed to unmarshal config file")
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if cf.Version != HEADER_CURRENT_VERSION {
|
if cf.Version != HEADER_CURRENT_VERSION {
|
||||||
return nil, nil, fmt.Errorf("Unsupported on-disk format %d\n", cf.Version)
|
return nil, nil, fmt.Errorf("Unsupported on-disk format %d", cf.Version)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, flag := range cf.FeatureFlags {
|
for _, flag := range cf.FeatureFlags {
|
||||||
if cf.isFeatureFlagKnown(flag) == false {
|
if cf.isFeatureFlagKnown(flag) == false {
|
||||||
return nil, nil, fmt.Errorf("Unsupported feature flag %s\n", flag)
|
return nil, nil, fmt.Errorf("Unsupported feature flag %s", flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,8 +98,8 @@ func LoadConfFile(filename string, password string) ([]byte, *ConfFile, error) {
|
|||||||
cfs := NewCryptFS(scryptHash, false, false, false)
|
cfs := NewCryptFS(scryptHash, false, false, false)
|
||||||
key, err := cfs.DecryptBlock(cf.EncryptedKey, 0, nil)
|
key, err := cfs.DecryptBlock(cf.EncryptedKey, 0, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warn.Printf("failed to unlock master key: %s\n", err.Error())
|
Warn.Printf("failed to unlock master key: %s", err.Error())
|
||||||
Warn.Printf("Password incorrect.\n")
|
Warn.Printf("Password incorrect.")
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package cryptfs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -33,10 +35,10 @@ func TestLoadV2(t *testing.T) {
|
|||||||
|
|
||||||
func TestLoadV2PwdError(t *testing.T) {
|
func TestLoadV2PwdError(t *testing.T) {
|
||||||
if !testing.Verbose() {
|
if !testing.Verbose() {
|
||||||
Warn.Disable()
|
Warn.SetOutput(ioutil.Discard)
|
||||||
}
|
}
|
||||||
_, _, err := LoadConfFile("config_test/v2.conf", "wrongpassword")
|
_, _, err := LoadConfFile("config_test/v2.conf", "wrongpassword")
|
||||||
Warn.Enable()
|
Warn.SetOutput(os.Stderr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Loading with wrong password must fail but it didn't")
|
t.Errorf("Loading with wrong password must fail but it didn't")
|
||||||
}
|
}
|
||||||
|
@ -55,12 +55,12 @@ func (be *CryptFS) DecryptBlock(ciphertext []byte, blockNo uint64, fileId []byte
|
|||||||
|
|
||||||
// All-zero block?
|
// All-zero block?
|
||||||
if bytes.Equal(ciphertext, be.allZeroBlock) {
|
if bytes.Equal(ciphertext, be.allZeroBlock) {
|
||||||
Debug.Printf("DecryptBlock: file hole encountered\n")
|
Debug.Printf("DecryptBlock: file hole encountered")
|
||||||
return make([]byte, be.plainBS), nil
|
return make([]byte, be.plainBS), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ciphertext) < be.gcmIVLen {
|
if len(ciphertext) < be.gcmIVLen {
|
||||||
Warn.Printf("DecryptBlock: Block is too short: %d bytes\n", len(ciphertext))
|
Warn.Printf("DecryptBlock: Block is too short: %d bytes", len(ciphertext))
|
||||||
return nil, errors.New("Block is too short")
|
return nil, errors.New("Block is too short")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ func (be *CryptFS) DecryptBlock(ciphertext []byte, blockNo uint64, fileId []byte
|
|||||||
plaintext, err := be.gcm.Open(plaintext, nonce, ciphertext, aData)
|
plaintext, err := be.gcm.Open(plaintext, nonce, ciphertext, aData)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warn.Printf("DecryptBlock: %s, len=%d, md5=%s\n", err.Error(), len(ciphertextOrig), Warn.Md5sum(ciphertextOrig))
|
Warn.Printf("DecryptBlock: %s, len=%d, md5=%s", err.Error(), len(ciphertextOrig), md5sum(ciphertextOrig))
|
||||||
Debug.Println(hex.Dump(ciphertextOrig))
|
Debug.Println(hex.Dump(ciphertextOrig))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
// compiled on 1.4.
|
// compiled on 1.4.
|
||||||
func goGCMWrapper(bc cipher.Block, nonceSize int) (cipher.AEAD, error) {
|
func goGCMWrapper(bc cipher.Block, nonceSize int) (cipher.AEAD, error) {
|
||||||
if nonceSize != 12 {
|
if nonceSize != 12 {
|
||||||
Warn.Printf("128 bit GCM IVs are not supported by Go 1.4 and lower.\n")
|
Warn.Printf("128 bit GCM IVs are not supported by Go 1.4 and lower.")
|
||||||
Warn.Printf("Please use openssl crypto or recompile using a newer Go runtime.\n")
|
Warn.Printf("Please use openssl crypto or recompile using a newer Go runtime.")
|
||||||
return nil, fmt.Errorf("128 bit GCM IVs are not supported by Go 1.4 and lower")
|
return nil, fmt.Errorf("128 bit GCM IVs are not supported by Go 1.4 and lower")
|
||||||
}
|
}
|
||||||
return cipher.NewGCM(bc)
|
return cipher.NewGCM(bc)
|
||||||
|
@ -28,7 +28,7 @@ func NewScryptKdf(logN int) scryptKdf {
|
|||||||
s.N = 1 << SCRYPT_DEFAULT_LOGN
|
s.N = 1 << SCRYPT_DEFAULT_LOGN
|
||||||
} else {
|
} else {
|
||||||
if logN < 10 {
|
if logN < 10 {
|
||||||
fmt.Printf("Error: scryptn below 10 is too low to make sense. Aborting.\n")
|
fmt.Println("Error: scryptn below 10 is too low to make sense. Aborting.")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
s.N = 1 << uint32(logN)
|
s.N = 1 << uint32(logN)
|
||||||
|
@ -2,67 +2,33 @@ package cryptfs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"io/ioutil"
|
||||||
"strings"
|
"log"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
type logChannel struct {
|
func JSONDump(obj interface{}) string {
|
||||||
enabled bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logChannel) Printf(format string, args ...interface{}) {
|
|
||||||
if l.enabled == true {
|
|
||||||
fmt.Printf(format, args...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logChannel) Println(s string) {
|
|
||||||
if l.enabled == true {
|
|
||||||
fmt.Println(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logChannel) Dump(d []byte) {
|
|
||||||
s := string(d)
|
|
||||||
fmt.Println(strings.Replace(s, "\000", "\\0", -1))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logChannel) JSONDump(obj interface{}) {
|
|
||||||
if !l.enabled {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b, err := json.MarshalIndent(obj, "", "\t")
|
b, err := json.MarshalIndent(obj, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
return err.Error()
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(string(b))
|
return string(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logChannel) Enable() {
|
|
||||||
l.enabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logChannel) Disable() {
|
|
||||||
l.enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only actually calculate the md5sum if the log channel is enabled to save
|
|
||||||
// CPU cycles
|
|
||||||
func (l *logChannel) Md5sum(buf []byte) string {
|
|
||||||
if l.enabled == false {
|
|
||||||
return "disabled"
|
|
||||||
}
|
|
||||||
return md5sum(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// As defined by http://elinux.org/Debugging_by_printing#Log_Levels
|
// As defined by http://elinux.org/Debugging_by_printing#Log_Levels
|
||||||
|
|
||||||
// Debug messages
|
// Debug messages
|
||||||
var Debug = logChannel{false}
|
var Debug *log.Logger
|
||||||
|
|
||||||
// Informational message e.g. startup information
|
// Informational message e.g. startup information
|
||||||
var Info = logChannel{true}
|
var Info *log.Logger
|
||||||
|
|
||||||
// A warning, meaning nothing serious by itself but might indicate problems
|
// A warning, meaning nothing serious by itself but might indicate problems
|
||||||
var Warn = logChannel{true}
|
var Warn *log.Logger
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Debug = log.New(ioutil.Discard, "", 0)
|
||||||
|
Info = log.New(os.Stdout, "", 0)
|
||||||
|
Warn = log.New(os.Stderr, "", 0)
|
||||||
|
}
|
||||||
|
@ -24,7 +24,7 @@ func TestMain(m *testing.M) {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if testing.Verbose() {
|
if testing.Verbose() {
|
||||||
fmt.Printf("***** Testing with OpenSSL\n")
|
fmt.Println("***** Testing with OpenSSL")
|
||||||
}
|
}
|
||||||
resetTmpDir() // <- this also create gocryptfs.diriv
|
resetTmpDir() // <- this also create gocryptfs.diriv
|
||||||
mount(defaultCipherDir, defaultPlainDir, "--zerokey")
|
mount(defaultCipherDir, defaultPlainDir, "--zerokey")
|
||||||
@ -40,7 +40,7 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if testing.Verbose() {
|
if testing.Verbose() {
|
||||||
fmt.Printf("***** Testing with native Go crypto\n")
|
fmt.Println("***** Testing with native Go crypto")
|
||||||
}
|
}
|
||||||
resetTmpDir()
|
resetTmpDir()
|
||||||
mount(defaultCipherDir, defaultPlainDir, "--zerokey", "--openssl=false")
|
mount(defaultCipherDir, defaultPlainDir, "--zerokey", "--openssl=false")
|
||||||
@ -52,7 +52,7 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if testing.Verbose() {
|
if testing.Verbose() {
|
||||||
fmt.Printf("***** Testing \"--plaintextnames\"\n")
|
fmt.Println("***** Testing \"--plaintextnames\"")
|
||||||
}
|
}
|
||||||
resetTmpDir()
|
resetTmpDir()
|
||||||
mount(defaultCipherDir, defaultPlainDir, "--zerokey", "--plaintextnames")
|
mount(defaultCipherDir, defaultPlainDir, "--zerokey", "--plaintextnames")
|
||||||
@ -77,7 +77,7 @@ func testWriteN(t *testing.T, fn string, n int) string {
|
|||||||
d := make([]byte, n)
|
d := make([]byte, n)
|
||||||
written, err := file.Write(d)
|
written, err := file.Write(d)
|
||||||
if err != nil || written != len(d) {
|
if err != nil || written != len(d) {
|
||||||
t.Errorf("err=\"%s\", written=%d\n", err, written)
|
t.Errorf("err=\"%s\", written=%d", err, written)
|
||||||
}
|
}
|
||||||
err = file.Close()
|
err = file.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -92,7 +92,7 @@ func testWriteN(t *testing.T, fn string, n int) string {
|
|||||||
hashActual := md5fn(defaultPlainDir + fn)
|
hashActual := md5fn(defaultPlainDir + fn)
|
||||||
|
|
||||||
if hashActual != hashWant {
|
if hashActual != hashWant {
|
||||||
t.Errorf("Wrong content, hashWant=%s hashActual=%s\n", hashWant, hashActual)
|
t.Errorf("Wrong content, hashWant=%s hashActual=%s", hashWant, hashActual)
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashActual
|
return hashActual
|
||||||
|
@ -58,7 +58,6 @@ func BenchmarkStreamRead(t *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
f2.Close()
|
f2.Close()
|
||||||
//fmt.Printf("done\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(fn)
|
file, err := os.Open(fn)
|
||||||
@ -70,7 +69,7 @@ func BenchmarkStreamRead(t *testing.B) {
|
|||||||
for i = 0; i < t.N; i++ {
|
for i = 0; i < t.N; i++ {
|
||||||
_, err := file.Read(buf)
|
_, err := file.Read(buf)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
fmt.Printf("Test file too small\n")
|
fmt.Println("Test file too small")
|
||||||
t.SkipNow()
|
t.SkipNow()
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
46
main.go
46
main.go
@ -1,8 +1,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@ -55,7 +57,7 @@ func initDir(args *argContainer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create gocryptfs.conf
|
// Create gocryptfs.conf
|
||||||
cryptfs.Info.Printf("Choose a password for protecting your files.\n")
|
cryptfs.Info.Printf("Choose a password for protecting your files.")
|
||||||
password := readPasswordTwice(args.extpass)
|
password := readPasswordTwice(args.extpass)
|
||||||
err = cryptfs.CreateConfFile(args.config, password, args.plaintextnames, args.scryptn)
|
err = cryptfs.CreateConfFile(args.config, password, args.plaintextnames, args.scryptn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -72,8 +74,8 @@ func initDir(args *argContainer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cryptfs.Info.Printf(colorGreen+"The filesystem has been created successfully.\n"+colorReset)
|
cryptfs.Info.Printf(colorGreen + "The filesystem has been created successfully." + colorReset)
|
||||||
cryptfs.Info.Printf(colorGrey+"You can now mount it using: %s %s MOUNTPOINT\n"+colorReset,
|
cryptfs.Info.Printf(colorGrey+"You can now mount it using: %s %s MOUNTPOINT"+colorReset,
|
||||||
PROGRAM_NAME, args.cipherdir)
|
PROGRAM_NAME, args.cipherdir)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
@ -98,15 +100,15 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *cryptfs.ConfFil
|
|||||||
fmt.Printf("Password: ")
|
fmt.Printf("Password: ")
|
||||||
pw := readPassword(args.extpass)
|
pw := readPassword(args.extpass)
|
||||||
cryptfs.Info.Printf("Decrypting master key... ")
|
cryptfs.Info.Printf("Decrypting master key... ")
|
||||||
cryptfs.Warn.Disable() // Silence DecryptBlock() error messages on incorrect password
|
cryptfs.Warn.SetOutput(ioutil.Discard) // Silence DecryptBlock() error messages on incorrect password
|
||||||
masterkey, confFile, err = cryptfs.LoadConfFile(args.config, pw)
|
masterkey, confFile, err = cryptfs.LoadConfFile(args.config, pw)
|
||||||
cryptfs.Warn.Enable()
|
cryptfs.Warn.SetOutput(os.Stderr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
fmt.Println(colorRed + "Wrong password." + colorReset)
|
fmt.Println(colorRed + "Wrong password." + colorReset)
|
||||||
os.Exit(ERREXIT_LOADCONF)
|
os.Exit(ERREXIT_LOADCONF)
|
||||||
}
|
}
|
||||||
cryptfs.Info.Printf("done.\n")
|
cryptfs.Info.Printf("done.")
|
||||||
|
|
||||||
return masterkey, confFile
|
return masterkey, confFile
|
||||||
}
|
}
|
||||||
@ -114,7 +116,7 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *cryptfs.ConfFil
|
|||||||
// changePassword - change the password of config file "filename"
|
// changePassword - change the password of config file "filename"
|
||||||
func changePassword(args *argContainer) {
|
func changePassword(args *argContainer) {
|
||||||
masterkey, confFile := loadConfig(args)
|
masterkey, confFile := loadConfig(args)
|
||||||
fmt.Printf("Please enter your new password.\n")
|
fmt.Println("Please enter your new password.")
|
||||||
newPw := readPasswordTwice(args.extpass)
|
newPw := readPasswordTwice(args.extpass)
|
||||||
confFile.EncryptKey(masterkey, newPw, confFile.ScryptObject.LogN())
|
confFile.EncryptKey(masterkey, newPw, confFile.ScryptObject.LogN())
|
||||||
err := confFile.WriteFile()
|
err := confFile.WriteFile()
|
||||||
@ -122,7 +124,7 @@ func changePassword(args *argContainer) {
|
|||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(ERREXIT_INIT)
|
os.Exit(ERREXIT_INIT)
|
||||||
}
|
}
|
||||||
cryptfs.Info.Printf("Password changed.\n")
|
cryptfs.Info.Printf("Password changed.")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,8 +177,8 @@ func main() {
|
|||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
if args.debug {
|
if args.debug {
|
||||||
cryptfs.Debug.Enable()
|
cryptfs.Debug.SetOutput(os.Stdout)
|
||||||
cryptfs.Debug.Printf("Debug output enabled\n")
|
cryptfs.Debug.Printf("Debug output enabled")
|
||||||
}
|
}
|
||||||
// Every operation below requires CIPHERDIR. Check that we have it.
|
// Every operation below requires CIPHERDIR. Check that we have it.
|
||||||
if flagSet.NArg() >= 1 {
|
if flagSet.NArg() >= 1 {
|
||||||
@ -192,7 +194,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
// "-q"
|
// "-q"
|
||||||
if args.quiet {
|
if args.quiet {
|
||||||
cryptfs.Info.Disable()
|
cryptfs.Info.SetOutput(ioutil.Discard)
|
||||||
}
|
}
|
||||||
// "-config"
|
// "-config"
|
||||||
if args.config != "" {
|
if args.config != "" {
|
||||||
@ -200,7 +202,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf(colorRed+"Invalid \"-config\" setting: %v\n"+colorReset, err)
|
fmt.Printf(colorRed+"Invalid \"-config\" setting: %v\n"+colorReset, err)
|
||||||
}
|
}
|
||||||
cryptfs.Info.Printf("Using config file at custom location %s\n", args.config)
|
cryptfs.Info.Printf("Using config file at custom location %s", args.config)
|
||||||
} else {
|
} else {
|
||||||
args.config = filepath.Join(args.cipherdir, cryptfs.ConfDefaultName)
|
args.config = filepath.Join(args.cipherdir, cryptfs.ConfDefaultName)
|
||||||
}
|
}
|
||||||
@ -211,13 +213,13 @@ func main() {
|
|||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(ERREXIT_INIT)
|
os.Exit(ERREXIT_INIT)
|
||||||
}
|
}
|
||||||
cryptfs.Info.Printf("Writing CPU profile to %s\n", args.cpuprofile)
|
cryptfs.Info.Printf("Writing CPU profile to %s", args.cpuprofile)
|
||||||
pprof.StartCPUProfile(f)
|
pprof.StartCPUProfile(f)
|
||||||
defer pprof.StopCPUProfile()
|
defer pprof.StopCPUProfile()
|
||||||
}
|
}
|
||||||
// "-openssl"
|
// "-openssl"
|
||||||
if args.openssl == false {
|
if args.openssl == false {
|
||||||
cryptfs.Info.Printf("Openssl disabled\n")
|
cryptfs.Info.Printf("Openssl disabled")
|
||||||
}
|
}
|
||||||
// Operation flags: init, passwd or mount
|
// Operation flags: init, passwd or mount
|
||||||
// "-init"
|
// "-init"
|
||||||
@ -257,13 +259,13 @@ func main() {
|
|||||||
var confFile *cryptfs.ConfFile
|
var confFile *cryptfs.ConfFile
|
||||||
if args.masterkey != "" {
|
if args.masterkey != "" {
|
||||||
// "-masterkey"
|
// "-masterkey"
|
||||||
cryptfs.Info.Printf("Using explicit master key.\n")
|
cryptfs.Info.Printf("Using explicit master key.")
|
||||||
masterkey = parseMasterKey(args.masterkey)
|
masterkey = parseMasterKey(args.masterkey)
|
||||||
cryptfs.Info.Printf("THE MASTER KEY IS VISIBLE VIA \"ps -auxwww\", ONLY USE THIS MODE FOR EMERGENCIES.\n")
|
cryptfs.Info.Printf("THE MASTER KEY IS VISIBLE VIA \"ps -auxwww\", ONLY USE THIS MODE FOR EMERGENCIES.")
|
||||||
} else if args.zerokey {
|
} else if args.zerokey {
|
||||||
// "-zerokey"
|
// "-zerokey"
|
||||||
cryptfs.Info.Printf("Using all-zero dummy master key.\n")
|
cryptfs.Info.Printf("Using all-zero dummy master key.")
|
||||||
cryptfs.Info.Printf("ZEROKEY MODE PROVIDES NO SECURITY AT ALL AND SHOULD ONLY BE USED FOR TESTING.\n")
|
cryptfs.Info.Printf("ZEROKEY MODE PROVIDES NO SECURITY AT ALL AND SHOULD ONLY BE USED FOR TESTING.")
|
||||||
masterkey = make([]byte, cryptfs.KEY_LEN)
|
masterkey = make([]byte, cryptfs.KEY_LEN)
|
||||||
} else {
|
} else {
|
||||||
// Load master key from config file
|
// Load master key from config file
|
||||||
@ -271,7 +273,7 @@ func main() {
|
|||||||
printMasterKey(masterkey)
|
printMasterKey(masterkey)
|
||||||
}
|
}
|
||||||
// Initialize FUSE server
|
// Initialize FUSE server
|
||||||
cryptfs.Debug.Printf("cli args: %v\n", args)
|
cryptfs.Debug.Printf("cli args: %v", args)
|
||||||
srv := pathfsFrontend(masterkey, args, confFile)
|
srv := pathfsFrontend(masterkey, args, confFile)
|
||||||
cryptfs.Info.Println(colorGreen + "Filesystem mounted and ready." + colorReset)
|
cryptfs.Info.Println(colorGreen + "Filesystem mounted and ready." + colorReset)
|
||||||
// We are ready - send USR1 signal to our parent
|
// We are ready - send USR1 signal to our parent
|
||||||
@ -318,8 +320,8 @@ func pathfsFrontend(key []byte, args argContainer, confFile *cryptfs.ConfFile) *
|
|||||||
frontendArgs.DirIV = false
|
frontendArgs.DirIV = false
|
||||||
frontendArgs.EMENames = false
|
frontendArgs.EMENames = false
|
||||||
}
|
}
|
||||||
cryptfs.Debug.Printf("frontendArgs: ")
|
jsonBytes, _ := json.MarshalIndent(frontendArgs, "", "\t")
|
||||||
cryptfs.Debug.JSONDump(frontendArgs)
|
cryptfs.Debug.Printf("frontendArgs: %s", string(jsonBytes))
|
||||||
|
|
||||||
finalFs := pathfs_frontend.NewFS(frontendArgs)
|
finalFs := pathfs_frontend.NewFS(frontendArgs)
|
||||||
pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
|
pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
|
||||||
@ -364,7 +366,7 @@ func handleSigint(srv *fuse.Server, mountpoint string) {
|
|||||||
err := srv.Unmount()
|
err := srv.Unmount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
cryptfs.Info.Printf("Trying lazy unmount\n")
|
cryptfs.Info.Printf("Trying lazy unmount")
|
||||||
cmd := exec.Command("fusermount", "-u", "-z", mountpoint)
|
cmd := exec.Command("fusermount", "-u", "-z", mountpoint)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
@ -144,20 +144,20 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
|
|||||||
blocks := f.cfs.ExplodePlainRange(off, length)
|
blocks := f.cfs.ExplodePlainRange(off, length)
|
||||||
alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks)
|
alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks)
|
||||||
skip := blocks[0].Skip
|
skip := blocks[0].Skip
|
||||||
cryptfs.Debug.Printf("JointCiphertextRange(%d, %d) -> %d, %d, %d\n", off, length, alignedOffset, alignedLength, skip)
|
cryptfs.Debug.Printf("JointCiphertextRange(%d, %d) -> %d, %d, %d", off, length, alignedOffset, alignedLength, skip)
|
||||||
ciphertext := make([]byte, int(alignedLength))
|
ciphertext := make([]byte, int(alignedLength))
|
||||||
f.fdLock.Lock()
|
f.fdLock.Lock()
|
||||||
n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset))
|
n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset))
|
||||||
f.fdLock.Unlock()
|
f.fdLock.Unlock()
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
cryptfs.Warn.Printf("read: ReadAt: %s\n", err.Error())
|
cryptfs.Warn.Printf("read: ReadAt: %s", err.Error())
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Truncate ciphertext buffer down to actually read bytes
|
// Truncate ciphertext buffer down to actually read bytes
|
||||||
ciphertext = ciphertext[0:n]
|
ciphertext = ciphertext[0:n]
|
||||||
|
|
||||||
firstBlockNo := blocks[0].BlockNo
|
firstBlockNo := blocks[0].BlockNo
|
||||||
cryptfs.Debug.Printf("ReadAt offset=%d bytes (%d blocks), want=%d, got=%d\n", alignedOffset, firstBlockNo, alignedLength, n)
|
cryptfs.Debug.Printf("ReadAt offset=%d bytes (%d blocks), want=%d, got=%d", alignedOffset, firstBlockNo, alignedLength, n)
|
||||||
|
|
||||||
// Decrypt it
|
// Decrypt it
|
||||||
plaintext, err := f.cfs.DecryptBlocks(ciphertext, firstBlockNo, f.header.Id)
|
plaintext, err := f.cfs.DecryptBlocks(ciphertext, firstBlockNo, f.header.Id)
|
||||||
@ -165,7 +165,7 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
|
|||||||
curruptBlockNo := firstBlockNo + f.cfs.PlainOffToBlockNo(uint64(len(plaintext)))
|
curruptBlockNo := firstBlockNo + f.cfs.PlainOffToBlockNo(uint64(len(plaintext)))
|
||||||
cipherOff := f.cfs.BlockNoToCipherOff(curruptBlockNo)
|
cipherOff := f.cfs.BlockNoToCipherOff(curruptBlockNo)
|
||||||
plainOff := f.cfs.BlockNoToPlainOff(curruptBlockNo)
|
plainOff := f.cfs.BlockNoToPlainOff(curruptBlockNo)
|
||||||
cryptfs.Warn.Printf("ino%d: doRead: corrupt block #%d (plainOff=%d, cipherOff=%d)\n",
|
cryptfs.Warn.Printf("ino%d: doRead: corrupt block #%d (plainOff=%d, cipherOff=%d)",
|
||||||
f.ino, curruptBlockNo, plainOff, cipherOff)
|
f.ino, curruptBlockNo, plainOff, cipherOff)
|
||||||
return nil, fuse.EIO
|
return nil, fuse.EIO
|
||||||
}
|
}
|
||||||
@ -187,23 +187,23 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
|
|||||||
// Read - FUSE call
|
// Read - FUSE call
|
||||||
func (f *file) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fuse.Status) {
|
func (f *file) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fuse.Status) {
|
||||||
|
|
||||||
cryptfs.Debug.Printf("ino%d: FUSE Read: offset=%d length=%d\n", f.ino, len(buf), off)
|
cryptfs.Debug.Printf("ino%d: FUSE Read: offset=%d length=%d", f.ino, len(buf), off)
|
||||||
|
|
||||||
if f.writeOnly {
|
if f.writeOnly {
|
||||||
cryptfs.Warn.Printf("ino%d: Tried to read from write-only file\n", f.ino)
|
cryptfs.Warn.Printf("ino%d: Tried to read from write-only file", f.ino)
|
||||||
return nil, fuse.EBADF
|
return nil, fuse.EBADF
|
||||||
}
|
}
|
||||||
|
|
||||||
out, status := f.doRead(uint64(off), uint64(len(buf)))
|
out, status := f.doRead(uint64(off), uint64(len(buf)))
|
||||||
|
|
||||||
if status == fuse.EIO {
|
if status == fuse.EIO {
|
||||||
cryptfs.Warn.Printf("ino%d: Read failed with EIO, offset=%d, length=%d\n", f.ino, len(buf), off)
|
cryptfs.Warn.Printf("ino%d: Read failed with EIO, offset=%d, length=%d", f.ino, len(buf), off)
|
||||||
}
|
}
|
||||||
if status != fuse.OK {
|
if status != fuse.OK {
|
||||||
return nil, status
|
return nil, status
|
||||||
}
|
}
|
||||||
|
|
||||||
cryptfs.Debug.Printf("ino%d: Read: status %v, returning %d bytes\n", f.ino, status, len(out))
|
cryptfs.Debug.Printf("ino%d: Read: status %v, returning %d bytes", f.ino, status, len(out))
|
||||||
return fuse.ReadResultData(out), status
|
return fuse.ReadResultData(out), status
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,25 +244,25 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
|
|||||||
o, _ := b.PlaintextRange()
|
o, _ := b.PlaintextRange()
|
||||||
oldData, status := f.doRead(o, f.cfs.PlainBS())
|
oldData, status := f.doRead(o, f.cfs.PlainBS())
|
||||||
if status != fuse.OK {
|
if status != fuse.OK {
|
||||||
cryptfs.Warn.Printf("RMW read failed: %s\n", status.String())
|
cryptfs.Warn.Printf("RMW read failed: %s", status.String())
|
||||||
return written, status
|
return written, status
|
||||||
}
|
}
|
||||||
// Modify
|
// Modify
|
||||||
blockData = f.cfs.MergeBlocks(oldData, blockData, int(b.Skip))
|
blockData = f.cfs.MergeBlocks(oldData, blockData, int(b.Skip))
|
||||||
cryptfs.Debug.Printf("len(oldData)=%d len(blockData)=%d\n", len(oldData), len(blockData))
|
cryptfs.Debug.Printf("len(oldData)=%d len(blockData)=%d", len(oldData), len(blockData))
|
||||||
}
|
}
|
||||||
|
|
||||||
blockOffset, blockLen := b.CiphertextRange()
|
blockOffset, blockLen := b.CiphertextRange()
|
||||||
blockData = f.cfs.EncryptBlock(blockData, b.BlockNo, f.header.Id)
|
blockData = f.cfs.EncryptBlock(blockData, b.BlockNo, f.header.Id)
|
||||||
cryptfs.Debug.Printf("ino%d: Writing %d bytes to block #%d, md5=%s\n",
|
cryptfs.Debug.Printf("ino%d: Writing %d bytes to block #%d",
|
||||||
f.ino, uint64(len(blockData))-f.cfs.BlockOverhead(), b.BlockNo, cryptfs.Debug.Md5sum(blockData))
|
f.ino, uint64(len(blockData))-f.cfs.BlockOverhead(), b.BlockNo)
|
||||||
|
|
||||||
// Prevent partially written (=corrupt) blocks by preallocating the space beforehand
|
// Prevent partially written (=corrupt) blocks by preallocating the space beforehand
|
||||||
f.fdLock.Lock()
|
f.fdLock.Lock()
|
||||||
err := prealloc(int(f.fd.Fd()), int64(blockOffset), int64(blockLen))
|
err := prealloc(int(f.fd.Fd()), int64(blockOffset), int64(blockLen))
|
||||||
f.fdLock.Unlock()
|
f.fdLock.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("doWrite: fallocateRetry failed: %s\n", err.Error())
|
cryptfs.Warn.Printf("doWrite: fallocateRetry failed: %s", err.Error())
|
||||||
status = fuse.ToStatus(err)
|
status = fuse.ToStatus(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -272,7 +272,7 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
|
|||||||
_, err = f.fd.WriteAt(blockData, int64(blockOffset))
|
_, err = f.fd.WriteAt(blockData, int64(blockOffset))
|
||||||
f.fdLock.Unlock()
|
f.fdLock.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("doWrite: Write failed: %s\n", err.Error())
|
cryptfs.Warn.Printf("doWrite: Write failed: %s", err.Error())
|
||||||
status = fuse.ToStatus(err)
|
status = fuse.ToStatus(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -283,18 +283,18 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
|
|||||||
|
|
||||||
// Write - FUSE call
|
// Write - FUSE call
|
||||||
func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
|
func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
|
||||||
cryptfs.Debug.Printf("ino%d: FUSE Write: offset=%d length=%d\n", f.ino, off, len(data))
|
cryptfs.Debug.Printf("ino%d: FUSE Write: offset=%d length=%d", f.ino, off, len(data))
|
||||||
|
|
||||||
fi, err := f.fd.Stat()
|
fi, err := f.fd.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Write: Fstat failed: %v\n", err)
|
cryptfs.Warn.Printf("Write: Fstat failed: %v", err)
|
||||||
return 0, fuse.ToStatus(err)
|
return 0, fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
plainSize := f.cfs.CipherSizeToPlainSize(uint64(fi.Size()))
|
plainSize := f.cfs.CipherSizeToPlainSize(uint64(fi.Size()))
|
||||||
if f.createsHole(plainSize, off) {
|
if f.createsHole(plainSize, off) {
|
||||||
status := f.zeroPad(plainSize)
|
status := f.zeroPad(plainSize)
|
||||||
if status != fuse.OK {
|
if status != fuse.OK {
|
||||||
cryptfs.Warn.Printf("zeroPad returned error %v\n", status)
|
cryptfs.Warn.Printf("zeroPad returned error %v", status)
|
||||||
return 0, status
|
return 0, status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,14 +352,14 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
|
|||||||
// the file
|
// the file
|
||||||
fi, err := f.fd.Stat()
|
fi, err := f.fd.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Truncate: Fstat failed: %v\n", err)
|
cryptfs.Warn.Printf("Truncate: Fstat failed: %v", err)
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
oldSize := f.cfs.CipherSizeToPlainSize(uint64(fi.Size()))
|
oldSize := f.cfs.CipherSizeToPlainSize(uint64(fi.Size()))
|
||||||
{
|
{
|
||||||
oldB := float32(oldSize) / float32(f.cfs.PlainBS())
|
oldB := float32(oldSize) / float32(f.cfs.PlainBS())
|
||||||
newB := float32(newSize) / float32(f.cfs.PlainBS())
|
newB := float32(newSize) / float32(f.cfs.PlainBS())
|
||||||
cryptfs.Debug.Printf("ino%d: FUSE Truncate from %.2f to %.2f blocks (%d to %d bytes)\n", f.ino, oldB, newB, oldSize, newSize)
|
cryptfs.Debug.Printf("ino%d: FUSE Truncate from %.2f to %.2f blocks (%d to %d bytes)", f.ino, oldB, newB, oldSize, newSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// File grows
|
// File grows
|
||||||
@ -444,7 +444,7 @@ func (f *file) Chown(uid uint32, gid uint32) fuse.Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *file) GetAttr(a *fuse.Attr) fuse.Status {
|
func (f *file) GetAttr(a *fuse.Attr) fuse.Status {
|
||||||
cryptfs.Debug.Printf("file.GetAttr()\n")
|
cryptfs.Debug.Printf("file.GetAttr()")
|
||||||
st := syscall.Stat_t{}
|
st := syscall.Stat_t{}
|
||||||
f.fdLock.Lock()
|
f.fdLock.Lock()
|
||||||
err := syscall.Fstat(int(f.fd.Fd()), &st)
|
err := syscall.Fstat(int(f.fd.Fd()), &st)
|
||||||
@ -460,7 +460,7 @@ func (f *file) GetAttr(a *fuse.Attr) fuse.Status {
|
|||||||
|
|
||||||
// Allocate - FUSE call, fallocate(2)
|
// Allocate - FUSE call, fallocate(2)
|
||||||
func (f *file) Allocate(off uint64, sz uint64, mode uint32) fuse.Status {
|
func (f *file) Allocate(off uint64, sz uint64, mode uint32) fuse.Status {
|
||||||
cryptfs.Warn.Printf("Fallocate is not supported, returning ENOSYS - see https://github.com/rfjakob/gocryptfs/issues/1\n")
|
cryptfs.Warn.Printf("Fallocate is not supported, returning ENOSYS - see https://github.com/rfjakob/gocryptfs/issues/1")
|
||||||
return fuse.ENOSYS
|
return fuse.ENOSYS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +43,12 @@ func (fs *FS) getBackingPath(relPath string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
cAbsPath := filepath.Join(fs.args.Cipherdir, cPath)
|
cAbsPath := filepath.Join(fs.args.Cipherdir, cPath)
|
||||||
cryptfs.Debug.Printf("getBackingPath: %s + %s -> %s\n", fs.args.Cipherdir, relPath, cAbsPath)
|
cryptfs.Debug.Printf("getBackingPath: %s + %s -> %s", fs.args.Cipherdir, relPath, cAbsPath)
|
||||||
return cAbsPath, nil
|
return cAbsPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
|
func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
|
||||||
cryptfs.Debug.Printf("FS.GetAttr('%s')\n", name)
|
cryptfs.Debug.Printf("FS.GetAttr('%s')", name)
|
||||||
if fs.isFiltered(name) {
|
if fs.isFiltered(name) {
|
||||||
return nil, fuse.EPERM
|
return nil, fuse.EPERM
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Stat
|
|||||||
}
|
}
|
||||||
a, status := fs.FileSystem.GetAttr(cName, context)
|
a, status := fs.FileSystem.GetAttr(cName, context)
|
||||||
if a == nil {
|
if a == nil {
|
||||||
cryptfs.Debug.Printf("FS.GetAttr failed: %s\n", status.String())
|
cryptfs.Debug.Printf("FS.GetAttr failed: %s", status.String())
|
||||||
return a, status
|
return a, status
|
||||||
}
|
}
|
||||||
if a.IsRegular() {
|
if a.IsRegular() {
|
||||||
@ -71,7 +71,7 @@ func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
|
func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
|
||||||
cryptfs.Debug.Printf("OpenDir(%s)\n", dirName)
|
cryptfs.Debug.Printf("OpenDir(%s)", dirName)
|
||||||
cDirName, err := fs.encryptPath(dirName)
|
cDirName, err := fs.encryptPath(dirName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
@ -107,7 +107,7 @@ func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, f
|
|||||||
if !fs.args.PlaintextNames {
|
if !fs.args.PlaintextNames {
|
||||||
name, err = fs.CryptFS.DecryptName(cName, cachedIV, fs.args.EMENames)
|
name, err = fs.CryptFS.DecryptName(cName, cachedIV, fs.args.EMENames)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Invalid name \"%s\" in dir \"%s\": %s\n", cName, dirName, err)
|
cryptfs.Warn.Printf("Invalid name \"%s\" in dir \"%s\": %s", cName, dirName, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,10 +137,10 @@ func (fs *FS) Open(path string, flags uint32, context *fuse.Context) (fuseFile n
|
|||||||
iflags, writeOnly := fs.mangleOpenFlags(flags)
|
iflags, writeOnly := fs.mangleOpenFlags(flags)
|
||||||
cPath, err := fs.getBackingPath(path)
|
cPath, err := fs.getBackingPath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Debug.Printf("Open: getBackingPath: %v\n", err)
|
cryptfs.Debug.Printf("Open: getBackingPath: %v", err)
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
cryptfs.Debug.Printf("Open: %s\n", cPath)
|
cryptfs.Debug.Printf("Open: %s", cPath)
|
||||||
f, err := os.OpenFile(cPath, iflags, 0666)
|
f, err := os.OpenFile(cPath, iflags, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
@ -199,7 +199,7 @@ func (fs *FS) Mknod(path string, mode uint32, dev uint32, context *fuse.Context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FS) Truncate(path string, offset uint64, context *fuse.Context) (code fuse.Status) {
|
func (fs *FS) Truncate(path string, offset uint64, context *fuse.Context) (code fuse.Status) {
|
||||||
cryptfs.Warn.Printf("Truncate of a closed file is not supported, returning ENOSYS\n")
|
cryptfs.Warn.Printf("Truncate of a closed file is not supported, returning ENOSYS")
|
||||||
return fuse.ENOSYS
|
return fuse.ENOSYS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,12 +235,12 @@ func (fs *FS) Readlink(path string, context *fuse.Context) (out string, status f
|
|||||||
// Since gocryptfs v0.5 symlinks are encrypted like file contents (GCM)
|
// Since gocryptfs v0.5 symlinks are encrypted like file contents (GCM)
|
||||||
cBinTarget, err := base64.URLEncoding.DecodeString(cTarget)
|
cBinTarget, err := base64.URLEncoding.DecodeString(cTarget)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Readlink: %v\n", err)
|
cryptfs.Warn.Printf("Readlink: %v", err)
|
||||||
return "", fuse.EIO
|
return "", fuse.EIO
|
||||||
}
|
}
|
||||||
target, err := fs.CryptFS.DecryptBlock([]byte(cBinTarget), 0, nil)
|
target, err := fs.CryptFS.DecryptBlock([]byte(cBinTarget), 0, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Readlink: %v\n", err)
|
cryptfs.Warn.Printf("Readlink: %v", err)
|
||||||
return "", fuse.EIO
|
return "", fuse.EIO
|
||||||
}
|
}
|
||||||
return string(target), fuse.OK
|
return string(target), fuse.OK
|
||||||
@ -258,7 +258,7 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (code fuse.Status) {
|
func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (code fuse.Status) {
|
||||||
cryptfs.Debug.Printf("Symlink(\"%s\", \"%s\")\n", target, linkName)
|
cryptfs.Debug.Printf("Symlink(\"%s\", \"%s\")", target, linkName)
|
||||||
if fs.isFiltered(linkName) {
|
if fs.isFiltered(linkName) {
|
||||||
return fuse.EPERM
|
return fuse.EPERM
|
||||||
}
|
}
|
||||||
@ -270,7 +270,7 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
|
|||||||
if !fs.args.DirIV {
|
if !fs.args.DirIV {
|
||||||
cTarget, err := fs.encryptPath(target)
|
cTarget, err := fs.encryptPath(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Symlink: BUG: we should not get an error here: %v\n", err)
|
cryptfs.Warn.Printf("Symlink: BUG: we should not get an error here: %v", err)
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
err = os.Symlink(cTarget, cPath)
|
err = os.Symlink(cTarget, cPath)
|
||||||
@ -281,7 +281,7 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
|
|||||||
cTarget := base64.URLEncoding.EncodeToString(cBinTarget)
|
cTarget := base64.URLEncoding.EncodeToString(cBinTarget)
|
||||||
|
|
||||||
err = os.Symlink(cTarget, cPath)
|
err = os.Symlink(cTarget, cPath)
|
||||||
cryptfs.Debug.Printf("Symlink: os.Symlink(%s, %s) = %v\n", cTarget, cPath, err)
|
cryptfs.Debug.Printf("Symlink: os.Symlink(%s, %s) = %v", cTarget, cPath, err)
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +307,7 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod
|
|||||||
// If an empty directory is overwritten we will always get
|
// If an empty directory is overwritten we will always get
|
||||||
// ENOTEMPTY as the "empty" directory will still contain gocryptfs.diriv.
|
// ENOTEMPTY as the "empty" directory will still contain gocryptfs.diriv.
|
||||||
// Handle that case by removing the target directory and trying again.
|
// Handle that case by removing the target directory and trying again.
|
||||||
cryptfs.Debug.Printf("Rename: Handling ENOTEMPTY\n")
|
cryptfs.Debug.Printf("Rename: Handling ENOTEMPTY")
|
||||||
if fs.Rmdir(newPath, context) == fuse.OK {
|
if fs.Rmdir(newPath, context) == fuse.OK {
|
||||||
err = os.Rename(cOldPath, cNewPath)
|
err = os.Rename(cOldPath, cNewPath)
|
||||||
}
|
}
|
||||||
|
@ -41,10 +41,10 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu
|
|||||||
err = cryptfs.WriteDirIV(encPath)
|
err = cryptfs.WriteDirIV(encPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This should not happen
|
// This should not happen
|
||||||
cryptfs.Warn.Printf("Mkdir: WriteDirIV failed: %v\n", err)
|
cryptfs.Warn.Printf("Mkdir: WriteDirIV failed: %v", err)
|
||||||
err2 := syscall.Rmdir(encPath)
|
err2 := syscall.Rmdir(encPath)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
cryptfs.Warn.Printf("Mkdir: Rmdir rollback failed: %v\n", err2)
|
cryptfs.Warn.Printf("Mkdir: Rmdir rollback failed: %v", err2)
|
||||||
}
|
}
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu
|
|||||||
if origMode != mode {
|
if origMode != mode {
|
||||||
err = os.Chmod(encPath, os.FileMode(origMode))
|
err = os.Chmod(encPath, os.FileMode(origMode))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Mkdir: Chmod failed: %v\n", err)
|
cryptfs.Warn.Printf("Mkdir: Chmod failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,17 +74,17 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
|
|||||||
fd, err := os.Open(encPath)
|
fd, err := os.Open(encPath)
|
||||||
if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.EACCES {
|
if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.EACCES {
|
||||||
// We need permission to read and modify the directory
|
// We need permission to read and modify the directory
|
||||||
cryptfs.Debug.Printf("Rmdir: handling EACCESS\n")
|
cryptfs.Debug.Printf("Rmdir: handling EACCESS")
|
||||||
fi, err2 := os.Stat(encPath)
|
fi, err2 := os.Stat(encPath)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
cryptfs.Debug.Printf("Rmdir: Stat: %v\n", err2)
|
cryptfs.Debug.Printf("Rmdir: Stat: %v", err2)
|
||||||
return fuse.ToStatus(err2)
|
return fuse.ToStatus(err2)
|
||||||
}
|
}
|
||||||
origMode := fi.Mode()
|
origMode := fi.Mode()
|
||||||
newMode := origMode | 0700
|
newMode := origMode | 0700
|
||||||
err2 = os.Chmod(encPath, newMode)
|
err2 = os.Chmod(encPath, newMode)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
cryptfs.Debug.Printf("Rmdir: Chmod failed: %v\n", err2)
|
cryptfs.Debug.Printf("Rmdir: Chmod failed: %v", err2)
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -92,7 +92,7 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
|
|||||||
// Undo the chmod if removing the directory failed
|
// Undo the chmod if removing the directory failed
|
||||||
err3 := os.Chmod(encPath, origMode)
|
err3 := os.Chmod(encPath, origMode)
|
||||||
if err3 != nil {
|
if err3 != nil {
|
||||||
cryptfs.Warn.Printf("Rmdir: Chmod rollback failed: %v\n", err2)
|
cryptfs.Warn.Printf("Rmdir: Chmod rollback failed: %v", err2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -100,19 +100,19 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
|
|||||||
fd, err = os.Open(encPath)
|
fd, err = os.Open(encPath)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Debug.Printf("Rmdir: Open: %v\n", err)
|
cryptfs.Debug.Printf("Rmdir: Open: %v", err)
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
list, err := fd.Readdirnames(10)
|
list, err := fd.Readdirnames(10)
|
||||||
fd.Close()
|
fd.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Debug.Printf("Rmdir: Readdirnames: %v\n", err)
|
cryptfs.Debug.Printf("Rmdir: Readdirnames: %v", err)
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
if len(list) > 1 {
|
if len(list) > 1 {
|
||||||
return fuse.ToStatus(syscall.ENOTEMPTY)
|
return fuse.ToStatus(syscall.ENOTEMPTY)
|
||||||
} else if len(list) == 0 {
|
} else if len(list) == 0 {
|
||||||
cryptfs.Warn.Printf("Rmdir: gocryptfs.diriv missing, allowing deletion\n")
|
cryptfs.Warn.Printf("Rmdir: gocryptfs.diriv missing, allowing deletion")
|
||||||
return fuse.ToStatus(syscall.Rmdir(encPath))
|
return fuse.ToStatus(syscall.Rmdir(encPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,14 +121,14 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
|
|||||||
parentDir := filepath.Dir(encPath)
|
parentDir := filepath.Dir(encPath)
|
||||||
tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptfs.RandUint64())
|
tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptfs.RandUint64())
|
||||||
tmpDirivPath := filepath.Join(parentDir, tmpName)
|
tmpDirivPath := filepath.Join(parentDir, tmpName)
|
||||||
cryptfs.Debug.Printf("Rmdir: Renaming %s to %s\n", cryptfs.DIRIV_FILENAME, tmpDirivPath)
|
cryptfs.Debug.Printf("Rmdir: Renaming %s to %s", cryptfs.DIRIV_FILENAME, tmpDirivPath)
|
||||||
// The directory is in an inconsistent state between rename and rmdir. Protect against
|
// The directory is in an inconsistent state between rename and rmdir. Protect against
|
||||||
// concurrent readers.
|
// concurrent readers.
|
||||||
fs.dirIVLock.Lock()
|
fs.dirIVLock.Lock()
|
||||||
defer fs.dirIVLock.Unlock()
|
defer fs.dirIVLock.Unlock()
|
||||||
err = os.Rename(dirivPath, tmpDirivPath)
|
err = os.Rename(dirivPath, tmpDirivPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Rmdir: Renaming %s to %s failed: %v\n", cryptfs.DIRIV_FILENAME, tmpDirivPath, err)
|
cryptfs.Warn.Printf("Rmdir: Renaming %s to %s failed: %v", cryptfs.DIRIV_FILENAME, tmpDirivPath, err)
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Actual Rmdir
|
// Actual Rmdir
|
||||||
@ -138,14 +138,14 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
|
|||||||
// meantime, undo the rename
|
// meantime, undo the rename
|
||||||
err2 := os.Rename(tmpDirivPath, dirivPath)
|
err2 := os.Rename(tmpDirivPath, dirivPath)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
cryptfs.Warn.Printf("Rmdir: Rename rollback failed: %v\n", err2)
|
cryptfs.Warn.Printf("Rmdir: Rename rollback failed: %v", err2)
|
||||||
}
|
}
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Delete "gocryptfs.diriv.rmdir.INODENUMBER"
|
// Delete "gocryptfs.diriv.rmdir.INODENUMBER"
|
||||||
err = syscall.Unlink(tmpDirivPath)
|
err = syscall.Unlink(tmpDirivPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Rmdir: Could not clean up %s: %v\n", tmpName, err)
|
cryptfs.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
|
||||||
}
|
}
|
||||||
// The now-deleted directory may have been in the DirIV cache. Clear it.
|
// The now-deleted directory may have been in the DirIV cache. Clear it.
|
||||||
fs.CryptFS.DirIVCacheEnc.Clear()
|
fs.CryptFS.DirIVCacheEnc.Clear()
|
||||||
|
Loading…
Reference in New Issue
Block a user