main: check directories for existence early

This prevents that the user enters the password only to get an error
later.
This commit is contained in:
Jakob Unterwurzacher 2015-10-11 18:33:28 +02:00
parent a863a6569c
commit d1d444435c
3 changed files with 62 additions and 34 deletions

33
checkdir.go Normal file
View File

@ -0,0 +1,33 @@
package main
import (
"io/ioutil"
"fmt"
"os"
)
func checkDirEmpty(dir string) error {
err := checkDir(dir)
if err != nil {
return err
}
entries, err := ioutil.ReadDir(dir)
if err != nil {
return err
}
if len(entries) == 0 {
return nil
}
return fmt.Errorf("directory %s not empty", dir)
}
func checkDir(dir string) error {
fi, err := os.Stat(dir)
if err != nil {
return err
}
if ! fi.IsDir() {
return fmt.Errorf("%s is not a directory")
}
return nil
}

View File

@ -67,7 +67,8 @@ func LoadConfFile(filename string, password string) ([]byte, *ConfFile, error) {
cfs := NewCryptFS(scryptHash, false) cfs := NewCryptFS(scryptHash, false)
key, err := cfs.DecryptBlock(cf.EncryptedKey, 0) key, err := cfs.DecryptBlock(cf.EncryptedKey, 0)
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\n", err.Error())
Warn.Printf("Password incorrect.\n")
return nil, nil, err return nil, nil, err
} }

60
main.go
View File

@ -3,7 +3,6 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -29,25 +28,26 @@ const (
ERREXIT_NEWFS = 2 ERREXIT_NEWFS = 2
ERREXIT_MOUNT = 3 ERREXIT_MOUNT = 3
ERREXIT_SERVE = 4 ERREXIT_SERVE = 4
ERREXIT_MOUNT2 = 5
ERREXIT_CIPHERDIR = 6 ERREXIT_CIPHERDIR = 6
ERREXIT_INIT = 7 ERREXIT_INIT = 7
ERREXIT_LOADCONF = 8 ERREXIT_LOADCONF = 8
ERREXIT_PASSWORD = 9 ERREXIT_PASSWORD = 9
ERREXIT_MOUNTPOINT = 10
) )
func initDir(dirArg string) { func initDir(dirArg string) {
dir, _ := filepath.Abs(dirArg) dir, _ := filepath.Abs(dirArg)
if dirEmpty(dir) == false { err := checkDirEmpty(dir)
fmt.Printf("Error: Directory \"%s\" is not empty\n", dirArg) if err != nil {
fmt.Printf("Error: \"%s\": %v\n", dirArg, err)
os.Exit(ERREXIT_INIT) os.Exit(ERREXIT_INIT)
} }
confName := filepath.Join(dir, cryptfs.ConfDefaultName) confName := filepath.Join(dir, cryptfs.ConfDefaultName)
fmt.Printf("Choose a password for protecting your files.\n") fmt.Printf("Choose a password for protecting your files.\n")
password := readPasswordTwice() password := readPasswordTwice()
err := cryptfs.CreateConfFile(confName, password) err = cryptfs.CreateConfFile(confName, password)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(ERREXIT_INIT) os.Exit(ERREXIT_INIT)
@ -67,7 +67,7 @@ func main() {
// Parse command line arguments // Parse command line arguments
var debug, init, zerokey, fusedebug, openssl, passwd, foreground bool var debug, init, zerokey, fusedebug, openssl, passwd, foreground bool
var masterkey string var masterkey, mountpoint, cipherdir string
flag.Usage = usageText flag.Usage = usageText
flag.BoolVar(&debug, "debug", false, "Enable debug output") flag.BoolVar(&debug, "debug", false, "Enable debug output")
@ -106,23 +106,30 @@ func main() {
fmt.Printf("Usage: %s --init CIPHERDIR\n", PROGRAM_NAME) fmt.Printf("Usage: %s --init CIPHERDIR\n", PROGRAM_NAME)
os.Exit(ERREXIT_USAGE) os.Exit(ERREXIT_USAGE)
} }
initDir(flag.Arg(0)) initDir(flag.Arg(0)) // does not return
} else if passwd { }
if passwd {
if flag.NArg() != 1 { if flag.NArg() != 1 {
fmt.Printf("Usage: %s --passwd CIPHERDIR\n", PROGRAM_NAME) fmt.Printf("Usage: %s --passwd CIPHERDIR\n", PROGRAM_NAME)
os.Exit(ERREXIT_USAGE) os.Exit(ERREXIT_USAGE)
} }
} else if flag.NArg() < 2 { } else {
usageText() // Normal mount
os.Exit(ERREXIT_USAGE) if flag.NArg() < 2 {
usageText()
os.Exit(ERREXIT_USAGE)
}
mountpoint, _ = filepath.Abs(flag.Arg(1))
err := checkDirEmpty(mountpoint)
if err != nil {
fmt.Printf("Invalid MOUNTPOINT: %v\n", err)
os.Exit(ERREXIT_MOUNTPOINT)
}
} }
cipherdir, _ := filepath.Abs(flag.Arg(0)) cipherdir, _ = filepath.Abs(flag.Arg(0))
mountpoint, _ := filepath.Abs(flag.Arg(1)) err := checkDir(cipherdir)
cryptfs.Debug.Printf("cipherdir=%s\nmountpoint=%s\n", cipherdir, mountpoint)
_, err := os.Stat(cipherdir)
if err != nil { if err != nil {
fmt.Printf("Cipherdir: %s\n", err.Error()) fmt.Printf("Invalid CIPHERDIR: %v\n", err)
os.Exit(ERREXIT_CIPHERDIR) os.Exit(ERREXIT_CIPHERDIR)
} }
@ -139,7 +146,7 @@ func main() {
_, err = os.Stat(cfname) _, err = os.Stat(cfname)
if err != nil { if err != nil {
fmt.Printf("Error: %s not found in CIPHERDIR\n", cryptfs.ConfDefaultName) fmt.Printf("Error: %s not found in CIPHERDIR\n", cryptfs.ConfDefaultName)
fmt.Printf("Please run \"%s --init %s\" first\n", PROGRAM_NAME, flag.Arg(0)) fmt.Printf("Please run \"%s --init %s\" first\n", os.Args[0], flag.Arg(0))
os.Exit(ERREXIT_LOADCONF) os.Exit(ERREXIT_LOADCONF)
} }
if passwd == true { if passwd == true {
@ -154,7 +161,6 @@ func main() {
cryptfs.Warn.Enable() cryptfs.Warn.Enable()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
fmt.Println("Password incorrect.")
os.Exit(ERREXIT_LOADCONF) os.Exit(ERREXIT_LOADCONF)
} }
fmt.Printf("done.\n") fmt.Printf("done.\n")
@ -164,7 +170,7 @@ func main() {
newPassword := readPasswordTwice() newPassword := readPasswordTwice()
if newPassword == currentPassword { if newPassword == currentPassword {
fmt.Printf("New and old passwords are identical\n") fmt.Printf("New and old passwords are identical\n")
os.Exit(1) os.Exit(ERREXIT_PASSWORD)
} }
cf.EncryptKey(key, newPassword) cf.EncryptKey(key, newPassword)
err := cf.WriteFile() err := cf.WriteFile()
@ -193,18 +199,6 @@ func main() {
srv.Serve() srv.Serve()
} }
func dirEmpty(dir string) bool {
entries, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Println(err)
os.Exit(ERREXIT_CIPHERDIR)
}
if len(entries) == 0 {
return true
}
return false
}
func pathfsFrontend(key []byte, cipherdir string, mountpoint string, debug bool, openssl bool) *fuse.Server { func pathfsFrontend(key []byte, cipherdir string, mountpoint string, debug bool, openssl bool) *fuse.Server {
finalFs := pathfs_frontend.NewFS(key, cipherdir, openssl) finalFs := pathfs_frontend.NewFS(key, cipherdir, openssl)
@ -229,7 +223,7 @@ func pathfsFrontend(key []byte, cipherdir string, mountpoint string, debug bool,
srv, err := fuse.NewServer(conn.RawFS(), mountpoint, &mOpts) srv, err := fuse.NewServer(conn.RawFS(), mountpoint, &mOpts)
if err != nil { if err != nil {
fmt.Printf("Mount failed: %v", err) fmt.Printf("Mount failed: %v", err)
os.Exit(1) os.Exit(ERREXIT_MOUNT)
} }
srv.SetDebug(debug) srv.SetDebug(debug)